|
1 #! /usr/bin/env python |
|
2 |
|
3 """Python utility to print MD5 checksums of argument files. |
|
4 """ |
|
5 |
|
6 |
|
7 bufsize = 8096 |
|
8 fnfilter = None |
|
9 rmode = 'rb' |
|
10 |
|
11 usage = """ |
|
12 usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...] |
|
13 -b : read files in binary mode (default) |
|
14 -t : read files in text mode (you almost certainly don't want this!) |
|
15 -l : print last pathname component only |
|
16 -s bufsize: read buffer size (default %d) |
|
17 file ... : files to sum; '-' or no files means stdin |
|
18 """ % bufsize |
|
19 |
|
20 import sys |
|
21 import os |
|
22 import getopt |
|
23 import md5 |
|
24 |
|
25 def sum(*files): |
|
26 sts = 0 |
|
27 if files and isinstance(files[-1], file): |
|
28 out, files = files[-1], files[:-1] |
|
29 else: |
|
30 out = sys.stdout |
|
31 if len(files) == 1 and not isinstance(files[0], str): |
|
32 files = files[0] |
|
33 for f in files: |
|
34 if isinstance(f, str): |
|
35 if f == '-': |
|
36 sts = printsumfp(sys.stdin, '<stdin>', out) or sts |
|
37 else: |
|
38 sts = printsum(f, out) or sts |
|
39 else: |
|
40 sts = sum(f, out) or sts |
|
41 return sts |
|
42 |
|
43 def printsum(filename, out=sys.stdout): |
|
44 try: |
|
45 fp = open(filename, rmode) |
|
46 except IOError, msg: |
|
47 sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg)) |
|
48 return 1 |
|
49 if fnfilter: |
|
50 filename = fnfilter(filename) |
|
51 sts = printsumfp(fp, filename, out) |
|
52 fp.close() |
|
53 return sts |
|
54 |
|
55 def printsumfp(fp, filename, out=sys.stdout): |
|
56 m = md5.new() |
|
57 try: |
|
58 while 1: |
|
59 data = fp.read(bufsize) |
|
60 if not data: |
|
61 break |
|
62 m.update(data) |
|
63 except IOError, msg: |
|
64 sys.stderr.write('%s: I/O error: %s\n' % (filename, msg)) |
|
65 return 1 |
|
66 out.write('%s %s\n' % (m.hexdigest(), filename)) |
|
67 return 0 |
|
68 |
|
69 def main(args = sys.argv[1:], out=sys.stdout): |
|
70 global fnfilter, rmode, bufsize |
|
71 try: |
|
72 opts, args = getopt.getopt(args, 'blts:') |
|
73 except getopt.error, msg: |
|
74 sys.stderr.write('%s: %s\n%s' % (sys.argv[0], msg, usage)) |
|
75 return 2 |
|
76 for o, a in opts: |
|
77 if o == '-l': |
|
78 fnfilter = os.path.basename |
|
79 elif o == '-b': |
|
80 rmode = 'rb' |
|
81 elif o == '-t': |
|
82 rmode = 'r' |
|
83 elif o == '-s': |
|
84 bufsize = int(a) |
|
85 if not args: |
|
86 args = ['-'] |
|
87 return sum(args, out) |
|
88 |
|
89 if __name__ == '__main__' or __name__ == sys.argv[0]: |
|
90 sys.exit(main(sys.argv[1:], sys.stdout)) |