General utilities cleanup. Add signature support to catcrypt. Throw in
[u/mdw/catacomb] / hashsum.c
index 492eb9b..c9bb3ec 100644 (file)
--- a/hashsum.c
+++ b/hashsum.c
@@ -51,6 +51,7 @@
 #include <mLib/base64.h>
 
 #include "ghash.h"
+#include "cc.h"
 
 /*----- Static variables --------------------------------------------------*/
 
@@ -164,24 +165,24 @@ static size_t getb32(const char *p, octet *q, size_t sz, char **pp)
 
 /* --- Table --- */
 
-typedef struct encops {
+typedef struct encodeops {
   const char *name;
   void (*put)(const octet *, size_t, FILE *);
   size_t (*get)(const char *, octet *, size_t, char **);
-} encops;
+} encodeops;
 
-static const encops enctab[] = {
+static const encodeops encodingtab[] = {
   { "hex", puthex, gethex },
   { "base64", putb64, getb64 },
   { "base32", putb32, getb32 },
   { 0, 0, 0 }
 };
 
-static const encops *getenc(const char *ename)
+static const encodeops *getencoding(const char *ename)
 {
-  const encops *e;
+  const encodeops *e;
 
-  for (e = enctab; e->name; e++) {
+  for (e = encodingtab; e->name; e++) {
     if (strcmp(ename, e->name) == 0)
       return (e);
   }
@@ -431,7 +432,7 @@ static void putstring(FILE *fp, const char *p, unsigned raw)
 /*----- Guts --------------------------------------------------------------*/
 
 static int checkhash(const char *file, unsigned f,
-                    const gchash *gch, const encops *e)
+                    const gchash *gch, const encodeops *e)
 {
   int rc;
   FILE *fp;
@@ -468,10 +469,10 @@ static int checkhash(const char *file, unsigned f,
        xfree(buf);
        buf = xmalloc(2 * gch->hashsz);
       } else if (strcmp(q, "encoding") == 0) {
-       const encops *ee;
+       const encodeops *ee;
        if ((q = str_getword(&p)) == 0)
          continue;
-       if ((ee = getenc(q)) == 0)
+       if ((ee = getencoding(q)) == 0)
          continue;
        e = ee;
       } else if (strcmp(q, "escape") == 0)
@@ -531,7 +532,7 @@ static int checkhash(const char *file, unsigned f,
 }
 
 static int dohash(const char *file, unsigned f,
-                 const gchash *gch, const encops *e)
+                 const gchash *gch, const encodeops *e)
 {
   int rc = 0;
   octet *p = xmalloc(gch->hashsz);
@@ -557,13 +558,13 @@ static int dohash(const char *file, unsigned f,
 }
 
 static int dofile(const char *file, unsigned f,
-                 const gchash *gch, const encops *e)
+                 const gchash *gch, const encodeops *e)
 {
   return (f & f_check ? checkhash : dohash)(file, f, gch, e);
 }
 
 static int hashfiles(const char *file, unsigned f,
-                    const gchash *gch, const encops *e)
+                    const gchash *gch, const encodeops *e)
 {
   FILE *fp;
   dstr d = DSTR_INIT;
@@ -589,21 +590,21 @@ static int hashfiles(const char *file, unsigned f,
 }
 
 static int hashsum(const char *file, unsigned f,
-                  const gchash *gch, const encops *e)
+                  const gchash *gch, const encodeops *e)
 {
   return (f & f_files ? hashfiles : dofile)(file, f, gch, e);
 }
 
 /*----- Main driver -------------------------------------------------------*/
 
-static void version(FILE *fp)
+void version(FILE *fp)
 {
   pquis(fp, "$, Catacomb version " VERSION "\n");
 }
 
 static void usage(FILE *fp)
 {
-  pquis(fp, "Usage: $ [-f0ebcv] [-a algorithm] [files...]\n");
+  pquis(fp, "Usage: $ [-f0ebcv] [-a ALGORITHM] [-E ENC] [FILES...]\n");
 }
 
 static void help(FILE *fp, const gchash *gch)
@@ -617,6 +618,7 @@ Generates or checks message digests on files.  Options available:\n\
 -h, --help             Display this help message.\n\
 -V, --version          Display program's version number.\n\
 -u, --usage            Display a terse usage message.\n\
+-l, --list [ITEM...]   Show known hash functions and/or encodings.\n\
 \n\
 -a, --algorithm=ALG    Use the message digest algorithm ALG.\n\
 -E, --encoding=ENC     Represent hashes using encoding ENC.\n\
@@ -635,11 +637,18 @@ For a list of hashing algorithms and encodings, type `$ --list'.\n\
     fprintf(fp, "The default message digest algorithm is %s.\n", gch->name);
 }
 
+#define LISTS(LI)                                                      \
+  LI("Lists", list, listtab[i].name, listtab[i].name)                  \
+  LI("Hash functions", hash, ghashtab[i], ghashtab[i]->name)           \
+  LI("Encodings", enc, encodingtab[i].name, encodingtab[i].name)
+
+MAKELISTTAB(listtab, LISTS)
+
 int main(int argc, char *argv[])
 {
   unsigned f = 0;
   const gchash *gch = 0;
-  const encops *e = &enctab[0];
+  const encodeops *e = &encodingtab[0];
   int rc;
 
   /* --- Initialization --- */
@@ -699,29 +708,15 @@ int main(int argc, char *argv[])
       case 'u':
        usage(stdout);
        exit(0);
+      case 'l':
+       exit(displaylists(listtab, argv + optind));
       case 'a':
        if ((gch = gethash(optarg)) == 0)
          die(EXIT_FAILURE, "unknown hash algorithm `%s'", optarg);
        f |= f_oddhash;
        break;
-      case 'l': {
-       unsigned j;
-       printf("Algorithms: ");
-       for (j = 0; ghashtab[j]; j++) {
-         if (j) fputc(' ', stdout);
-         printf("%s", ghashtab[j]->name);
-       }
-       fputc('\n', stdout);
-       printf("Encodings: ");
-       for (j = 0; enctab[j].name; j++) {
-         if (j) fputc(' ', stdout);
-         printf("%s", enctab[j].name);
-       }
-       fputc('\n', stdout);
-       exit(0);
-      } break;
       case 'E':
-       if ((e = getenc(optarg)) == 0)
+       if ((e = getencoding(optarg)) == 0)
          die(EXIT_FAILURE, "unknown encoding `%s'", optarg);
        f |= f_oddenc;
        break;