]> git.decadent.org.uk Git - dak.git/commitdiff
Remove more obsolete code.
authorAnsgar Burchardt <ansgar@debian.org>
Thu, 28 May 2015 21:48:17 +0000 (23:48 +0200)
committerAnsgar Burchardt <ansgar@debian.org>
Thu, 28 May 2015 21:48:17 +0000 (23:48 +0200)
daklib/queue.py
daklib/utils.py
tests/test_process_gpgv_output.py [deleted file]
tools/import_changelogs.py [deleted file]

index 44176bf7cc77eacde11933b9381f97ce67350c10..b0ce511c5fb8b84742d429154a4929926e4990a5 100644 (file)
@@ -49,7 +49,7 @@ from holding import Holding
 from urgencylog import UrgencyLog
 from dbconn import *
 from summarystats import SummaryStats
-from utils import parse_changes, check_dsc_files, build_package_list
+from utils import parse_changes, check_dsc_files
 from textutils import fix_maintainer
 from lintian import parse_lintian_output, generate_reject_messages
 from contents import UnpackedSource
index cf3bd98e225783cd06c45ccc91e0aed5dd4a5e84..64f75fbe11fa106c222ff55b907e954a26dfd55f 100644 (file)
@@ -287,82 +287,6 @@ def hash_key(hashname):
 
 ################################################################################
 
