[Erp5-report] r30858 - /erp5/trunk/products/ERP5/bin/genbt5list
nobody at svn.erp5.org
nobody at svn.erp5.org
Wed Nov 25 16:52:20 CET 2009
Author: kazuhiko
Date: Wed Nov 25 16:52:20 2009
New Revision: 30858
URL: http://svn.erp5.org?rev=30858&view=rev
Log:
monkey patch tarfile library if python version is 2.4.
Modified:
erp5/trunk/products/ERP5/bin/genbt5list
Modified: erp5/trunk/products/ERP5/bin/genbt5list
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/bin/genbt5list?rev=30858&r1=30857&r2=30858&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/bin/genbt5list [utf8] (original)
+++ erp5/trunk/products/ERP5/bin/genbt5list [utf8] Wed Nov 25 16:52:20 2009
@@ -103,10 +103,6 @@
os.write(fd, '</repository>\n')
def main():
- if sys.version < '2.5':
- print "Python 2.4's tarfile.py has a bug that causes a broken bt5list."
- print "Please use Python 2.5 or later for this script."
- sys.exit(1)
if len(sys.argv) < 2:
dir_list = ['.']
else:
@@ -131,4 +127,123 @@
os.umask(cur_umask)
os.chdir(cwd)
+# monkey patch tarfile library if python version is 2.4.
+if sys.version_info[0:2] == (2, 4):
+ from tarfile import BLOCKSIZE, GNUTYPE_SPARSE, SUPPORTED_TYPES, TarFile, \
+ TarInfo, calc_chksum, normpath, nts
+
+ def frombuf(cls, buf):
+ """Construct a TarInfo object from a 512 byte string buffer.
+ """
+ tarinfo = cls()
+ tarinfo.name = nts(buf[0:100])
+ tarinfo.mode = int(buf[100:108], 8)
+ tarinfo.uid = int(buf[108:116],8)
+ tarinfo.gid = int(buf[116:124],8)
+
+ # There are two possible codings for the size field we
+ # have to discriminate, see comment in tobuf() below.
+ if buf[124] != chr(0200):
+ tarinfo.size = long(buf[124:136], 8)
+ else:
+ tarinfo.size = 0L
+ for i in range(11):
+ tarinfo.size <<= 8
+ tarinfo.size += ord(buf[125 + i])
+
+ tarinfo.mtime = long(buf[136:148], 8)
+ tarinfo.chksum = int(buf[148:156], 8)
+ tarinfo.type = buf[156:157]
+ tarinfo.linkname = nts(buf[157:257])
+ tarinfo.uname = nts(buf[265:297])
+ tarinfo.gname = nts(buf[297:329])
+ try:
+ tarinfo.devmajor = int(buf[329:337], 8)
+ tarinfo.devminor = int(buf[337:345], 8)
+ except ValueError:
+ tarinfo.devmajor = tarinfo.devmajor = 0
+ tarinfo.prefix = buf[345:500]
+
+ # The prefix field is used for filenames > 100 in
+ # the POSIX standard.
+ # name = prefix + '/' + name
+ if tarinfo.type != GNUTYPE_SPARSE:
+ tarinfo.name = normpath(os.path.join(nts(tarinfo.prefix), tarinfo.name))
+
+ # Directory names should have a '/' at the end.
+ if tarinfo.isdir() and tarinfo.name[-1:] != "/":
+ tarinfo.name += "/"
+ return tarinfo
+
+ TarInfo.frombuf = classmethod(frombuf)
+
+ def next(self):
+ """Return the next member of the archive as a TarInfo object, when
+ TarFile is opened for reading. Return None if there is no more
+ available.
+ """
+ self._check("ra")
+ if self.firstmember is not None:
+ m = self.firstmember
+ self.firstmember = None
+ return m
+
+ # Read the next block.
+ self.fileobj.seek(self.offset)
+ while True:
+ buf = self.fileobj.read(BLOCKSIZE)
+ if not buf:
+ return None
+ try:
+ tarinfo = TarInfo.frombuf(buf)
+ except ValueError:
+ if self.ignore_zeros:
+ if buf.count(NUL) == BLOCKSIZE:
+ adj = "empty"
+ else:
+ adj = "invalid"
+ self._dbg(2, "0x%X: %s block" % (self.offset, adj))
+ self.offset += BLOCKSIZE
+ continue
+ else:
+ # Block is empty or unreadable.
+ if self.offset == 0:
+ # If the first block is invalid. That does not
+ # look like a tar archive we can handle.
+ raise ReadError,"empty, unreadable or compressed file"
+ return None
+ break
+
+ # We shouldn't rely on this checksum, because some tar programs
+ # calculate it differently and it is merely validating the
+ # header block. We could just as well skip this part, which would
+ # have a slight effect on performance...
+ if tarinfo.chksum != calc_chksum(buf):
+ self._dbg(1, "tarfile: Bad Checksum %r" % tarinfo.name)
+
+ # Set the TarInfo object's offset to the current position of the
+ # TarFile and set self.offset to the position where the data blocks
+ # should begin.
+ tarinfo.offset = self.offset
+ self.offset += BLOCKSIZE
+
+ # Check if the TarInfo object has a typeflag for which a callback
+ # method is registered in the TYPE_METH. If so, then call it.
+ if tarinfo.type in self.TYPE_METH:
+ return self.TYPE_METH[tarinfo.type](self, tarinfo)
+
+ tarinfo.offset_data = self.offset
+ if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES:
+ # Skip the following data blocks.
+ self.offset += self._block(tarinfo.size)
+
+ if tarinfo.isreg() and tarinfo.name[:-1] == "/":
+ # some old tar programs don't know DIRTYPE
+ tarinfo.type = DIRTYPE
+
+ self.members.append(tarinfo)
+ return tarinfo
+
+ TarFile.next = next
+
main()
More information about the Erp5-report
mailing list