diff --git a/copyparty/szip.py b/copyparty/szip.py new file mode 100644 index 00000000..9c7a5e05 --- /dev/null +++ b/copyparty/szip.py @@ -0,0 +1,239 @@ +import os +import time +import zlib +import struct +from datetime import datetime + +from .util import fsenc + + +def dostime2unix(buf): + t, d = struct.unpack("> 5) & 0x3F + th = t >> 11 + + dd = d & 0x1F + dm = (d >> 5) & 0xF + dy = (d >> 9) + 1980 + + tt = (dy, dm, dd, th, tm, ts) + tf = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}" + iso = tf.format(*tt) + + dt = datetime.strptime(iso, "%Y-%m-%d %H:%M:%S") + return int(dt.timestamp()) + + +def unixtime2dos(ts): + tt = time.gmtime(ts) + dy, dm, dd, th, tm, ts = list(tt)[:6] + + bd = ((dy - 1980) << 9) + (dm << 5) + dd + bt = (th << 11) + (tm << 5) + ts // 2 + return struct.pack("= 0xFFFFFFFF + z64v = [sz, sz] if z64 else [] + if h_pos and h_pos >= 0xFFFFFFFF: + # central, also consider ptr to original header + z64v.append(h_pos) + + # confusingly this doesn't bump if h_pos + req_ver = b"\x2d\x00" if z64 else b"\x0a\x00" + + if crc32: + crc32 = struct.pack("= 4 * 1024 * 1024 * 1024 + + if z64 or not self.pre_crc: + buf = gen_fdesc(sz, crc, z64) + yield self._ct(buf) + + cdir_pos = self.pos + for name, sz, ts, crc, h_pos in self.items: + buf = gen_hdr(h_pos, name, sz, ts, self.utf8, crc, self.pre_crc) + yield self._ct(buf) + cdir_end = self.pos + + _, need_64 = gen_ecdr(self.items, cdir_pos, cdir_end) + if need_64: + ecdir64_pos = self.pos + buf = gen_ecdr64(self.items, cdir_pos, cdir_end) + yield self._ct(buf) + + buf = gen_ecdr64_loc(ecdir64_pos) + yield self._ct(buf) + + ecdr, _ = gen_ecdr(self.items, cdir_pos, cdir_end) + yield self._ct(ecdr)