]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/utils.py
Revert "Merge commit 'stew/content_generation' into merge"
[dak.git] / daklib / utils.py
index 9582dadb997cd8646e6f5c706485036b8a0d7d67..fd790b5930df56d0e49804a13178db33f7bca090 100755 (executable)
@@ -37,11 +37,13 @@ import stat
 import apt_pkg
 import database
 import time
-import tarfile
+import re
+import string
+import email as modemail
 from dak_exceptions import *
 from regexes import re_html_escaping, html_escaping, re_single_line_field, \
                     re_multi_line_field, re_srchasver, re_verwithext, \
-                    re_parse_maintainer, re_taint_free, re_gpg_uid
+                    re_parse_maintainer, re_taint_free, re_gpg_uid, re_re_mark
 
 ################################################################################
 
@@ -232,6 +234,10 @@ def parse_changes(filename, signing_rules=0):
     changes_in = open_file(filename)
     content = changes_in.read()
     changes_in.close()
+    try:
+        unicode(content, 'utf-8')
+    except UnicodeError:
+        raise ChangesUnicodeError, "Changes file not proper utf-8"
     return parse_deb822(content, signing_rules)
 
 ################################################################################
@@ -599,6 +605,67 @@ def send_mail (message, filename=""):
         os.write (fd, message)
         os.close (fd)
 
+    if Cnf.has_key("Dinstall::MailWhiteList") and \
+           Cnf["Dinstall::MailWhiteList"] != "":
+        message_in = open_file(filename)
+        message_raw = modemail.message_from_file(message_in)
+        message_in.close();
+
+        whitelist = [];
+        whitelist_in = open_file(Cnf["Dinstall::MailWhiteList"])
+        try:
+            for line in whitelist_in:
+                if re_re_mark.match(line):
+                    whitelist.append(re.compile(re_re_mark.sub("", line.strip(), 1)))
+                else:
+                    whitelist.append(re.compile(re.escape(line.strip())))
+        finally:
+            whitelist_in.close()
+
+        # Fields to check.
+        fields = ["To", "Bcc", "Cc"]
+        for field in fields:
+            # Check each field
+            value = message_raw.get(field, None)
+            if value != None:
+                match = [];
+                for item in value.split(","):
+                    (rfc822_maint, rfc2047_maint, name, email) = fix_maintainer(item.strip())
+                    mail_whitelisted = 0
+                    for wr in whitelist:
+                        if wr.match(email):
+                            mail_whitelisted = 1
+                            break
+                    if not mail_whitelisted:
+                        print "Skipping %s since it's not in %s" % (item, Cnf["Dinstall::MailWhiteList"])
+                        continue
+                    match.append(item)
+
+                # Doesn't have any mail in whitelist so remove the header
+                if len(match) == 0:
+                    del message_raw[field]
+                else:
+                    message_raw.replace_header(field, string.join(match, ", "))
+
+        # Change message fields in order if we don't have a To header
+        if not message_raw.has_key("To"):
+            fields.reverse()
+            for field in fields:
+                if message_raw.has_key(field):
+                    message_raw[fields[-1]] = message_raw[field]
+                    del message_raw[field]
+                    break
+            else:
+                # Clean up any temporary files
+                # and return, as we removed all recipients.
+                if message:
+                    os.unlink (filename);
+                return;
+
+        fd = os.open(filename, os.O_RDWR|os.O_EXCL, 0700);
+        os.write (fd, message_raw.as_string(True));
+        os.close (fd);
+
     # Invoke sendmail
     (result, output) = commands.getstatusoutput("%s < %s" % (Cnf["Dinstall::SendmailCommand"], filename))
     if (result != 0):
@@ -1282,7 +1349,10 @@ def check_signature (sig_filename, reject, data_filename="", keyrings=None, auto
         if len(args) >= 1:
             timestamp = args[0]
             if timestamp.count("T") == 0:
-                expiredate = time.strftime("%Y-%m-%d", time.gmtime(timestamp))
+                try:
+                    expiredate = time.strftime("%Y-%m-%d", time.gmtime(float(timestamp)))
+                except ValueError:
+                    expiredate = "unknown (%s)" % (timestamp)
             else:
                 expiredate = timestamp
         reject("The key used to sign %s has expired on %s" % (sig_filename, expiredate))
@@ -1428,61 +1498,31 @@ def is_email_alias(email):
 
 ################################################################################
 
-apt_pkg.init()
-
-Cnf = apt_pkg.newConfiguration()
-apt_pkg.ReadConfigFileISC(Cnf,default_config)
-
-if which_conf_file() != default_config:
-    apt_pkg.ReadConfigFileISC(Cnf,which_conf_file())
-
-################################################################################
-
-def generate_contents_information(filename):
+def get_changes_files(dir):
     """
-    Generate a list of flies contained in a .deb
+    Takes a directory and lists all .changes files in it (as well as chdir'ing
+    to the directory; this is due to broken behaviour on the part of p-u/p-a
+    when you're not in the right place)
 
-    @type filename: string
-    @param filename: the path to a .deb
-
-    @rtype: list
-    @return: a list of files in the data.tar.* portion of the .deb
+    Returns a list of filenames
     """
-    cmd = "ar t %s" % (filename)
-    (result, output) = commands.getstatusoutput(cmd)
-    if result != 0:
-        reject("%s: 'ar t' invocation failed." % (filename))
-        reject(utils.prefix_multi_line_string(output, " [ar output:] "), "")
+    try:
+        # Much of the rest of p-u/p-a depends on being in the right place
+        os.chdir(dir)
+        changes_files = [x for x in os.listdir(dir) if x.endswith('.changes')]
+    except OSError, e:
+        fubar("Failed to read list from directory %s (%s)" % (dir, e))
 
-    # Ugh ... this is ugly ... Code ripped from process_unchecked.py
-    chunks = output.split('\n')
+    return changes_files
 
-    contents = []
-    try:
-        cmd = "ar x %s %s" % (filename, chunks[2])
-        (result, output) = commands.getstatusoutput(cmd)
-        if result != 0:
-            reject("%s: '%s' invocation failed." % (filename, cmd))
-            reject(utils.prefix_multi_line_string(output, " [ar output:] "), "")
-
-        # Got deb tarballs, now lets go through and determine what bits
-        # and pieces the deb had ...
-        if chunks[2] == "data.tar.gz":
-            data = tarfile.open("data.tar.gz", "r:gz")
-        elif chunks[2] == "data.tar.bz2":
-            data = tarfile.open("data.tar.bz2", "r:bz2")
-        else:
-            os.remove(chunks[2])
-            reject("couldn't find data.tar.*")
+################################################################################
 
-        for tarinfo in data:
-            if not tarinfo.isdir():
-                contents.append(tarinfo.name[2:])
+apt_pkg.init()
 
-    finally:
-        if os.path.exists( chunks[2] ):
-            os.remove( chunks[2] )
+Cnf = apt_pkg.newConfiguration()
+apt_pkg.ReadConfigFileISC(Cnf,default_config)
 
-    return contents
+if which_conf_file() != default_config:
+    apt_pkg.ReadConfigFileISC(Cnf,which_conf_file())
 
-###############################################################################
+################################################################################