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