1 #include <errno.h>
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <md5.h>
8
9 /* When this was written, bionic's md5.h did not define this. */
10 #ifndef MD5_DIGEST_LENGTH
11 #define MD5_DIGEST_LENGTH 16
12 #endif
13
usage()14 static int usage()
15 {
16 fprintf(stderr,"md5 file ...\n");
17 return -1;
18 }
19
do_md5(const char * path)20 static int do_md5(const char *path)
21 {
22 unsigned int i;
23 int fd;
24 MD5_CTX md5_ctx;
25 unsigned char md5[MD5_DIGEST_LENGTH];
26
27 fd = open(path, O_RDONLY);
28 if (fd < 0) {
29 fprintf(stderr,"could not open %s, %s\n", path, strerror(errno));
30 return -1;
31 }
32
33 /* Note that bionic's MD5_* functions return void. */
34 MD5_Init(&md5_ctx);
35
36 while (1) {
37 char buf[4096];
38 ssize_t rlen;
39 rlen = read(fd, buf, sizeof(buf));
40 if (rlen == 0)
41 break;
42 else if (rlen < 0) {
43 (void)close(fd);
44 fprintf(stderr,"could not read %s, %s\n", path, strerror(errno));
45 return -1;
46 }
47 MD5_Update(&md5_ctx, buf, rlen);
48 }
49 if (close(fd)) {
50 fprintf(stderr,"could not close %s, %s\n", path, strerror(errno));
51 return -1;
52 }
53
54 MD5_Final(md5, &md5_ctx);
55
56 for (i = 0; i < (int)sizeof(md5); i++)
57 printf("%02x", md5[i]);
58 printf(" %s\n", path);
59
60 return 0;
61 }
62
md5_main(int argc,char * argv[])63 int md5_main(int argc, char *argv[])
64 {
65 int i, ret = 0;
66
67 if (argc < 2)
68 return usage();
69
70 /* loop over the file args */
71 for (i = 1; i < argc; i++) {
72 if (do_md5(argv[i]))
73 ret = 1;
74 }
75
76 return ret;
77 }
78