-def create_hash(where, files, hashname, hashfunc):
-    """
-    create_hash extends the passed files dict with the given hash by
-    iterating over all files on disk and passing them to the hashing
-    function given.
-    """
-
-    rejmsg = []
-    for f in files.keys():
-        try:
-            file_handle = open_file(f)
-        except CantOpenError:
-            rejmsg.append("Could not open file %s for checksumming" % (f))
-            continue
-
-        files[f][hash_key(hashname)] = hashfunc(file_handle)
-
-        file_handle.close()
-    return rejmsg
-
-################################################################################
-
-def check_hash(where, files, hashname, hashfunc):
-    """
-    check_hash checks the given hash in the files dict against the actual
-    files on disk.  The hash values need to be present consistently in
-    all file entries.  It does not modify its input in any way.
-    """
-
-    rejmsg = []
-    for f in files.keys():
-        try:
-            with open_file(f) as file_handle:
-                # Check for the hash entry, to not trigger a KeyError.
-                if not files[f].has_key(hash_key(hashname)):
-                    rejmsg.append("%s: misses %s checksum in %s" % (f, hashname,
-                        where))
-                    continue
-
-                # Actually check the hash for correctness.
-                if hashfunc(file_handle) != files[f][hash_key(hashname)]:
-                    rejmsg.append("%s: %s check failed in %s" % (f, hashname,
-                        where))
-        except CantOpenError:
-            # TODO: This happens when the file is in the pool.
-            # warn("Cannot open file %s" % f)
-            continue
-    return rejmsg
-
-################################################################################
-
-def check_size(where, files):
-    """
-    check_size checks the file sizes in the passed files dict against the
-    files on disk.
-    """
-
-    rejmsg = []
-    for f in files.keys():
-        try:
-            entry = os.stat(f)
-        except OSError as exc:
-            if exc.errno == errno.ENOENT:
-                # TODO: This happens when the file is in the pool.
-                continue
-            raise
-
-        actual_size = entry[stat.ST_SIZE]
-        size = int(files[f]["size"])
-        if size != actual_size:
-            rejmsg.append("%s: actual file size (%s) does not match size (%s) in %s"
-                   % (f, actual_size, size, where))
-    return rejmsg
-
-################################################################################
-
 def check_dsc_files(dsc_filename, dsc, dsc_files):
     """
     Verify that the files listed in the Files field of the .dsc are
@@ -436,92 +360,6 @@ def check_dsc_files(dsc_filename, dsc, dsc_files):
 
 ################################################################################
 
-def check_hash_fields(what, manifest):
-    """
-    check_hash_fields ensures that there are no checksum fields in the
-    given dict that we do not know about.
-    """
-
-    rejmsg = []
-    hashes = map(lambda x: x[0], known_hashes)
-    for field in manifest:
-        if field.startswith("checksums-"):
-            hashname = field.split("-",1)[1]
-            if hashname not in hashes:
-                rejmsg.append("Unsupported checksum field for %s "\
-                    "in %s" % (hashname, what))
-    return rejmsg
-
-################################################################################
-
-def _ensure_changes_hash(changes, format, version, files, hashname, hashfunc):
-    if format >= version:
-        # The version should contain the specified hash.
-        func = check_hash
-
-        # Import hashes from the changes
-        rejmsg = parse_checksums(".changes", files, changes, hashname)
-        if len(rejmsg) > 0:
-            return rejmsg
-    else:
-        # We need to calculate the hash because it can't possibly
-        # be in the file.
-        func = create_hash
-    return func(".changes", files, hashname, hashfunc)
-
-# We could add the orig which might be in the pool to the files dict to
-# access the checksums easily.
-
-def _ensure_dsc_hash(dsc, dsc_files, hashname, hashfunc):
-    """
-    ensure_dsc_hashes' task is to ensure that each and every *present* hash
-    in the dsc is correct, i.e. identical to the changes file and if necessary
-    the pool.  The latter task is delegated to check_hash.
-    """
-
-    rejmsg = []
-    if not dsc.has_key('Checksums-%s' % (hashname,)):
-        return rejmsg
-    # Import hashes from the dsc
-    parse_checksums(".dsc", dsc_files, dsc, hashname)
-    # And check it...
-    rejmsg.extend(check_hash(".dsc", dsc_files, hashname, hashfunc))
-    return rejmsg
-
-################################################################################
-
-def parse_checksums(where, files, manifest, hashname):
-    rejmsg = []
-    field = 'checksums-%s' % hashname
-    if not field in manifest:
-        return rejmsg
-    for line in manifest[field].split('\n'):
-        if not line:
-            break
-        clist = line.strip().split(' ')
-        if len(clist) == 3:
-            checksum, size, checkfile = clist
-        else:
-            rejmsg.append("Cannot parse checksum line [%s]" % (line))
-            continue
-        if not files.has_key(checkfile):
-        # TODO: check for the file's entry in the original files dict, not
-        # the one modified by (auto)byhand and other weird stuff
-        #    rejmsg.append("%s: not present in files but in checksums-%s in %s" %
-        #        (file, hashname, where))
-            continue
-        if not files[checkfile]["size"] == size:
-            rejmsg.append("%s: size differs for files and checksums-%s entry "\
-                "in %s" % (checkfile, hashname, where))
-            continue
-        files[checkfile][hash_key(hashname)] = checksum
-    for f in files.keys():
-        if not files[f].has_key(hash_key(hashname)):
-            rejmsg.append("%s: no entry in checksums-%s in %s" % (f, hashname, where))
-    return rejmsg
-
-################################################################################
-
 # Dropped support for 1.4 and ``buggy dchanges 3.4'' (?!) compared to di.pl
 
 def build_file_list(changes, is_a_dsc=0, field="files", hashname="md5sum"):
@@ -566,35 +404,6 @@ def build_file_list(changes, is_a_dsc=0, field="files", hashname="md5sum"):
 
 ################################################################################
 
-# see https://bugs.debian.org/619131
-def build_package_list(dsc, session = None):
-    if not dsc.has_key("package-list"):
-        return {}
-
-    packages = {}
-
-    for line in dsc["package-list"].split("\n"):
-        if not line:
-            break
-
-        fields = line.split()
-        name = fields[0]
-        package_type = fields[1]
-        (section, component) = extract_component_from_section(fields[2])
-        priority = fields[3]
-
-        # Validate type if we have a session
-        if session and get_override_type(package_type, session) is None:
-            # Maybe just warn and ignore? exit(1) might be a bit hard...
-            utils.fubar("invalid type (%s) in Package-List." % (package_type))
-
-        if name not in packages or packages[name]["type"] == "dsc":
-            packages[name] = dict(priority=priority, section=section, type=package_type, component=component, files=[])
-
-    return packages
-
-################################################################################
-
 def send_mail (message, filename="", whitelists=None):
     """sendmail wrapper, takes _either_ a message string or a file as arguments
 
