comparison cutils/shasum.py @ 167:ffd14e2de130

Formatting
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 09 Jan 2025 14:17:01 +0100
parents a813094ae4f5
children f04d4b1c14b3
comparison
equal deleted inserted replaced
166:ed45abb4940f 167:ffd14e2de130
31 aparser = argparse.ArgumentParser( 31 aparser = argparse.ArgumentParser(
32 description="Python implementation of shasum", 32 description="Python implementation of shasum",
33 fromfile_prefix_chars='@') 33 fromfile_prefix_chars='@')
34 aparser.add_argument( 34 aparser.add_argument(
35 "--algorithm", "-a", action="store", type=util.argv2algo, 35 "--algorithm", "-a", action="store", type=util.argv2algo,
36 help="1 (default, aka sha1), 224, 256, 384, 512, 3 (alias for sha3-512), 3-224, 3-256, 3-384, 3-512, blake2b, blake2b-256, blake2s, blake2 (alias for blake2b), blake2-256 (alias for blake2b-256), md5") 36 help="""1 (default, aka sha1), 224, 256, 384, 512,
37 3 (alias for sha3-512), 3-224, 3-256, 3-384, 3-512,
38 blake2b, blake2b-256, blake2s, blake2 (alias for blake2b),
39 blake2-256 (alias for blake2b-256), md5""")
37 aparser.add_argument( 40 aparser.add_argument(
38 "--base64", action="store_true", 41 "--base64", action="store_true",
39 help="Output checksums in base64 notation, not hexadecimal (OpenBSD).") 42 help="Output checksums in base64 notation, not hexadecimal (OpenBSD).")
40 aparser.add_argument( 43 aparser.add_argument(
41 "--binary", "-b", action="store_false", dest="text_mode", default=False, 44 "--binary", "-b", action="store_false", dest="text_mode",
45 default=False,
42 help="Read in binary mode (default)") 46 help="Read in binary mode (default)")
43 aparser.add_argument( 47 aparser.add_argument(
44 "--bsd", "-B", action="store_true", dest="bsd", default=False, 48 "--bsd", "-B", action="store_true", dest="bsd", default=False,
45 help="Write BSD style output. This is also the default output format of :command:`openssl dgst`.") 49 help="""Write BSD style output. This is also the default output format
50 of :command:`openssl dgst`.""")
46 aparser.add_argument( 51 aparser.add_argument(
47 "--check", "-c", action="store_true", 52 "--check", "-c", action="store_true",
48 help="""Read digests from FILEs and check them. 53 help="""Read digests from FILEs and check them.
49 If this option is specified, the FILE options become checklists. Each 54 If this option is specified, the FILE options become checklists. Each
50 checklist should contain hash results in a supported format, which will 55 checklist should contain hash results in a supported format, which will
58 the CHECKLIST. Any specified FILE that is not listed in the CHECKLIST will 63 the CHECKLIST. Any specified FILE that is not listed in the CHECKLIST will
59 generate an error.""") 64 generate an error.""")
60 aparser.add_argument( 65 aparser.add_argument(
61 "--checklist-allow-distinfo", action="store_true", 66 "--checklist-allow-distinfo", action="store_true",
62 dest="allow_distinfo", 67 dest="allow_distinfo",
63 help='Allow FreeBSD "distinfo" formatted checklists: ignore SIZE and TIMESTAMP lines.') 68 help='''Allow FreeBSD "distinfo" formatted checklists:
69 ignore SIZE and TIMESTAMP lines.''')
64 70
65 aparser.add_argument( 71 aparser.add_argument(
66 "--follow-symlinks", action="store_true", dest="follow_symlinks", 72 "--follow-symlinks", action="store_true", dest="follow_symlinks",
67 help="""Also follow symlinks that resolve to directories. Only effective if `--recurse` is activated.""") 73 help="""Also follow symlinks that resolve to directories.
74 Only effective if `--recurse` is activated.""")
68 75
69 aparser.add_argument( 76 aparser.add_argument(
70 "--mmap", action="store_true", dest="mmap", default=None, 77 "--mmap", action="store_true", dest="mmap", default=None,
71 help="""Use mmap if available. Default is to determine automatically 78 help="""Use mmap if available. Default is to determine automatically
72 from the filesize.""") 79 from the filesize.""")
74 "--no-mmap", action="store_false", dest="mmap", default=None, 81 "--no-mmap", action="store_false", dest="mmap", default=None,
75 help="Dont use mmap.") 82 help="Dont use mmap.")
76 83
77 aparser.add_argument( 84 aparser.add_argument(
78 "--recurse", action="store_true", 85 "--recurse", action="store_true",
79 help="Recurse into sub-directories while interpreting every FILE as a directory.") 86 help="""Recurse into sub-directories while interpreting every
87 FILE as a directory.""")
80 88
81 aparser.add_argument( 89 aparser.add_argument(
82 "--reverse", "-r", action="store_false", dest="bsd", default=False, 90 "--reverse", "-r", action="store_false", dest="bsd", default=False,
83 help="Explicitely select normal coreutils style output (to be option compatible with BSD style commands and :command:`openssl dgst -r`)") 91 help="""Explicitely select normal coreutils style output
92 (to be option compatible with BSD style commands and
93 :command:`openssl dgst -r`)""")
84 aparser.add_argument( 94 aparser.add_argument(
85 "--tag", action="store_true", dest="bsd", default=False, 95 "--tag", action="store_true", dest="bsd", default=False,
86 help="Alias for the `--bsd' option (to be compatible with :command:`b2sum`)") 96 help="""Alias for the `--bsd' option (to be compatible with
97 :command:`b2sum`)""")
87 aparser.add_argument( 98 aparser.add_argument(
88 "--text", "-t", action="store_true", dest="text_mode", default=False, 99 "--text", "-t", action="store_true", dest="text_mode", default=False,
89 help="Read in text mode (not supported)") 100 help="Read in text mode (not supported)")
90 aparser.add_argument( 101 aparser.add_argument(
91 "--version", "-v", action="version", version="%s (rv:%s)" % (__version__, __revision__)) 102 "--version", "-v", action="version",
103 version="%s (rv:%s)" % (__version__, __revision__))
92 aparser.add_argument( 104 aparser.add_argument(
93 "files", nargs="*", metavar="FILE") 105 "files", nargs="*", metavar="FILE")
94 106
95 opts = aparser.parse_args(args=argv) 107 opts = aparser.parse_args(args=argv)
96 108
225 else: 237 else:
226 return False 238 return False
227 else: 239 else:
228 # base64 240 # base64
229 if re.search( 241 if re.search(
230 r"\A(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?\Z", 242 r"\A(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?\Z", # noqa: E501 line too long
231 expected_digest): 243 expected_digest):
232 try: 244 try:
233 exd = base64.b64decode(expected_digest) 245 exd = base64.b64decode(expected_digest)
234 except TypeError: 246 except TypeError:
235 return False 247 return False
262 res = "FAILED" 274 res = "FAILED"
263 exit_code = 1 275 exit_code = 1
264 print("{}: {}: {}".format(tag, "-", res), file=dest) 276 print("{}: {}: {}".format(tag, "-", res), file=dest)
265 else: 277 else:
266 for fn in opts.files: 278 for fn in opts.files:
267 pl = get_parsed_digest_line_from_checklist(opts.checklist, opts, fn) 279 pl = get_parsed_digest_line_from_checklist(
280 opts.checklist, opts, fn)
268 if pl is None: 281 if pl is None:
269 print("{}: MISSING".format(fn), file=dest) 282 print("{}: MISSING".format(fn), file=dest)
270 exit_code = 1 283 exit_code = 1
271 else: 284 else:
272 tag, algo, cl_filename, cl_digest = pl 285 tag, algo, cl_filename, cl_digest = pl
351 raise ValueError( 364 raise ValueError(
352 "improperly formatted digest line: {}".format(checkline)) 365 "improperly formatted digest line: {}".format(checkline))
353 if parts[0] in ("SIZE", "TIMESTAMP"): 366 if parts[0] in ("SIZE", "TIMESTAMP"):
354 assert opts.allow_distinfo 367 assert opts.allow_distinfo
355 continue 368 continue
356 fn = util.normalize_filename(parts[2], strip_leading_dot_slash=True) 369 fn = util.normalize_filename(
370 parts[2], strip_leading_dot_slash=True)
357 if fn in filenames: 371 if fn in filenames:
358 return parts 372 return parts
359 else: 373 else:
360 return None 374 return None
361 375
430 if use_base64: 444 if use_base64:
431 digest = base64.b64encode(digest).decode("ascii") 445 digest = base64.b64encode(digest).decode("ascii")
432 else: 446 else:
433 digest = binascii.hexlify(digest).decode("ascii") 447 digest = binascii.hexlify(digest).decode("ascii")
434 print("{} {}{}".format( 448 print("{} {}{}".format(
435 digest, 449 digest,
436 '*' if binary else ' ', 450 '*' if binary else ' ',
437 '-' if filename is None else util.normalize_filename(filename)), 451 '-' if filename is None else util.normalize_filename(filename)),
438 file=dest) 452 file=dest)
439 453
440 454
441 if __name__ == "__main__": 455 if __name__ == "__main__":
442 sys.exit(main()) 456 sys.exit(main())