summaryrefslogtreecommitdiffstats
path: root/presto-utils/deltasig.py
diff options
context:
space:
mode:
Diffstat (limited to 'presto-utils/deltasig.py')
-rw-r--r--presto-utils/deltasig.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/presto-utils/deltasig.py b/presto-utils/deltasig.py
new file mode 100644
index 0000000..d5a9b18
--- /dev/null
+++ b/presto-utils/deltasig.py
@@ -0,0 +1,103 @@
+#!/usr/bin/python -t
+
+import gzip
+import types
+import struct
+import sys
+from dumpMetadata import byteranges
+
+BUF_SIZE = 32768
+
+
+def get_signature_from_file(sigfile):
+ f = open(sigfile, "r")
+ sig = f.read()
+ f.close()
+ return sig
+
+def make_delta_from_sig(src_delta, sigfile, dst_delta):
+ # Open source deltarpm and read/write header
+ (range_start, range_end) = byteranges(src_delta)
+
+ sfd = open(src_delta, "r")
+ dfd = open(dst_delta, "w")
+
+ dfd.write(sfd.read(range_end))
+
+ # Switch to compressed mode
+ try:
+ scfd = gzip.GzipFile("", "rb", 9, sfd)
+ except:
+ raise zlibError("Data not stored in gzip format")
+
+ if scfd.read(4) != "DLT3":
+ raise Exception("Not a deltarpm")
+
+ dcfd = gzip.GzipFile("", "wb", 9, dfd)
+ dcfd.write("DLT3")
+
+ # Get nevr and write it
+ len_str = scfd.read(4)
+ (length, ) = struct.unpack('>I', len_str)
+ nevr_length = len_str
+ nevr = scfd.read(length)
+
+ dcfd.write("%s%s" % (nevr_length, nevr))
+
+ # Read sequence and write it
+ len_str = scfd.read(4)
+ (length, ) = struct.unpack('>I', len_str)
+ dcfd.write(len_str + scfd.read(length))
+
+ # Read md5 and discard, replacing with \x00's. New versions of deltarpm
+ # will see this and use the rpm's md5 checksum rather than this one.
+ scfd.read(16)
+ dcfd.write("\x00" * 16)
+
+ # Read and write target size
+ dcfd.write(scfd.read(4))
+
+ # Read and write other data
+ dcfd.write(scfd.read(12))
+ len_str = scfd.read(4)
+ (length, ) = struct.unpack('>I', len_str)
+ dcfd.write(len_str + scfd.read(length*2*4))
+ dcfd.write(scfd.read(4))
+
+ # Read and write lead
+ dcfd.write(scfd.read(96))
+
+ # Write signature from signature file and skip signature in src deltarpm
+ signature = get_signature_from_file(sigfile)
+ dcfd.write(signature)
+
+ scfd.read(8)
+ binindex = scfd.read(4)
+ (sigindex, ) = struct.unpack('>I', binindex)
+ bindata = scfd.read(4)
+ (sigdata, ) = struct.unpack('>I', bindata)
+ # each index is 4 32bit segments - so each is 16 bytes
+ sigindexsize = sigindex * 16
+ sigsize = sigdata + sigindexsize
+ # we have to round off to the next 8 byte boundary
+ disttoboundary = (sigsize % 8)
+ if disttoboundary != 0:
+ disttoboundary = 8 - disttoboundary
+ scfd.read(sigsize + disttoboundary)
+
+ data = scfd.read(BUF_SIZE)
+ while data != "":
+ dcfd.write(data)
+ data = scfd.read(BUF_SIZE)
+
+def main():
+ if len(sys.argv) != 4:
+ print "Usage: %s <original deltarpm> <signature> <new deltarpm>" % sys.argv[0]
+ sys.exit(1)
+
+ make_delta_from_sig(sys.argv[1], sys.argv[2], sys.argv[3])
+
+if __name__ == '__main__':
+ main()
+
+