@@ -813,56 +622,6 @@ def size_type (c):
 
 ################################################################################
 
-def cc_fix_changes (changes):
-    o = changes.get("architecture", "")
-    if o:
-        del changes["architecture"]
-    changes["architecture"] = {}
-    for j in o.split():
-        changes["architecture"][j] = 1
-
-def changes_compare (a, b):
-    """ Sort by source name, source version, 'have source', and then by filename """
-    try:
-        a_changes = parse_changes(a)
-    except:
-        return -1
-
-    try:
-        b_changes = parse_changes(b)
-    except:
-        return 1
-
-    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)
-    if q:
-        return q
-
-    # Sort by source version
-    a_version = a_changes.get("version", "0")
-    b_version = b_changes.get("version", "0")
-    q = apt_pkg.version_compare(a_version, b_version)
-    if q:
-        return q
-
-    # Sort by 'have 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
-    elif b_has_source and not a_has_source:
-        return 1
-
-    # Fall back to sort by filename
-    return cmp(a, b)
-
-################################################################################
-
 def find_next_free (dest, too_many=100):
     extra = 0
     orig_dest = dest
@@ -899,54 +658,6 @@ def prefix_multi_line_string(str, prefix, include_blank_lines=0):
 
 ################################################################################
 
-def validate_changes_file_arg(filename, require_changes=1):
-    """
-    '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'
-    argument:
-
-      - If 'require_changes' == -1, errors are ignored and the .changes
-        filename is returned.
-      - If 'require_changes' == 0, a warning is given and 'None' is returned.
-      - If 'require_changes' == 1, a fatal error is raised.
-
-    """
-    error = None
-
-    orig_filename = filename
-    if filename.endswith(".dak"):
-        filename = filename[:-4]+".changes"
-
-    if not filename.endswith(".changes"):
-        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"
-            else:
-                error = "file not found"
-
-    if error:
-        if require_changes == 1:
-            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 .dak file
-            return filename
-    else:
-        return filename
-
-################################################################################
-
-def real_arch(arch):
-    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]
@@ -1072,286 +783,12 @@ def split_args (s, dwim=True):
 
 ################################################################################
 
