commit 04f32f4d9aae63f80f5aa9b771190f47593bf62e Author: Hiltjo Posthuma <hil...@codemadness.org> Date: Sun Mar 23 12:18:38 2014 +0100
checksum tools: implement -c Signed-off-by: Hiltjo Posthuma <hil...@codemadness.org> diff --git a/crypt.h b/crypt.h index 7242cdf..1855d37 100644 --- a/crypt.h +++ b/crypt.h @@ -6,6 +6,7 @@ struct crypt_ops { void *s; }; +int cryptcheck(char *, int, char **, struct crypt_ops *, uint8_t *, size_t); int cryptmain(int, char **, struct crypt_ops *, uint8_t *, size_t); int cryptsum(struct crypt_ops *, FILE *, const char *, uint8_t *); void mdprint(const uint8_t *, const char *, size_t); diff --git a/md5sum.c b/md5sum.c index b51ca4e..19babd6 100644 --- a/md5sum.c +++ b/md5sum.c @@ -24,13 +24,17 @@ int main(int argc, char *argv[]) { uint8_t md[MD5_DIGEST_LENGTH]; + char *checkfile = NULL; ARGBEGIN { case 'c': - eprintf("not implemented "); + checkfile = EARGF(usage()); + break; default: usage(); } ARGEND; + if(checkfile) + return cryptcheck(checkfile, argc, argv, &md5_ops, md, sizeof(md)); return cryptmain(argc, argv, &md5_ops, md, sizeof(md)); } diff --git a/sha1sum.c b/sha1sum.c index 14bda3f..48fe7c5 100644 --- a/sha1sum.c +++ b/sha1sum.c @@ -24,13 +24,16 @@ int main(int argc, char *argv[]) { uint8_t md[SHA1_DIGEST_LENGTH]; + char *checkfile = NULL; ARGBEGIN { case 'c': - eprintf("not implemented "); + checkfile = EARGF(usage()); default: usage(); } ARGEND; + if(checkfile) + return cryptcheck(checkfile, argc, argv, &sha1_ops, md, sizeof(md)); return cryptmain(argc, argv, &sha1_ops, md, sizeof(md)); } diff --git a/sha256sum.c b/sha256sum.c index 957182e..8f9ed1f 100644 --- a/sha256sum.c +++ b/sha256sum.c @@ -24,13 +24,16 @@ int main(int argc, char *argv[]) { uint8_t md[SHA256_DIGEST_LENGTH]; + char *checkfile = NULL; ARGBEGIN { case 'c': - eprintf("not implemented "); + checkfile = EARGF(usage()); default: usage(); } ARGEND; + if(checkfile) + return cryptcheck(checkfile, argc, argv, &sha256_ops, md, sizeof(md)); return cryptmain(argc, argv, &sha256_ops, md, sizeof(md)); } diff --git a/sha512sum.c b/sha512sum.c index 79bec11..97ffaca 100644 --- a/sha512sum.c +++ b/sha512sum.c @@ -24,13 +24,16 @@ int main(int argc, char *argv[]) { uint8_t md[SHA512_DIGEST_LENGTH]; + char *checkfile = NULL; ARGBEGIN { case 'c': - eprintf("not implemented "); + checkfile = EARGF(usage()); default: usage(); } ARGEND; + if(checkfile) + return cryptcheck(checkfile, argc, argv, &sha512_ops, md, sizeof(md)); return cryptmain(argc, argv, &sha512_ops, md, sizeof(md)); } diff --git a/util/crypt.c b/util/crypt.c index 1c797a4..7048659 100644 --- a/util/crypt.c +++ b/util/crypt.c @@ -2,9 +2,96 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> +#include <string.h> #include "../util.h" +#include "../text.h" #include "../crypt.h" +static int +hexdec(int c) { + if(c >= '0' && c <= '9') + return c - '0'; + else if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + else if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + return -1; /* unknown character */ +} + +static int +mdcheckline(const char *s, uint8_t *md, size_t sz) { + size_t i; + int b1, b2; + + for(i = 0; i < sz; i++) { + if(!*s || (b1 = hexdec(*s++)) < 0) + return -1; /* invalid format */ + if(!*s || (b2 = hexdec(*s++)) < 0) + return -1; /* invalid format */ + if((uint8_t)((b1 << 4) | b2) != md[i]) + return 0; /* value mismatch */ + } + return (i == sz) ? 1 : 0; +} + +int +cryptcheck(char *sumfile, int argc, char *argv[], + struct crypt_ops *ops, uint8_t *md, size_t sz) +{ + FILE *cfp, *fp; + char *buf = NULL, *line, *file, *p; + int r, nonmatch = 0, formatsucks = 0, noread = 0, ret = EXIT_SUCCESS; + size_t bufsiz = 0; + + if(!(cfp = fopen(sumfile, "r"))) + eprintf("fopen %s:", sumfile); + + while((line = afgets(&buf, &bufsiz, cfp))) { + if(!(file = strstr(line, " "))) { + formatsucks++; + continue; + } + if((file - line) / 2 != sz) { + formatsucks++; /* checksum length mismatch */ + continue; + } + *file = '