Package entropy :: Module tools

Source Code for Module entropy.tools

   1  # -*- coding: utf-8 -*- 
   2  # Entropy miscellaneous tools module 
   3  from __future__ import with_statement 
   4  """ 
   5   
   6      @author: Fabio Erculiani <lxnay@sabayonlinux.org> 
   7      @contact: lxnay@sabayonlinux.org 
   8      @copyright: Fabio Erculiani 
   9      @license: GPL-2 
  10   
  11      B{Entropy miscellaneous tools module}. 
  12      In this module are enclosed all the miscellaneous functions 
  13      used arount the Entropy codebase. 
  14   
  15  """ 
  16   
  17  import stat 
  18  import errno 
  19  import re 
  20  import sys 
  21  import os 
  22  import time 
  23  import shutil 
  24  import tarfile 
  25  import subprocess 
  26  import grp 
  27  import pwd 
  28  import hashlib 
  29  import random 
  30  from entropy.output import TextInterface, print_info, red, darkgreen, green 
  31  from entropy.const import etpConst, const_kill_threads, const_islive 
  32  from entropy.exceptions import FileNotFound, InvalidAtom, InvalidDataType, \ 
  33      DirectoryNotFound 
  34   
35 -def is_root():
36 """ 37 Return whether running process has root priviledges. 38 39 @return: root priviledges 40 @rtype: bool 41 """ 42 return not etpConst['uid']
43
44 -def is_user_in_entropy_group(uid = None):
45 """ 46 docstring_title 47 48 @keyword uid: 49 @type uid: 50 @return: 51 @rtype: 52 """ 53 54 if uid == None: 55 uid = os.getuid() 56 if uid == 0: 57 return True 58 59 try: 60 username = pwd.getpwuid(uid)[0] 61 except KeyError: 62 return False 63 64 try: 65 data = grp.getgrnam(etpConst['sysgroup']) 66 except KeyError: 67 return False 68 69 etp_group_users = data[3] 70 71 if not etp_group_users or \ 72 username not in etp_group_users: 73 return False 74 75 return True
76
77 -def get_uid_from_user(username):
78 """ 79 docstring_title 80 81 @param username: 82 @type username: 83 @return: 84 @rtype: 85 """ 86 try: 87 return pwd.getpwnam(username)[2] 88 except (KeyError, IndexError,): 89 return -1
90
91 -def get_gid_from_group(groupname):
92 """ 93 docstring_title 94 95 @param groupname: 96 @type groupname: 97 @return: 98 @rtype: 99 """ 100 try: 101 return grp.getgrnam(groupname)[2] 102 except (KeyError, IndexError,): 103 return -1
104
105 -def get_user_from_uid(uid):
106 """ 107 docstring_title 108 109 @param uid: 110 @type uid: 111 @return: 112 @rtype: 113 """ 114 try: 115 return pwd.getpwuid(uid)[0] 116 except KeyError: 117 return None
118
119 -def get_group_from_gid(gid):
120 """ 121 docstring_title 122 123 @param gid: 124 @type gid: 125 @return: 126 @rtype: 127 """ 128 try: 129 return grp.getgrgid(gid)[0] 130 except (KeyError, IndexError,): 131 return -1
132
133 -def kill_threads():
134 """ 135 docstring_title 136 137 @return: 138 @rtype: 139 """ 140 const_kill_threads()
141 153
154 -def get_traceback():
155 """ 156 docstring_title 157 158 @return: 159 @rtype: 160 """ 161 import traceback 162 from cStringIO import StringIO 163 buf = StringIO() 164 traceback.print_exc(file = buf) 165 return buf.getvalue()
166 211 212 # Get the content of an online page 213 # @returns content: if the file exists 214 # @returns False: if the file is not found
215 -def get_remote_data(url, timeout = 5):
216 """ 217 docstring_title 218 219 @param url: 220 @type url: 221 @keyword timeout: 222 @type timeout: 223 @return: 224 @rtype: 225 """ 226 227 import socket 228 import urllib2 229 # now pray the server 230 from entropy.core.settings.base import SystemSettings 231 sys_settings = SystemSettings() 232 proxy_settings = sys_settings['system']['proxy'] 233 try: 234 mydict = {} 235 if proxy_settings['ftp']: 236 mydict['ftp'] = proxy_settings['ftp'] 237 if proxy_settings['http']: 238 mydict['http'] = proxy_settings['http'] 239 if mydict: 240 mydict['username'] = proxy_settings['username'] 241 mydict['password'] = proxy_settings['password'] 242 add_proxy_opener(urllib2, mydict) 243 else: 244 # unset 245 urllib2._opener = None 246 try: 247 item = urllib2.urlopen(url, timeout = timeout) 248 except TypeError: # Python 2.5 support 249 socket.setdefaulttimeout(timeout) 250 item = urllib2.urlopen(url) 251 result = item.readlines() 252 item.close() 253 del item 254 if (not result): 255 socket.setdefaulttimeout(2) 256 return False 257 socket.setdefaulttimeout(2) 258 return result 259 except: 260 socket.setdefaulttimeout(2) 261 return False
262
263 -def is_png_file(path):
264 """ 265 docstring_title 266 267 @param path: 268 @type path: 269 @return: 270 @rtype: 271 """ 272 f = open(path, "r") 273 x = f.read(4) 274 if x == '\x89PNG': 275 return True 276 return False
277
278 -def is_jpeg_file(path):
279 """ 280 docstring_title 281 282 @param path: 283 @type path: 284 @return: 285 @rtype: 286 """ 287 f = open(path, "r") 288 x = f.read(10) 289 if x == '\xff\xd8\xff\xe0\x00\x10JFIF': 290 return True 291 return False
292
293 -def is_bmp_file(path):
294 """ 295 docstring_title 296 297 @param path: 298 @type path: 299 @return: 300 @rtype: 301 """ 302 f = open(path, "r") 303 x = f.read(2) 304 if x == 'BM': 305 return True 306 return False
307
308 -def is_gif_file(path):
309 """ 310 docstring_title 311 312 @param path: 313 @type path: 314 @return: 315 @rtype: 316 """ 317 f = open(path, "r") 318 x = f.read(5) 319 if x == 'GIF89': 320 return True 321 return False
322
323 -def is_supported_image_file(path):
324 """ 325 docstring_title 326 327 @param path: 328 @type path: 329 @return: 330 @rtype: 331 """ 332 calls = [is_png_file, is_jpeg_file, is_bmp_file, is_gif_file] 333 for mycall in calls: 334 if mycall(path): 335 return True 336 return False
337
338 -def is_april_first():
339 """ 340 docstring_title 341 342 @return: 343 @rtype: 344 """ 345 april_first = "01-04" 346 cur_time = time.strftime("%d-%m") 347 if april_first == cur_time: 348 return True 349 return False
350
351 -def add_proxy_opener(module, data):
352 """ 353 docstring_title 354 355 @param module: 356 @type module: 357 @param data: 358 @type data: 359 @return: 360 @rtype: 361 """ 362 import types 363 if type(module) != types.ModuleType: # FIXME: check if it's urllib2 364 InvalidDataType("InvalidDataType: not a module") 365 if not data: 366 return 367 368 username = None 369 password = None 370 authinfo = None 371 if data.has_key('password'): 372 username = data.pop('username') 373 if data.has_key('password'): 374 username = data.pop('password') 375 if username == None or password == None: 376 username = None 377 password = None 378 else: 379 passmgr = module.HTTPPasswordMgrWithDefaultRealm() 380 if data['http']: 381 passmgr.add_password(None, data['http'], username, password) 382 if data['ftp']: 383 passmgr.add_password(None, data['ftp'], username, password) 384 authinfo = module.ProxyBasicAuthHandler(passmgr) 385 386 proxy_support = module.ProxyHandler(data) 387 if authinfo: 388 opener = module.build_opener(proxy_support, authinfo) 389 else: 390 opener = module.build_opener(proxy_support) 391 module.install_opener(opener)
392
393 -def is_valid_ascii(string):
394 """ 395 docstring_title 396 397 @param string: 398 @type string: 399 @return: 400 @rtype: 401 """ 402 try: 403 mystring = str(string) 404 del mystring 405 except: 406 return False 407 return True
408
409 -def is_valid_unicode(string):
410 """ 411 docstring_title 412 413 @param string: 414 @type string: 415 @return: 416 @rtype: 417 """ 418 try: 419 unicode(string) 420 except: 421 return False 422 return True
423
424 -def is_valid_email(email):
425 """ 426 docstring_title 427 428 @param email: 429 @type email: 430 @return: 431 @rtype: 432 """ 433 monster = "(?:[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:.[a-z0-9!#$%" + \ 434 "&'*+/=?^_{|}~-]+)*|\"(?:" + \ 435 "[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]" + \ 436 "|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9]" + \ 437 "(?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" + \ 438 "|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)" + \ 439 "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?" + \ 440 "|[a-z0-9-]*[a-z0-9]:(?:" + \ 441 "[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]" + \ 442 "|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])" 443 evil = re.compile(monster) 444 if evil.match(email): 445 return True 446 return False
447
448 -def islive():
449 """ 450 docstring_title 451 452 @return: 453 @rtype: 454 """ 455 return const_islive()
456
457 -def get_file_size(file_path):
458 """ 459 docstring_title 460 461 @param file_path: 462 @type file_path: 463 @return: 464 @rtype: 465 """ 466 my = file_path[:] 467 if isinstance(my, unicode): 468 my = my.encode("utf-8") 469 mystat = os.lstat(my) 470 return int(mystat.st_size)
471
472 -def sum_file_sizes(file_list):
473 """ 474 docstring_title 475 476 @param file_list: 477 @type file_list: 478 @return: 479 @rtype: 480 """ 481 size = 0 482 for myfile in file_list: 483 try: 484 size += get_file_size(myfile) 485 except (OSError, IOError,): 486 continue 487 return size
488
489 -def check_required_space(mountpoint, bytes_required):
490 """ 491 docstring_title 492 493 @param mountpoint: 494 @type mountpoint: 495 @param bytes_required: 496 @type bytes_required: 497 @return: 498 @rtype: 499 """ 500 import statvfs 501 st = os.statvfs(mountpoint) 502 freeblocks = st[statvfs.F_BFREE] 503 blocksize = st[statvfs.F_BSIZE] 504 freespace = freeblocks*blocksize 505 if bytes_required > freespace: 506 # it's NOT fine 507 return False 508 return True
509
510 -def getstatusoutput(cmd):
511 """Return (status, output) of executing cmd in a shell.""" 512 pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') 513 text = pipe.read() 514 sts = pipe.close() 515 if sts is None: sts = 0 516 if text[-1:] == '\n': 517 text = text[:-1] 518 return sts, text
519 520 # Copyright 1998-2004 Gentoo Foundation 521 # Copyright 2009 Fabio Erculiani (reducing code complexity) 522 # Distributed under the terms of the GNU General Public License v2 523 # $Id: __init__.py 12159 2008-12-05 00:08:58Z zmedico $ 524 # atomic file move function
525 -def movefile(src, dest, src_basedir = None):
526 """ 527 docstring_title 528 529 @param src: 530 @type src: 531 @param dest: 532 @type dest: 533 @keyword src_basedir: 534 @type src_basedir: 535 @return: 536 @rtype: 537 """ 538 539 sstat = os.lstat(src) 540 destexists = 1 541 try: 542 dstat = os.lstat(dest) 543 except (OSError, IOError,): 544 dstat = os.lstat(os.path.dirname(dest)) 545 destexists = 0 546 547 if destexists: 548 if stat.S_ISLNK(dstat[stat.ST_MODE]): 549 try: 550 os.unlink(dest) 551 destexists = 0 552 except (OSError, IOError,): 553 pass 554 555 if stat.S_ISLNK(sstat[stat.ST_MODE]): 556 try: 557 target = os.readlink(src) 558 if src_basedir != None: 559 if target.find(src_basedir) == 0: 560 target = target[len(src_basedir):] 561 if destexists and not stat.S_ISDIR(dstat[stat.ST_MODE]): 562 os.unlink(dest) 563 os.symlink(target, dest) 564 os.lchown(dest, sstat[stat.ST_UID], sstat[stat.ST_GID]) 565 return True 566 except SystemExit: 567 raise 568 except Exception, e: 569 print "!!! failed to properly create symlink:" 570 print "!!!", dest, "->", target 571 print "!!!", e 572 return False 573 574 renamefailed = True 575 if sstat.st_dev == dstat.st_dev: 576 try: 577 os.rename(src, dest) 578 renamefailed = False 579 except Exception, e: 580 if e[0] != errno.EXDEV: 581 # Some random error. 582 print "!!! Failed to move", src, "to", dest 583 print "!!!", e 584 return False 585 # Invalid cross-device-link 'bind' mounted or actually Cross-Device 586 587 if renamefailed: 588 didcopy = True 589 if stat.S_ISREG(sstat[stat.ST_MODE]): 590 try: # For safety copy then move it over. 591 while 1: 592 tmp_dest = "%s#entropy_new_%s" % (dest, get_random_number(),) 593 if not os.path.lexists(tmp_dest): 594 break 595 shutil.copyfile(src, tmp_dest) 596 os.rename(tmp_dest, dest) 597 didcopy = True 598 except SystemExit, e: 599 raise 600 except Exception, e: 601 print '!!! copy', src, '->', dest, 'failed.' 602 print "!!!", e 603 return False 604 else: 605 #we don't yet handle special, so we need to fall back to /bin/mv 606 a = getstatusoutput("mv -f '%s' '%s'" % (src, dest,)) 607 if a[0] != 0: 608 print "!!! Failed to move special file:" 609 print "!!! '" + src + "' to '" + dest + "'" 610 print "!!!", a 611 return False 612 try: 613 if didcopy: 614 if stat.S_ISLNK(sstat[stat.ST_MODE]): 615 os.lchown(dest, sstat[stat.ST_UID], sstat[stat.ST_GID]) 616 else: 617 os.chown(dest, sstat[stat.ST_UID], sstat[stat.ST_GID]) 618 os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown 619 os.unlink(src) 620 except SystemExit, e: 621 raise 622 except Exception, e: 623 print "!!! Failed to chown/chmod/unlink in movefile()" 624 print "!!!", dest 625 print "!!!", e 626 return False 627 628 try: 629 os.utime(dest, (sstat.st_atime, sstat.st_mtime)) 630 except OSError: 631 # The utime can fail here with EPERM even though the move succeeded. 632 # Instead of failing, use stat to return the mtime if possible. 633 try: 634 long(os.stat(dest).st_mtime) 635 return True 636 except OSError, e: 637 print "!!! Failed to stat in movefile()\n" 638 print "!!! %s\n" % dest 639 print "!!! %s\n" % str(e) 640 return False 641 642 return True
643
644 -def ebeep(count = 5):
645 """ 646 docstring_title 647 648 @keyword count: 649 @type count: 650 @return: 651 @rtype: 652 """ 653 mycount = count 654 while mycount > 0: 655 os.system("sleep 0.35; echo -ne \"\a\"; sleep 0.35") 656 mycount -= 1
657
658 -def application_lock_check(gentle = False):
659 """ 660 docstring_title 661 662 @keyword gentle: 663 @type gentle: 664 @return: 665 @rtype: 666 """ 667 if etpConst['applicationlock']: 668 if not gentle: 669 SystemExit(10) 670 return True 671 return False
672
673 -def get_random_number():
674 """ 675 docstring_title 676 677 @return: 678 @rtype: 679 """ 680 try: 681 return abs(hash(os.urandom(2)))%99999 682 except NotImplementedError: 683 random.seed() 684 return random.randint(10000, 99999)
685
686 -def split_indexable_into_chunks(mystr, chunk_len):
687 """ 688 docstring_title 689 690 @param mystr: 691 @type mystr: 692 @param chunk_len: 693 @type chunk_len: 694 @return: 695 @rtype: 696 """ 697 chunks = [] 698 my = mystr[:] 699 mylen = len(my) 700 while mylen: 701 chunk = my[:chunk_len] 702 chunks.append(chunk) 703 my_chunk_len = len(chunk) 704 my = my[my_chunk_len:] 705 mylen -= my_chunk_len 706 return chunks
707
708 -def countdown(secs = 5, what = "Counting...", back = False):
709 """ 710 docstring_title 711 712 @keyword secs: 713 @type secs: 714 @keyword what: 715 @type what: 716 @keyword back: 717 @type back: 718 @return: 719 @rtype: 720 """ 721 if secs: 722 if back: 723 try: 724 print red(">>"), what, 725 except UnicodeEncodeError: 726 print red(">>"), what.encode('utf-8'), 727 else: 728 try: 729 print what 730 except UnicodeEncodeError: 731 print what.encode('utf-8') 732 for i in range(secs)[::-1]: 733 sys.stdout.write(red(str(i+1)+" ")) 734 sys.stdout.flush() 735 time.sleep(1)
736
737 -def md5sum(filepath):
738 """ 739 docstring_title 740 741 @param filepath: 742 @type filepath: 743 @return: 744 @rtype: 745 """ 746 m = hashlib.md5() 747 readfile = open(filepath) 748 block = readfile.read(1024) 749 while block: 750 m.update(block) 751 block = readfile.read(1024) 752 readfile.close() 753 return m.hexdigest()
754
755 -def sha512(filepath):
756 """ 757 docstring_title 758 759 @param filepath: 760 @type filepath: 761 @return: 762 @rtype: 763 """ 764 m = hashlib.sha512() 765 readfile = open(filepath) 766 block = readfile.read(1024) 767 while block: 768 m.update(block) 769 block = readfile.read(1024) 770 readfile.close() 771 return m.hexdigest()
772
773 -def sha256(filepath):
774 """ 775 docstring_title 776 777 @param filepath: 778 @type filepath: 779 @return: 780 @rtype: 781 """ 782 m = hashlib.sha256() 783 readfile = open(filepath) 784 block = readfile.read(1024) 785 while block: 786 m.update(block) 787 block = readfile.read(1024) 788 readfile.close() 789 return m.hexdigest()
790
791 -def sha1(filepath):
792 """ 793 docstring_title 794 795 @param filepath: 796 @type filepath: 797 @return: 798 @rtype: 799 """ 800 m = hashlib.sha1() 801 readfile = open(filepath) 802 block = readfile.read(1024) 803 while block: 804 m.update(block) 805 block = readfile.read(1024) 806 readfile.close() 807 return m.hexdigest()
808
809 -def md5sum_directory(directory):
810 """ 811 docstring_title 812 813 @param directory: 814 @type directory: 815 @return: 816 @rtype: 817 """ 818 if not os.path.isdir(directory): 819 DirectoryNotFound("DirectoryNotFound: directory just does not exist.") 820 myfiles = os.listdir(directory) 821 m = hashlib.md5() 822 if not myfiles: 823 return "0" # no files means 0 824 825 for currentdir, subdirs, files in os.walk(directory): 826 for myfile in files: 827 myfile = os.path.join(currentdir, myfile) 828 readfile = open(myfile) 829 block = readfile.read(1024) 830 while block: 831 m.update(block) 832 block = readfile.read(1024) 833 readfile.close() 834 return m.hexdigest()
835
836 -def md5obj_directory(directory):
837 """ 838 docstring_title 839 840 @param directory: 841 @type directory: 842 @return: 843 @rtype: 844 """ 845 if not os.path.isdir(directory): 846 DirectoryNotFound("DirectoryNotFound: directory just does not exist.") 847 myfiles = os.listdir(directory) 848 m = hashlib.md5() 849 if not myfiles: 850 return m 851 852 for currentdir, subdirs, files in os.walk(directory): 853 for myfile in files: 854 myfile = os.path.join(currentdir, myfile) 855 readfile = open(myfile) 856 block = readfile.read(1024) 857 while block: 858 m.update(block) 859 block = readfile.read(1024) 860 readfile.close() 861 return m
862 863 # kindly stolen from Anaconda 864 # Copyright 1999-2008 Red Hat, Inc. <iutil.py>
865 -def getfd(filespec, readOnly = 0):
866 """ 867 docstring_title 868 869 @param filespec: 870 @type filespec: 871 @keyword readOnly: 872 @type readOnly: 873 @return: 874 @rtype: 875 """ 876 import types 877 if type(filespec) == types.IntType: 878 return filespec 879 if filespec == None: 880 filespec = "/dev/null" 881 882 flags = os.O_RDWR | os.O_CREAT 883 if (readOnly): 884 flags = os.O_RDONLY 885 return os.open(filespec, flags)
886
887 -def uncompress_file(file_path, destination_path, opener):
888 """ 889 docstring_title 890 891 @param file_path: 892 @type file_path: 893 @param destination_path: 894 @type destination_path: 895 @param opener: 896 @type opener: 897 @return: 898 @rtype: 899 """ 900 f_out = open(destination_path, "wb") 901 f_in = opener(file_path, "rb") 902 data = f_in.read(8192) 903 while data: 904 f_out.write(data) 905 data = f_in.read(8192) 906 f_out.flush() 907 f_out.close() 908 f_in.close()
909
910 -def compress_file(file_path, destination_path, opener, compress_level = None):
911 """ 912 docstring_title 913 914 @param file_path: 915 @type file_path: 916 @param destination_path: 917 @type destination_path: 918 @param opener: 919 @type opener: 920 @keyword compress_level: 921 @type compress_level: 922 @return: 923 @rtype: 924 """ 925 f_in = open(file_path, "rb") 926 if compress_level != None: 927 f_out = opener(destination_path, "wb", compresslevel = compress_level) 928 else: 929 f_out = opener(destination_path, "wb") 930 data = f_in.read(8192) 931 while data: 932 f_out.write(data) 933 data = f_in.read(8192) 934 if hasattr(f_out, 'flush'): 935 f_out.flush() 936 f_out.close() 937 f_in.close()
938 939 # files_to_compress must be a list of valid file paths
940 -def compress_files(dest_file, files_to_compress, compressor = "bz2"):
941 """ 942 docstring_title 943 944 @param dest_file: 945 @type dest_file: 946 @param files_to_compress: 947 @type files_to_compress: 948 @keyword compressor: 949 @type compressor: 950 @return: 951 @rtype: 952 """ 953 954 if compressor not in ("bz2", "gz",): 955 AttributeError("invalid compressor specified") 956 957 id_strings = {} 958 tar = tarfile.open(dest_file, "w:%s" % (compressor,)) 959 try: 960 for path in files_to_compress: 961 exist = os.lstat(path) 962 tarinfo = tar.gettarinfo(path, os.path.basename(path)) 963 tarinfo.uname = id_strings.setdefault(tarinfo.uid, str(tarinfo.uid)) 964 tarinfo.gname = id_strings.setdefault(tarinfo.gid, str(tarinfo.gid)) 965 if not stat.S_ISREG(exist.st_mode): continue 966 tarinfo.type = tarfile.REGTYPE 967 with open(path) as f: 968 tar.addfile(tarinfo, f) 969 finally: 970 tar.close()
971
972 -def universal_uncompress(compressed_file, dest_path, catch_empty = False):
973 """ 974 docstring_title 975 976 @param compressed_file: 977 @type compressed_file: 978 @param dest_path: 979 @type dest_path: 980 @keyword catch_empty: 981 @type catch_empty: 982 @return: 983 @rtype: 984 """ 985 986 try: 987 tar = tarfile.open(compressed_file, "r") 988 except tarfile.ReadError: 989 if catch_empty: 990 return True 991 return False 992 except EOFError: 993 return False 994 995 try: 996 997 dest_path = dest_path.encode('utf-8') 998 def mymf(tarinfo): 999 """ 1000 docstring_title 1001 1002 @param tarinfo: 1003 @type tarinfo: 1004 @return: 1005 @rtype: 1006 """ 1007 if tarinfo.isdir(): 1008 # Extract directory with a safe mode, so that 1009 # all files below can be extracted as well. 1010 try: 1011 os.makedirs(os.path.join(dest_path, tarinfo.name), 0777) 1012 except EnvironmentError: 1013 pass 1014 return tarinfo 1015 tar.extract(tarinfo, dest_path) 1016 del tar.members[:] 1017 return tarinfo
1018 1019 def mycmp(a, b): 1020 """ 1021 docstring_title 1022 1023 @param a: 1024 @type a: 1025 @param b: 1026 @type b: 1027 @return: 1028 @rtype: 1029 """ 1030 return cmp(a.name, b.name) 1031 1032 directories = sorted(map(mymf, tar), mycmp, reverse = True) 1033 1034 # Set correct owner, mtime and filemode on directories. 1035 def mymf2(tarinfo): 1036 """ 1037 docstring_title 1038 1039 @param tarinfo: 1040 @type tarinfo: 1041 @return: 1042 @rtype: 1043 """ 1044 epath = os.path.join(dest_path, tarinfo.name) 1045 try: 1046 tar.chown(tarinfo, epath) 1047 1048 # this is mandatory on uid/gid that don't exist 1049 # and in this strict order !! 1050 uname = tarinfo.uname 1051 gname = tarinfo.gname 1052 ugdata_valid = False 1053 try: 1054 int(gname) 1055 int(uname) 1056 except ValueError: 1057 ugdata_valid = True 1058 1059 try: 1060 if ugdata_valid: 1061 # get uid/gid 1062 # if not found, returns -1 that won't change anything 1063 uid, gid = get_uid_from_user(uname), \ 1064 get_gid_from_group(gname) 1065 os.lchown(epath, uid, gid) 1066 except OSError: 1067 pass 1068 1069 tar.utime(tarinfo, epath) 1070 tar.chmod(tarinfo, epath) 1071 except tarfile.ExtractError: 1072 if tar.errorlevel > 1: 1073 return False 1074 done = map(mymf2, directories) 1075 del done 1076 1077 except EOFError: 1078 return False 1079 1080 finally: 1081 tar.close() 1082 1083 return True 1084
1085 -def unpack_gzip(gzipfilepath):
1086 """ 1087 docstring_title 1088 1089 @param gzipfilepath: 1090 @type gzipfilepath: 1091 @return: 1092 @rtype: 1093 """ 1094 import gzip 1095 filepath = gzipfilepath[:-3] # remove .gz 1096 item = open(filepath, "wb") 1097 filegz = gzip.GzipFile(gzipfilepath, "rb") 1098 chunk = filegz.read(8192) 1099 while chunk: 1100 item.write(chunk) 1101 chunk = filegz.read(8192) 1102 filegz.close() 1103 item.flush() 1104 item.close() 1105 return filepath
1106
1107 -def unpack_bzip2(bzip2filepath):
1108 """ 1109 docstring_title 1110 1111 @param bzip2filepath: 1112 @type bzip2filepath: 1113 @return: 1114 @rtype: 1115 """ 1116 import bz2 1117 filepath = bzip2filepath[:-4] # remove .bz2 1118 item = open(filepath, "wb") 1119 filebz2 = bz2.BZ2File(bzip2filepath, "rb") 1120 chunk = filebz2.read(8192) 1121 while chunk: 1122 item.write(chunk) 1123 chunk = filebz2.read(8192) 1124 filebz2.close() 1125 item.flush() 1126 item.close() 1127 return filepath
1128
1129 -def backup_client_repository():
1130 """ 1131 docstring_title 1132 1133 @return: 1134 @rtype: 1135 """ 1136 if os.path.isfile(etpConst['etpdatabaseclientfilepath']): 1137 rnd = get_random_number() 1138 source = etpConst['etpdatabaseclientfilepath'] 1139 dest = etpConst['etpdatabaseclientfilepath']+".backup."+str(rnd) 1140 shutil.copy2(source, dest) 1141 user = os.stat(source)[4] 1142 group = os.stat(source)[5] 1143 os.chown(dest, user, group) 1144 shutil.copystat(source, dest) 1145 return dest 1146 return ""
1147
1148 -def extract_xpak(tbz2file, tmpdir = None):
1149 """ 1150 docstring_title 1151 1152 @param tbz2file: 1153 @type tbz2file: 1154 @keyword tmpdir: 1155 @type tmpdir: 1156 @return: 1157 @rtype: 1158 """ 1159 # extract xpak content 1160 xpakpath = suck_xpak(tbz2file, etpConst['packagestmpdir']) 1161 return unpack_xpak(xpakpath, tmpdir)
1162
1163 -def read_xpak(tbz2file):
1164 """ 1165 docstring_title 1166 1167 @param tbz2file: 1168 @type tbz2file: 1169 @return: 1170 @rtype: 1171 """ 1172 xpakpath = suck_xpak(tbz2file, etpConst['entropyunpackdir']) 1173 f = open(xpakpath, "rb") 1174 data = f.read() 1175 f.close() 1176 os.remove(xpakpath) 1177 return data
1178
1179 -def unpack_xpak(xpakfile, tmpdir = None):
1180 """ 1181 docstring_title 1182 1183 @param xpakfile: 1184 @type xpakfile: 1185 @keyword tmpdir: 1186 @type tmpdir: 1187 @return: 1188 @rtype: 1189 """ 1190 try: 1191 import entropy.xpak as xpak 1192 if tmpdir is None: 1193 tmpdir = etpConst['packagestmpdir']+"/"+os.path.basename(xpakfile)[:-5]+"/" 1194 if os.path.isdir(tmpdir): 1195 shutil.rmtree(tmpdir, True) 1196 os.makedirs(tmpdir) 1197 xpakdata = xpak.getboth(xpakfile) 1198 xpak.xpand(xpakdata, tmpdir) 1199 del xpakdata 1200 try: 1201 os.remove(xpakfile) 1202 except OSError: 1203 pass 1204 except: 1205 return None 1206 return tmpdir
1207
1208 -def suck_xpak(tbz2file, outputpath):
1209 """ 1210 docstring_title 1211 1212 @param tbz2file: 1213 @type tbz2file: 1214 @param outputpath: 1215 @type outputpath: 1216 @return: 1217 @rtype: 1218 """ 1219 1220 dest_filename = os.path.basename(tbz2file)[:-5]+".xpak" 1221 xpakpath = os.path.join(outputpath, dest_filename) 1222 old = open(tbz2file, "rb") 1223 1224 # position old to the end 1225 old.seek(0, os.SEEK_END) 1226 # read backward until we find 1227 bytes = old.tell() 1228 counter = bytes - 1 1229 xpak_end = "XPAKSTOP" 1230 xpak_start = "XPAKPACK" 1231 xpak_entry_point = "X" 1232 xpak_tag_len = len(xpak_start) 1233 chunk_len = 3 1234 data_start_position = None 1235 data_end_position = None 1236 1237 while counter >= (0 - chunk_len): 1238 1239 old.seek(counter - bytes, os.SEEK_END) 1240 if (bytes - (abs(counter - bytes))) < chunk_len: 1241 chunk_len = 1 1242 read_bytes = old.read(chunk_len) 1243 read_len = len(read_bytes) 1244 1245 entry_idx = read_bytes.rfind(xpak_entry_point) 1246 if entry_idx != -1: 1247 1248 cut_gotten = read_bytes[entry_idx:] 1249 offset = xpak_tag_len - len(cut_gotten) 1250 chunk = cut_gotten + old.read(offset) 1251 1252 if (chunk == xpak_end) and (data_start_position is None): 1253 data_end_position = old.tell() 1254 1255 elif (chunk == xpak_start) and (data_end_position is not None): 1256 data_start_position = old.tell() - xpak_tag_len 1257 break 1258 1259 counter -= read_len 1260 1261 if data_start_position is None: 1262 return None 1263 if data_end_position is None: 1264 return None 1265 1266 # now write to found metadata to file 1267 # starting from data_start_position 1268 # ending to data_end_position 1269 db = open(xpakpath, "wb") 1270 old.seek(data_start_position) 1271 to_read = data_end_position - data_start_position 1272 while to_read > 0: 1273 data = old.read(to_read) 1274 db.write(data) 1275 to_read -= len(data) 1276 1277 db.flush() 1278 db.close() 1279 old.close() 1280 return xpakpath
1281
1282 -def append_xpak(tbz2file, atom):
1283 """ 1284 docstring_title 1285 1286 @param tbz2file: 1287 @type tbz2file: 1288 @param atom: 1289 @type atom: 1290 @return: 1291 @rtype: 1292 """ 1293 import entropy.xpak as xpak 1294 from entropy.spm.plugins.factory import get_default_instance 1295 text = TextInterface() 1296 spm = get_default_instance(text) 1297 dbbuild = spm.get_installed_package_build_script_path(atom) 1298 dbdir = os.path.dirname(dbbuild) 1299 if os.path.isdir(dbdir): 1300 tbz2 = xpak.tbz2(tbz2file) 1301 tbz2.recompose(dbdir) 1302 return tbz2file
1303
1304 -def aggregate_edb(tbz2file, dbfile):
1305 """ 1306 docstring_title 1307 1308 @param tbz2file: 1309 @type tbz2file: 1310 @param dbfile: 1311 @type dbfile: 1312 @return: 1313 @rtype: 1314 """ 1315 f = open(tbz2file, "abw") 1316 f.write(etpConst['databasestarttag']) 1317 g = open(dbfile, "rb") 1318 chunk = g.read(8192) 1319 while chunk: 1320 f.write(chunk) 1321 chunk = g.read(8192) 1322 g.close() 1323 f.flush() 1324 f.close()
1325
1326 -def extract_edb(tbz2file, dbpath = None):
1327 """ 1328 docstring_title 1329 1330 @param tbz2file: 1331 @type tbz2file: 1332 @keyword dbpath: 1333 @type dbpath: 1334 @return: 1335 @rtype: 1336 """ 1337 1338 old = open(tbz2file, "rb") 1339 if not dbpath: 1340 dbpath = tbz2file[:-5] + ".db" 1341 1342 start_position = locate_edb(old) 1343 if not start_position: 1344 old.close() 1345 try: 1346 os.remove(dbpath) 1347 except OSError: 1348 return None 1349 return None 1350 1351 db = open(dbpath, "wb") 1352 data = old.read(1024) 1353 while data: 1354 db.write(data) 1355 data = old.read(1024) 1356 db.flush() 1357 db.close() 1358 1359 return dbpath
1360
1361 -def locate_edb(fileobj):
1362 """ 1363 docstring_title 1364 1365 @param fileobj: 1366 @type fileobj: 1367 @return: 1368 @rtype: 1369 """ 1370 1371 # position old to the end 1372 fileobj.seek(0, os.SEEK_END) 1373 # read backward until we find 1374 bytes = fileobj.tell() 1375 counter = bytes - 1 1376 1377 db_tag = etpConst['databasestarttag'] 1378 db_tag_len = len(db_tag) 1379 give_up_threshold = 1024000 * 30 # 30Mb 1380 entry_point = db_tag[::-1][0] 1381 max_read_len = 8 1382 start_position = None 1383 1384 while counter >= 0: 1385 cur_threshold = abs((counter-bytes)) 1386 if cur_threshold >= give_up_threshold: 1387 start_position = None 1388 break 1389 fileobj.seek(counter-bytes, os.SEEK_END) 1390 read_bytes = fileobj.read(max_read_len) 1391 read_len = len(read_bytes) 1392 entry_idx = read_bytes.rfind(entry_point) 1393 if entry_idx != -1: 1394 rollback = (read_len - entry_idx) * -1 1395 fileobj.seek(rollback, os.SEEK_CUR) 1396 chunk = fileobj.read(db_tag_len) 1397 if chunk == db_tag: 1398 start_position = fileobj.tell() 1399 break 1400 counter -= read_len 1401 1402 return start_position
1403
1404 -def remove_edb(tbz2file, savedir):
1405 """ 1406 docstring_title 1407 1408 @param tbz2file: 1409 @type tbz2file: 1410 @param savedir: 1411 @type savedir: 1412 @return: 1413 @rtype: 1414 """ 1415 old = open(tbz2file, "rb") 1416 1417 start_position = locate_edb(old) 1418 if not start_position: 1419 old.close() 1420 return None 1421 1422 new_path = os.path.join(savedir, os.path.basename(tbz2file)) 1423 new = open(new_path, "wb") 1424 1425 old.seek(0) 1426 counter = 0 1427 max_read_len = 1024 1428 db_tag = etpConst['databasestarttag'] 1429 db_tag_len = len(db_tag) 1430 start_position -= db_tag_len 1431 1432 while counter < start_position: 1433 delta = start_position - counter 1434 if delta < max_read_len: 1435 max_read_len = delta 1436 bytes = old.read(max_read_len) 1437 read_bytes = len(bytes) 1438 new.write(bytes) 1439 counter += read_bytes 1440 1441 new.flush() 1442 new.close() 1443 old.close() 1444 return savedir+"/"+os.path.basename(tbz2file)
1445 1446 # This function creates the .md5 file related to the given package file
1447 -def create_md5_file(filepath):
1448 """ 1449 docstring_title 1450 1451 @param filepath: 1452 @type filepath: 1453 @return: 1454 @rtype: 1455 """ 1456 md5hash = md5sum(filepath) 1457 hashfile = filepath+etpConst['packagesmd5fileext'] 1458 f = open(hashfile, "w") 1459 name = os.path.basename(filepath) 1460 f.write(md5hash+" "+name+"\n") 1461 f.flush() 1462 f.close() 1463 return hashfile
1464
1465 -def create_sha512_file(filepath):
1466 """ 1467 docstring_title 1468 1469 @param filepath: 1470 @type filepath: 1471 @return: 1472 @rtype: 1473 """ 1474 sha512hash = sha512(filepath) 1475 hashfile = filepath+etpConst['packagessha512fileext'] 1476 f = open(hashfile, "w") 1477 tbz2name = os.path.basename(filepath) 1478 f.write(sha512hash+" "+tbz2name+"\n") 1479 f.flush() 1480 f.close() 1481 return hashfile
1482
1483 -def create_sha256_file(filepath):
1484 """ 1485 docstring_title 1486 1487 @param filepath: 1488 @type filepath: 1489 @return: 1490 @rtype: 1491 """ 1492 sha256hash = sha256(filepath) 1493 hashfile = filepath+etpConst['packagessha256fileext'] 1494 f = open(hashfile, "w") 1495 tbz2name = os.path.basename(filepath) 1496 f.write(sha256hash+" "+tbz2name+"\n") 1497 f.flush() 1498 f.close() 1499 return hashfile
1500
1501 -def create_sha1_file(filepath):
1502 """ 1503 docstring_title 1504 1505 @param filepath: 1506 @type filepath: 1507 @return: 1508 @rtype: 1509 """ 1510 sha1hash = sha1(filepath) 1511 hashfile = filepath+etpConst['packagessha1fileext'] 1512 f = open(hashfile, "w") 1513 tbz2name = os.path.basename(filepath) 1514 f.write(sha1hash+" "+tbz2name+"\n") 1515 f.flush() 1516 f.close() 1517 return hashfile
1518
1519 -def compare_md5(filepath, checksum):
1520 """ 1521 docstring_title 1522 1523 @param filepath: 1524 @type filepath: 1525 @param checksum: 1526 @type checksum: 1527 @return: 1528 @rtype: 1529 """ 1530 checksum = str(checksum) 1531 result = md5sum(filepath) 1532 result = str(result) 1533 if checksum == result: 1534 return True 1535 return False
1536
1537 -def compare_sha512(filepath, checksum):
1538 """ 1539 docstring_title 1540 1541 @param filepath: 1542 @type filepath: 1543 @param checksum: 1544 @type checksum: 1545 @return: 1546 @rtype: 1547 """ 1548 checksum = str(checksum) 1549 result = sha512(filepath) 1550 result = str(result) 1551 if checksum == result: 1552 return True 1553 return False
1554
1555 -def compare_sha256(filepath, checksum):
1556 """ 1557 docstring_title 1558 1559 @param filepath: 1560 @type filepath: 1561 @param checksum: 1562 @type checksum: 1563 @return: 1564 @rtype: 1565 """ 1566 checksum = str(checksum) 1567 result = sha256(filepath) 1568 result = str(result) 1569 if checksum == result: 1570 return True 1571 return False
1572
1573 -def compare_sha1(filepath, checksum):
1574 """ 1575 docstring_title 1576 1577 @param filepath: 1578 @type filepath: 1579 @param checksum: 1580 @type checksum: 1581 @return: 1582 @rtype: 1583 """ 1584 checksum = str(checksum) 1585 result = sha1(filepath) 1586 result = str(result) 1587 if checksum == result: 1588 return True 1589 return False
1590
1591 -def md5string(string):
1592 """ 1593 docstring_title 1594 1595 @param string: 1596 @type string: 1597 @return: 1598 @rtype: 1599 """ 1600 m = hashlib.md5() 1601 m.update(string) 1602 return m.hexdigest()
1603 1604 # used to properly sort /usr/portage/profiles/updates files
1605 -def sort_update_files(update_list):
1606 """ 1607 docstring_title 1608 1609 @param update_list: 1610 @type update_list: 1611 @return: 1612 @rtype: 1613 """ 1614 sort_dict = {} 1615 # sort per year 1616 for item in update_list: 1617 # get year 1618 year = item.split("-")[1] 1619 if sort_dict.has_key(year): 1620 sort_dict[year].append(item) 1621 else: 1622 sort_dict[year] = [] 1623 sort_dict[year].append(item) 1624 new_list = [] 1625 keys = sort_dict.keys() 1626 keys.sort() 1627 for key in keys: 1628 sort_dict[key].sort() 1629 new_list += sort_dict[key] 1630 del sort_dict 1631 return new_list
1632
1633 -def generic_file_content_parser(filepath):
1634 """ 1635 docstring_title 1636 1637 @param filepath: 1638 @type filepath: 1639 @return: 1640 @rtype: 1641 """ 1642 data = [] 1643 if os.access(filepath, os.R_OK | os.F_OK): 1644 gen_f = open(filepath, "r") 1645 content = gen_f.readlines() 1646 gen_f.close() 1647 # filter comments and white lines 1648 content = [x.strip().rsplit("#", 1)[0].strip() for x in content \ 1649 if not x.startswith("#") and x.strip()] 1650 for line in content: 1651 if line in data: 1652 continue 1653 data.append(line) 1654 return data
1655 1656 # used by equo, this function retrieves the new safe Gentoo-aware file path
1657 -def allocate_masked_file(file, fromfile):
1658 """ 1659 docstring_title 1660 1661 @param file: 1662 @type file: 1663 @param fromfile: 1664 @type fromfile: 1665 @return: 1666 @rtype: 1667 """ 1668 1669 # check if file and tofile are equal 1670 if os.path.isfile(file) and os.path.isfile(fromfile): 1671 old = md5sum(fromfile) 1672 new = md5sum(file) 1673 if old == new: 1674 return file, False 1675 1676 counter = -1 1677 newfile = "" 1678 previousfile = "" 1679 1680 while 1: 1681 counter += 1 1682 txtcounter = str(counter) 1683 oldtxtcounter = str(counter-1) 1684 txtcounter_len = 4-len(txtcounter) 1685 cnt = 0 1686 while cnt < txtcounter_len: 1687 txtcounter = "0"+txtcounter 1688 oldtxtcounter = "0"+oldtxtcounter 1689 cnt += 1 1690 newfile = os.path.dirname(file)+"/"+"._cfg"+txtcounter+"_"+os.path.basename(file) 1691 if counter > 0: 1692 previousfile = os.path.dirname(file)+"/"+"._cfg"+oldtxtcounter+"_"+os.path.basename(file) 1693 else: 1694 previousfile = os.path.dirname(file)+"/"+"._cfg0000_"+os.path.basename(file) 1695 if not os.path.exists(newfile): 1696 break 1697 if not newfile: 1698 newfile = os.path.dirname(file)+"/"+"._cfg0000_"+os.path.basename(file) 1699 else: 1700 1701 if os.path.exists(previousfile): 1702 1703 # compare fromfile with previousfile 1704 new = md5sum(fromfile) 1705 old = md5sum(previousfile) 1706 if new == old: 1707 return previousfile, False 1708 1709 # compare old and new, if they match, suggest previousfile directly 1710 new = md5sum(file) 1711 old = md5sum(previousfile) 1712 if (new == old): 1713 return previousfile, False 1714 1715 return newfile, True
1716
1717 -def extract_elog(file):
1718 """ 1719 docstring_title 1720 1721 @param file: 1722 @type file: 1723 @return: 1724 @rtype: 1725 """ 1726 1727 logline = False 1728 logoutput = [] 1729 f = open(file, "r") 1730 reallog = f.readlines() 1731 f.close() 1732 1733 for line in reallog: 1734 if line.startswith("INFO: postinst") or line.startswith("LOG: postinst"): 1735 logline = True 1736 continue 1737 # disable all the others 1738 elif line.startswith("LOG:"): 1739 logline = False 1740 continue 1741 if (logline) and (line.strip()): 1742 # trap ! 1743 logoutput.append(line.strip()) 1744 return logoutput
1745 1746 # Imported from Gentoo portage_dep.py 1747 # Copyright 2003-2004 Gentoo Foundation 1748 # done to avoid the import of portage_dep here 1749 1750 ver_regexp = re.compile("^(cvs\\.)?(\\d+)((\\.\\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\\d*)*)(-r(\\d+))?$") 1751 suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$") 1752 suffix_value = {"pre": -2, "p": 0, "alpha": -4, "beta": -3, "rc": -1} 1753 endversion_keys = ["pre", "p", "alpha", "beta", "rc"] 1754 1755
1756 -def isjustpkgname(mypkg):
1757 """ 1758 docstring_title 1759 1760 @param mypkg: 1761 @type mypkg: 1762 @return: 1763 @rtype: 1764 """ 1765 myparts = mypkg.split('-') 1766 for x in myparts: 1767 if ververify(x): 1768 return 0 1769 return 1
1770
1771 -def ververify(myverx, silent = 1):
1772 """ 1773 docstring_title 1774 1775 @param myverx: 1776 @type myverx: 1777 @keyword silent: 1778 @type silent: 1779 @return: 1780 @rtype: 1781 """ 1782 1783 myver = myverx[:] 1784 if myver.endswith("*"): 1785 myver = myver[:-1] 1786 if ver_regexp.match(myver): 1787 return 1 1788 else: 1789 if not silent: 1790 print "!!! syntax error in version: %s" % myver 1791 return 0
1792 1793 1794 # Copyright 2003-2004 Gentoo Foundation 1795 # Distributed under the terms of the GNU General Public License v2 1796 # $Id: dep.py 11813 2008-11-06 04:56:17Z zmedico $ 1797 valid_category = re.compile("^\w[\w-]*") 1798 invalid_atom_chars_regexp = re.compile("[()|@]") 1799
1800 -def isvalidatom(myatom, allow_blockers = True):
1801 """ 1802 Check to see if a depend atom is valid 1803 1804 Example usage: 1805 >>> isvalidatom('media-libs/test-3.0') 1806 0 1807 >>> isvalidatom('>=media-libs/test-3.0') 1808 1 1809 1810 @param atom: The depend atom to check against 1811 @type atom: String 1812 @rtype: Integer 1813 @return: One of the following: 1814 1) 0 if the atom is invalid 1815 2) 1 if the atom is valid 1816 """ 1817 atom = remove_tag(myatom) 1818 atom = remove_usedeps(atom) 1819 if invalid_atom_chars_regexp.search(atom): 1820 return 0 1821 if allow_blockers and atom[:1] == "!": 1822 if atom[1:2] == "!": 1823 atom = atom[2:] 1824 else: 1825 atom = atom[1:] 1826 1827 # media-sound/amarok/x ? 1828 if atom.count("/") > 1: 1829 return 0 1830 1831 cpv = dep_getcpv(atom) 1832 cpv_catsplit = catsplit(cpv) 1833 mycpv_cps = None 1834 if cpv: 1835 if len(cpv_catsplit) == 2: 1836 if valid_category.match(cpv_catsplit[0]) is None: 1837 return 0 1838 if cpv_catsplit[0] == "null": 1839 # "null" category is valid, missing category is not. 1840 mycpv_cps = catpkgsplit(cpv.replace("null/", "cat/", 1)) 1841 if mycpv_cps: 1842 mycpv_cps = list(mycpv_cps) 1843 mycpv_cps[0] = "null" 1844 if not mycpv_cps: 1845 mycpv_cps = catpkgsplit(cpv) 1846 1847 operator = get_operator(atom) 1848 if operator: 1849 if operator[0] in "<>" and remove_slot(atom).endswith("*"): 1850 return 0 1851 if mycpv_cps: 1852 if len(cpv_catsplit) == 2: 1853 # >=cat/pkg-1.0 1854 return 1 1855 else: 1856 return 0 1857 else: 1858 # >=cat/pkg or >=pkg-1.0 (no category) 1859 return 0 1860 if mycpv_cps: 1861 # cat/pkg-1.0 1862 return 0 1863 1864 if len(cpv_catsplit) == 2: 1865 # cat/pkg 1866 return 1 1867 return 0
1868
1869 -def catsplit(mydep):
1870 """ 1871 docstring_title 1872 1873 @param mydep: 1874 @type mydep: 1875 @return: 1876 @rtype: 1877 """ 1878 return mydep.split("/", 1)
1879
1880 -def get_operator(mydep):
1881 """ 1882 Return the operator used in a depstring. 1883 1884 Example usage: 1885 >>> from portage.dep import * 1886 >>> get_operator(">=test-1.0") 1887 '>=' 1888 1889 @param mydep: The dep string to check 1890 @type mydep: String 1891 @rtype: String 1892 @return: The operator. One of: 1893 '~', '=', '>', '<', '=*', '>=', or '<=' 1894 """ 1895 if mydep: 1896 mydep = remove_slot(mydep) 1897 if not mydep: 1898 return None 1899 if mydep[0] == "~": 1900 operator = "~" 1901 elif mydep[0] == "=": 1902 if mydep[-1] == "*": 1903 operator = "=*" 1904 else: 1905 operator = "=" 1906 elif mydep[0] in "><": 1907 if len(mydep) > 1 and mydep[1] == "=": 1908 operator = mydep[0:2] 1909 else: 1910 operator = mydep[0] 1911 else: 1912 operator = None 1913 1914 return operator
1915
1916 -def isjustname(mypkg):
1917 """ 1918 Checks to see if the depstring is only the package name (no version parts) 1919 1920 Example usage: 1921 >>> isjustname('media-libs/test-3.0') 1922 0 1923 >>> isjustname('test') 1924 1 1925 >>> isjustname('media-libs/test') 1926 1 1927 1928 @param mypkg: The package atom to check 1929 @param mypkg: String 1930 @rtype: Integer 1931 @return: One of the following: 1932 1) 0 if the package string is not just the package name 1933 2) 1 if it is 1934 """ 1935 1936 myparts = mypkg.split('-') 1937 for x in myparts: 1938 if ververify(x): 1939 return 0 1940 return 1
1941
1942 -def isspecific(mypkg):
1943 """ 1944 Checks to see if a package is in category/package-version or package-version format, 1945 possibly returning a cached result. 1946 1947 Example usage: 1948 >>> isspecific('media-libs/test') 1949 0 1950 >>> isspecific('media-libs/test-3.0') 1951 1 1952 1953 @param mypkg: The package depstring to check against 1954 @type mypkg: String 1955 @rtype: Integer 1956 @return: One of the following: 1957 1) 0 if the package string is not specific 1958 2) 1 if it is 1959 """ 1960 mysplit = mypkg.split("/") 1961 if not isjustname(mysplit[-1]): 1962 return 1 1963 return 0
1964 1965
1966 -def catpkgsplit(mydata, silent = 1):
1967 """ 1968 Takes a Category/Package-Version-Rev and returns a list of each. 1969 1970 @param mydata: Data to split 1971 @type mydata: string 1972 @param silent: suppress error messages 1973 @type silent: Boolean (integer) 1974 @rype: list 1975 @return: 1976 1. If each exists, it returns [cat, pkgname, version, rev] 1977 2. If cat is not specificed in mydata, cat will be "null" 1978 3. if rev does not exist it will be '-r0' 1979 4. If cat is invalid (specified but has incorrect syntax) 1980 an InvalidData Exception will be thrown 1981 """ 1982 1983 # Categories may contain a-zA-z0-9+_- but cannot start with - 1984 mysplit = mydata.split("/") 1985 p_split = None 1986 if len(mysplit) == 1: 1987 retval = ["null"] 1988 p_split = pkgsplit(mydata, silent=silent) 1989 elif len(mysplit) == 2: 1990 retval = [mysplit[0]] 1991 p_split = pkgsplit(mysplit[1], silent=silent) 1992 if not p_split: 1993 return None 1994 retval.extend(p_split) 1995 return retval
1996
1997 -def pkgsplit(mypkg, silent=1):
1998 """ 1999 docstring_title 2000 2001 @param mypkg: 2002 @type mypkg: 2003 @keyword silent=1: 2004 @type silent=1: 2005 @return: 2006 @rtype: 2007 """ 2008 myparts = mypkg.split("-") 2009 2010 if len(myparts) < 2: 2011 if not silent: 2012 print "!!! Name error in", mypkg+": missing a version or name part." 2013 return None 2014 for x in myparts: 2015 if len(x) == 0: 2016 if not silent: 2017 print "!!! Name error in", mypkg+": empty \"-\" part." 2018 return None 2019 2020 #verify rev 2021 revok = 0 2022 myrev = myparts[-1] 2023 2024 if len(myrev) and myrev[0] == "r": 2025 try: 2026 int(myrev[1:]) 2027 revok = 1 2028 except ValueError: # from int() 2029 pass 2030 if revok: 2031 verPos = -2 2032 revision = myparts[-1] 2033 else: 2034 verPos = -1 2035 revision = "r0" 2036 2037 if ververify(myparts[verPos]): 2038 if len(myparts) == (-1*verPos): 2039 return None 2040 else: 2041 for x in myparts[:verPos]: 2042 if ververify(x): 2043 return None 2044 #names can't have versiony looking parts 2045 myval = ["-".join(myparts[:verPos]), myparts[verPos], revision] 2046 return myval 2047 else: 2048 return None
2049
2050 -def dep_getkey(mydepx):
2051 """ 2052 Return the category/package-name of a depstring. 2053 2054 Example usage: 2055 >>> dep_getkey('media-libs/test-3.0') 2056 'media-libs/test' 2057 2058 @param mydep: The depstring to retrieve the category/package-name of 2059 @type mydep: String 2060 @rtype: String 2061 @return: The package category/package-version 2062 """ 2063 if not mydepx: 2064 return mydepx 2065 mydep = mydepx[:] 2066 mydep = remove_tag(mydep) 2067 mydep = remove_usedeps(mydep) 2068 2069 mydep = dep_getcpv(mydep) 2070 if mydep and isspecific(mydep): 2071 mysplit = catpkgsplit(mydep) 2072 if not mysplit: 2073 return mydep 2074 return mysplit[0] + "/" + mysplit[1] 2075 2076 return mydep
2077 2078
2079 -def dep_getcpv(mydep):
2080 """ 2081 Return the category-package-version with any operators/slot specifications stripped off 2082 2083 Example usage: 2084 >>> dep_getcpv('>=media-libs/test-3.0') 2085 'media-libs/test-3.0' 2086 2087 @param mydep: The depstring 2088 @type mydep: String 2089 @rtype: String 2090 @return: The depstring with the operator removed 2091 """ 2092 2093 if mydep and mydep[0] == "*": 2094 mydep = mydep[1:] 2095 if mydep and mydep[-1] == "*": 2096 mydep = mydep[:-1] 2097 if mydep and mydep[0] == "!": 2098 mydep = mydep[1:] 2099 if mydep[:2] in [">=", "<="]: 2100 mydep = mydep[2:] 2101 elif mydep[:1] in "=<>~": 2102 mydep = mydep[1:] 2103 colon = mydep.rfind(":") 2104 if colon != -1: 2105 mydep = mydep[:colon] 2106 2107 return mydep
2108
2109 -def dep_getslot(mydep):
2110 """ 2111 2112 # Imported from portage.dep 2113 # $Id: dep.py 11281 2008-07-30 06:12:19Z zmedico $ 2114 2115 Retrieve the slot on a depend. 2116 2117 Example usage: 2118 >>> dep_getslot('app-misc/test:3') 2119 '3' 2120 2121 @param mydep: The depstring to retrieve the slot of 2122 @type mydep: String 2123 @rtype: String 2124 @return: The slot 2125 """ 2126 colon = mydep.find(":") 2127 if colon != -1: 2128 bracket = mydep.find("[", colon) 2129 if bracket == -1: 2130 return mydep[colon+1:] 2131 else: 2132 return mydep[colon+1:bracket] 2133 return None
2134
2135 -def dep_getusedeps(depend):
2136 2137 """ 2138 2139 # Imported from portage.dep 2140 # $Id: dep.py 11281 2008-07-30 06:12:19Z zmedico $ 2141 2142 Pull a listing of USE Dependencies out of a dep atom. 2143 2144 Example usage: 2145 >>> dep_getusedeps('app-misc/test:3[foo,-bar]') 2146 ('foo', '-bar') 2147 2148 @param depend: The depstring to process 2149 @type depend: String 2150 @rtype: List 2151 @return: List of use flags ( or [] if no flags exist ) 2152 """ 2153 2154 use_list = [] 2155 open_bracket = depend.find('[') 2156 # -1 = failure (think c++ string::npos) 2157 comma_separated = False 2158 bracket_count = 0 2159 while( open_bracket != -1 ): 2160 bracket_count += 1 2161 if bracket_count > 1: 2162 InvalidAtom("USE Dependency with more " + \ 2163 "than one set of brackets: %s" % (depend,)) 2164 close_bracket = depend.find(']', open_bracket ) 2165 if close_bracket == -1: 2166 InvalidAtom("USE Dependency with no closing bracket: %s" % depend ) 2167 use = depend[open_bracket + 1: close_bracket] 2168 # foo[1:1] may return '' instead of None, we don't want '' in the result 2169 if not use: 2170 InvalidAtom("USE Dependency with " + \ 2171 "no use flag ([]): %s" % depend ) 2172 if not comma_separated: 2173 comma_separated = "," in use 2174 2175 if comma_separated and bracket_count > 1: 2176 InvalidAtom("USE Dependency contains a mixture of " + \ 2177 "comma and bracket separators: %s" % depend ) 2178 2179 if comma_separated: 2180 for x in use.split(","): 2181 if x: 2182 use_list.append(x) 2183 else: 2184 InvalidAtom("USE Dependency with no use " + \ 2185 "flag next to comma: %s" % depend ) 2186 else: 2187 use_list.append(use) 2188 2189 # Find next use flag 2190 open_bracket = depend.find( '[', open_bracket+1 ) 2191 2192 return tuple(use_list)
2193
2194 -def remove_usedeps(depend):
2195 """ 2196 docstring_title 2197 2198 @param depend: 2199 @type depend: 2200 @return: 2201 @rtype: 2202 """ 2203 mydepend = depend[:] 2204 2205 close_bracket = mydepend.find(']') 2206 after_closebracket = '' 2207 if close_bracket != -1: after_closebracket = mydepend[close_bracket+1:] 2208 2209 open_bracket = mydepend.find('[') 2210 if open_bracket != -1: mydepend = mydepend[:open_bracket] 2211 2212 return mydepend+after_closebracket
2213
2214 -def remove_slot(mydep):
2215 """ 2216 2217 # Imported from portage.dep 2218 # $Id: dep.py 11281 2008-07-30 06:12:19Z zmedico $ 2219 2220 Removes dep components from the right side of an atom: 2221 * slot 2222 * use 2223 * repo 2224 """ 2225 colon = mydep.find(":") 2226 if colon != -1: 2227 mydep = mydep[:colon] 2228 else: 2229 bracket = mydep.find("[") 2230 if bracket != -1: 2231 mydep = mydep[:bracket] 2232 return mydep
2233 2234 # input must be a valid package version or a full atom
2235 -def remove_revision(ver):
2236 """ 2237 docstring_title 2238 2239 @param ver: 2240 @type ver: 2241 @return: 2242 @rtype: 2243 """ 2244 myver = ver.split("-") 2245 if myver[-1][0] == "r": 2246 return '-'.join(myver[:-1]) 2247 return ver
2248
2249 -def remove_tag(mydep):
2250 """ 2251 docstring_title 2252 2253 @param mydep: 2254 @type mydep: 2255 @return: 2256 @rtype: 2257 """ 2258 colon = mydep.rfind("#") 2259 if colon == -1: 2260 return mydep 2261 return mydep[:colon]
2262
2263 -def remove_entropy_revision(mydep):
2264 """ 2265 docstring_title 2266 2267 @param mydep: 2268 @type mydep: 2269 @return: 2270 @rtype: 2271 """ 2272 dep = remove_package_operators(mydep) 2273 operators = mydep[:-len(dep)] 2274 colon = dep.rfind("~") 2275 if colon == -1: 2276 return mydep 2277 return operators+dep[:colon]
2278
2279 -def dep_get_entropy_revision(mydep):
2280 """ 2281 docstring_title 2282 2283 @param mydep: 2284 @type mydep: 2285 @return: 2286 @rtype: 2287 """ 2288 #dep = remove_package_operators(mydep) 2289 colon = mydep.rfind("~") 2290 if colon != -1: 2291 myrev = mydep[colon+1:] 2292 try: 2293 myrev = int(myrev) 2294 except ValueError: 2295 return None 2296 return myrev 2297 return None
2298 2299 2300 dep_revmatch = re.compile('^r[0-9]')
2301 -def dep_get_portage_revision(mydep):
2302 """ 2303 docstring_title 2304 2305 @param mydep: 2306 @type mydep: 2307 @return: 2308 @rtype: 2309 """ 2310 myver = mydep.split("-") 2311 myrev = myver[-1] 2312 if dep_revmatch.match(myrev): 2313 return myrev 2314 else: 2315 return "r0"
2316 2317
2318 -def dep_get_match_in_repos(mydep):
2319 """ 2320 docstring_title 2321 2322 @param mydep: 2323 @type mydep: 2324 @return: 2325 @rtype: 2326 """ 2327 colon = mydep.rfind("@") 2328 if colon != -1: 2329 mydata = mydep[colon+1:] 2330 mydata = mydata.split(",") 2331 if not mydata: 2332 mydata = None 2333 return mydep[:colon], mydata 2334 else: 2335 return mydep, None
2336
2337 -def dep_gettag(dep):
2338 2339 """ 2340 Retrieve the slot on a depend. 2341 2342 Example usage: 2343 >>> dep_gettag('app-misc/test#2.6.23-sabayon-r1') 2344 '2.6.23-sabayon-r1' 2345 2346 """ 2347 2348 colon = dep.rfind("#") 2349 if colon != -1: 2350 mydep = dep[colon+1:] 2351 rslt = remove_slot(mydep) 2352 return rslt 2353 return None
2354
2355 -def remove_package_operators(atom):
2356 """ 2357 docstring_title 2358 2359 @param atom: 2360 @type atom: 2361 @return: 2362 @rtype: 2363 """ 2364 try: 2365 while atom: 2366 if atom[0] in ('>', '<', '=', '~',): 2367 atom = atom[1:] 2368 continue 2369 break 2370 except IndexError: 2371 pass 2372 return atom
2373 2374 # Version compare function taken from portage_versions.py 2375 # portage_versions.py -- core Portage functionality 2376 # Copyright 1998-2006 Gentoo Foundation
2377 -def compare_versions(ver1, ver2):
2378 """ 2379 docstring_title 2380 2381 @param ver1: 2382 @type ver1: 2383 @param ver2: 2384 @type ver2: 2385 @return: 2386 @rtype: 2387 """ 2388 2389 if ver1 == ver2: 2390 return 0 2391 #mykey=ver1+":"+ver2 2392 match1 = None 2393 match2 = None 2394 if ver1: 2395 match1 = ver_regexp.match(ver1) 2396 if ver2: 2397 match2 = ver_regexp.match(ver2) 2398 2399 # checking that the versions are valid 2400 invalid = False 2401 invalid_rc = 0 2402 if not match1: 2403 invalid = True 2404 elif not match1.groups(): 2405 invalid = True 2406 elif not match2: 2407 invalid_rc = 1 2408 invalid = True 2409 elif not match2.groups(): 2410 invalid_rc = 1 2411 invalid = True 2412 if invalid: return invalid_rc 2413 2414 # building lists of the version parts before the suffix 2415 # first part is simple 2416 list1 = [int(match1.group(2))] 2417 list2 = [int(match2.group(2))] 2418 2419 # this part would greatly benefit from a fixed-length version pattern 2420 if len(match1.group(3)) or len(match2.group(3)): 2421 vlist1 = match1.group(3)[1:].split(".") 2422 vlist2 = match2.group(3)[1:].split(".") 2423 for i in range(0, max(len(vlist1), len(vlist2))): 2424 # Implcit .0 is given a value of -1, so that 1.0.0 > 1.0, since it 2425 # would be ambiguous if two versions that aren't literally equal 2426 # are given the same value (in sorting, for example). 2427 if len(vlist1) <= i or len(vlist1[i]) == 0: 2428 list1.append(-1) 2429 list2.append(int(vlist2[i])) 2430 elif len(vlist2) <= i or len(vlist2[i]) == 0: 2431 list1.append(int(vlist1[i])) 2432 list2.append(-1) 2433 # Let's make life easy and use integers unless we're forced to use floats 2434 elif (vlist1[i][0] != "0" and vlist2[i][0] != "0"): 2435 list1.append(int(vlist1[i])) 2436 list2.append(int(vlist2[i])) 2437 # now we have to use floats so 1.02 compares correctly against 1.1 2438 else: 2439 list1.append(float("0."+vlist1[i])) 2440 list2.append(float("0."+vlist2[i])) 2441 2442 # and now the final letter 2443 if len(match1.group(5)): 2444 list1.append(ord(match1.group(5))) 2445 if len(match2.group(5)): 2446 list2.append(ord(match2.group(5))) 2447 2448 for i in range(0, max(len(list1), len(list2))): 2449 if len(list1) <= i: 2450 return -1 2451 elif len(list2) <= i: 2452 return 1 2453 elif list1[i] != list2[i]: 2454 return list1[i] - list2[i] 2455 2456 # main version is equal, so now compare the _suffix part 2457 list1 = match1.group(6).split("_")[1:] 2458 list2 = match2.group(6).split("_")[1:] 2459 2460 for i in range(0, max(len(list1), len(list2))): 2461 if len(list1) <= i: 2462 s1 = ("p", "0") 2463 else: 2464 s1 = suffix_regexp.match(list1[i]).groups() 2465 if len(list2) <= i: 2466 s2 = ("p", "0") 2467 else: 2468 s2 = suffix_regexp.match(list2[i]).groups() 2469 if s1[0] != s2[0]: 2470 return suffix_value[s1[0]] - suffix_value[s2[0]] 2471 if s1[1] != s2[1]: 2472 # it's possible that the s(1|2)[1] == '' 2473 # in such a case, fudge it. 2474 try: 2475 r1 = int(s1[1]) 2476 except ValueError: 2477 r1 = 0 2478 try: 2479 r2 = int(s2[1]) 2480 except ValueError: 2481 r2 = 0 2482 return r1 - r2 2483 2484 # the suffix part is equal to, so finally check the revision 2485 if match1.group(10): 2486 r1 = int(match1.group(10)) 2487 else: 2488 r1 = 0 2489 if match2.group(10): 2490 r2 = int(match2.group(10)) 2491 else: 2492 r2 = 0 2493 return r1 - r2
2494
2495 -def entropy_compare_versions(listA, listB):
2496 ''' 2497 @description: compare two lists composed by 2498 [version,tag,revision] and [version,tag,revision] 2499 if listA > listB --> positive number 2500 if listA == listB --> 0 2501 if listA < listB --> negative number 2502 @input package: listA[version,tag,rev] and listB[version,tag,rev] 2503 @output: integer number 2504 ''' 2505 2506 # if both are tagged, check tag first 2507 rc = 0 2508 if listA[1] and listB[1]: 2509 rc = cmp(listA[1], listB[1]) 2510 if rc == 0: 2511 rc = compare_versions(listA[0], listB[0]) 2512 2513 if rc == 0: 2514 # check tag 2515 if listA[1] > listB[1]: 2516 return 1 2517 elif listA[1] < listB[1]: 2518 return -1 2519 else: 2520 # check rev 2521 if listA[2] > listB[2]: 2522 return 1 2523 elif listA[2] < listB[2]: 2524 return -1 2525 else: 2526 return 0 2527 return rc
2528
2529 -def g_n_w_cmp(a, b):
2530 ''' 2531 @description: reorder a version list 2532 @input versionlist: a list 2533 @output: the ordered list 2534 ''' 2535 rc = compare_versions(a, b) 2536 if rc < 0: 2537 return -1 2538 elif rc > 0: 2539 return 1 2540 else: 2541 return 0
2542
2543 -def get_newer_version(versions):
2544 """ 2545 docstring_title 2546 2547 @param versions: 2548 @type versions: 2549 @return: 2550 @rtype: 2551 """ 2552 return sorted(versions, g_n_w_cmp, reverse = True)
2553
2554 -def get_newer_version_stable(versions):
2555 """ 2556 docstring_title 2557 2558 @param versions: 2559 @type versions: 2560 @return: 2561 @rtype: 2562 """ 2563 2564 if len(versions) == 1: 2565 return versions 2566 2567 versionlist = versions[:] 2568 2569 rc = False 2570 while not rc: 2571 change = False 2572 for x in range(len(versionlist)): 2573 pkgA = versionlist[x] 2574 try: 2575 pkgB = versionlist[x+1] 2576 except: 2577 pkgB = "0" 2578 result = compare_versions(pkgA, pkgB) 2579 if result < 0: 2580 versionlist[x] = pkgB 2581 versionlist[x+1] = pkgA 2582 change = True 2583 if not change: 2584 rc = True 2585 2586 return versionlist
2587 2588
2589 -def g_e_n_w_cmp(a, b):
2590 ''' 2591 @description: reorder a version list 2592 @input versionlist: a list 2593 @output: the ordered list 2594 ''' 2595 rc = entropy_compare_versions(a, b) 2596 if rc < 0: return -1 2597 elif rc > 0: return 1 2598 else: return 0
2599
2600 -def get_entropy_newer_version(versions):
2601 """ 2602 docstring_title 2603 2604 @param versions: 2605 @type versions: 2606 @return: 2607 @rtype: 2608 """ 2609 return sorted(versions, g_e_n_w_cmp, reverse = True)
2610
2611 -def get_entropy_newer_version_stable(versions):
2612 ''' 2613 descendent order 2614 versions = [(version,tag,revision),(version,tag,revision)] 2615 ''' 2616 if len(versions) == 1: 2617 return versions 2618 2619 myversions = versions[:] 2620 # ease the work 2621 2622 rc = False 2623 while not rc: 2624 change = False 2625 for x in range(len(myversions)): 2626 pkgA = myversions[x] 2627 try: 2628 pkgB = myversions[x+1] 2629 except: 2630 pkgB = ("0", "", 0) 2631 result = entropy_compare_versions(pkgA, pkgB) 2632 if result < 0: 2633 myversions[x] = pkgB 2634 myversions[x+1] = pkgA 2635 change = True 2636 if not change: 2637 rc = True 2638 2639 return myversions
2640 2641
2642 -def isnumber(x):
2643 """ 2644 docstring_title 2645 2646 @param x: 2647 @type x: 2648 @return: 2649 @rtype: 2650 """ 2651 try: 2652 t = int(x) 2653 del t 2654 return True 2655 except: 2656 return False
2657 2658
2659 -def istextfile(filename, blocksize = 512):
2660 """ 2661 docstring_title 2662 2663 @param filename: 2664 @type filename: 2665 @keyword blocksize: 2666 @type blocksize: 2667 @return: 2668 @rtype: 2669 """ 2670 f = open(filename) 2671 r = istext(f.read(blocksize)) 2672 f.close() 2673 return r
2674
2675 -def istext(s):
2676 """ 2677 docstring_title 2678 2679 @param s: 2680 @type s: 2681 @return: 2682 @rtype: 2683 """ 2684 import string 2685 _null_trans = string.maketrans("", "") 2686 text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b")) 2687 2688 if "\0" in s: 2689 return False 2690 2691 if not s: # Empty files are considered text 2692 return True 2693 2694 # Get the non-text characters (maps a character to itself then 2695 # use the 'remove' option to get rid of the text characters.) 2696 t = s.translate(_null_trans, text_characters) 2697 2698 # If more than 30% non-text characters, then 2699 # this is considered a binary file 2700 if len(t)/len(s) > 0.30: 2701 return False 2702 return True
2703 2704 # this functions removes duplicates without breaking the list order 2705 # nameslist: a list that contains duplicated names 2706 # @returns filtered list
2707 -def filter_duplicated_entries(alist):
2708 """ 2709 docstring_title 2710 2711 @param alist: 2712 @type alist: 2713 @return: 2714 @rtype: 2715 """ 2716 mydata = {} 2717 return [mydata.setdefault(e, e) for e in alist if e not in mydata]
2718 2719 2720 # Escapeing functions 2721 mappings = { 2722 "'":"''", 2723 '"':'""', 2724 ' ':'+' 2725 } 2726
2727 -def escape(*args):
2728 """ 2729 docstring_title 2730 2731 @param *args: 2732 @type *args: 2733 @return: 2734 @rtype: 2735 """ 2736 arg_lst = [] 2737 if len(args)==1: 2738 return escape_single(args[0]) 2739 for x in args: 2740 arg_lst.append(escape_single(x)) 2741 return tuple(arg_lst)
2742
2743 -def escape_single(x):
2744 """ 2745 docstring_title 2746 2747 @param x: 2748 @type x: 2749 @return: 2750 @rtype: 2751 """ 2752 if type(x) == type(()) or type(x) == type([]): 2753 return escape(x) 2754 if type(x) == type(""): 2755 tmpstr = '' 2756 for d in range(len(x)): 2757 if x[d] in mappings.keys(): 2758 if x[d] in ("'", '"'): 2759 if d+1 < len(x): 2760 if x[d+1] != x[d]: 2761 tmpstr += mappings[x[d]] 2762 else: 2763 tmpstr += mappings[x[d]] 2764 else: 2765 tmpstr += mappings[x[d]] 2766 else: 2767 tmpstr += x[d] 2768 else: 2769 tmpstr = x 2770 return tmpstr
2771
2772 -def unescape(val):
2773 """ 2774 docstring_title 2775 2776 @param val: 2777 @type val: 2778 @return: 2779 @rtype: 2780 """ 2781 if type(val)==type(""): 2782 tmpstr = '' 2783 for key, item in mappings.items(): 2784 val = val.replace(item, key) 2785 tmpstr = val 2786 else: 2787 tmpstr = val 2788 return tmpstr
2789
2790 -def unescape_list(*args):
2791 """ 2792 docstring_title 2793 2794 @param *args: 2795 @type *args: 2796 @return: 2797 @rtype: 2798 """ 2799 arg_lst = [] 2800 for x in args: 2801 arg_lst.append(unescape(x)) 2802 return tuple(arg_lst)
2803
2804 -def extract_ftp_host_from_uri(uri):
2805 """ 2806 docstring_title 2807 2808 @param uri: 2809 @type uri: 2810 @return: 2811 @rtype: 2812 """ 2813 myuri = spliturl(uri)[1] 2814 # remove username:pass@ 2815 myuri = myuri.split("@")[len(myuri.split("@"))-1] 2816 return myuri
2817
2818 -def spliturl(url):
2819 """ 2820 docstring_title 2821 2822 @param url: 2823 @type url: 2824 @return: 2825 @rtype: 2826 """ 2827 import urlparse 2828 return urlparse.urlsplit(url)
2829
2830 -def compress_tar_bz2(storepath, pathtocompress):
2831 """ 2832 docstring_title 2833 2834 @param storepath: 2835 @type storepath: 2836 @param pathtocompress: 2837 @type pathtocompress: 2838 @return: 2839 @rtype: 2840 """ 2841 cmd = "cd \""+pathtocompress+"\" && tar cjf \""+storepath+"\" " + \ 2842 ". &> /dev/null" 2843 return subprocess.call(cmd, shell = True)
2844
2845 -def spawn_function(f, *args, **kwds):
2846 """ 2847 docstring_title 2848 2849 @param f: 2850 @type f: 2851 @param *args: 2852 @type *args: 2853 @param **kwds: 2854 @type **kwds: 2855 @return: 2856 @rtype: 2857 """ 2858 2859 uid = kwds.get('spf_uid') 2860 if uid != None: kwds.pop('spf_uid') 2861 2862 gid = kwds.get('spf_gid') 2863 if gid != None: kwds.pop('spf_gid') 2864 2865 write_pid_func = kwds.get('write_pid_func') 2866 if write_pid_func != None: 2867 kwds.pop('write_pid_func') 2868 2869 try: 2870 import cPickle as pickle 2871 except ImportError: 2872 import pickle 2873 pread, pwrite = os.pipe() 2874 pid = os.fork() 2875 if pid > 0: 2876 if write_pid_func != None: 2877 write_pid_func(pid) 2878 os.close(pwrite) 2879 f = os.fdopen(pread, 'rb') 2880 status, result = pickle.load(f) 2881 os.waitpid(pid, 0) 2882 f.close() 2883 if status == 0: 2884 return result 2885 else: 2886 result 2887 else: 2888 os.close(pread) 2889 if gid != None: 2890 os.setgid(gid) 2891 if uid != None: 2892 os.setuid(uid) 2893 try: 2894 result = f(*args, **kwds) 2895 status = 0 2896 except Exception, exc: 2897 result = exc 2898 status = 1 2899 f = os.fdopen(pwrite, 'wb') 2900 try: 2901 pickle.dump((status, result), f, pickle.HIGHEST_PROTOCOL) 2902 except pickle.PicklingError, exc: 2903 pickle.dump((2, exc), f, pickle.HIGHEST_PROTOCOL) 2904 f.close() 2905 os._exit(0)
2906 2907 # tar* uncompress function...
2908 -def uncompress_tar_bz2(filepath, extractPath = None, catchEmpty = False):
2909 """ 2910 docstring_title 2911 2912 @param filepath: 2913 @type filepath: 2914 @keyword extractPath: 2915 @type extractPath: 2916 @keyword catchEmpty: 2917 @type catchEmpty: 2918 @return: 2919 @rtype: 2920 """ 2921 2922 if extractPath == None: 2923 extractPath = os.path.dirname(filepath) 2924 if not os.path.isfile(filepath): 2925 FileNotFound('FileNotFound: archive does not exist') 2926 2927 try: 2928 tar = tarfile.open(filepath, "r") 2929 except tarfile.ReadError: 2930 if catchEmpty: 2931 return 0 2932 raise 2933 except EOFError: 2934 return -1 2935 2936 def fix_uid_gid(tarinfo, epath): 2937 """ 2938 docstring_title 2939 2940 @param tarinfo: 2941 @type tarinfo: 2942 @param epath: 2943 @type epath: 2944 @return: 2945 @rtype: 2946 """ 2947 # workaround for buggy tar files 2948 uname = tarinfo.uname 2949 gname = tarinfo.gname 2950 ugdata_valid = False 2951 try: 2952 int(gname) 2953 int(uname) 2954 except ValueError: 2955 ugdata_valid = True 2956 try: 2957 if ugdata_valid: # FIXME: will be removed in 2011 2958 # get uid/gid 2959 # if not found, returns -1 that won't change anything 2960 uid, gid = get_uid_from_user(uname), \ 2961 get_gid_from_group(gname) 2962 os.lchown(epath, uid, gid) 2963 except OSError: 2964 pass
2965 2966 def mycmp(a, b): 2967 """ 2968 docstring_title 2969 2970 @param a: 2971 @type a: 2972 @param b: 2973 @type b: 2974 @return: 2975 @rtype: 2976 """ 2977 return cmp(a[0].name, b[0].name) 2978 2979 try: 2980 2981 encoded_path = extractPath.encode('utf-8') 2982 def mymf(tarinfo): 2983 """ 2984 docstring_title 2985 2986 @param tarinfo: 2987 @type tarinfo: 2988 @return: 2989 @rtype: 2990 """ 2991 epath = os.path.join(encoded_path, tarinfo.name) 2992 if tarinfo.isdir(): 2993 # Extract directory with a safe mode, so that 2994 # all files below can be extracted as well. 2995 try: 2996 os.makedirs(epath, 0777) 2997 except EnvironmentError: 2998 pass 2999 return tarinfo, epath 3000 3001 tar.extract(tarinfo, encoded_path) 3002 3003 del tar.members[:] 3004 return tarinfo, epath 3005 3006 entries = sorted(map(mymf, tar), mycmp, reverse = True) 3007 3008 # Set correct owner, mtime and filemode on directories. 3009 def mymf2(tardata): 3010 """ 3011 docstring_title 3012 3013 @param tardata: 3014 @type tardata: 3015 @return: 3016 @rtype: 3017 """ 3018 tarinfo, epath = tardata 3019 try: 3020 3021 tar.chown(tarinfo, epath) 3022 fix_uid_gid(tarinfo, epath) 3023 tar.utime(tarinfo, epath) 3024 # mode = tarinfo.mode 3025 # xorg-server /usr/bin/X symlink of /usr/bin/Xorg 3026 # which is setuid. Symlinks don't need chmod. PERIOD! 3027 if not os.path.islink(epath): 3028 tar.chmod(tarinfo, epath) 3029 3030 except tarfile.ExtractError: 3031 if tar.errorlevel > 1: 3032 raise 3033 3034 done = map(mymf2, entries) 3035 del done 3036 3037 except EOFError: 3038 return -1 3039 3040 finally: 3041 tar.close() 3042 3043 if os.listdir(extractPath): 3044 return 0 3045 return -1 3046
3047 -def bytes_into_human(bytes):
3048 """ 3049 docstring_title 3050 3051 @param bytes: 3052 @type bytes: 3053 @return: 3054 @rtype: 3055 """ 3056 size = str(round(float(bytes)/1024, 1)) 3057 if bytes < 1024: 3058 size = str(round(float(bytes)))+"b" 3059 elif bytes < 1023999: 3060 size += "kB" 3061 elif bytes > 1023999: 3062 size = str(round(float(size)/1024, 1)) 3063 size += "MB" 3064 return size
3065
3066 -def hide_ftp_password(uri):
3067 """ 3068 docstring_title 3069 3070 @param uri: 3071 @type uri: 3072 @return: 3073 @rtype: 3074 """ 3075 ftppassword = uri.split("@")[:-1] 3076 if not ftppassword: return uri 3077 ftppassword = '@'.join(ftppassword) 3078 ftppassword = ftppassword.split(":")[-1] 3079 if not ftppassword: 3080 return uri 3081 newuri = uri.replace(ftppassword, "xxxxxxxx") 3082 return newuri
3083
3084 -def extract_ftp_data(ftpuri):
3085 """ 3086 docstring_title 3087 3088 @param ftpuri: 3089 @type ftpuri: 3090 @return: 3091 @rtype: 3092 """ 3093 ftpuser = ftpuri.split("ftp://")[-1].split(":")[0] 3094 if (ftpuser == ""): 3095 ftpuser = "anonymous@" 3096 ftppassword = "anonymous" 3097 else: 3098 ftppassword = ftpuri.split("@")[:-1] 3099 if len(ftppassword) > 1: 3100 ftppassword = '@'.join(ftppassword) 3101 ftppassword = ftppassword.split(":")[-1] 3102 if (ftppassword == ""): 3103 ftppassword = "anonymous" 3104 else: 3105 ftppassword = ftppassword[0] 3106 ftppassword = ftppassword.split(":")[-1] 3107 if (ftppassword == ""): 3108 ftppassword = "anonymous" 3109 3110 ftpport = ftpuri.split(":")[-1] 3111 try: 3112 ftpport = int(ftpport) 3113 except ValueError: 3114 ftpport = 21 3115 3116 ftpdir = '/' 3117 if ftpuri.count("/") > 2: 3118 ftpdir = ftpuri.split("ftp://")[-1] 3119 ftpdir = ftpdir.split("/")[-1] 3120 ftpdir = ftpdir.split(":")[0] 3121 if ftpdir.endswith("/"): 3122 ftpdir = ftpdir[:len(ftpdir)-1] 3123 if not ftpdir: ftpdir = "/" 3124 3125 return ftpuser, ftppassword, ftpport, ftpdir
3126
3127 -def get_file_unix_mtime(path):
3128 """ 3129 docstring_title 3130 3131 @param path: 3132 @type path: 3133 @return: 3134 @rtype: 3135 """ 3136 return os.path.getmtime(path)
3137
3138 -def get_random_temp_file():
3139 """ 3140 docstring_title 3141 3142 @return: 3143 @rtype: 3144 """ 3145 if not os.path.isdir(etpConst['packagestmpdir']): 3146 os.makedirs(etpConst['packagestmpdir']) 3147 path = os.path.join(etpConst['packagestmpdir'], 3148 "temp_"+str(get_random_number())) 3149 while os.path.lexists(path): 3150 path = os.path.join(etpConst['packagestmpdir'], 3151 "temp_"+str(get_random_number())) 3152 return path
3153
3154 -def get_file_timestamp(path):
3155 """ 3156 docstring_title 3157 3158 @param path: 3159 @type path: 3160 @return: 3161 @rtype: 3162 """ 3163 from datetime import datetime 3164 # used in this way for convenience 3165 unixtime = os.path.getmtime(path) 3166 humantime = datetime.fromtimestamp(unixtime) 3167 # format properly 3168 humantime = str(humantime) 3169 outputtime = "" 3170 for char in humantime: 3171 if char != "-" and char != " " and char != ":": 3172 outputtime += char 3173 return outputtime
3174
3175 -def convert_unix_time_to_human_time(unixtime):
3176 """ 3177 docstring_title 3178 3179 @param unixtime: 3180 @type unixtime: 3181 @return: 3182 @rtype: 3183 """ 3184 from datetime import datetime 3185 humantime = str(datetime.fromtimestamp(unixtime)) 3186 return humantime
3187
3188 -def convert_unix_time_to_datetime(unixtime):
3189 """ 3190 docstring_title 3191 3192 @param unixtime: 3193 @type unixtime: 3194 @return: 3195 @rtype: 3196 """ 3197 from datetime import datetime 3198 return datetime.fromtimestamp(unixtime)
3199
3200 -def get_current_unix_time():
3201 """ 3202 docstring_title 3203 3204 @return: 3205 @rtype: 3206 """ 3207 return time.time()
3208
3209 -def get_year():
3210 """ 3211 docstring_title 3212 3213 @return: 3214 @rtype: 3215 """ 3216 return time.strftime("%Y")
3217
3218 -def convert_seconds_to_fancy_output(seconds):
3219 """ 3220 docstring_title 3221 3222 @param seconds: 3223 @type seconds: 3224 @return: 3225 @rtype: 3226 """ 3227 3228 mysecs = seconds 3229 myminutes = 0 3230 myhours = 0 3231 mydays = 0 3232 3233 while mysecs >= 60: 3234 mysecs -= 60 3235 myminutes += 1 3236 3237 while myminutes >= 60: 3238 myminutes -= 60 3239 myhours += 1 3240 3241 while myhours >= 24: 3242 myhours -= 24 3243 mydays += 1 3244 3245 output = [] 3246 output.append(str(mysecs)+"s") 3247 if myminutes > 0 or myhours > 0: 3248 output.append(str(myminutes)+"m") 3249 if myhours > 0 or mydays > 0: 3250 output.append(str(myhours)+"h") 3251 if mydays > 0: 3252 output.append(str(mydays)+"d") 3253 output.reverse() 3254 return ':'.join(output)
3255 3256 # Temporary files cleaner
3257 -def cleanup(toCleanDirs = []):
3258 """ 3259 docstring_title 3260 3261 @keyword toCleanDirs: 3262 @type toCleanDirs: 3263 @return: 3264 @rtype: 3265 """ 3266 3267 if not toCleanDirs: 3268 toCleanDirs = [ etpConst['packagestmpdir'], etpConst['logdir'] ] 3269 counter = 0 3270 3271 for xdir in toCleanDirs: 3272 print_info(red(" * ")+"Cleaning "+darkgreen(xdir)+" directory...", back = True) 3273 if os.path.isdir(xdir): 3274 dircontent = os.listdir(xdir) 3275 if dircontent != []: 3276 for data in dircontent: 3277 subprocess.call(["rm", "-rf", os.path.join(xdir, data)]) 3278 counter += 1 3279 3280 print_info(green(" * ")+"Cleaned: "+str(counter)+" files and directories") 3281 return 0
3282
3283 -def flatten(l, ltypes = (list, tuple)):
3284 """ 3285 docstring_title 3286 3287 @param l: 3288 @type l: 3289 @keyword ltypes: 3290 @type ltypes: 3291 @param tuple: 3292 @type tuple: 3293 @return: 3294 @rtype: 3295 """ 3296 i = 0 3297 while i < len(l): 3298 while isinstance(l[i], ltypes): 3299 if not l[i]: 3300 l.pop(i) 3301 if not len(l): 3302 break 3303 else: 3304 l[i:i+1] = list(l[i]) 3305 i += 1 3306 return l
3307
3308 -def read_repositories_conf():
3309 """ 3310 docstring_title 3311 3312 @return: 3313 @rtype: 3314 """ 3315 content = [] 3316 if os.path.isfile(etpConst['repositoriesconf']): 3317 f = open(etpConst['repositoriesconf']) 3318 content = f.readlines() 3319 f.close() 3320 return content
3321
3322 -def write_ordered_repositories_entries(ordered_repository_list):
3323 """ 3324 docstring_title 3325 3326 @param ordered_repository_list: 3327 @type ordered_repository_list: 3328 @return: 3329 @rtype: 3330 """ 3331 content = read_repositories_conf() 3332 content = [x.strip() for x in content] 3333 repolines = [x for x in content if x.startswith("repository|") and (len(x.split("|")) == 5)] 3334 content = [x for x in content if x not in repolines] 3335 for repoid in ordered_repository_list: 3336 # get repoid from repolines 3337 for x in repolines: 3338 repoidline = x.split("|")[1] 3339 if repoid == repoidline: 3340 content.append(x) 3341 _save_repositories_content(content)
3342
3343 -def save_repository_settings(repodata, remove = False, disable = False, enable = False):
3344 """ 3345 docstring_title 3346 3347 @param repodata: 3348 @type repodata: 3349 @keyword remove: 3350 @type remove: 3351 @keyword disable: 3352 @type disable: 3353 @keyword enable: 3354 @type enable: 3355 @return: 3356 @rtype: 3357 """ 3358 3359 if repodata['repoid'].endswith(".tbz2"): 3360 return 3361 3362 content = read_repositories_conf() 3363 content = [x.strip() for x in content] 3364 if not disable and not enable: 3365 content = [x for x in content if not x.startswith("repository|"+repodata['repoid'])] 3366 if remove: 3367 # also remove possible disable repo 3368 content = [x for x in content if not (x.startswith("#") and not x.startswith("##") and (x.find("repository|"+repodata['repoid']) != -1))] 3369 if not remove: 3370 3371 repolines = [x for x in content if x.startswith("repository|") or (x.startswith("#") and not x.startswith("##") and (x.find("repository|") != -1))] 3372 content = [x for x in content if x not in repolines] # exclude lines from repolines 3373 # filter sane repolines lines 3374 repolines = [x for x in repolines if (len(x.split("|")) == 5)] 3375 repolines_data = {} 3376 repocount = 0 3377 for x in repolines: 3378 repolines_data[repocount] = {} 3379 repolines_data[repocount]['repoid'] = x.split("|")[1] 3380 repolines_data[repocount]['line'] = x 3381 if disable and x.split("|")[1] == repodata['repoid']: 3382 if not x.startswith("#"): 3383 x = "#"+x 3384 repolines_data[repocount]['line'] = x 3385 elif enable and x.split("|")[1] == repodata['repoid'] and x.startswith("#"): 3386 repolines_data[repocount]['line'] = x[1:] 3387 repocount += 1 3388 3389 if not disable and not enable: # so it's a add 3390 3391 line = "repository|%s|%s|%s|%s#%s#%s,%s" % ( repodata['repoid'], 3392 repodata['description'], 3393 ' '.join(repodata['plain_packages']), 3394 repodata['plain_database'], 3395 repodata['dbcformat'], 3396 repodata['service_port'], 3397 repodata['ssl_service_port'], 3398 ) 3399 3400 # seek in repolines_data for a disabled entry and remove 3401 to_remove = set() 3402 for cc in repolines_data: 3403 if repolines_data[cc]['line'].startswith("#") and \ 3404 (repolines_data[cc]['line'].find("repository|"+repodata['repoid']) != -1): 3405 # then remove 3406 to_remove.add(cc) 3407 for x in to_remove: 3408 del repolines_data[x] 3409 3410 repolines_data[repocount] = {} 3411 repolines_data[repocount]['repoid'] = repodata['repoid'] 3412 repolines_data[repocount]['line'] = line 3413 3414 # inject new repodata 3415 keys = repolines_data.keys() 3416 keys.sort() 3417 for cc in keys: 3418 #repoid = repolines_data[cc]['repoid'] 3419 # write the first 3420 line = repolines_data[cc]['line'] 3421 content.append(line) 3422 3423 try: 3424 _save_repositories_content(content) 3425 except OSError: # permission denied? 3426 return False 3427 return True
3428
3429 -def _save_repositories_content(content):
3430 """ 3431 docstring_title 3432 3433 @param content: 3434 @type content: 3435 @return: 3436 @rtype: 3437 """ 3438 if os.path.isfile(etpConst['repositoriesconf']): 3439 if os.path.isfile(etpConst['repositoriesconf']+".old"): 3440 os.remove(etpConst['repositoriesconf']+".old") 3441 shutil.copy2(etpConst['repositoriesconf'], etpConst['repositoriesconf']+".old") 3442 f = open(etpConst['repositoriesconf'], "w") 3443 for x in content: 3444 f.write(x+"\n") 3445 f.flush() 3446 f.close()
3447
3448 -def write_parameter_to_file(config_file, name, data):
3449 """ 3450 docstring_title 3451 3452 @param config_file: 3453 @type config_file: 3454 @param name: 3455 @type name: 3456 @param data: 3457 @type data: 3458 @return: 3459 @rtype: 3460 """ 3461 3462 # check write perms 3463 if not os.access(os.path.dirname(config_file), os.W_OK): 3464 return False 3465 3466 content = [] 3467 if os.path.isfile(config_file): 3468 f = open(config_file, "r") 3469 content = [x.strip() for x in f.readlines()] 3470 f.close() 3471 3472 # write new 3473 config_file_tmp = config_file+".tmp" 3474 f = open(config_file_tmp, "w") 3475 param_found = False 3476 if data: 3477 proposed_line = "%s|%s" % (name, data,) 3478 myreg = re.compile('^(%s)?[|].*$' % (name,)) 3479 else: 3480 proposed_line = "# %s|" % (name,) 3481 myreg_rem = re.compile('^(%s)?[|].*$' % (name,)) 3482 myreg = re.compile('^#([ \t]+?)?(%s)?[|].*$' % (name,)) 3483 new_content = [] 3484 for line in content: 3485 if myreg_rem.match(line): 3486 continue 3487 new_content.append(line) 3488 content = new_content 3489 3490 for line in content: 3491 if myreg.match(line): 3492 param_found = True 3493 line = proposed_line 3494 f.write(line+"\n") 3495 if not param_found: 3496 f.write(proposed_line+"\n") 3497 f.flush() 3498 f.close() 3499 shutil.move(config_file_tmp, config_file) 3500 return True
3501
3502 -def write_new_branch(branch):
3503 """ 3504 docstring_title 3505 3506 @param branch: 3507 @type branch: 3508 @return: 3509 @rtype: 3510 """ 3511 return write_parameter_to_file(etpConst['repositoriesconf'], "branch", 3512 branch)
3513
3514 -def is_entropy_package_file(tbz2file):
3515 """ 3516 docstring_title 3517 3518 @param tbz2file: 3519 @type tbz2file: 3520 @return: 3521 @rtype: 3522 """ 3523 if not os.path.exists(tbz2file): 3524 return False 3525 try: 3526 obj = open(tbz2file, "r") 3527 entry_point = locate_edb(obj) 3528 if entry_point is None: 3529 obj.close() 3530 return False 3531 obj.close() 3532 return True 3533 except (IOError, OSError,): 3534 return False
3535
3536 -def is_valid_string(string):
3537 """ 3538 docstring_title 3539 3540 @param string: 3541 @type string: 3542 @return: 3543 @rtype: 3544 """ 3545 invalid = [ord(x) for x in string if ord(x) not in xrange(32, 127)] 3546 if invalid: return False 3547 return True
3548
3549 -def is_valid_path(path):
3550 """ 3551 docstring_title 3552 3553 @param path: 3554 @type path: 3555 @return: 3556 @rtype: 3557 """ 3558 try: 3559 os.stat(path) 3560 except OSError: 3561 return False 3562 return True
3563
3564 -def is_valid_md5(myhash):
3565 """ 3566 docstring_title 3567 3568 @param myhash: 3569 @type myhash: 3570 @return: 3571 @rtype: 3572 """ 3573 if re.findall(r'(?i)(?<![a-z0-9])[a-f0-9]{32}(?![a-z0-9])', myhash): 3574 return True 3575 return False
3576
3577 -def open_buffer():
3578 """ 3579 docstring_title 3580 3581 @return: 3582 @rtype: 3583 """ 3584 try: 3585 import cStringIO as stringio 3586 except ImportError: 3587 import StringIO as stringio 3588 return stringio.StringIO()
3589
3590 -def seek_till_newline(f):
3591 """ 3592 docstring_title 3593 3594 @param f: 3595 @type f: 3596 @return: 3597 @rtype: 3598 """ 3599 count = 0 3600 f.seek(count, os.SEEK_END) 3601 size = f.tell() 3602 while count > (size*-1): 3603 count -= 1 3604 f.seek(count, os.SEEK_END) 3605 myc = f.read(1) 3606 if myc == "\n": 3607 break 3608 f.seek(count+1, os.SEEK_END) 3609 pos = f.tell() 3610 f.truncate(pos)
3611
3612 -def read_elf_class(elf_file):
3613 """ 3614 docstring_title 3615 3616 @param elf_file: 3617 @type elf_file: 3618 @return: 3619 @rtype: 3620 """ 3621 import struct 3622 f = open(elf_file, "rb") 3623 f.seek(4) 3624 elf_class = f.read(1) 3625 f.close() 3626 elf_class = struct.unpack('B', elf_class)[0] 3627 return elf_class
3628
3629 -def is_elf_file(elf_file):
3630 """ 3631 docstring_title 3632 3633 @param elf_file: 3634 @type elf_file: 3635 @return: 3636 @rtype: 3637 """ 3638 import struct 3639 f = open(elf_file, "rb") 3640 data = f.read(4) 3641 f.close() 3642 try: 3643 data = struct.unpack('BBBB', data) 3644 except struct.error: 3645 return False 3646 if data == (127, 69, 76, 70): 3647 return True 3648 return False
3649
3650 -def resolve_dynamic_library(library, requiring_executable):
3651 """ 3652 Resolve given library name (as contained into ELF metadata) to 3653 a library path. 3654 3655 @param library: library name (as contained into ELF metadata) 3656 @type library: string 3657 @param requiring_executable: path to ELF object that contains the given 3658 library name 3659 @type requiring_executable: string 3660 @return: resolved library path 3661 @rtype: string 3662 """ 3663 def do_resolve(mypaths): 3664 """ 3665 docstring_title 3666 3667 @param mypaths: 3668 @type mypaths: 3669 @return: 3670 @rtype: 3671 """ 3672 found_path = None 3673 for mypath in mypaths: 3674 mypath = os.path.join(etpConst['systemroot']+mypath, library) 3675 if not os.access(mypath, os.R_OK): 3676 continue 3677 if os.path.isdir(mypath): 3678 continue 3679 if not is_elf_file(mypath): 3680 continue 3681 found_path = mypath 3682 break 3683 return found_path
3684 3685 mypaths = collect_linker_paths() 3686 found_path = do_resolve(mypaths) 3687 3688 if not found_path: 3689 mypaths = read_elf_linker_paths(requiring_executable) 3690 found_path = do_resolve(mypaths) 3691 3692 return found_path 3693 3694 readelf_avail_check = False 3695 ldd_avail_check = False
3696 -def read_elf_dynamic_libraries(elf_file):
3697 """ 3698 docstring_title 3699 3700 @param elf_file: 3701 @type elf_file: 3702 @return: 3703 @rtype: 3704 """ 3705 global readelf_avail_check 3706 if not readelf_avail_check: 3707 if not os.access(etpConst['systemroot']+"/usr/bin/readelf", os.X_OK): 3708 FileNotFound('FileNotFound: no readelf') 3709 readelf_avail_check = True 3710 return set([x.strip().split()[-1][1:-1] for x in getstatusoutput('/usr/bin/readelf -d %s' % (elf_file,))[1].split("\n") if (x.find("(NEEDED)") != -1)])
3711
3712 -def read_elf_broken_symbols(elf_file):
3713 """ 3714 docstring_title 3715 3716 @param elf_file: 3717 @type elf_file: 3718 @return: 3719 @rtype: 3720 """ 3721 global ldd_avail_check 3722 if not ldd_avail_check: 3723 if not os.access(etpConst['systemroot']+"/usr/bin/ldd", os.X_OK): 3724 FileNotFound('FileNotFound: no ldd') 3725 ldd_avail_check = True 3726 return set([x.strip().split("\t")[0].split()[-1] for x in getstatusoutput('/usr/bin/ldd -r %s' % (elf_file,))[1].split("\n") if (x.find("undefined symbol:") != -1)])
3727
3728 -def read_elf_linker_paths(elf_file):
3729 """ 3730 docstring_title 3731 3732 @param elf_file: 3733 @type elf_file: 3734 @return: 3735 @rtype: 3736 """ 3737 global readelf_avail_check 3738 if not readelf_avail_check: 3739 if not os.access(etpConst['systemroot']+"/usr/bin/readelf", os.X_OK): 3740 FileNotFound('FileNotFound: no readelf') 3741 readelf_avail_check = True 3742 data = [x.strip().split()[-1][1:-1].split(":") for x in getstatusoutput('readelf -d %s' % (elf_file,))[1].split("\n") if not ((x.find("(RPATH)") == -1) and (x.find("(RUNPATH)") == -1))] 3743 mypaths = [] 3744 for mypath in data: 3745 for xpath in mypath: 3746 xpath = xpath.replace("$ORIGIN", os.path.dirname(elf_file)) 3747 mypaths.append(xpath) 3748 return mypaths
3749
3750 -def xml_from_dict_extended(dictionary):
3751 """ 3752 docstring_title 3753 3754 @param dictionary: 3755 @type dictionary: 3756 @return: 3757 @rtype: 3758 """ 3759 from xml.dom import minidom 3760 doc = minidom.Document() 3761 ugc = doc.createElement("entropy") 3762 for key, value in dictionary.items(): 3763 item = doc.createElement('item') 3764 item.setAttribute('value', key) 3765 if isinstance(value, str): 3766 mytype = "str" 3767 elif isinstance(value, unicode): 3768 mytype = "unicode" 3769 elif isinstance(value, list): 3770 mytype = "list" 3771 elif isinstance(value, set): 3772 mytype = "set" 3773 elif isinstance(value, frozenset): 3774 mytype = "frozenset" 3775 elif isinstance(value, dict): 3776 mytype = "dict" 3777 elif isinstance(value, tuple): 3778 mytype = "tuple" 3779 elif isinstance(value, int): 3780 mytype = "int" 3781 elif isinstance(value, float): 3782 mytype = "float" 3783 elif value == None: 3784 mytype = "None" 3785 value = "None" 3786 else: TypeError 3787 item.setAttribute('type', mytype) 3788 item_value = doc.createTextNode("%s" % (value,)) 3789 item.appendChild(item_value) 3790 ugc.appendChild(item) 3791 doc.appendChild(ugc) 3792 return doc.toxml()
3793
3794 -def dict_from_xml_extended(xml_string):
3795 """ 3796 docstring_title 3797 3798 @param xml_string: 3799 @type xml_string: 3800 @return: 3801 @rtype: 3802 """ 3803 from xml.dom import minidom 3804 doc = minidom.parseString(xml_string) 3805 entropies = doc.getElementsByTagName("entropy") 3806 if not entropies: 3807 return {} 3808 entropy = entropies[0] 3809 items = entropy.getElementsByTagName('item') 3810 3811 my_map = { 3812 "str": str, 3813 "unicode": unicode, 3814 "list": list, 3815 "set": set, 3816 "frozenset": frozenset, 3817 "dict": dict, 3818 "tuple": tuple, 3819 "int": int, 3820 "float": float, 3821 "None": None, 3822 } 3823 3824 mydict = {} 3825 for item in items: 3826 key = item.getAttribute('value') 3827 if not key: continue 3828 mytype = item.getAttribute('type') 3829 mytype_m = my_map.get(mytype) 3830 if mytype_m == None: TypeError 3831 try: 3832 data = item.firstChild.data 3833 except AttributeError: 3834 data = '' 3835 if mytype in ("list", "set", "frozenset", "dict", "tuple",): 3836 if data: 3837 if data[0] not in ("(", "[", "s", "{",): 3838 data = '' 3839 mydict[key] = eval(data) 3840 elif mytype == "None": 3841 mydict[key] = None 3842 else: 3843 mydict[key] = mytype_m(data) 3844 return mydict
3845
3846 -def xml_from_dict(dictionary):
3847 """ 3848 docstring_title 3849 3850 @param dictionary: 3851 @type dictionary: 3852 @return: 3853 @rtype: 3854 """ 3855 from xml.dom import minidom 3856 doc = minidom.Document() 3857 ugc = doc.createElement("entropy") 3858 for key, value in dictionary.items(): 3859 item = doc.createElement('item') 3860 item.setAttribute('value', key) 3861 item_value = doc.createTextNode(value) 3862 item.appendChild(item_value) 3863 ugc.appendChild(item) 3864 doc.appendChild(ugc) 3865 return doc.toxml()
3866
3867 -def dict_from_xml(xml_string):
3868 """ 3869 docstring_title 3870 3871 @param xml_string: 3872 @type xml_string: 3873 @return: 3874 @rtype: 3875 """ 3876 from xml.dom import minidom 3877 doc = minidom.parseString(xml_string) 3878 entropies = doc.getElementsByTagName("entropy") 3879 if not entropies: 3880 return {} 3881 entropy = entropies[0] 3882 items = entropy.getElementsByTagName('item') 3883 mydict = {} 3884 for item in items: 3885 key = item.getAttribute('value') 3886 if not key: 3887 continue 3888 try: 3889 data = item.firstChild.data 3890 except AttributeError: 3891 data = '' 3892 mydict[key] = data 3893 return mydict
3894
3895 -def create_package_filename(category, name, version, package_tag):
3896 """ 3897 docstring_title 3898 3899 @param category: 3900 @type category: 3901 @param name: 3902 @type name: 3903 @param version: 3904 @type version: 3905 @param package_tag: 3906 @type package_tag: 3907 @return: 3908 @rtype: 3909 """ 3910 if package_tag: 3911 package_tag = "#%s" % (package_tag,) 3912 else: 3913 package_tag = '' 3914 3915 package_name = "%s:%s-%s" % (category, name, version,) 3916 package_name += package_tag 3917 package_name += etpConst['packagesext'] 3918 return package_name
3919
3920 -def create_package_atom_string(category, name, version, package_tag):
3921 """ 3922 docstring_title 3923 3924 @param category: 3925 @type category: 3926 @param name: 3927 @type name: 3928 @param version: 3929 @type version: 3930 @param package_tag: 3931 @type package_tag: 3932 @return: 3933 @rtype: 3934 """ 3935 if package_tag: 3936 package_tag = "#%s" % (package_tag,) 3937 else: 3938 package_tag = '' 3939 package_name = "%s/%s-%s" % (category, name, version,) 3940 package_name += package_tag 3941 return package_name
3942
3943 -def extract_packages_from_set_file(filepath):
3944 """ 3945 docstring_title 3946 3947 @param filepath: 3948 @type filepath: 3949 @return: 3950 @rtype: 3951 """ 3952 f = open(filepath, "r") 3953 items = set() 3954 line = f.readline() 3955 while line: 3956 x = line.strip().rsplit("#", 1)[0] 3957 if x and (not x.startswith('#')): 3958 items.add(x) 3959 line = f.readline() 3960 f.close() 3961 return items
3962
3963 -def collect_linker_paths():
3964 """ 3965 docstring_title 3966 3967 @return: 3968 @rtype: 3969 """ 3970 3971 ldpaths = [] 3972 try: 3973 f = open(etpConst['systemroot']+"/etc/ld.so.conf", "r") 3974 paths = f.readlines() 3975 for path in paths: 3976 path = path.strip() 3977 if path: 3978 if path[0] == "/": 3979 ldpaths.append(os.path.normpath(path)) 3980 f.close() 3981 except (IOError, OSError, TypeError, ValueError, IndexError,): 3982 pass 3983 3984 # can happen that /lib /usr/lib are not in LDPATH 3985 if "/lib" not in ldpaths: 3986 ldpaths.append("/lib") 3987 if "/usr/lib" not in ldpaths: 3988 ldpaths.append("/usr/lib") 3989 3990 return ldpaths
3991
3992 -def collect_paths():
3993 """ 3994 docstring_title 3995 3996 @return: 3997 @rtype: 3998 """ 3999 path = set() 4000 paths = os.getenv("PATH") 4001 if paths != None: 4002 paths = set(paths.split(":")) 4003 path |= paths 4004 return path
4005
4006 -def list_to_utf8(mylist):
4007 """ 4008 docstring_title 4009 4010 @param mylist: 4011 @type mylist: 4012 @return: 4013 @rtype: 4014 """ 4015 mynewlist = [] 4016 for item in mylist: 4017 try: 4018 mynewlist.append(item.decode("utf-8")) 4019 except UnicodeDecodeError: 4020 try: 4021 mynewlist.append(item.decode("latin1").decode("utf-8")) 4022 except: 4023 raise 4024 return mynewlist
4025