-def gpgv_get_status_output(cmd, status_read, status_write):
-    """
-    Our very own version of commands.getouputstatus(), hacked to support
-    gpgv's status fd.
-    """
-
-    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)
-        for i in range(3, 256):
-            if i != status_write:
-                try:
-                    os.close(i)
-                except:
-                    pass
-        try:
-            os.execvp(cmd[0], cmd)
-        finally:
-            os._exit(1)
-
-    # Parent
-    os.close(p2cread)
-    os.dup2(c2pread, c2pwrite)
-    os.dup2(errout, errin)
-
-    output = status = ""
-    while 1:
-        i, o, e = select.select([c2pwrite, errin, status_read], [], [])
-        more_data = []
-        for fd in i:
-            r = os.read(fd, 8196)
-            if len(r) > 0:
-                more_data.append(fd)
-                if fd == c2pwrite or fd == errin:
-                    output += r
-                elif fd == status_read:
-                    status += r
-                else:
-                    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)
-            except:
-                pass
-            break
-
-    return output, status, exit_status
-
-################################################################################
-
-def process_gpgv_output(status):
-    # Process the status-fd output
-    keywords = {}
-    internal_error = ""
-    for line in status.split('\n'):
-        line = line.strip()
-        if line == "":
-            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]
-        if gnupg != "[GNUPG:]":
-            internal_error += "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg)
-            continue
-        args = split[2:]
-        if keywords.has_key(keyword) and keyword not in [ "NODATA", "SIGEXPIRED", "KEYEXPIRED" ]:
-            internal_error += "found duplicate status token ('%s').\n" % (keyword)
-            continue
-        else:
-            keywords[keyword] = args
-
-    return (keywords, internal_error)
-
-################################################################################
-
-def retrieve_key (filename, keyserver=None, keyring=None):
-    """
-    Retrieve the key that signed 'filename' from 'keyserver' and
-    add it to 'keyring'.  Returns nothing on success, or an error message
-    on error.
-    """
-
-    # Defaults for keyserver and keyring
-    if not keyserver:
-        keyserver = Cnf["Dinstall::KeyServer"]
-    if not keyring:
-        keyring = get_primary_keyring_path()
-
-    # Ensure the filename contains no shell meta-characters or other badness
-    if not re_taint_free.match(filename):
-        return "%s: tainted filename" % (filename)
-
-    # Invoke gpgv on the file
-    status_read, status_write = os.pipe()
-    cmd = "gpgv --status-fd %s --keyring /dev/null %s" % (status_write, filename)
-    (_, status, _) = gpgv_get_status_output(cmd, status_read, status_write)
-
-    # Process the status-fd output
-    (keywords, internal_error) = process_gpgv_output(status)
-    if internal_error:
-        return internal_error
-
-    if not keywords.has_key("NO_PUBKEY"):
-        return "didn't find expected NO_PUBKEY in gpgv status-fd output"
-
-    fingerprint = keywords["NO_PUBKEY"][0]
-    # XXX - gpg sucks.  You can't use --secret-keyring=/dev/null as
-    # it'll try to create a lockfile in /dev.  A better solution might
-    # be a tempfile or something.
-    cmd = "gpg --no-default-keyring --secret-keyring=%s --no-options" \
-          % (Cnf["Dinstall::SigningKeyring"])
-    cmd += " --keyring %s --keyserver %s --recv-key %s" \
-           % (keyring, keyserver, fingerprint)
-    (result, output) = commands.getstatusoutput(cmd)
-    if (result != 0):
-        return "'%s' failed with exit code %s" % (cmd, result)
-
-    return ""
-
-################################################################################
-
 def gpg_keyring_args(keyrings=None):
     if not keyrings:
         keyrings = get_active_keyring_paths()
 
     return " ".join(["--keyring %s" % x for x in keyrings])
 
