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 = '

Reply via email to