X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/5685a696f1a1d1944b6eb1326e0df9ed84128ebd..2a7c52031aa0096b4f20ec1dd72e5f6e08a19aa9:/hashsum.c diff --git a/hashsum.c b/hashsum.c index dbb6662..9721410 100644 --- a/hashsum.c +++ b/hashsum.c @@ -7,7 +7,7 @@ * (c) 2000 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,12 +15,12 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * Catacomb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with Catacomb; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -51,6 +51,7 @@ #include #include "ghash.h" +#include "cc.h" /*----- Static variables --------------------------------------------------*/ @@ -93,7 +94,7 @@ static size_t gethex(const char *p, octet *q, size_t sz, char **pp) } if (pp) *pp = (char *)p; - return (i); + return (i); } /* --- Base64 encoding --- */ @@ -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); } @@ -210,7 +211,7 @@ static int fhash(const char *file, unsigned f, const gchash *gch, void *buf) ghash *h; int e; - if (!file) + if (!file || strcmp(file, "-") == 0) fp = stdin; else if ((fp = fopen(file, f & f_binary ? "rb" : "r")) == 0) return (-1); @@ -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; @@ -440,7 +441,7 @@ static int checkhash(const char *file, unsigned f, unsigned long n = 0, nfail = 0; octet *buf = xmalloc(2 * gch->hashsz); - if (!file) + if (!file || strcmp(file, "-") == 0) fp = stdin; else if ((fp = fopen(file, f & f_raw ? "r" : "rb")) == 0) { moan("couldn't open `%s': %s", file, strerror(errno)); @@ -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,20 +558,20 @@ 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; int rc = 0; int rrc; - if (!file) + if (!file || strcmp(file, "-") == 0) fp = stdin; else if ((fp = fopen(file, f & f_raw ? "r" : "rb")) == 0) { moan("couldn't open `%s': %s", file, strerror(errno)); @@ -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,8 +618,10 @@ 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\ \n\ -f, --files Read a list of file names from standard input.\n\ -0, --null File names are null terminated, not plain text.\n\ @@ -628,17 +631,24 @@ Generates or checks message digests on files. Options available:\n\ -b, --binary When reading files, treat them as binary.\n\ -v, --verbose Be verbose when checking digests.\n\ \n\ -For a list of supported message digest algorithms, type `$ --list'.\n\ +For a list of hashing algorithms and encodings, type `$ --list'.\n\ "); if (gch) 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 --- */ @@ -698,23 +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; - for (j = 0; ghashtab[j]; j++) { - if (j) - fputc(' ', stdout); - printf("%s", ghashtab[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; @@ -751,22 +753,23 @@ int main(int argc, char *argv[]) /* --- Generate output --- */ - if (!(f & f_check)) { + if (!(f & f_check) && (argc || (f & f_files))) { if (f & f_oddhash) printf("#hash %s\n", gch->name); if (f & f_oddenc) printf("#encoding %s\n", e->name); if (f & f_escape) fputs("#escape\n", stdout); } - - if (argc) { + if (!argc) + rc = hashsum(0, f, gch, e); + else { int i; int rrc; + rc = 0; for (i = 0; i < argc; i++) { if ((rrc = hashsum(argv[i], f, gch, e)) != 0) rc = rrc; } - } else - rc = hashsum(0, f, gch, e); + } return (rc); }