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