-################################################################################
-@session_wrapper
-def check_signature (sig_filename, data_filename="", keyrings=None, autofetch=None, session=None):
-    """
-    Check the signature of a file and return the fingerprint if the
-    signature is valid or 'None' if it's not.  The first argument is the
-    filename whose signature should be checked.  The second argument is a
-    reject function and is called when an error is found.  The reject()
-    function must allow for two arguments: the first is the error message,
-    the second is an optional prefix string.  It's possible for reject()
-    to be called more than once during an invocation of check_signature().
-    The third argument is optional and is the name of the files the
-    detached signature applies to.  The fourth argument is optional and is
-    a *list* of keyrings to use.  'autofetch' can either be None, True or
-    False.  If None, the default behaviour specified in the config will be
-    used.
-    """
-
-    rejects = []
-
-    # Ensure the filename contains no shell meta-characters or other badness
-    if not re_taint_free.match(sig_filename):
-        rejects.append("!!WARNING!! tainted signature filename: '%s'." % (sig_filename))
-        return (None, rejects)
-
-    if data_filename and not re_taint_free.match(data_filename):
-        rejects.append("!!WARNING!! tainted data filename: '%s'." % (data_filename))
-        return (None, rejects)
-
-    if not keyrings:
-        keyrings = [ x.keyring_name for x in session.query(Keyring).filter(Keyring.active == True).all() ]
-
-    # Autofetch the signing key if that's enabled
-    if autofetch == None:
-        autofetch = Cnf.get("Dinstall::KeyAutoFetch")
-    if autofetch:
-        error_msg = retrieve_key(sig_filename)
-        if error_msg:
-            rejects.append(error_msg)
-            return (None, rejects)
-
-    # Build the command line
-    status_read, status_write = os.pipe()
-    cmd = "gpgv --status-fd %s %s %s %s" % (
-        status_write, gpg_keyring_args(keyrings), sig_filename, data_filename)
-
-    # Invoke gpgv on the file
-    (output, status, exit_status) = gpgv_get_status_output(cmd, status_read, status_write)
-
-    # Process the status-fd output
-    (keywords, internal_error) = process_gpgv_output(status)
-
-    # If we failed to parse the status-fd output, let's just whine and bail now
-    if internal_error:
-        rejects.append("internal error while performing signature check on %s." % (sig_filename))
-        rejects.append(internal_error, "")
-        rejects.append("Please report the above errors to the Archive maintainers by replying to this mail.", "")
-        return (None, rejects)
-
-    # Now check for obviously bad things in the processed output
-    if keywords.has_key("KEYREVOKED"):
-        rejects.append("The key used to sign %s has been revoked." % (sig_filename))
-    if keywords.has_key("BADSIG"):
-        rejects.append("bad signature on %s." % (sig_filename))
-    if keywords.has_key("ERRSIG") and not keywords.has_key("NO_PUBKEY"):
-        rejects.append("failed to check signature on %s." % (sig_filename))
-    if keywords.has_key("NO_PUBKEY"):
-        args = keywords["NO_PUBKEY"]
-        if len(args) >= 1:
-            key = args[0]
-        rejects.append("The key (0x%s) used to sign %s wasn't found in the keyring(s)." % (key, sig_filename))
-    if keywords.has_key("BADARMOR"):
-        rejects.append("ASCII armour of signature was corrupt in %s." % (sig_filename))
-    if keywords.has_key("NODATA"):
-        rejects.append("no signature found in %s." % (sig_filename))
-    if keywords.has_key("EXPKEYSIG"):
-        args = keywords["EXPKEYSIG"]
-        if len(args) >= 1:
-            key = args[0]
-        rejects.append("Signature made by expired key 0x%s" % (key))
-    if keywords.has_key("KEYEXPIRED") and not keywords.has_key("GOODSIG"):
-        args = keywords["KEYEXPIRED"]
-        expiredate=""
-        if len(args) >= 1:
-            timestamp = args[0]
-            if timestamp.count("T") == 0:
-                try:
-                    expiredate = time.strftime("%Y-%m-%d", time.gmtime(float(timestamp)))
-                except ValueError:
-                    expiredate = "unknown (%s)" % (timestamp)
-            else:
-                expiredate = timestamp
-        rejects.append("The key used to sign %s has expired on %s" % (sig_filename, expiredate))
-
-    if len(rejects) > 0:
-        return (None, rejects)
-
-    # Next check gpgv exited with a zero return code
-    if exit_status:
-        rejects.append("gpgv failed while checking %s." % (sig_filename))
-        if status.strip():
-            rejects.append(prefix_multi_line_string(status, " [GPG status-fd output:] "))
-        else:
-            rejects.append(prefix_multi_line_string(output, " [GPG output:] "))
-        return (None, rejects)
-
-    # Sanity check the good stuff we expect
-    if not keywords.has_key("VALIDSIG"):
-        rejects.append("signature on %s does not appear to be valid [No VALIDSIG]." % (sig_filename))
-    else:
-        args = keywords["VALIDSIG"]
-        if len(args) < 1:
-            rejects.append("internal error while checking signature on %s." % (sig_filename))
-        else:
-            fingerprint = args[0]
-    if not keywords.has_key("GOODSIG"):
-        rejects.append("signature on %s does not appear to be valid [No GOODSIG]." % (sig_filename))
-    if not keywords.has_key("SIG_ID"):
-        rejects.append("signature on %s does not appear to be valid [No SIG_ID]." % (sig_filename))
-
-    # 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="",NOTATION_DATA="",NOTATION_NAME="",KEYEXPIRED="",POLICY_URL="")
-
-    for keyword in keywords.keys():
-        if not known_keywords.has_key(keyword):
-            rejects.append("found unknown status token '%s' from gpgv with args '%r' in %s." % (keyword, keywords[keyword], sig_filename))
-
-    if len(rejects) > 0:
-        return (None, rejects)
-    else:
-        return (fingerprint, [])
-
 ################################################################################
 
 def gpg_get_key_addresses(fingerprint):
