-new_ack_new = {};
-new_ack_old = {};
-install_count = 0;
-install_bytes = 0.0;
-reprocess = 0;
-orig_tar_id = None;
-orig_tar_location = "";
-legacy_source_untouchable = {};
-Subst = {};
-nmu = None;
-
-#########################################################################################
-
-def usage (exit_code):
- print """Usage: dinstall [OPTION]... [CHANGES]...
- -a, --automatic automatic run
- -D, --debug=VALUE turn on debugging
- -h, --help show this help and exit.
- -k, --ack-new acknowledge new packages !! for cron.daily only !!
- -m, --manual-reject=MSG manual reject with `msg'
- -n, --no-action don't do anything
- -p, --no-lock don't check lockfile !! for cron.daily only !!
- -u, --distribution=DIST override distribution to `dist'
- -v, --version display the version number and exit"""
- sys.exit(exit_code)
-
-#########################################################################################
-
-def check_signature (filename):
- global reject_message
-
- (result, output) = commands.getstatusoutput("gpg --emulate-md-encode-bug --batch --no-options --no-default-keyring --always-trust --keyring=%s --keyring=%s < %s >/dev/null" % (Cnf["Dinstall::PGPKeyring"], Cnf["Dinstall::GPGKeyring"], filename))
- if (result != 0):
- reject_message = "Rejected: GPG signature check failed on `%s'.\n%s\n" % (os.path.basename(filename), output)
- return 0
- return 1
-
-######################################################################################################
-
-class nmu_p:
- # Read in the group maintainer override file
- def __init__ (self):
- self.group_maint = {};
- if Cnf.get("Dinstall::GroupOverrideFilename"):
- filename = Cnf["Dir::OverrideDir"] + Cnf["Dinstall::GroupOverrideFilename"];
- file = utils.open_file(filename, 'r');
- for line in file.readlines():
- line = string.strip(utils.re_comments.sub('', line));
- if line != "":
- self.group_maint[line] = 1;
- file.close();
-
- def is_an_nmu (self, changes, dsc):
- (dsc_rfc822, dsc_name, dsc_email) = utils.fix_maintainer (dsc.get("maintainer",Cnf["Dinstall::MyEmailAddress"]));
- # changes["changedbyname"] == dsc_name is probably never true, but better safe than sorry
- if dsc_name == changes["maintainername"] and (changes["changedbyname"] == "" or changes["changedbyname"] == dsc_name):
- return 0;
-
- if dsc.has_key("maintainers"):
- maintainers = string.split(dsc["maintainers"], ",");
- maintainernames = {};
- for i in maintainers:
- (rfc822, name, email) = utils.fix_maintainer (string.strip(i));
- maintainernames[name] = "";
- if maintainernames.has_key(changes["changedbyname"]):
- return 0;
-
- # Some group maintained packages (e.g. Debian QA) are never NMU's
- if self.group_maint.has_key(changes["maintainername"]):
- return 0;
-
- return 1;
-
-######################################################################################################
-
-# See if a given package is in the override table
-
-def in_override_p (package, component, suite, binary_type, file):
- global files;
-
- if binary_type == "": # must be source
- type = "dsc";
- else:
- type = binary_type;
-
- # Override suite name; used for example with proposed-updates
- if Cnf.Find("Suite::%s::OverrideSuite" % (suite)) != "":
- suite = Cnf["Suite::%s::OverrideSuite" % (suite)];
-
- # Avoid <undef> on unknown distributions
- suite_id = db_access.get_suite_id(suite);
- if suite_id == -1:
- return None;
- component_id = db_access.get_component_id(component);
- type_id = db_access.get_override_type_id(type);
-
- # FIXME: nasty non-US speficic hack
- if string.lower(component[:7]) == "non-us/":
- component = component[7:];
-
- q = projectB.query("SELECT s.section, p.priority FROM override o, section s, priority p WHERE package = '%s' AND suite = %s AND component = %s AND type = %s AND o.section = s.id AND o.priority = p.id"
- % (package, suite_id, component_id, type_id));
- result = q.getresult();
- # If checking for a source package fall back on the binary override type
- if type == "dsc" and not result:
- type_id = db_access.get_override_type_id("deb");
- q = projectB.query("SELECT s.section, p.priority FROM override o, section s, priority p WHERE package = '%s' AND suite = %s AND component = %s AND type = %s AND o.section = s.id AND o.priority = p.id"
- % (package, suite_id, component_id, type_id));
- result = q.getresult();
-
- # Remember the section and priority so we can check them later if appropriate
- if result != []:
- files[file]["override section"] = result[0][0];
- files[file]["override priority"] = result[0][1];
-
- return result;
-
-#####################################################################################################################
-
-def check_changes(filename):
- global reject_message, changes, files
-
- # Default in case we bail out
- changes["maintainer822"] = Cnf["Dinstall::MyEmailAddress"];
- changes["changedby822"] = Cnf["Dinstall::MyEmailAddress"];
- changes["architecture"] = {};
-
- # Parse the .changes field into a dictionary
- try:
- changes = utils.parse_changes(filename, 0)
- except utils.cant_open_exc:
- reject_message = "Rejected: can't read changes file '%s'.\n" % (filename)
- return 0;
- except utils.changes_parse_error_exc, line:
- reject_message = "Rejected: error parsing changes file '%s', can't grok: %s.\n" % (filename, line)
- return 0;
-
- # Parse the Files field from the .changes into another dictionary
- try:
- files = utils.build_file_list(changes, "");
- except utils.changes_parse_error_exc, line:
- reject_message = "Rejected: error parsing changes file '%s', can't grok: %s.\n" % (filename, line);
-
- # Check for mandatory fields
- for i in ("source", "binary", "architecture", "version", "distribution","maintainer", "files"):
- if not changes.has_key(i):
- reject_message = "Rejected: Missing field `%s' in changes file.\n" % (i)
- return 0 # Avoid <undef> errors during later tests
-
- # Override the Distribution: field if appropriate
- if Cnf["Dinstall::Options::Override-Distribution"] != "":
- reject_message = reject_message + "Warning: Distribution was overriden from %s to %s.\n" % (changes["distribution"], Cnf["Dinstall::Options::Override-Distribution"])
- changes["distribution"] = Cnf["Dinstall::Options::Override-Distribution"]
-
- # Split multi-value fields into a lower-level dictionary
- for i in ("architecture", "distribution", "binary", "closes"):
- o = changes.get(i, "")
- if o != "":
- del changes[i]
- changes[i] = {}
- for j in string.split(o):
- changes[i][j] = 1
-
- # Fix the Maintainer: field to be RFC822 compatible
- (changes["maintainer822"], changes["maintainername"], changes["maintaineremail"]) = utils.fix_maintainer (changes["maintainer"])
-
- # Fix the Changed-By: field to be RFC822 compatible; if it exists.
- (changes["changedby822"], changes["changedbyname"], changes["changedbyemail"]) = utils.fix_maintainer(changes.get("changed-by",""));
-
- # Ensure all the values in Closes: are numbers
- if changes.has_key("closes"):
- for i in changes["closes"].keys():
- if re_isanum.match (i) == None:
- reject_message = reject_message + "Rejected: `%s' from Closes field isn't a number.\n" % (i)
-
- # Map frozen to unstable if frozen doesn't exist
- if changes["distribution"].has_key("frozen") and not Cnf.has_key("Suite::Frozen"):
- del changes["distribution"]["frozen"]
- changes["distribution"]["unstable"] = 1;
- reject_message = reject_message + "Mapping frozen to unstable.\n"
-
- # Map testing to unstable
- if changes["distribution"].has_key("testing"):
- del changes["distribution"]["testing"]
- changes["distribution"]["unstable"] = 1;
- reject_message = reject_message + "Mapping testing to unstable.\n"
-
- # Ensure target distributions exist
- for i in changes["distribution"].keys():
- if not Cnf.has_key("Suite::%s" % (i)):
- reject_message = reject_message + "Rejected: Unknown distribution `%s'.\n" % (i)
-
- # Ensure there _is_ a target distribution
- if changes["distribution"].keys() == []:
- reject_message = reject_message + "Rejected: huh? Distribution field is empty in changes file.\n";
-
- # Map unreleased arches from stable to unstable
- if changes["distribution"].has_key("stable"):
- for i in changes["architecture"].keys():
- if not Cnf.has_key("Suite::Stable::Architectures::%s" % (i)):
- reject_message = reject_message + "Mapping stable to unstable for unreleased arch `%s'.\n" % (i)
- del changes["distribution"]["stable"]
- changes["distribution"]["unstable"] = 1;
-
- # Map arches not being released from frozen to unstable
- if changes["distribution"].has_key("frozen"):
- for i in changes["architecture"].keys():
- if not Cnf.has_key("Suite::Frozen::Architectures::%s" % (i)):
- reject_message = reject_message + "Mapping frozen to unstable for non-releasing arch `%s'.\n" % (i)
- del changes["distribution"]["frozen"]
- changes["distribution"]["unstable"] = 1;
-
- # Handle uploads to stable
- if changes["distribution"].has_key("stable"):
- # If running from within proposed-updates; assume an install to stable
- if string.find(os.getcwd(), 'proposed-updates') != -1:
- # FIXME: should probably remove anything that != stable
- for i in ("frozen", "unstable"):
- if changes["distribution"].has_key(i):
- reject_message = reject_message + "Removing %s from distribution list.\n" % (i)
- del changes["distribution"][i]
- changes["stable upload"] = 1;
- # If we can't find a file from the .changes; assume it's a package already in the pool and move into the pool
- file = files.keys()[0];
- if os.access(file, os.R_OK) == 0:
- pool_dir = Cnf["Dir::PoolDir"] + '/' + utils.poolify(changes["source"], files[file]["component"]);
- os.chdir(pool_dir);
- # Otherwise (normal case) map stable to updates
- else:
- reject_message = reject_message + "Mapping stable to updates.\n";
- del changes["distribution"]["stable"];
- changes["distribution"]["proposed-updates"] = 1;
-
- # chopversion = no epoch; chopversion2 = no epoch and no revision (e.g. for .orig.tar.gz comparison)
- changes["chopversion"] = utils.re_no_epoch.sub('', changes["version"])
- changes["chopversion2"] = utils.re_no_revision.sub('', changes["chopversion"])
-
- if string.find(reject_message, "Rejected:") != -1:
- return 0
- else:
- return 1
-
-def check_files():
- global reject_message
-
- archive = utils.where_am_i();