1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <libsec.h>
5
6 #pragma varargck type "M" uchar*
7
8 static int
digestfmt(Fmt * fmt)9 digestfmt(Fmt *fmt)
10 {
11 char buf[MD5dlen*2+1];
12 uchar *p;
13 int i;
14
15 p = va_arg(fmt->args, uchar*);
16 for(i=0; i<MD5dlen; i++)
17 sprint(buf+2*i, "%.2ux", p[i]);
18 return fmtstrcpy(fmt, buf);
19 }
20
21 static void
sum(int fd,char * name)22 sum(int fd, char *name)
23 {
24 int n;
25 uchar buf[8192], digest[MD5dlen];
26 DigestState *s;
27
28 s = md5(nil, 0, nil, nil);
29 while((n = read(fd, buf, sizeof buf)) > 0)
30 md5(buf, n, nil, s);
31 if(n < 0){
32 fprint(2, "reading %s: %r\n", name ? name : "stdin");
33 return;
34 }
35 md5(nil, 0, digest, s);
36 if(name == nil)
37 print("%M\n", digest);
38 else
39 print("%M\t%s\n", digest, name);
40 }
41
42 void
main(int argc,char * argv[])43 main(int argc, char *argv[])
44 {
45 int i, fd;
46
47 ARGBEGIN{
48 default:
49 fprint(2, "usage: md5sum [file...]\n");
50 exits("usage");
51 }ARGEND
52
53 fmtinstall('M', digestfmt);
54
55 if(argc == 0)
56 sum(0, nil);
57 else for(i = 0; i < argc; i++){
58 fd = open(argv[i], OREAD);
59 if(fd < 0){
60 fprint(2, "md5sum: can't open %s: %r\n", argv[i]);
61 continue;
62 }
63 sum(fd, argv[i]);
64 close(fd);
65 }
66 exits(nil);
67 }
68