blob: 2fb8b053ada35d6819335d9a25013e31720615e9 [file] [log] [blame]
Scott Andersond0455c92012-01-11 18:13:26 -08001#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
14static int usage()
15{
16 fprintf(stderr,"md5 file ...\n");
17 return -1;
18}
19
20static 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
63int 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}