X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils.py;h=2f42cb39a617f8d794158d45ad964e4e239e62fb;hb=502dd2a56d9a8dc58555874e54808b071acb6799;hp=1afcb77b0ae9caaabab1433785a15584bd028169;hpb=5cd51865d3ea349934a3b40a31b46e9d9a81dad4;p=dak.git diff --git a/utils.py b/utils.py index 1afcb77b..2f42cb39 100644 --- a/utils.py +++ b/utils.py @@ -1,6 +1,6 @@ # Utility functions # Copyright (C) 2000 James Troup -# $Id: utils.py,v 1.2 2000-11-25 04:18:30 troup Exp $ +# $Id: utils.py,v 1.13 2001-01-28 09:06:44 troup Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,10 +25,12 @@ re_arch_from_filename = re.compile(r"/binary-[^/]+/") re_extract_src_version = re.compile (r"(\S+)\s*\((.*)\)") changes_parse_error_exc = "Can't parse line in .changes file"; +invalid_dsc_format_exc = "Invalid .dsc file"; nk_format_exc = "Unknown Format: in .changes file"; no_files_exc = "No Files: field in .dsc file."; cant_open_exc = "Can't read file."; unknown_hostname_exc = "Unknown hostname"; +cant_overwrite_exc = "Permission denied; can't overwrite existent file." ###################################################################################### @@ -53,15 +55,81 @@ def our_raw_input(): ###################################################################################### -def parse_changes(filename): +# What a mess. FIXME +def extract_component_from_section(section): + component = ""; + + if string.find(section, '/') != -1: + component = string.split(section, '/')[0]; + if string.lower(component) == "non-us" and string.count(section, '/') > 0: + s = string.split(section, '/')[1]; + if s == "main" or s == "non-free" or s == "contrib": # Avoid e.g. non-US/libs + component = string.split(section, '/')[0]+ '/' + string.split(section, '/')[1]; + + if string.lower(section) == "non-us": + component = "non-US/main"; + + if component == "": + component = "main"; + elif string.lower(component) == "non-us": + component = "non-US/main"; + + return (section, component); + +###################################################################################### + +# dsc_whitespace_rules turns on strict format checking to avoid +# allowing in source packages which are unextracable by the +# inappropriately fragile dpkg-source. +# +# The rules are: +# +# +# o The PGP header consists of "-----BEGIN PGP SIGNED MESSAGE-----" +# followed by any PGP header data and must end with a blank line. +# +# o The data section must end with a blank line and must be followed by +# "-----BEGIN PGP SIGNATURE-----". + +def parse_changes(filename, dsc_whitespace_rules): changes_in = open_file(filename,'r'); - error = "" + error = ""; changes = {}; lines = changes_in.readlines(); + + # Reindex by line number so we can easily verify the format of + # .dsc files... + index = 0; + indexed_lines = {}; for line in lines: + index = index + 1; + indexed_lines[index] = line[:-1]; + + inside_signature = 0; + + indices = indexed_lines.keys() + index = 0; + while index < max(indices): + index = index + 1; + line = indexed_lines[index]; + if line == "": + if dsc_whitespace_rules: + index = index + 1; + if index > max(indices): + raise invalid_dsc_format_exc, index; + line = indexed_lines[index]; + if not re.match('^-----BEGIN PGP SIGNATURE', line): + raise invalid_dsc_format_exc, index; + inside_signature = 0; + break; if re.match('^-----BEGIN PGP SIGNATURE', line): break; - if re.match(r'^\s*$|^-----BEGIN PGP SIGNED MESSAGE', line): + if re.match(r'^-----BEGIN PGP SIGNED MESSAGE', line): + if dsc_whitespace_rules: + inside_signature = 1; + while index < max(indices) and line != "": + index = index + 1; + line = indexed_lines[index]; continue; slf = re.match(r'^(\S*)\s*:\s*(.*)', line); if slf: @@ -77,10 +145,16 @@ def parse_changes(filename): changes[field] = changes[field] + mlf.groups()[0] + '\n'; continue; error = error + line; + + if dsc_whitespace_rules and inside_signature: + raise invalid_dsc_format_exc, index; + changes_in.close(); changes["filecontents"] = string.join (lines, ""); + if error != "": raise changes_parse_error_exc, error; + return changes; ###################################################################################### @@ -103,30 +177,19 @@ def build_file_list(changes, dsc): if i == "": break s = string.split(i) - section = priority = component = "" - if dsc != "": - (md5, size, name) = s - else: - (md5, size, section, priority, name) = s + section = priority = ""; + try: + if dsc != "": + (md5, size, name) = s + else: + (md5, size, section, priority, name) = s + except ValueError: + raise changes_parse_error_exc, i if section == "": section = "-" if priority == "": priority = "-" - # What a mess. FIXME - if string.find(section, '/') != -1: - component = string.split(section, '/')[0] - if string.lower(component) == "non-us" and string.count(section, '/') > 1: - s = string.split(section, '/')[1] - if s == "main" or s == "non-free" or s == "contrib": # Avoid e.g. non-US/libs - component = string.split(section, '/')[0]+ '/' + string.split(section, '/')[1] - - if string.lower(section) == "non-us": - component = "non-US/main"; - - if component == "": - component = "main"; - elif string.lower(component) == "non-us": - component = "non-US/main"; + (section, component) = extract_component_from_section(section); files[name] = { "md5sum" : md5, "size" : size, @@ -188,6 +251,9 @@ def send_mail (message, filename): def poolify (source, component): if component != "": component = component + '/'; + # FIXME: this is nasty + component = string.lower(component); + component = string.replace(component, 'non-us/', 'non-US/'); if source[:3] == "lib": return component + source[:4] + '/' + source + '/' else: @@ -196,7 +262,7 @@ def poolify (source, component): ###################################################################################### def move (src, dest): - if os.path.exists(dest) and stat.S_ISDIR(os.stat(dest)[stat.ST_MODE]): + if os.path.exists(dest) and os.path.isdir(dest): dest_dir = dest; else: dest_dir = os.path.dirname(dest); @@ -205,10 +271,32 @@ def move (src, dest): os.makedirs(dest_dir, 02775); os.umask(umask); #print "Moving %s to %s..." % (src, dest); + if os.path.exists(dest) and os.path.isdir(dest): + dest = dest + '/' + os.path.basename(src); + # Check for overwrite permission on existent files + if os.path.exists(dest) and not os.access(dest, os.W_OK): + raise cant_overwrite_exc shutil.copy2(src, dest); os.chmod(dest, 0664); os.unlink(src); +def copy (src, dest): + if os.path.exists(dest) and os.path.isdir(dest): + dest_dir = dest; + else: + dest_dir = os.path.dirname(dest); + if not os.path.exists(dest_dir): + umask = os.umask(00000); + os.makedirs(dest_dir, 02775); + os.umask(umask); + #print "Copying %s to %s..." % (src, dest); + if os.path.exists(dest) and os.path.isdir(dest): + dest = dest + '/' + os.path.basename(src); + if os.path.exists(dest) and not os.access(dest, os.W_OK): + raise cant_overwrite_exc + shutil.copy2(src, dest); + os.chmod(dest, 0664); + ###################################################################################### # FIXME: this is inherently nasty. Can't put this mapping in a conf @@ -219,7 +307,7 @@ def where_am_i (): res = socket.gethostbyaddr(socket.gethostname()); if res[0] == 'pandora.debian.org': return 'non-US'; - elif res[1] == 'auric.debian.org': + elif res[0] == 'auric.debian.org': return 'ftp-master'; else: raise unknown_hostname_exc, res; @@ -239,3 +327,21 @@ def which_conf_file (): ###################################################################################### +# Escape characters which have meaning to SQL's regex comparison operator ('~') +# (woefully incomplete) + +def regex_safe (s): + s = string.replace(s, '+', '\\\\+'); + return s + +###################################################################################### + +def size_type (c): + t = " b"; + if c > 10000: + c = c / 1000; + t = " Kb"; + if c > 10000: + c = c / 1000; + t = " Mb"; + return ("%d%s" % (c, t))