xref: /aosp_15_r20/external/toybox/toys/lsb/md5sum.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
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