def iter_tar(f): while True: header = f.read(512) if not header: break typ = header[156:157] name = tarfile.nts(header[0:100], ENCODING, 'surrogateescape') prefix = tarfile.nts(header[345:500], ENCODING, 'surrogateescape') if prefix and typ not in tarfile.GNU_TYPES: name = f'{prefix}/{name}' if not name: continue size = tarfile.nti(header[124:136]) if size: contents = tarfile.nts(f.read(size), ENCODING, 'surrogateescape') else: contents = None if name != '././@PaxHeader': yield name, contents mod = f.tell() % 512 if mod: f.seek(512 - mod, 1)
def test_char_fields(self): self.assertEqual(tarfile.stn("foo", 8, "ascii", "strict"), b"foo\0\0\0\0\0") self.assertEqual(tarfile.stn("foobar", 3, "ascii", "strict"), b"foo") self.assertEqual(tarfile.nts(b"foo\0\0\0\0\0", "ascii", "strict"), "foo") self.assertEqual(tarfile.nts(b"foo\0bar\0", "ascii", "strict"), "foo")
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)) # Some old tar programs represent a directory as a regular # file with a trailing slash. if tarinfo.isreg() and tarinfo.name.endswith("/"): tarinfo.type = DIRTYPE # Directory names should have a '/' at the end. if tarinfo.isdir(): tarinfo.name += "/" return tarinfo
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)
def update_event(self, inp=-1): self.set_output_val(0, tarfile.nts(self.input(0), self.input(1), self.input(2)))
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))