#include <errno.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <md5.h> /* When this was written, bionic's md5.h did not define this. */ #ifndef MD5_DIGEST_LENGTH #define MD5_DIGEST_LENGTH 16 #endif static int usage() { fprintf(stderr,"md5 file ...\n"); return -1; } static int do_md5(const char *path) { unsigned int i; int fd; MD5_CTX md5_ctx; unsigned char md5[MD5_DIGEST_LENGTH]; fd = open(path, O_RDONLY); if (fd < 0) { fprintf(stderr,"could not open %s, %s\n", path, strerror(errno)); return -1; } /* Note that bionic's MD5_* functions return void. */ MD5_Init(&md5_ctx); while (1) { char buf[4096]; ssize_t rlen; rlen = read(fd, buf, sizeof(buf)); if (rlen == 0) break; else if (rlen < 0) { (void)close(fd); fprintf(stderr,"could not read %s, %s\n", path, strerror(errno)); return -1; } MD5_Update(&md5_ctx, buf, rlen); } if (close(fd)) { fprintf(stderr,"could not close %s, %s\n", path, strerror(errno)); return -1; } MD5_Final(md5, &md5_ctx); for (i = 0; i < (int)sizeof(md5); i++) printf("%02x", md5[i]); printf(" %s\n", path); return 0; } int md5_main(int argc, char *argv[]) { int i, ret = 0; if (argc < 2) return usage(); /* loop over the file args */ for (i = 1; i < argc; i++) { if (do_md5(argv[i])) ret = 1; } return ret; }