]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/sha1sum.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / sha1sum.c
1 /*
2  * sha1sum - compute SHA1 or SHA2 digest
3  */
4 #include <u.h>
5 #include <libc.h>
6 #include <libsec.h>
7
8 #pragma varargck        type    "M"     uchar*
9
10 typedef struct Sha2 Sha2;
11 struct Sha2 {
12         int     bits;
13         int     dlen;
14         DigestState* (*func)(uchar *, ulong, uchar *, DigestState *);
15 };
16
17 static Sha2 sha2s[] = {
18         224,    SHA2_224dlen,   sha2_224,
19         256,    SHA2_256dlen,   sha2_256,
20         384,    SHA2_384dlen,   sha2_384,
21         512,    SHA2_512dlen,   sha2_512,
22 };
23
24 static DigestState* (*shafunc)(uchar *, ulong, uchar *, DigestState *);
25 static int shadlen;
26
27 static int
28 digestfmt(Fmt *fmt)
29 {
30         char buf[SHA2_512dlen*2 + 1];
31         uchar *p;
32         int i;
33
34         p = va_arg(fmt->args, uchar*);
35         for(i = 0; i < shadlen; i++)
36                 sprint(buf + 2*i, "%.2ux", p[i]);
37         return fmtstrcpy(fmt, buf);
38 }
39
40 static void
41 sum(int fd, char *name)
42 {
43         int n;
44         uchar buf[8192], digest[SHA2_512dlen];
45         DigestState *s;
46
47         s = (*shafunc)(nil, 0, nil, nil);
48         while((n = read(fd, buf, sizeof buf)) > 0)
49                 (*shafunc)(buf, n, nil, s);
50         if(n < 0){
51                 fprint(2, "reading %s: %r\n", name? name: "stdin");
52                 return;
53         }
54         (*shafunc)(nil, 0, digest, s);
55         if(name == nil)
56                 print("%M\n", digest);
57         else
58                 print("%M\t%s\n", digest, name);
59 }
60
61 static void
62 usage(void)
63 {
64         fprint(2, "usage: %s [-2 bits] [file...]\n", argv0);
65         exits("usage");
66 }
67
68 void
69 main(int argc, char *argv[])
70 {
71         int i, fd, bits;
72         Sha2 *sha;
73
74         shafunc = sha1;
75         shadlen = SHA1dlen;
76         ARGBEGIN{
77         case '2':
78                 bits = atoi(EARGF(usage()));
79                 for (sha = sha2s; sha < sha2s + nelem(sha2s); sha++)
80                         if (sha->bits == bits)
81                                 break;
82                 if (sha >= sha2s + nelem(sha2s))
83                         sysfatal("unknown number of sha2 bits: %d", bits);
84                 shafunc = sha->func;
85                 shadlen = sha->dlen;
86                 break;
87         default:
88                 usage();
89         }ARGEND
90
91         fmtinstall('M', digestfmt);
92
93         if(argc == 0)
94                 sum(0, nil);
95         else
96                 for(i = 0; i < argc; i++){
97                         fd = open(argv[i], OREAD);
98                         if(fd < 0){
99                                 fprint(2, "%s: can't open %s: %r\n", argv0, argv[i]);
100                                 continue;
101                         }
102                         sum(fd, argv[i]);
103                         close(fd);
104                 }
105         exits(nil);
106 }