Package entropy :: Module tools

Source Code for Module entropy.tools

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