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