1*cf5a6c84SAndroid Build Coastguard Worker /* md5sum.c - Calculate hashes md5, sha1, sha224, sha256, sha384, sha512.
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2012, 2021 Rob Landley <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/md5sum.html
6*cf5a6c84SAndroid Build Coastguard Worker * and http://www.ietf.org/rfc/rfc1321.txt
7*cf5a6c84SAndroid Build Coastguard Worker * and http://www.ietf.org/rfc/rfc4634.txt
8*cf5a6c84SAndroid Build Coastguard Worker *
9*cf5a6c84SAndroid Build Coastguard Worker * They're combined this way to share infrastructure, and because md5sum is
10*cf5a6c84SAndroid Build Coastguard Worker * a LSB standard command (but sha1sum and newer hashes are a good idea,
11*cf5a6c84SAndroid Build Coastguard Worker * see http://valerieaurora.org/hash.html).
12*cf5a6c84SAndroid Build Coastguard Worker *
13*cf5a6c84SAndroid Build Coastguard Worker * We optionally use openssl (or equivalent) to access assembly optimized
14*cf5a6c84SAndroid Build Coastguard Worker * versions of these functions, but provide a built-in version to reduce
15*cf5a6c84SAndroid Build Coastguard Worker * required dependencies.
16*cf5a6c84SAndroid Build Coastguard Worker *
17*cf5a6c84SAndroid Build Coastguard Worker * coreutils supports --status but not -s, busybox supports -s but not --status
18*cf5a6c84SAndroid Build Coastguard Worker
19*cf5a6c84SAndroid Build Coastguard Worker USE_MD5SUM(NEWTOY(md5sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
20*cf5a6c84SAndroid Build Coastguard Worker USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
21*cf5a6c84SAndroid Build Coastguard Worker USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
22*cf5a6c84SAndroid Build Coastguard Worker USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
23*cf5a6c84SAndroid Build Coastguard Worker USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
24*cf5a6c84SAndroid Build Coastguard Worker USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
25*cf5a6c84SAndroid Build Coastguard Worker
26*cf5a6c84SAndroid Build Coastguard Worker config MD5SUM
27*cf5a6c84SAndroid Build Coastguard Worker bool "md5sum"
28*cf5a6c84SAndroid Build Coastguard Worker default y
29*cf5a6c84SAndroid Build Coastguard Worker help
30*cf5a6c84SAndroid Build Coastguard Worker usage: ???sum [-bcs] [FILE]...
31*cf5a6c84SAndroid Build Coastguard Worker
32*cf5a6c84SAndroid Build Coastguard Worker Calculate hash for each input file, reading from stdin if none, writing
33*cf5a6c84SAndroid Build Coastguard Worker hexadecimal digits to stdout for each input file (md5=32 hex digits,
34*cf5a6c84SAndroid Build Coastguard Worker sha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.
35*cf5a6c84SAndroid Build Coastguard Worker
36*cf5a6c84SAndroid Build Coastguard Worker -b Brief (hash only, no filename)
37*cf5a6c84SAndroid Build Coastguard Worker -c Check each line of each FILE is the same hash+filename we'd output
38*cf5a6c84SAndroid Build Coastguard Worker -s No output, exit status 0 if all hashes match, 1 otherwise
39*cf5a6c84SAndroid Build Coastguard Worker
40*cf5a6c84SAndroid Build Coastguard Worker config SHA1SUM
41*cf5a6c84SAndroid Build Coastguard Worker bool "sha1sum"
42*cf5a6c84SAndroid Build Coastguard Worker default y
43*cf5a6c84SAndroid Build Coastguard Worker help
44*cf5a6c84SAndroid Build Coastguard Worker See md5sum
45*cf5a6c84SAndroid Build Coastguard Worker
46*cf5a6c84SAndroid Build Coastguard Worker config SHA224SUM
47*cf5a6c84SAndroid Build Coastguard Worker bool "sha224sum"
48*cf5a6c84SAndroid Build Coastguard Worker default y
49*cf5a6c84SAndroid Build Coastguard Worker help
50*cf5a6c84SAndroid Build Coastguard Worker See md5sum
51*cf5a6c84SAndroid Build Coastguard Worker
52*cf5a6c84SAndroid Build Coastguard Worker config SHA256SUM
53*cf5a6c84SAndroid Build Coastguard Worker bool "sha256sum"
54*cf5a6c84SAndroid Build Coastguard Worker default y
55*cf5a6c84SAndroid Build Coastguard Worker help
56*cf5a6c84SAndroid Build Coastguard Worker See md5sum
57*cf5a6c84SAndroid Build Coastguard Worker
58*cf5a6c84SAndroid Build Coastguard Worker config SHA384SUM
59*cf5a6c84SAndroid Build Coastguard Worker bool "sha384sum"
60*cf5a6c84SAndroid Build Coastguard Worker default y
61*cf5a6c84SAndroid Build Coastguard Worker help
62*cf5a6c84SAndroid Build Coastguard Worker See md5sum
63*cf5a6c84SAndroid Build Coastguard Worker
64*cf5a6c84SAndroid Build Coastguard Worker config SHA512SUM
65*cf5a6c84SAndroid Build Coastguard Worker bool "sha512sum"
66*cf5a6c84SAndroid Build Coastguard Worker default y
67*cf5a6c84SAndroid Build Coastguard Worker help
68*cf5a6c84SAndroid Build Coastguard Worker See md5sum
69*cf5a6c84SAndroid Build Coastguard Worker */
70*cf5a6c84SAndroid Build Coastguard Worker
71*cf5a6c84SAndroid Build Coastguard Worker #define FORCE_FLAGS
72*cf5a6c84SAndroid Build Coastguard Worker #define FOR_md5sum
73*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
74*cf5a6c84SAndroid Build Coastguard Worker
GLOBALS(int sawline;)75*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
76*cf5a6c84SAndroid Build Coastguard Worker int sawline;
77*cf5a6c84SAndroid Build Coastguard Worker )
78*cf5a6c84SAndroid Build Coastguard Worker
79*cf5a6c84SAndroid Build Coastguard Worker // Callback for loopfiles()
80*cf5a6c84SAndroid Build Coastguard Worker // Call builtin or lib hash function, then display output if necessary
81*cf5a6c84SAndroid Build Coastguard Worker static void do_hash(int fd, char *name)
82*cf5a6c84SAndroid Build Coastguard Worker {
83*cf5a6c84SAndroid Build Coastguard Worker hash_by_name(fd, toys.which->name, toybuf);
84*cf5a6c84SAndroid Build Coastguard Worker
85*cf5a6c84SAndroid Build Coastguard Worker if (name) printf("%s %s\n"+4*FLAG(b), toybuf, name);
86*cf5a6c84SAndroid Build Coastguard Worker }
87*cf5a6c84SAndroid Build Coastguard Worker
do_c_line(char * line)88*cf5a6c84SAndroid Build Coastguard Worker static void do_c_line(char *line)
89*cf5a6c84SAndroid Build Coastguard Worker {
90*cf5a6c84SAndroid Build Coastguard Worker int space = 0, fail = 0, fd;
91*cf5a6c84SAndroid Build Coastguard Worker char *name;
92*cf5a6c84SAndroid Build Coastguard Worker
93*cf5a6c84SAndroid Build Coastguard Worker for (name = line; *name; name++) {
94*cf5a6c84SAndroid Build Coastguard Worker if (isspace(*name)) {
95*cf5a6c84SAndroid Build Coastguard Worker space++;
96*cf5a6c84SAndroid Build Coastguard Worker *name = 0;
97*cf5a6c84SAndroid Build Coastguard Worker } else if (space) break;
98*cf5a6c84SAndroid Build Coastguard Worker }
99*cf5a6c84SAndroid Build Coastguard Worker if (!space || !*line || !*name) return error_msg("bad line %s", line);
100*cf5a6c84SAndroid Build Coastguard Worker
101*cf5a6c84SAndroid Build Coastguard Worker fd = !strcmp(name, "-") ? 0 : open(name, O_RDONLY);
102*cf5a6c84SAndroid Build Coastguard Worker
103*cf5a6c84SAndroid Build Coastguard Worker TT.sawline = 1;
104*cf5a6c84SAndroid Build Coastguard Worker if (fd==-1) {
105*cf5a6c84SAndroid Build Coastguard Worker perror_msg_raw(name);
106*cf5a6c84SAndroid Build Coastguard Worker *toybuf = 0;
107*cf5a6c84SAndroid Build Coastguard Worker } else do_hash(fd, 0);
108*cf5a6c84SAndroid Build Coastguard Worker if (strcasecmp(line, toybuf)) toys.exitval = fail = 1;
109*cf5a6c84SAndroid Build Coastguard Worker if (!FLAG(s)) printf("%s: %s\n", name, fail ? "FAILED" : "OK");
110*cf5a6c84SAndroid Build Coastguard Worker if (fd>0) close(fd);
111*cf5a6c84SAndroid Build Coastguard Worker }
112*cf5a6c84SAndroid Build Coastguard Worker
113*cf5a6c84SAndroid Build Coastguard Worker // Used instead of loopfiles_line to report error on files containing no hashes.
do_c_file(char * name)114*cf5a6c84SAndroid Build Coastguard Worker static void do_c_file(char *name)
115*cf5a6c84SAndroid Build Coastguard Worker {
116*cf5a6c84SAndroid Build Coastguard Worker FILE *fp = !strcmp(name, "-") ? stdin : fopen(name, "r");
117*cf5a6c84SAndroid Build Coastguard Worker char *line;
118*cf5a6c84SAndroid Build Coastguard Worker
119*cf5a6c84SAndroid Build Coastguard Worker if (!fp) return perror_msg_raw(name);
120*cf5a6c84SAndroid Build Coastguard Worker
121*cf5a6c84SAndroid Build Coastguard Worker TT.sawline = 0;
122*cf5a6c84SAndroid Build Coastguard Worker
123*cf5a6c84SAndroid Build Coastguard Worker for (;;) {
124*cf5a6c84SAndroid Build Coastguard Worker if (!(line = xgetline(fp))) break;
125*cf5a6c84SAndroid Build Coastguard Worker do_c_line(line);
126*cf5a6c84SAndroid Build Coastguard Worker free(line);
127*cf5a6c84SAndroid Build Coastguard Worker }
128*cf5a6c84SAndroid Build Coastguard Worker if (fp!=stdin) fclose(fp);
129*cf5a6c84SAndroid Build Coastguard Worker
130*cf5a6c84SAndroid Build Coastguard Worker if (!TT.sawline) error_msg("%s: no lines", name);
131*cf5a6c84SAndroid Build Coastguard Worker }
132*cf5a6c84SAndroid Build Coastguard Worker
md5sum_main(void)133*cf5a6c84SAndroid Build Coastguard Worker void md5sum_main(void)
134*cf5a6c84SAndroid Build Coastguard Worker {
135*cf5a6c84SAndroid Build Coastguard Worker int i;
136*cf5a6c84SAndroid Build Coastguard Worker
137*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(c)) for (i = 0; toys.optargs[i]; i++) do_c_file(toys.optargs[i]);
138*cf5a6c84SAndroid Build Coastguard Worker else {
139*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(s)) error_exit("-s only with -c");
140*cf5a6c84SAndroid Build Coastguard Worker loopfiles(toys.optargs, do_hash);
141*cf5a6c84SAndroid Build Coastguard Worker }
142*cf5a6c84SAndroid Build Coastguard Worker }
143