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 ################################################################################
33 from debian_bundle import deb822
34 from dbconn import DBConn
37 def __init__(self, filename):
38 self.filename = filename
43 # we need to remove the temporary directory, if we created one
44 if self.tmpdir and os.path.exists(self.tmpdir):
45 shutil.rmtree(self.tmpdir)
48 # get a list of the ar contents
51 cmd = "ar t %s" % (self.filename)
53 (result, output) = commands.getstatusoutput(cmd)
56 reject("%s: 'ar t' invocation failed." % (self.filename))
57 reject(utils.prefix_multi_line_string(output, " [ar output:] "), "")
58 self.chunks = output.split('\n')
63 # Internal function which extracts the contents of the .ar to
64 # a temporary directory
67 tmpdir = tempfile.mkdtemp()
71 cmd = "ar x %s %s %s" % (os.path.join(cwd,self.filename), self.chunks[1], self.chunks[2])
72 (result, output) = commands.getstatusoutput(cmd)
74 reject("%s: '%s' invocation failed." % (filename, cmd))
75 reject(utils.prefix_multi_line_string(output, " [ar output:] "), "")
84 Check deb contents making sure the .deb contains:
87 3. data.tar.gz or data.tar.bz2
88 in that order, and nothing else.
91 rejected = not self.chunks
92 if len(self.chunks) != 3:
94 reject("%s: found %d chunks, expected 3." % (self.filename, len(self.chunks)))
95 if self.chunks[0] != "debian-binary":
97 reject("%s: first chunk is '%s', expected 'debian-binary'." % (self.filename, self.chunks[0]))
98 if self.chunks[1] != "control.tar.gz":
100 reject("%s: second chunk is '%s', expected 'control.tar.gz'." % (self.filename, self.chunks[1]))
101 if self.chunks[2] not in [ "data.tar.bz2", "data.tar.gz" ]:
103 reject("%s: third chunk is '%s', expected 'data.tar.gz' or 'data.tar.bz2'." % (self.filename, self.chunks[2]))
107 def scan_package(self):
109 Unpack the .deb, do sanity checking, and gather info from it.
111 Currently information gathering consists of getting the contents list. In
112 the hopefully near future, it should also include gathering info from the
115 @return True if the deb is valid and contents were imported
117 rejected = not self.valid_deb()
120 if not rejected and self.tmpdir:
123 os.chdir(self.tmpdir)
124 if self.chunks[1] == "control.tar.gz":
125 control = tarfile.open(os.path.join(self.tmpdir, "control.tar.gz" ), "r:gz")
126 elif self.chunks[1] == "control.tar.bz2":
127 control = tarfile.open(os.path.join(self.tmpdir, "control.tar.bz2" ), "r:bz2")
129 pkg = deb822.Packages.iter_paragraphs( control.extractfile('./control') ).next()
131 if self.chunks[2] == "data.tar.gz":
132 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.gz"), "r:gz")
133 elif self.chunks[2] == "data.tar.bz2":
134 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.bz2" ), "r:bz2")
136 return DBConn().insert_content_paths(pkg, [ tarinfo.name for tarinfo in data if tarinfo.isdir()])
139 traceback.print_exc()
149 if __name__ == "__main__":
150 Binary( "/srv/ftp.debian.org/queue/accepted/halevt_0.1.3-2_amd64.deb" ).scan_package()