4 Functions related debian binary packages
6 @contact: Debian FTPMaster <ftpmaster@debian.org>
7 @copyright: 2009 Mike O'Connor <stew@debian.org>
8 @license: GNU General Public License version 2 or later
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 ################################################################################
34 from debian_bundle import deb822
35 from dbconn import DBConn
38 def __init__(self, filename):
39 self.filename = filename
45 make sure we cleanup when we are garbage collected.
51 we need to remove the temporary directory, if we created one
53 if self.tmpdir and os.path.exists(self.tmpdir):
55 shutil.rmtree(self.tmpdir)
58 # get a list of the ar contents
61 cmd = "ar t %s" % (self.filename)
63 (result, output) = commands.getstatusoutput(cmd)
66 reject("%s: 'ar t' invocation failed." % (self.filename))
67 reject(utils.prefix_multi_line_string(output, " [ar output:] "), "")
68 self.chunks = output.split('\n')
73 # Internal function which extracts the contents of the .ar to
74 # a temporary directory
77 tmpdir = tempfile.mkdtemp()
81 cmd = "ar x %s %s %s" % (os.path.join(cwd,self.filename), self.chunks[1], self.chunks[2])
82 (result, output) = commands.getstatusoutput(cmd)
84 reject("%s: '%s' invocation failed." % (filename, cmd))
85 reject(utils.prefix_multi_line_string(output, " [ar output:] "), "")
88 atexit.register( self.cleanup )
95 Check deb contents making sure the .deb contains:
98 3. data.tar.gz or data.tar.bz2
99 in that order, and nothing else.
102 rejected = not self.chunks
103 if len(self.chunks) != 3:
105 reject("%s: found %d chunks, expected 3." % (self.filename, len(self.chunks)))
106 if self.chunks[0] != "debian-binary":
108 reject("%s: first chunk is '%s', expected 'debian-binary'." % (self.filename, self.chunks[0]))
109 if self.chunks[1] != "control.tar.gz":
111 reject("%s: second chunk is '%s', expected 'control.tar.gz'." % (self.filename, self.chunks[1]))
112 if self.chunks[2] not in [ "data.tar.bz2", "data.tar.gz" ]:
114 reject("%s: third chunk is '%s', expected 'data.tar.gz' or 'data.tar.bz2'." % (self.filename, self.chunks[2]))
118 def scan_package(self):
120 Unpack the .deb, do sanity checking, and gather info from it.
122 Currently information gathering consists of getting the contents list. In
123 the hopefully near future, it should also include gathering info from the
126 @return True if the deb is valid and contents were imported
128 rejected = not self.valid_deb()
131 if not rejected and self.tmpdir:
134 os.chdir(self.tmpdir)
135 if self.chunks[1] == "control.tar.gz":
136 control = tarfile.open(os.path.join(self.tmpdir, "control.tar.gz" ), "r:gz")
138 pkg = deb822.Packages.iter_paragraphs( control.extractfile('./control') ).next()
140 if self.chunks[2] == "data.tar.gz":
141 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.gz"), "r:gz")
142 elif self.chunks[2] == "data.tar.bz2":
143 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.bz2" ), "r:bz2")
145 return DBConn().insert_content_paths(pkg, [ tarinfo.name for tarinfo in data if tarinfo.isdir()])
148 traceback.print_exc()
158 if __name__ == "__main__":
159 Binary( "/srv/ftp.debian.org/queue/accepted/halevt_0.1.3-2_amd64.deb" ).scan_package()