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 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} 78