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