diff --git a/tests/test_process_gpgv_output.py b/tests/test_process_gpgv_output.py
deleted file mode 100755 (executable)
index ea1fb33..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-from base_test import DakTestCase
-
-import unittest
-
-from daklib.utils import process_gpgv_output
-
-class ProcessGPGVOutputTestCase(DakTestCase):
-    def assertParse(self, input, output):
-        self.assertEqual(process_gpgv_output(input)[0], output)
-
-    def assertNotParse(self, input):
-        ret = process_gpgv_output(input)
-        self.assertNotEqual(len(ret[1]), 0)
-
-    ##
-
-    def testEmpty(self):
-        self.assertParse('', {})
-
-    def testBroken(self):
-        self.assertNotParse('foo')
-        self.assertNotParse('  foo  ')
-        self.assertNotParse('[PREFIXPG:] KEY VAL1 VAL2 VAL3')
-
-    def testSimple(self):
-        self.assertParse(
-            '[GNUPG:] KEY VAL1 VAL2 VAL3',
-            {'KEY': ['VAL1', 'VAL2', 'VAL3']},
-        )
-
-    def testNoKeys(self):
-        self.assertParse('[GNUPG:] KEY', {'KEY': []})
-
-    def testDuplicate(self):
-        self.assertNotParse('[GNUPG:] TEST_KEY\n[GNUPG:] TEST_KEY')
-        self.assertNotParse('[GNUPG:] KEY VAL1\n[GNUPG:] KEY VAL2')
-
-    def testDuplicateSpecial(self):
-        # NODATA and friends are special
-        for special in ('NODATA', 'SIGEXPIRED', 'KEYEXPIRED'):
-            self.assertParse(
-                '[GNUPG:] %s\n[GNUPG:] %s' % (special, special),
-                {special: []},
-            )
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tools/import_changelogs.py b/tools/import_changelogs.py
deleted file mode 100755 (executable)
index 9ab5192..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/python
-# (c) 2010 Luca Falavigna <dktrkranz@debian.org>
-# Free software licensed under the GPL version 2 or later
-
-import os
-import sys
-import fnmatch
-from glob import glob
-sys.path.append('../dak')
-from daklib.dbconn import *
-from daklib import utils
-from daklib.queue import Upload
-
-i = 0
-t = 0
-pattern = '*.changes'
-changes_dir = '/srv/ftp.debian.org/queue/done'
-
-def find_changes(pattern, root):
-    for path, dirs, files in os.walk(os.path.abspath(root)):
-        for filename in fnmatch.filter(files, pattern):
-            yield os.path.join(path, filename)
-
-for changes_file in find_changes(pattern, changes_dir):
-    t = t + 1
-for changes_file in find_changes(pattern, changes_dir):
-    u = Upload()
-    u.pkg.changes_file = changes_file
-    (u.pkg.changes["fingerprint"], rejects) = utils.check_signature(changes_file)
-    if u.load_changes(changes_file):
-        try:
-            u.store_changelog()
-        except:
-            print 'Unable to handle %s' % changes_file
-    else:
-        print u.rejects
-    i = i + 1
-    sys.stdout.write('%d out of %d processed\r' % (i, t))