summaryrefslogtreecommitdiff
path: root/rdiff-backup/python-rdiff
blob: 14896b8c8f75a87a3083a2014f2aad1c833e3e21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/env python

import sys
from rdiff_backup import librsync

blocksize = 64*1024 # just used in copying
librsync_blocksize = None # If not set, use defaults in _librsync module

def usage():
	"""Print usage and then exit"""
	print """
Usage: %(cmd)s "signature" basis_file signature_file
       %(cmd)s "delta" signature_file new_file delta_file
       %(cmd)s "patch" basis_file delta_file new_file
""" % {'cmd': sys.argv[0]}
	sys.exit(1)

def copy_and_close(infp, outfp):
	"""Copy file streams infp to outfp in blocks, closing when done"""
	while 1:
		buf = infp.read(blocksize)
		if not buf: break
		outfp.write(buf)
	assert not infp.close() and not outfp.close()

def write_sig(input_path, output_path):
	"""Open file at input_path, write signature to output_path"""
	infp = open(input_path, "rb")
	if librsync_blocksize: sigfp = librsync.SigFile(infp, librsync_blocksize)
	else: sigfp = librsync.SigFile(infp)
	copy_and_close(sigfp, open(output_path, "wb"))

def write_delta(sig_path, new_path, output_path):
	"""Read signature and new file, write to delta to delta_path"""
	deltafp = librsync.DeltaFile(open(sig_path, "rb"), open(new_path, "rb"))
	copy_and_close(deltafp, open(output_path, "wb"))

def write_patch(basis_path, delta_path, out_path):
	"""Patch file at basis_path with delta at delta_path, write to out_path"""
	patchfp = librsync.PatchedFile(open(basis_path, "rb"),
								   open(delta_path, "rb"))
	copy_and_close(patchfp, open(out_path, "wb"))

def check_different(filelist):
	"""Make sure no files the same"""
	d = {}
	for file in filelist: d[file] = file
	assert len(d) == len(filelist), "Error, must use all different filenames"

def Main():
	"""Run program"""
	if len(sys.argv) < 4: usage()
	mode = sys.argv[1]
	file_args = sys.argv[2:]
	check_different(file_args)
	if mode == "signature":
		if len(file_args) != 2: usage()
		write_sig(*file_args)
	elif mode == "delta":
		if len(file_args) != 3: usage()
		write_delta(*file_args)
	elif mode == "patch":
		if len(file_args) != 3: usage()
		write_patch(*file_args)
	else: usage()


if __name__ == "__main__": Main()