X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=dak%2Flib%2Futils.py;h=4b103f53a30fa495318002f0c93b42d377c7aed7;hb=06ce98c8111a8b09e5603dbbd34324a216412d69;hp=580ceda8d0920734dafd0a9ce65951b638a419fc;hpb=59fd5aa2a8be3b76dbc968429c457f096adfa472;p=dak.git diff --git a/dak/lib/utils.py b/dak/lib/utils.py index 580ceda8..4b103f53 100644 --- a/dak/lib/utils.py +++ b/dak/lib/utils.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Utility functions -# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 James Troup +# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 James Troup # $Id: utils.py,v 1.73 2005-03-18 05:24:38 troup Exp $ ################################################################################ @@ -23,9 +23,9 @@ ################################################################################ import codecs, commands, email.Header, os, pwd, re, select, socket, shutil, \ - string, sys, tempfile, traceback; -import apt_pkg; -import db_access; + string, sys, tempfile, traceback +import apt_pkg +import dak.lib.database ################################################################################ @@ -34,34 +34,34 @@ re_no_epoch = re.compile(r"^\d+\:") re_no_revision = re.compile(r"-[^-]+$") re_arch_from_filename = re.compile(r"/binary-[^/]+/") re_extract_src_version = re.compile (r"(\S+)\s*\((.*)\)") -re_isadeb = re.compile (r"(.+?)_(.+?)_(.+)\.u?deb$"); -re_issource = re.compile (r"(.+)_(.+?)\.(orig\.tar\.gz|diff\.gz|tar\.gz|dsc)$"); +re_isadeb = re.compile (r"(.+?)_(.+?)_(.+)\.u?deb$") +re_issource = re.compile (r"(.+)_(.+?)\.(orig\.tar\.gz|diff\.gz|tar\.gz|dsc)$") -re_single_line_field = re.compile(r"^(\S*)\s*:\s*(.*)"); -re_multi_line_field = re.compile(r"^\s(.*)"); -re_taint_free = re.compile(r"^[-+~/\.\w]+$"); +re_single_line_field = re.compile(r"^(\S*)\s*:\s*(.*)") +re_multi_line_field = re.compile(r"^\s(.*)") +re_taint_free = re.compile(r"^[-+~/\.\w]+$") -re_parse_maintainer = re.compile(r"^\s*(\S.*\S)\s*\<([^\>]+)\>"); +re_parse_maintainer = re.compile(r"^\s*(\S.*\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 or .changes file."; -cant_open_exc = "Can't open file"; -unknown_hostname_exc = "Unknown hostname"; +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 or .changes file." +cant_open_exc = "Can't open file" +unknown_hostname_exc = "Unknown hostname" cant_overwrite_exc = "Permission denied; can't overwrite existent file." -file_exists_exc = "Destination file exists"; -sendmail_failed_exc = "Sendmail invocation failed"; -tried_too_hard_exc = "Tried too hard to find a free filename."; +file_exists_exc = "Destination file exists" +sendmail_failed_exc = "Sendmail invocation failed" +tried_too_hard_exc = "Tried too hard to find a free filename." -default_config = "/etc/katie/katie.conf"; -default_apt_config = "/etc/katie/apt.conf"; +default_config = "/etc/dak/dak.conf" +default_apt_config = "/etc/dak/apt.conf" ################################################################################ class Error(Exception): """Base class for exceptions in this module.""" - pass; + pass class ParseMaintError(Error): """Exception raised for errors in parsing a maintainer field. @@ -71,68 +71,68 @@ class ParseMaintError(Error): """ def __init__(self, message): - self.args = message,; - self.message = message; + self.args = message, + self.message = message ################################################################################ def open_file(filename, mode='r'): try: - f = open(filename, mode); + f = open(filename, mode) except IOError: - raise cant_open_exc, filename; + raise cant_open_exc, filename return f ################################################################################ def our_raw_input(prompt=""): if prompt: - sys.stdout.write(prompt); - sys.stdout.flush(); + sys.stdout.write(prompt) + sys.stdout.flush() try: - ret = raw_input(); - return ret; + ret = raw_input() + return ret except EOFError: - sys.stderr.write("\nUser interrupt (^D).\n"); - raise SystemExit; + sys.stderr.write("\nUser interrupt (^D).\n") + raise SystemExit ################################################################################ def str_isnum (s): for c in s: if c not in string.digits: - return 0; - return 1; + return 0 + return 1 ################################################################################ def extract_component_from_section(section): - component = ""; + component = "" if section.find('/') != -1: - component = section.split('/')[0]; + component = section.split('/')[0] if component.lower() == "non-us" and section.find('/') != -1: - s = component + '/' + section.split('/')[1]; + s = component + '/' + section.split('/')[1] if Cnf.has_key("Component::%s" % s): # Avoid e.g. non-US/libs - component = s; + component = s if section.lower() == "non-us": - component = "non-US/main"; + component = "non-US/main" # non-US prefix is case insensitive if component.lower()[:6] == "non-us": - component = "non-US"+component[6:]; + component = "non-US"+component[6:] # Expand default component if component == "": if Cnf.has_key("Component::%s" % section): - component = section; + component = section else: - component = "main"; + component = "main" elif component == "non-US": - component = "non-US/main"; + component = "non-US/main" - return (section, component); + return (section, component) ################################################################################ @@ -157,127 +157,127 @@ The rules for (signing_rules == 1)-mode are: "-----BEGIN PGP SIGNATURE-----". """ - error = ""; - changes = {}; + error = "" + changes = {} - changes_in = open_file(filename); - lines = changes_in.readlines(); + changes_in = open_file(filename) + lines = changes_in.readlines() if not lines: - raise changes_parse_error_exc, "[Empty changes file]"; + raise changes_parse_error_exc, "[Empty changes file]" # Reindex by line number so we can easily verify the format of # .dsc files... - index = 0; - indexed_lines = {}; + index = 0 + indexed_lines = {} for line in lines: - index += 1; - indexed_lines[index] = line[:-1]; + index += 1 + indexed_lines[index] = line[:-1] - inside_signature = 0; + inside_signature = 0 - num_of_lines = len(indexed_lines.keys()); - index = 0; - first = -1; + num_of_lines = len(indexed_lines.keys()) + index = 0 + first = -1 while index < num_of_lines: - index += 1; - line = indexed_lines[index]; + index += 1 + line = indexed_lines[index] if line == "": if signing_rules == 1: - index += 1; + index += 1 if index > num_of_lines: - raise invalid_dsc_format_exc, index; - line = indexed_lines[index]; + raise invalid_dsc_format_exc, index + line = indexed_lines[index] if not line.startswith("-----BEGIN PGP SIGNATURE"): - raise invalid_dsc_format_exc, index; - inside_signature = 0; - break; + raise invalid_dsc_format_exc, index + inside_signature = 0 + break else: - continue; + continue if line.startswith("-----BEGIN PGP SIGNATURE"): - break; + break if line.startswith("-----BEGIN PGP SIGNED MESSAGE"): - inside_signature = 1; + inside_signature = 1 if signing_rules == 1: while index < num_of_lines and line != "": - index += 1; - line = indexed_lines[index]; - continue; + index += 1 + line = indexed_lines[index] + continue # If we're not inside the signed data, don't process anything if signing_rules >= 0 and not inside_signature: - continue; - slf = re_single_line_field.match(line); + continue + slf = re_single_line_field.match(line) if slf: - field = slf.groups()[0].lower(); - changes[field] = slf.groups()[1]; - first = 1; - continue; + field = slf.groups()[0].lower() + changes[field] = slf.groups()[1] + first = 1 + continue if line == " .": - changes[field] += '\n'; - continue; - mlf = re_multi_line_field.match(line); + changes[field] += '\n' + continue + mlf = re_multi_line_field.match(line) if mlf: if first == -1: - raise changes_parse_error_exc, "'%s'\n [Multi-line field continuing on from nothing?]" % (line); + raise changes_parse_error_exc, "'%s'\n [Multi-line field continuing on from nothing?]" % (line) if first == 1 and changes[field] != "": - changes[field] += '\n'; - first = 0; - changes[field] += mlf.groups()[0] + '\n'; - continue; - error += line; + changes[field] += '\n' + first = 0 + changes[field] += mlf.groups()[0] + '\n' + continue + error += line if signing_rules == 1 and inside_signature: - raise invalid_dsc_format_exc, index; + raise invalid_dsc_format_exc, index - changes_in.close(); - changes["filecontents"] = "".join(lines); + changes_in.close() + changes["filecontents"] = "".join(lines) if error: - raise changes_parse_error_exc, error; + raise changes_parse_error_exc, error - return changes; + return changes ################################################################################ # Dropped support for 1.4 and ``buggy dchanges 3.4'' (?!) compared to di.pl def build_file_list(changes, is_a_dsc=0): - files = {}; + files = {} # Make sure we have a Files: field to parse... if not changes.has_key("files"): - raise no_files_exc; + raise no_files_exc # Make sure we recognise the format of the Files: field - format = changes.get("format", ""); + format = changes.get("format", "") if format != "": - format = float(format); + format = float(format) if not is_a_dsc and (format < 1.5 or format > 2.0): - raise nk_format_exc, format; + raise nk_format_exc, format # Parse each entry/line: for i in changes["files"].split('\n'): if not i: - break; - s = i.split(); - section = priority = ""; + break + s = i.split() + section = priority = "" try: if is_a_dsc: - (md5, size, name) = s; + (md5, size, name) = s else: - (md5, size, section, priority, name) = s; + (md5, size, section, priority, name) = s except ValueError: - raise changes_parse_error_exc, i; + raise changes_parse_error_exc, i if section == "": - section = "-"; + section = "-" if priority == "": - priority = "-"; + priority = "-" - (section, component) = extract_component_from_section(section); + (section, component) = extract_component_from_section(section) files[name] = Dict(md5sum=md5, size=size, section=section, - priority=priority, component=component); + priority=priority, component=component) return files @@ -287,27 +287,27 @@ def force_to_utf8(s): """Forces a string to UTF-8. If the string isn't already UTF-8, it's assumed to be ISO-8859-1.""" try: - unicode(s, 'utf-8'); - return s; + unicode(s, 'utf-8') + return s except UnicodeError: - latin1_s = unicode(s,'iso8859-1'); - return latin1_s.encode('utf-8'); + latin1_s = unicode(s,'iso8859-1') + return latin1_s.encode('utf-8') def rfc2047_encode(s): """Encodes a (header) string per RFC2047 if necessary. If the string is neither ASCII nor UTF-8, it's assumed to be ISO-8859-1.""" try: codecs.lookup('ascii')[1](s) - return s; + return s except UnicodeError: - pass; + pass try: codecs.lookup('utf-8')[1](s) - h = email.Header.Header(s, 'utf-8', 998); - return str(h); + h = email.Header.Header(s, 'utf-8', 998) + return str(h) except UnicodeError: - h = email.Header.Header(s, 'iso-8859-1', 998); - return str(h); + h = email.Header.Header(s, 'iso-8859-1', 998) + return str(h) ################################################################################ @@ -327,38 +327,38 @@ contains '.' or ',' (as allowed by Debian policy), (1) and (2) are switched to 'email (name)' format.""" maintainer = maintainer.strip() if not maintainer: - return ('', '', '', ''); + return ('', '', '', '') if maintainer.find("<") == -1: - email = maintainer; - name = ""; + email = maintainer + name = "" elif (maintainer[0] == "<" and maintainer[-1:] == ">"): - email = maintainer[1:-1]; - name = ""; + email = maintainer[1:-1] + name = "" else: - m = re_parse_maintainer.match(maintainer); + m = re_parse_maintainer.match(maintainer) if not m: raise ParseMaintError, "Doesn't parse as a valid Maintainer field." - name = m.group(1); - email = m.group(2); + name = m.group(1) + email = m.group(2) # Get an RFC2047 compliant version of the name - rfc2047_name = rfc2047_encode(name); + rfc2047_name = rfc2047_encode(name) # Force the name to be UTF-8 - name = force_to_utf8(name); + name = force_to_utf8(name) if name.find(',') != -1 or name.find('.') != -1: - rfc822_maint = "%s (%s)" % (email, name); - rfc2047_maint = "%s (%s)" % (email, rfc2047_name); + rfc822_maint = "%s (%s)" % (email, name) + rfc2047_maint = "%s (%s)" % (email, rfc2047_name) else: - rfc822_maint = "%s <%s>" % (name, email); - rfc2047_maint = "%s <%s>" % (rfc2047_name, email); + rfc822_maint = "%s <%s>" % (name, email) + rfc2047_maint = "%s <%s>" % (rfc2047_name, email) if email.find("@") == -1 and email.find("buildd_") != 0: raise ParseMaintError, "No @ found in email address part." - return (rfc822_maint, rfc2047_maint, name, email); + return (rfc822_maint, rfc2047_maint, name, email) ################################################################################ @@ -366,27 +366,27 @@ switched to 'email (name)' format.""" def send_mail (message, filename=""): # If we've been passed a string dump it into a temporary file if message: - filename = tempfile.mktemp(); - fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700); - os.write (fd, message); - os.close (fd); + filename = tempfile.mktemp() + fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700) + os.write (fd, message) + os.close (fd) # Invoke sendmail - (result, output) = commands.getstatusoutput("%s < %s" % (Cnf["Dinstall::SendmailCommand"], filename)); + (result, output) = commands.getstatusoutput("%s < %s" % (Cnf["Dinstall::SendmailCommand"], filename)) if (result != 0): - raise sendmail_failed_exc, output; + raise sendmail_failed_exc, output # Clean up any temporary files if message: - os.unlink (filename); + os.unlink (filename) ################################################################################ def poolify (source, component): if component: - component += '/'; + component += '/' # FIXME: this is nasty - component = component.lower().replace("non-us/", "non-US/"); + component = component.lower().replace("non-us/", "non-US/") if source[:3] == "lib": return component + source[:4] + '/' + source + '/' else: @@ -396,39 +396,39 @@ def poolify (source, component): def move (src, dest, overwrite = 0, perms = 0664): if os.path.exists(dest) and os.path.isdir(dest): - dest_dir = dest; + dest_dir = dest else: - dest_dir = os.path.dirname(dest); + 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 "Moving %s to %s..." % (src, dest); + umask = os.umask(00000) + 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 += '/' + os.path.basename(src); + dest += '/' + os.path.basename(src) # Don't overwrite unless forced to if os.path.exists(dest): if not overwrite: - fubar("Can't move %s to %s - file already exists." % (src, dest)); + fubar("Can't move %s to %s - file already exists." % (src, dest)) else: if not os.access(dest, os.W_OK): - fubar("Can't move %s to %s - can't write to existing file." % (src, dest)); - shutil.copy2(src, dest); - os.chmod(dest, perms); - os.unlink(src); + fubar("Can't move %s to %s - can't write to existing file." % (src, dest)) + shutil.copy2(src, dest) + os.chmod(dest, perms) + os.unlink(src) def copy (src, dest, overwrite = 0, perms = 0664): if os.path.exists(dest) and os.path.isdir(dest): - dest_dir = dest; + dest_dir = dest else: - dest_dir = os.path.dirname(dest); + 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); + 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 += '/' + os.path.basename(src); + dest += '/' + os.path.basename(src) # Don't overwrite unless forced to if os.path.exists(dest): if not overwrite: @@ -436,32 +436,32 @@ def copy (src, dest, overwrite = 0, perms = 0664): else: if not os.access(dest, os.W_OK): raise cant_overwrite_exc - shutil.copy2(src, dest); - os.chmod(dest, perms); + shutil.copy2(src, dest) + os.chmod(dest, perms) ################################################################################ def where_am_i (): - res = socket.gethostbyaddr(socket.gethostname()); - database_hostname = Cnf.get("Config::" + res[0] + "::DatabaseHostname"); + res = socket.gethostbyaddr(socket.gethostname()) + database_hostname = Cnf.get("Config::" + res[0] + "::DatabaseHostname") if database_hostname: - return database_hostname; + return database_hostname else: - return res[0]; + return res[0] def which_conf_file (): - res = socket.gethostbyaddr(socket.gethostname()); - if Cnf.get("Config::" + res[0] + "::KatieConfig"): - return Cnf["Config::" + res[0] + "::KatieConfig"] + res = socket.gethostbyaddr(socket.gethostname()) + if Cnf.get("Config::" + res[0] + "::DakConfig"): + return Cnf["Config::" + res[0] + "::DakConfig"] else: - return default_config; + return default_config def which_apt_conf_file (): - res = socket.gethostbyaddr(socket.gethostname()); + res = socket.gethostbyaddr(socket.gethostname()) if Cnf.get("Config::" + res[0] + "::AptConfig"): return Cnf["Config::" + res[0] + "::AptConfig"] else: - return default_apt_config; + return default_apt_config ################################################################################ @@ -469,140 +469,140 @@ def which_apt_conf_file (): # (woefully incomplete) def regex_safe (s): - s = s.replace('+', '\\\\+'); - s = s.replace('.', '\\\\.'); + s = s.replace('+', '\\\\+') + s = s.replace('.', '\\\\.') return s ################################################################################ # Perform a substition of template def TemplateSubst(map, filename): - file = open_file(filename); - template = file.read(); + file = open_file(filename) + template = file.read() for x in map.keys(): - template = template.replace(x,map[x]); - file.close(); - return template; + template = template.replace(x,map[x]) + file.close() + return template ################################################################################ def fubar(msg, exit_code=1): - sys.stderr.write("E: %s\n" % (msg)); - sys.exit(exit_code); + sys.stderr.write("E: %s\n" % (msg)) + sys.exit(exit_code) def warn(msg): - sys.stderr.write("W: %s\n" % (msg)); + sys.stderr.write("W: %s\n" % (msg)) ################################################################################ # Returns the user name with a laughable attempt at rfc822 conformancy # (read: removing stray periods). def whoami (): - return pwd.getpwuid(os.getuid())[4].split(',')[0].replace('.', ''); + return pwd.getpwuid(os.getuid())[4].split(',')[0].replace('.', '') ################################################################################ def size_type (c): - t = " B"; + t = " B" if c > 10240: - c = c / 1024; - t = " KB"; + c = c / 1024 + t = " KB" if c > 10240: - c = c / 1024; - t = " MB"; + c = c / 1024 + t = " MB" return ("%d%s" % (c, t)) ################################################################################ def cc_fix_changes (changes): - o = changes.get("architecture", ""); + o = changes.get("architecture", "") if o: - del changes["architecture"]; - changes["architecture"] = {}; + del changes["architecture"] + changes["architecture"] = {} for j in o.split(): - changes["architecture"][j] = 1; + changes["architecture"][j] = 1 # Sort by source name, source version, 'have source', and then by filename def changes_compare (a, b): try: - a_changes = parse_changes(a); + a_changes = parse_changes(a) except: - return -1; + return -1 try: - b_changes = parse_changes(b); + b_changes = parse_changes(b) except: - return 1; + return 1 - cc_fix_changes (a_changes); - cc_fix_changes (b_changes); + cc_fix_changes (a_changes) + cc_fix_changes (b_changes) # Sort by source name - a_source = a_changes.get("source"); - b_source = b_changes.get("source"); - q = cmp (a_source, b_source); + a_source = a_changes.get("source") + b_source = b_changes.get("source") + q = cmp (a_source, b_source) if q: - return q; + return q # Sort by source version - a_version = a_changes.get("version", "0"); - b_version = b_changes.get("version", "0"); - q = apt_pkg.VersionCompare(a_version, b_version); + a_version = a_changes.get("version", "0") + b_version = b_changes.get("version", "0") + q = apt_pkg.VersionCompare(a_version, b_version) if q: - return q; + return q # Sort by 'have source' - a_has_source = a_changes["architecture"].get("source"); - b_has_source = b_changes["architecture"].get("source"); + a_has_source = a_changes["architecture"].get("source") + b_has_source = b_changes["architecture"].get("source") if a_has_source and not b_has_source: - return -1; + return -1 elif b_has_source and not a_has_source: - return 1; + return 1 # Fall back to sort by filename - return cmp(a, b); + return cmp(a, b) ################################################################################ def find_next_free (dest, too_many=100): - extra = 0; - orig_dest = dest; + extra = 0 + orig_dest = dest while os.path.exists(dest) and extra < too_many: - dest = orig_dest + '.' + repr(extra); - extra += 1; + dest = orig_dest + '.' + repr(extra) + extra += 1 if extra >= too_many: - raise tried_too_hard_exc; - return dest; + raise tried_too_hard_exc + return dest ################################################################################ def result_join (original, sep = '\t'): - list = []; + list = [] for i in xrange(len(original)): if original[i] == None: - list.append(""); + list.append("") else: - list.append(original[i]); - return sep.join(list); + list.append(original[i]) + return sep.join(list) ################################################################################ def prefix_multi_line_string(str, prefix, include_blank_lines=0): - out = ""; + out = "" for line in str.split('\n'): - line = line.strip(); + line = line.strip() if line or include_blank_lines: - out += "%s%s\n" % (prefix, line); + out += "%s%s\n" % (prefix, line) # Strip trailing new line if out: - out = out[:-1]; - return out; + out = out[:-1] + return out ################################################################################ def validate_changes_file_arg(filename, require_changes=1): - """'filename' is either a .changes or .katie file. If 'filename' is a -.katie file, it's changed to be the corresponding .changes file. The + """'filename' is either a .changes or .dak file. If 'filename' is a +.dak file, it's changed to be the corresponding .changes file. The function then checks if the .changes file a) exists and b) is readable and returns the .changes filename if so. If there's a problem, the next action depends on the option 'require_changes' @@ -613,61 +613,61 @@ argument: o If 'require_changes' == 0, a warning is given and 'None' is returned. o If 'require_changes' == 1, a fatal error is raised. """ - error = None; + error = None orig_filename = filename - if filename.endswith(".katie"): - filename = filename[:-6]+".changes"; + if filename.endswith(".dak"): + filename = filename[:-6]+".changes" if not filename.endswith(".changes"): - error = "invalid file type; not a changes file"; + error = "invalid file type; not a changes file" else: if not os.access(filename,os.R_OK): if os.path.exists(filename): - error = "permission denied"; + error = "permission denied" else: - error = "file not found"; + error = "file not found" if error: if require_changes == 1: - fubar("%s: %s." % (orig_filename, error)); + fubar("%s: %s." % (orig_filename, error)) elif require_changes == 0: - warn("Skipping %s - %s" % (orig_filename, error)); - return None; - else: # We only care about the .katie file - return filename; + warn("Skipping %s - %s" % (orig_filename, error)) + return None + else: # We only care about the .dak file + return filename else: - return filename; + return filename ################################################################################ def real_arch(arch): - return (arch != "source" and arch != "all"); + return (arch != "source" and arch != "all") ################################################################################ def join_with_commas_and(list): - if len(list) == 0: return "nothing"; - if len(list) == 1: return list[0]; - return ", ".join(list[:-1]) + " and " + list[-1]; + if len(list) == 0: return "nothing" + if len(list) == 1: return list[0] + return ", ".join(list[:-1]) + " and " + list[-1] ################################################################################ def pp_deps (deps): - pp_deps = []; + pp_deps = [] for atom in deps: - (pkg, version, constraint) = atom; + (pkg, version, constraint) = atom if constraint: - pp_dep = "%s (%s %s)" % (pkg, constraint, version); + pp_dep = "%s (%s %s)" % (pkg, constraint, version) else: - pp_dep = pkg; - pp_deps.append(pp_dep); - return " |".join(pp_deps); + pp_dep = pkg + pp_deps.append(pp_dep) + return " |".join(pp_deps) ################################################################################ def get_conf(): - return Cnf; + return Cnf ################################################################################ @@ -675,59 +675,59 @@ def get_conf(): def parse_args(Options): # Process suite if Options["Suite"]: - suite_ids_list = []; + suite_ids_list = [] for suite in split_args(Options["Suite"]): - suite_id = db_access.get_suite_id(suite); + suite_id = dak.lib.database.get_suite_id(suite) if suite_id == -1: - warn("suite '%s' not recognised." % (suite)); + warn("suite '%s' not recognised." % (suite)) else: - suite_ids_list.append(suite_id); + suite_ids_list.append(suite_id) if suite_ids_list: - con_suites = "AND su.id IN (%s)" % ", ".join(map(str, suite_ids_list)); + con_suites = "AND su.id IN (%s)" % ", ".join(map(str, suite_ids_list)) else: - fubar("No valid suite given."); + fubar("No valid suite given.") else: - con_suites = ""; + con_suites = "" # Process component if Options["Component"]: - component_ids_list = []; + component_ids_list = [] for component in split_args(Options["Component"]): - component_id = db_access.get_component_id(component); + component_id = dak.lib.database.get_component_id(component) if component_id == -1: - warn("component '%s' not recognised." % (component)); + warn("component '%s' not recognised." % (component)) else: - component_ids_list.append(component_id); + component_ids_list.append(component_id) if component_ids_list: - con_components = "AND c.id IN (%s)" % ", ".join(map(str, component_ids_list)); + con_components = "AND c.id IN (%s)" % ", ".join(map(str, component_ids_list)) else: - fubar("No valid component given."); + fubar("No valid component given.") else: - con_components = ""; + con_components = "" # Process architecture - con_architectures = ""; + con_architectures = "" if Options["Architecture"]: - arch_ids_list = []; - check_source = 0; + arch_ids_list = [] + check_source = 0 for architecture in split_args(Options["Architecture"]): if architecture == "source": - check_source = 1; + check_source = 1 else: - architecture_id = db_access.get_architecture_id(architecture); + architecture_id = dak.lib.database.get_architecture_id(architecture) if architecture_id == -1: - warn("architecture '%s' not recognised." % (architecture)); + warn("architecture '%s' not recognised." % (architecture)) else: - arch_ids_list.append(architecture_id); + arch_ids_list.append(architecture_id) if arch_ids_list: - con_architectures = "AND a.id IN (%s)" % ", ".join(map(str, arch_ids_list)); + con_architectures = "AND a.id IN (%s)" % ", ".join(map(str, arch_ids_list)) else: if not check_source: - fubar("No valid architecture given."); + fubar("No valid architecture given.") else: - check_source = 1; + check_source = 1 - return (con_suites, con_architectures, con_components, check_source); + return (con_suites, con_architectures, con_components, check_source) ################################################################################ @@ -735,36 +735,36 @@ def parse_args(Options): # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215) def print_exc(): - tb = sys.exc_info()[2]; + tb = sys.exc_info()[2] while tb.tb_next: - tb = tb.tb_next; - stack = []; - frame = tb.tb_frame; + tb = tb.tb_next + stack = [] + frame = tb.tb_frame while frame: - stack.append(frame); - frame = frame.f_back; - stack.reverse(); - traceback.print_exc(); + stack.append(frame) + frame = frame.f_back + stack.reverse() + traceback.print_exc() for frame in stack: print "\nFrame %s in %s at line %s" % (frame.f_code.co_name, frame.f_code.co_filename, - frame.f_lineno); + frame.f_lineno) for key, value in frame.f_locals.items(): - print "\t%20s = " % key,; + print "\t%20s = " % key, try: - print value; + print value except: - print ""; + print "" ################################################################################ def try_with_debug(function): try: - function(); + function() except SystemExit: - raise; + raise except: - print_exc(); + print_exc() ################################################################################ @@ -773,29 +773,29 @@ def try_with_debug(function): def arch_compare_sw (a, b): if a == "source" and b == "source": - return 0; + return 0 elif a == "source": - return -1; + return -1 elif b == "source": - return 1; + return 1 - return cmp (a, b); + return cmp (a, b) ################################################################################ # Split command line arguments which can be separated by either commas # or whitespace. If dwim is set, it will complain about string ending -# in comma since this usually means someone did 'madison -a i386, m68k +# in comma since this usually means someone did 'dak ls -a i386, m68k # foo' or something and the inevitable confusion resulting from 'm68k' # being treated as an argument is undesirable. def split_args (s, dwim=1): if s.find(",") == -1: - return s.split(); + return s.split() else: if s[-1:] == "," and dwim: - fubar("split_args: found trailing comma, spurious space maybe?"); - return s.split(","); + fubar("split_args: found trailing comma, spurious space maybe?") + return s.split(",") ################################################################################ @@ -806,64 +806,64 @@ def Dict(**dict): return dict # Our very own version of commands.getouputstatus(), hacked to support # gpgv's status fd. def gpgv_get_status_output(cmd, status_read, status_write): - cmd = ['/bin/sh', '-c', cmd]; - p2cread, p2cwrite = os.pipe(); - c2pread, c2pwrite = os.pipe(); - errout, errin = os.pipe(); - pid = os.fork(); + cmd = ['/bin/sh', '-c', cmd] + p2cread, p2cwrite = os.pipe() + c2pread, c2pwrite = os.pipe() + errout, errin = os.pipe() + pid = os.fork() if pid == 0: # Child - os.close(0); - os.close(1); - os.dup(p2cread); - os.dup(c2pwrite); - os.close(2); - os.dup(errin); + os.close(0) + os.close(1) + os.dup(p2cread) + os.dup(c2pwrite) + os.close(2) + os.dup(errin) for i in range(3, 256): if i != status_write: try: - os.close(i); + os.close(i) except: - pass; + pass try: - os.execvp(cmd[0], cmd); + os.execvp(cmd[0], cmd) finally: - os._exit(1); + os._exit(1) # Parent os.close(p2cread) - os.dup2(c2pread, c2pwrite); - os.dup2(errout, errin); + os.dup2(c2pread, c2pwrite) + os.dup2(errout, errin) - output = status = ""; + output = status = "" while 1: - i, o, e = select.select([c2pwrite, errin, status_read], [], []); - more_data = []; + i, o, e = select.select([c2pwrite, errin, status_read], [], []) + more_data = [] for fd in i: - r = os.read(fd, 8196); + r = os.read(fd, 8196) if len(r) > 0: - more_data.append(fd); + more_data.append(fd) if fd == c2pwrite or fd == errin: - output += r; + output += r elif fd == status_read: - status += r; + status += r else: - fubar("Unexpected file descriptor [%s] returned from select\n" % (fd)); + fubar("Unexpected file descriptor [%s] returned from select\n" % (fd)) if not more_data: pid, exit_status = os.waitpid(pid, 0) try: - os.close(status_write); - os.close(status_read); - os.close(c2pread); - os.close(c2pwrite); - os.close(p2cwrite); - os.close(errin); - os.close(errout); + os.close(status_write) + os.close(status_read) + os.close(c2pread) + os.close(c2pwrite) + os.close(p2cwrite) + os.close(errin) + os.close(errout) except: - pass; - break; + pass + break - return output, status, exit_status; + return output, status, exit_status ############################################################ @@ -883,168 +883,168 @@ a *list* of keyrings to use. # Ensure the filename contains no shell meta-characters or other badness if not re_taint_free.match(sig_filename): - reject("!!WARNING!! tainted signature filename: '%s'." % (sig_filename)); - return None; + reject("!!WARNING!! tainted signature filename: '%s'." % (sig_filename)) + return None if data_filename and not re_taint_free.match(data_filename): - reject("!!WARNING!! tainted data filename: '%s'." % (data_filename)); - return None; + reject("!!WARNING!! tainted data filename: '%s'." % (data_filename)) + return None if not keyrings: keyrings = (Cnf["Dinstall::PGPKeyring"], Cnf["Dinstall::GPGKeyring"]) # Build the command line status_read, status_write = os.pipe(); - cmd = "gpgv --status-fd %s" % (status_write); + cmd = "gpgv --status-fd %s" % (status_write) for keyring in keyrings: - cmd += " --keyring %s" % (keyring); - cmd += " %s %s" % (sig_filename, data_filename); + cmd += " --keyring %s" % (keyring) + cmd += " %s %s" % (sig_filename, data_filename) # Invoke gpgv on the file - (output, status, exit_status) = gpgv_get_status_output(cmd, status_read, status_write); + (output, status, exit_status) = gpgv_get_status_output(cmd, status_read, status_write) # Process the status-fd output - keywords = {}; - bad = internal_error = ""; + keywords = {} + bad = internal_error = "" for line in status.split('\n'): - line = line.strip(); + line = line.strip() if line == "": - continue; - split = line.split(); + continue + split = line.split() if len(split) < 2: - internal_error += "gpgv status line is malformed (< 2 atoms) ['%s'].\n" % (line); - continue; - (gnupg, keyword) = split[:2]; + internal_error += "gpgv status line is malformed (< 2 atoms) ['%s'].\n" % (line) + continue + (gnupg, keyword) = split[:2] if gnupg != "[GNUPG:]": - internal_error += "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg); - continue; - args = split[2:]; + internal_error += "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg) + continue + args = split[2:] if keywords.has_key(keyword) and (keyword != "NODATA" and keyword != "SIGEXPIRED"): - internal_error += "found duplicate status token ('%s').\n" % (keyword); - continue; + internal_error += "found duplicate status token ('%s').\n" % (keyword) + continue else: - keywords[keyword] = args; + keywords[keyword] = args # If we failed to parse the status-fd output, let's just whine and bail now if internal_error: - reject("internal error while performing signature check on %s." % (sig_filename)); - reject(internal_error, ""); - reject("Please report the above errors to the Archive maintainers by replying to this mail.", ""); - return None; + reject("internal error while performing signature check on %s." % (sig_filename)) + reject(internal_error, "") + reject("Please report the above errors to the Archive maintainers by replying to this mail.", "") + return None # Now check for obviously bad things in the processed output if keywords.has_key("SIGEXPIRED"): - reject("The key used to sign %s has expired." % (sig_filename)); - bad = 1; + reject("The key used to sign %s has expired." % (sig_filename)) + bad = 1 if keywords.has_key("KEYREVOKED"): - reject("The key used to sign %s has been revoked." % (sig_filename)); - bad = 1; + reject("The key used to sign %s has been revoked." % (sig_filename)) + bad = 1 if keywords.has_key("BADSIG"): - reject("bad signature on %s." % (sig_filename)); - bad = 1; + reject("bad signature on %s." % (sig_filename)) + bad = 1 if keywords.has_key("ERRSIG") and not keywords.has_key("NO_PUBKEY"): - reject("failed to check signature on %s." % (sig_filename)); - bad = 1; + reject("failed to check signature on %s." % (sig_filename)) + bad = 1 if keywords.has_key("NO_PUBKEY"): - args = keywords["NO_PUBKEY"]; + args = keywords["NO_PUBKEY"] if len(args) >= 1: - key = args[0]; - reject("The key (0x%s) used to sign %s wasn't found in the keyring(s)." % (key, sig_filename)); - bad = 1; + key = args[0] + reject("The key (0x%s) used to sign %s wasn't found in the keyring(s)." % (key, sig_filename)) + bad = 1 if keywords.has_key("BADARMOR"): - reject("ASCII armour of signature was corrupt in %s." % (sig_filename)); - bad = 1; + reject("ASCII armour of signature was corrupt in %s." % (sig_filename)) + bad = 1 if keywords.has_key("NODATA"): - reject("no signature found in %s." % (sig_filename)); - bad = 1; + reject("no signature found in %s." % (sig_filename)) + bad = 1 if bad: - return None; + return None # Next check gpgv exited with a zero return code if exit_status: - reject("gpgv failed while checking %s." % (sig_filename)); + reject("gpgv failed while checking %s." % (sig_filename)) if status.strip(): - reject(prefix_multi_line_string(status, " [GPG status-fd output:] "), ""); + reject(prefix_multi_line_string(status, " [GPG status-fd output:] "), "") else: - reject(prefix_multi_line_string(output, " [GPG output:] "), ""); - return None; + reject(prefix_multi_line_string(output, " [GPG output:] "), "") + return None # Sanity check the good stuff we expect if not keywords.has_key("VALIDSIG"): - reject("signature on %s does not appear to be valid [No VALIDSIG]." % (sig_filename)); - bad = 1; + reject("signature on %s does not appear to be valid [No VALIDSIG]." % (sig_filename)) + bad = 1 else: - args = keywords["VALIDSIG"]; + args = keywords["VALIDSIG"] if len(args) < 1: - reject("internal error while checking signature on %s." % (sig_filename)); - bad = 1; + reject("internal error while checking signature on %s." % (sig_filename)) + bad = 1 else: - fingerprint = args[0]; + fingerprint = args[0] if not keywords.has_key("GOODSIG"): - reject("signature on %s does not appear to be valid [No GOODSIG]." % (sig_filename)); - bad = 1; + reject("signature on %s does not appear to be valid [No GOODSIG]." % (sig_filename)) + bad = 1 if not keywords.has_key("SIG_ID"): - reject("signature on %s does not appear to be valid [No SIG_ID]." % (sig_filename)); - bad = 1; + reject("signature on %s does not appear to be valid [No SIG_ID]." % (sig_filename)) + bad = 1 # Finally ensure there's not something we don't recognise known_keywords = Dict(VALIDSIG="",SIG_ID="",GOODSIG="",BADSIG="",ERRSIG="", SIGEXPIRED="",KEYREVOKED="",NO_PUBKEY="",BADARMOR="", - NODATA=""); + NODATA="") for keyword in keywords.keys(): if not known_keywords.has_key(keyword): - reject("found unknown status token '%s' from gpgv with args '%r' in %s." % (keyword, keywords[keyword], sig_filename)); - bad = 1; + reject("found unknown status token '%s' from gpgv with args '%r' in %s." % (keyword, keywords[keyword], sig_filename)) + bad = 1 if bad: - return None; + return None else: - return fingerprint; + return fingerprint ################################################################################ # Inspired(tm) by http://www.zopelabs.com/cookbook/1022242603 def wrap(paragraph, max_length, prefix=""): - line = ""; - s = ""; - have_started = 0; - words = paragraph.split(); + line = "" + s = "" + have_started = 0 + words = paragraph.split() for word in words: - word_size = len(word); + word_size = len(word) if word_size > max_length: if have_started: - s += line + '\n' + prefix; - s += word + '\n' + prefix; + s += line + '\n' + prefix + s += word + '\n' + prefix else: if have_started: - new_length = len(line) + word_size + 1; + new_length = len(line) + word_size + 1 if new_length > max_length: - s += line + '\n' + prefix; - line = word; + s += line + '\n' + prefix + line = word else: - line += ' ' + word; + line += ' ' + word else: - line = word; - have_started = 1; + line = word + have_started = 1 if have_started: - s += line; + s += line - return s; + return s ################################################################################ # Relativize an absolute symlink from 'src' -> 'dest' relative to 'root'. # Returns fixed 'src' def clean_symlink (src, dest, root): - src = src.replace(root, '', 1); - dest = dest.replace(root, '', 1); - dest = os.path.dirname(dest); - new_src = '../' * len(dest.split('/')); - return new_src + src; + src = src.replace(root, '', 1) + dest = dest.replace(root, '', 1) + dest = os.path.dirname(dest) + new_src = '../' * len(dest.split('/')) + return new_src + src ################################################################################ @@ -1054,29 +1054,29 @@ If 'directory' is non-null, it will be the directory the file is pre-created in. If 'dotprefix' is non-null, the filename will be prefixed with a '.'.""" if directory: - old_tempdir = tempfile.tempdir; - tempfile.tempdir = directory; + old_tempdir = tempfile.tempdir + tempfile.tempdir = directory - filename = tempfile.mktemp(); + filename = tempfile.mktemp() if dotprefix: - filename = "%s/.%s" % (os.path.dirname(filename), os.path.basename(filename)); - fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, perms); - os.close(fd); + filename = "%s/.%s" % (os.path.dirname(filename), os.path.basename(filename)) + fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, perms) + os.close(fd) if directory: - tempfile.tempdir = old_tempdir; + tempfile.tempdir = old_tempdir - return filename; + return filename ################################################################################ -apt_pkg.init(); +apt_pkg.init() -Cnf = apt_pkg.newConfiguration(); -apt_pkg.ReadConfigFileISC(Cnf,default_config); +Cnf = apt_pkg.newConfiguration() +apt_pkg.ReadConfigFileISC(Cnf,default_config) if which_conf_file() != default_config: - apt_pkg.ReadConfigFileISC(Cnf,which_conf_file()); + apt_pkg.ReadConfigFileISC(Cnf,which_conf_file()) ################################################################################