From: Anthony Towns Date: Thu, 17 Nov 2005 08:47:31 +0000 (+0000) Subject: oops, actually cvs add dak, tiffani, README.quotes X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8352a5d65b401655ccd629b0587abecd0fabbac;p=dak oops, actually cvs add dak, tiffani, README.quotes --- diff --git a/dak b/dak new file mode 100755 index 00000000..8a329689 --- /dev/null +++ b/dak @@ -0,0 +1,162 @@ +#!/usr/bin/env python + +# Launch dak functionality +# Copyright (c) 2005 Anthony Towns +# $Id: dak,v 1.1 2005-11-17 08:47:31 ajt 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +################################################################################ + +# well I don't know where you're from but in AMERICA, there's a little +# thing called "abstinent until proven guilty." +# -- http://harrietmiers.blogspot.com/2005/10/wow-i-feel-loved.html + +# (if James had a blog, I bet I could find a funny quote in it to use!) + +################################################################################ + +import sys + +################################################################################ + +# maps a command name to a module name +functionality = [ + ("ls", "Show which suites packages are in", + ("madison", "main"), ["madison"]), + ("rm", "Remove packages from suites", "melanie"), + + ("decode-dot-dak", "Display contents of a .katie file", "ashley"), + ("override", "Query/change the overrides", "alicia"), + + ("install", "Install a package from accepted (security only)", + "amber"), # XXX - hmm (ajt) + ("reject-proposed-updates", "Manually reject from proposed-updates", "lauren"), + ("process-new", "Process NEW and BYHAND packages", "lisa"), + + ("control-overrides", "Manipulate/list override entries in bulk", + "natalie"), + ("control-suite", "Manipulate suites in bulk", "heidi"), + + ("stats", "Generate stats pr0n", "saffron"), + ("cruft-report", "Check for obsolete or duplicated packages", + "rene"), + ("queue-report", "Produce a report on NEW and BYHAND packages", + "helena"), + ("compare-suites", "Show fixable discrepencies between suites", + "andrea"), + + ("check-archive", "Archive sanity checks", "tea"), + ("check-overrides", "Override cruft checks", "cindy"), + ("check-proposed-updates", "Dependency checking for proposed-updates", + "jeri"), + + ("examine-package", "Show information useful for NEW processing", + "fernanda"), + + ("init-db", "Update the database to match the conf file", + "alyson"), + ("init-dirs", "Initial setup of the archive", "rose"), + ("import-archive", "Populate SQL database based from an archive tree", + "neve"), + + ("poolize", "Move packages from dists/ to pool/", "catherine"), + ("symlink-dists", "Generate compatability symlinks from dists/", + "claire"), + + ("process-unchecked", "Process packages in queue/unchecked", "jennifer"), + + ("process-accepted", "Install packages into the pool", "kelly"), + ("generate-releases", "Generate Release files", "ziyi"), + ("generate-index-diffs", "Generate .diff/Index files", "tiffani"), + + ("make-suite-file-list", + "Generate lists of packages per suite for apt-ftparchive", "jenna"), + ("make-maintainers", "Generates Maintainers file for BTS etc", + "charisma"), + ("make-overrides", "Generates override files", "denise"), + + ("mirror-split", "Split the pool/ by architecture groups", + "billie"), + + ("clean-proposed-updates", "Remove obsolete .changes from proposed-updates", + "halle"), + ("clean-queues", "Clean cruft from incoming", "shania"), + ("clean-suites", + "Clean unused/superseded packages from the archive", "rhona"), + + ("split-done", "Split queue/done into a data-based hierarchy", + "nina"), + + ("import-ldap-fingerprints", + "Syncs fingerprint and uid tables with Debian LDAP db", "emilie"), + ("import-users-from-passwd", + "Sync PostgreSQL users with passwd file", "julia"), + ("find-null-maintainers", + "Check for users with no packages in the archive", "rosamund"), +] + +names = {} +for f in functionality: + if isinstance(f[2], str): + names[f[2]] = names[f[0]] = (f[2], "main") + else: + names[f[0]] = f[2] + for a in f[3]: names[a] = f[2] + +################################################################################ + +def main(): + if len(sys.argv) == 0: + print "err, argc == 0? how is that possible?" + sys.exit(1); + elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == "--help"): + print "Sub commands:" + for f in functionality: + print " %-23s %s" % (f[0], f[1]) + sys.exit(0); + else: + # should set PATH based on sys.argv[0] maybe + # possibly should set names based on sys.argv[0] too + sys.path = [sys.path[0]+"/py-symlinks"] + sys.path + + cmdname = sys.argv[0] + cmdname = cmdname[cmdname.rfind("/")+1:] + if cmdname in names: + pass # invoke directly + else: + cmdname = sys.argv[1] + sys.argv = [sys.argv[0] + " " + sys.argv[1]] + sys.argv[2:] + if cmdname not in names: + match = [] + for f in names: + if f.startswith(cmdname): + match.append(f) + if len(match) == 1: + cmdname = match[0] + elif len(match) > 1: + print "ambiguous command: %s" % ", ".join(match) + sys.exit(1); + else: + print "unknown command \"%s\"" % (cmdname) + sys.exit(1); + + func = names[cmdname] + x = __import__(func[0]) + x.__getattribute__(func[1])() + +if __name__ == "__main__": + main() + diff --git a/docs/README.quotes b/docs/README.quotes new file mode 100644 index 00000000..413cf625 --- /dev/null +++ b/docs/README.quotes @@ -0,0 +1,315 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +| SirDibos: that sentence sounds like it wants to be a bug report when it grows up + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +| From: Andrew Morton +| Subject: Re: Linux 2.6.0-test1 Ext3 Ooops. Reboot needed. +| To: Ricardo Galli +| Cc: linux-kernel@vger.kernel.org +| Date: Fri, 18 Jul 2003 14:27:20 -0700 +| +| Ricardo Galli wrote: +| > +| > "File alteration monitor", from Debian. +| +| OK. +| +| > $ apt-cache show fam +| +| I was attacked by dselect as a small child and have since avoided debian. +| Is there a tarball anywhere? + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +| From: Bob Hilliard +| +| In my experience, James has been very responsive, albeit not +| verbose, to reasonable questions/requests that don't start out saying +| "James is a bum - throw him out". + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +| Kamion: are you too busy to look at my generic +| include/exclude stuff for the bts yet? +| eigood: expect me to be busy for about the next week at this +| rate +| my %field_match = ( +| 'subject' => \&contains_field_match, +| 'severity' => \&exact_field_match, +| that's how it works, basically +| I'm a big fan of callbacks +| [...] +| Kamion: how do you feel about having +| per-bug/per-package/per-source notes support in the bts? +| eigood: as I said five minutes ago, I really don't have time +| to think about it right now, sorry +| here, maybe it would be clearer if I /part +| <-- Kamion (~cjwatson@host81-129-36-235.in-addr.btopenworld.com) has left #debian-devel (too busy. no, really.) +| no need to be hostile +| eigood: he told you he's too busy and you kept bugging him. take +| a hint :) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + bwahahaha. Dear "security@debian.org" Thank you for your + email about "[SECURITY] [DSA-403-1] userland can access Linux + kernel memory" ...I need to filter out spam... To send email to + vhs@flexdesign.com please put "ducks" anywhere on your subject + line. ...Thanks, Bob... + I'll be sure to do that... + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Hmm, that was a nice short bug report. + to submit@: "strdup(NULL) segfaults" to -done@: "Yes, go away" +[...] + how did he pass T&S? sheer bloody-mindedness? +[...] + Good attention to detail? + Masking of psychopathic tendencies? +* drow shrugs + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + the people love me + like pneumonia + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +test.c:5: `long long long' is too long for GCC + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +http://yro.slashdot.org/comments.pl?sid=91696&cid=7890274 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + argh. + i accidentally banned all mails to the bts that had 'ossi' in them + "possible" etc + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +Wednesday, December 24th, 2003 +3:34 pm +Dear PC World, + +1) The most common chipset used in Pentium-II machines is the Intel 440BX. It is also relatively common in slower P-IIIs, and is approximately identical to the 440MX (a one-chip version aimed at laptops). + +2) The 440BX has the interesting feature of only being able to address up to 128MBit density RAM. This is a relatively widely known issue. + +3) Simple maths suggests that if you have a 128MB DIMM with 4 chips on it, they are likely to be 256MBit parts. + +4) Marking said DIMMs as being suitable for Pentium-IIs is therefore really indescribably stupid, you wankwits. Please fuck off and die in a great big chemical fire before I get back there to beat you. + +Love, + +Matthew. + +PS, + +Die. No, really. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +Wednesday, November 12th, 2003 +2:43 am +It's true that you learn something new every day. Yesterday I discovered that playdough is electrically conductive. I also discovered that RAM becomes unhappy if all of its pins are joined together with electrically conductive material. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +Monday, November 3rd, 2003 +3:13 pm +Hint to people attempting to sell things online: + +DON'T PUT http://172.16.100.107/ IN YOUR URLS, YOU INCOMPETENT FUCKMONKEYS + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +| priviledged positions? What privilege? The honour of working harder +| than most people for absolutely no recognition? + +Manoj Srivastava in <87lln8aqfm.fsf@glaurung.internal.golden-gryphon.com> + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + you could just r00t klecker through [...] and do it yourself + heh + I think there's a bit in the DMUP about that + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + well, thing is, he doesn't seem to understand you usually don't + have the time to give everyone status updates when a fly moves a + leg + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +In Soviet Russia... + +The cops arrest YOU for not showing papers. Wait, I didn't have to +reverse it this time, what's going on? + +http://slashdot.org/comments.pl?sid=97501&cid=8334726 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + ... Messaging IRCops isn't the end of the world, + unless its "/msg ircop I fucked your wife." + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +| From: Andrew Morton +| Subject: Re: [PATCH] Compile kernel with GCC-3.5 and without regparm +| To: "Art Haas" +| Cc: linux-kernel@vger.kernel.org +| Date: Tue, 2 Mar 2004 16:59:28 -0800 +| X-Mailer: Sylpheed version 0.9.7 (GTK+ 1.2.10; i586-pc-linux-gnu) +| +| "Art Haas" wrote: +| > +| > I tried to build the kernel with my CVS GCC-3.5 compiler today, and had +| > all sorts of failures about prototypes not matching. +| +| -mm is where the gcc-3.5 action is. There seems to be a bit of an arms +| race going on wherein the gcc developers are trying to break the kernel +| build faster than I and others can fix it. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +(Note that the above is a gross oversimplification, and ignores issues +including but not necessarily limited to subarchitectures, and quality +of hardware coverage within certian architectures. It contains forward +looking statements, and may cause cancer in lab animals.) + +Joey Hess in <20040317065216.GA29816@kitenet.net> + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + now there's a thought + DD trading cards + official joeyh action figure, with rapid-fire upload action + lamont with pump-action NMU flame-thrower! + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + "attempt to de-scare ... may cause cancer" +* aj thinks elmo needs to work on his de-scaring + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + the Thom Remote Management Unit + TRMU + i cost 3 times the amount an IBM remote management card would. per use. + last time *i* checked, you were free + oh, different service + never mind + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +From: Stan Shebs +Subject: Re: MS/CW-style inline assembly for GCC +To: gcc@gcc.gnu.org +Date: Mon, 03 May 2004 17:35:40 -0700 + +Can you be more specific about the difficulties? The CW version didn't +seem that hard (unless Apple mgmt is reading this, in which case it was +fiendishly difficult :-) ), but I did impose some restrictions in edge +[...] + +Stan + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +buildd@caballero:~/logs$ du -sh kernel-patch-powerpc-2.6.5_2.6.5-2_20040506-1033 +54G kernel-patch-powerpc-2.6.5_2.6.5-2_20040506-1033 + +Next week on "When Good Buildds Go Bad"[...] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + 153 NP+ 11 James Troup (7.9K) you know you want it. err. +* aj looks disturbed as he trolls through his saved mail + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +From: Andrew Morton +Subject: 2.6.6-mm5 +To: linux-kernel@vger.kernel.org +Date: Sat, 22 May 2004 01:36:36 -0700 +X-Mailer: Sylpheed version 0.9.7 (GTK+ 1.2.10; i386-redhat-linux-gnu) + +[...] + + Although this feature has been around for a while it is new code, and the + usual cautions apply. If it munches all your files please tell Jens and + he'll type them in again for you. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +From: Randall Donald +Subject: foo_3.4-1_i386.changes REJECTED +To: John Doe +Cc: Debian Installer +Date: Thu, 17 Jun 2004 23:17:48 -0400 + +Hi, + + Description: something to put here + Maybe I need a long description here! + +Yes, you do! + +-- +Randall Donald + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + I don't test, I upload to unstable and a milllllion users test it for me :) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +This is based on an actual radio conversation between a U.S. Navy +aircraft carrier, U.S.S. Abraham Lincoln, and Canadian authorities off +the coast of Newfoundland in October, 1995. The radio conversation was +released by the Chief of Naval Operations on 10/10/95 authorized by +the Freedom of Information Act. + +Canadians: Please divert your course 15 degrees to the South to avoid + collision. + +Americans: Recommend you divert your course 15 degrees to the North to + avoid a collision. + +Canadians: Negative. You will have to divert your course 15 degrees to + the South to avoid a collision. + +Americans: This is the Captain of a US Navy ship. I say again, divert + YOUR course. + +Canadians: No, I say again, you divert YOUR course. + +Americans: THIS IS THE AIRCRAFT CARRIER USS LINCOLN, THE SECOND + LARGEST SHIP IN THE UNITED STATES' ATLANTIC FLEET. WE ARE + ACCOMPANIED BY THREE DESTROYERS, THREE CRUISERS AND + NUMEROUS SUPPORT VESSELS. I DEMAND THAT YOU CHANGE YOUR + COURSE 15 DEGREES NORTH--I SAY AGAIN, THAT'S ONE FIVE + DEGREES NORTH--OR COUNTER-MEASURES WILL BE UNDERTAKEN TO + ENSURE THE SAFETY OF THIS SHIP. + +Canadians: This is a lighthouse. Your call. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + i didn't slam today's dinstall too badly, did I? + File "/org/ftp.debian.org/katie/kelly", line 608, in main + sys.stderr.write("Installed %d package %s, %s.\n" % (install_count, sets, utils.size_type(int(install_bytes)))); + OverflowError: float too large to convert diff --git a/tiffani b/tiffani new file mode 100755 index 00000000..db856778 --- /dev/null +++ b/tiffani @@ -0,0 +1,397 @@ +#!/usr/bin/env python + +########################################################### +# generates partial package updates list + +# idea and basic implementation by Anthony, some changes by Andreas +# parts are stolen from ziyi +# +# Copyright (C) 2004-5 Anthony Towns +# Copyright (C) 2004-5 Andreas Barth + +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +# < elmo> bah, don't bother me with annoying facts +# < elmo> I was on a roll + + +################################################################################ + +import sys, os, tempfile +import apt_pkg +import utils + +################################################################################ + +projectB = None; +Cnf = None; +Logger = None; +Options = None; + +################################################################################ + +def usage (exit_code=0): + print """Usage: tiffani [OPTIONS] [suites] +Write out ed-style diffs to Packages/Source lists + + -h, --help show this help and exit + -c give the canonical path of the file + -p name for the patch (defaults to current time) + -n take no action + """ + sys.exit(exit_code); + + +def tryunlink(file): + try: + os.unlink(file) + except OSError: + print "warning: removing of %s denied" % (file) + +def smartstat(file): + for ext in ["", ".gz", ".bz2"]: + if os.path.isfile(file + ext): + return (ext, os.stat(file + ext)) + return (None, None) + +def smartlink(f, t): + if os.path.isfile(f): + os.link(f,t) + elif os.path.isfile("%s.gz" % (f)): + os.system("gzip -d < %s.gz > %s" % (f, t)) + elif os.path.isfile("%s.bz2" % (f)): + os.system("bzip2 -d < %s.bz2 > %s" % (f, t)) + else: + print "missing: %s" % (f) + raise IOError, f + +def smartopen(file): + if os.path.isfile(file): + f = open(file, "r") + elif os.path.isfile("%s.gz" % file): + f = create_temp_file(os.popen("zcat %s.gz" % file, "r")) + elif os.path.isfile("%s.bz2" % file): + f = create_temp_file(os.popen("bzcat %s.bz2" % file, "r")) + else: + f = None + return f + +def pipe_file(f, t): + f.seek(0) + while 1: + l = f.read() + if not l: break + t.write(l) + t.close() + +class Updates: + def __init__(self, readpath = None, max = 14): + self.can_path = None + self.history = {} + self.history_order = [] + self.max = max + self.readpath = readpath + self.filesizesha1 = None + + if readpath: + try: + f = open(readpath + "/Index") + x = f.readline() + + def read_hashs(ind, f, self, x=x): + while 1: + x = f.readline() + if not x or x[0] != " ": break + l = x.split() + if not self.history.has_key(l[2]): + self.history[l[2]] = [None,None] + self.history_order.append(l[2]) + self.history[l[2]][ind] = (l[0], int(l[1])) + return x + + while x: + l = x.split() + + if len(l) == 0: + x = f.readline() + continue + + if l[0] == "SHA1-History:": + x = read_hashs(0,f,self) + continue + + if l[0] == "SHA1-Patches:": + x = read_hashs(1,f,self) + continue + + if l[0] == "Canonical-Name:" or l[0]=="Canonical-Path:": + self.can_path = l[1] + + if l[0] == "SHA1-Current:" and len(l) == 3: + self.filesizesha1 = (l[1], int(l[2])) + + x = f.readline() + + except IOError: + 0 + + def dump(self, out=sys.stdout): + if self.can_path: + out.write("Canonical-Path: %s\n" % (self.can_path)) + + if self.filesizesha1: + out.write("SHA1-Current: %s %7d\n" % (self.filesizesha1)) + + hs = self.history + l = self.history_order[:] + + cnt = len(l) + if cnt > self.max: + for h in l[:cnt-self.max]: + tryunlink("%s/%s.gz" % (self.readpath, h)) + del hs[h] + l = l[cnt-self.max:] + self.history_order = l[:] + + out.write("SHA1-History:\n") + for h in l: + out.write(" %s %7d %s\n" % (hs[h][0][0], hs[h][0][1], h)) + out.write("SHA1-Patches:\n") + for h in l: + out.write(" %s %7d %s\n" % (hs[h][1][0], hs[h][1][1], h)) + +def create_temp_file(r): + f = tempfile.TemporaryFile() + while 1: + x = r.readline() + if not x: break + f.write(x) + r.close() + del x,r + f.flush() + f.seek(0) + return f + +def sizesha1(f): + size = os.fstat(f.fileno())[6] + f.seek(0) + sha1sum = apt_pkg.sha1sum(f) + return (sha1sum, size) + +def genchanges(Options, outdir, oldfile, origfile, maxdiffs = 14): + if Options.has_key("NoAct"): + print "not doing anything" + return + + patchname = Options["PatchName"] + + # origfile = /path/to/Packages + # oldfile = ./Packages + # newfile = ./Packages.tmp + # difffile = outdir/patchname + # index => outdir/Index + + # (outdir, oldfile, origfile) = argv + + newfile = oldfile + ".new" + difffile = "%s/%s" % (outdir, patchname) + + upd = Updates(outdir, int(maxdiffs)) + (oldext, oldstat) = smartstat(oldfile) + (origext, origstat) = smartstat(origfile) + if not origstat: + print "%s doesn't exist" % (origfile) + return + if not oldstat: + print "initial run" + os.link(origfile + origext, oldfile + origext) + return + + if oldstat[1:3] == origstat[1:3]: + print "hardlink unbroken, assuming unchanged" + return + + oldf = smartopen(oldfile) + oldsizesha1 = sizesha1(oldf) + + # should probably early exit if either of these checks fail + # alternatively (optionally?) could just trim the patch history + + if upd.filesizesha1: + if upd.filesizesha1 != oldsizesha1: + print "old file seems to have changed! %s %s => %s %s" % (upd.filesizesha1 + oldsizesha1) + + # XXX this should be usable now + # + #for d in upd.history.keys(): + # df = smartopen("%s/%s" % (outdir,d)) + # act_sha1size = sizesha1(df) + # df.close() + # exp_sha1size = upd.history[d][1] + # if act_sha1size != exp_sha1size: + # print "patch file %s seems to have changed! %s %s => %s %s" % \ + # (d,) + exp_sha1size + act_sha1size + + if Options.has_key("CanonicalPath"): upd.can_path=Options["CanonicalPath"] + + if os.path.exists(newfile): os.unlink(newfile) + smartlink(origfile, newfile) + newf = open(newfile, "r") + newsizesha1 = sizesha1(newf) + newf.close() + + if newsizesha1 == oldsizesha1: + os.unlink(newfile) + oldf.close() + print "file unchanged, not generating diff" + else: + if not os.path.isdir(outdir): os.mkdir(outdir) + print "generating diff" + w = os.popen("diff --ed - %s | gzip -c -9 > %s.gz" % + (newfile, difffile), "w") + pipe_file(oldf, w) + oldf.close() + + difff = smartopen(difffile) + difsizesha1 = sizesha1(difff) + difff.close() + + upd.history[patchname] = (oldsizesha1, difsizesha1) + upd.history_order.append(patchname) + + upd.filesizesha1 = newsizesha1 + + os.unlink(oldfile + oldext) + os.link(origfile + origext, oldfile + origext) + os.unlink(newfile) + + f = open(outdir + "/Index", "w") + upd.dump(f) + f.close() + + +def main(): + global Cnf, Options, Logger + + os.umask(0002); + + Cnf = utils.get_conf(); + Arguments = [ ('h', "help", "Tiffani::Options::Help"), + ('c', None, "Tiffani::Options::CanonicalPath", "hasArg"), + ('p', "patchname", "Tiffani::Options::PatchName", "hasArg"), + ('r', "rootdir", "Tiffani::Options::RootDir", "hasArg"), + ('d', "tmpdir", "Tiffani::Options::TempDir", "hasArg"), + ('m', "maxdiffs", "Tiffani::Options::MaxDiffs", "hasArg"), + ('n', "n-act", "Tiffani::Options::NoAct"), + ]; + suites = apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv); + Options = Cnf.SubTree("Tiffani::Options"); + if Options.has_key("Help"): usage(); + + maxdiffs = Options.get("MaxDiffs::Default", "14") + maxpackages = Options.get("MaxDiffs::Packages", maxdiffs) + maxcontents = Options.get("MaxDiffs::Contents", maxdiffs) + maxsources = Options.get("MaxDiffs::Sources", maxdiffs) + + if not Options.has_key("PatchName"): + format = "%Y-%m-%d-%H%M.%S" + i,o = os.popen2("date +%s" % (format)) + i.close() + Options["PatchName"] = o.readline()[:-1] + o.close() + + AptCnf = apt_pkg.newConfiguration() + apt_pkg.ReadConfigFileISC(AptCnf,utils.which_apt_conf_file()) + + if Options.has_key("RootDir"): Cnf["Dir::Root"] = Options["RootDir"] + + if not suites: + suites = Cnf.SubTree("Suite").List() + + for suite in suites: + if suite == "Experimental": continue + + print "Processing: " + suite + SuiteBlock = Cnf.SubTree("Suite::" + suite) + + if SuiteBlock.has_key("Untouchable"): + print "Skipping: " + suite + " (untouchable)" + continue + + suite = suite.lower() + + architectures = SuiteBlock.ValueList("Architectures") + + if SuiteBlock.has_key("Components"): + components = SuiteBlock.ValueList("Components") + else: + components = [] + + suite_suffix = Cnf.Find("Dinstall::SuiteSuffix"); + if components and suite_suffix: + longsuite = suite + "/" + suite_suffix; + else: + longsuite = suite; + + tree = SuiteBlock.get("Tree", "dists/%s" % (longsuite)) + + if AptCnf.has_key("tree::%s" % (tree)): + sections = AptCnf["tree::%s::Sections" % (tree)].split() + elif AptCnf.has_key("bindirectory::%s" % (tree)): + sections = AptCnf["bindirectory::%s::Sections" % (tree)].split() + else: + aptcnf_filename = os.path.basename(utils.which_apt_conf_file()); + print "ALERT: suite %s not in %s, nor untouchable!" % (suite, aptcnf_filename); + continue + + for architecture in architectures: + if architecture == "all": + continue + + if architecture != "source": + # Process Contents + file = "%s/Contents-%s" % (Cnf["Dir::Root"] + tree, + architecture) + storename = "%s/%s_contents_%s" % (Options["TempDir"], suite, architecture) + print "running contents for %s %s : " % (suite, architecture), + genchanges(Options, file + ".diff", storename, file, \ + Cnf.get("Suite::%s::Tiffani::MaxDiffs::Contents" % (suite), maxcontents)) + + # use sections instead of components since katie.conf + # treats "foo/bar main" as suite "foo", suitesuffix "bar" and + # component "bar/main". suck. + + for component in sections: + if architecture == "source": + longarch = architecture + packages = "Sources" + maxsuite = maxsources + else: + longarch = "binary-%s"% (architecture) + packages = "Packages" + maxsuite = maxpackages + + file = "%s/%s/%s/%s" % (Cnf["Dir::Root"] + tree, + component, longarch, packages) + storename = "%s/%s_%s_%s" % (Options["TempDir"], suite, component, architecture) + print "running for %s %s %s : " % (suite, component, architecture), + genchanges(Options, file + ".diff", storename, file, \ + Cnf.get("Suite::%s::Tiffani::MaxDiffs::%s" % (suite, packages), maxsuite)) + +################################################################################ + +if __name__ == '__main__': + main()