X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/f0c52873e4c1e3a16bb2d5a086df2526f698e4ac..cd6eca4375f46a35b93e2fea4b0428a23b451aa3:/catsign.c diff --git a/catsign.c b/catsign.c index 8171404..3bbd7b2 100644 --- a/catsign.c +++ b/catsign.c @@ -29,6 +29,8 @@ /*----- Header files ------------------------------------------------------*/ +#define _FILE_OFFSET_BITS 64 + #include "config.h" #include @@ -92,6 +94,7 @@ typedef struct sigmsg { #define F_BUFFER 256u #define F_UTC 512u #define F_NOCHECK 1024u +#define F_PROGRESS 2048u /*----- Chunk I/O ---------------------------------------------------------*/ @@ -132,6 +135,7 @@ typedef struct msgcanon { unsigned f; FILE *fp; enc *e; + fprogress ff; size_t (*read)(struct msgcanon *, void *); void (*write)(struct msgcanon *, const void *, size_t); void (*close)(struct msgcanon *); @@ -176,6 +180,7 @@ full: ungetc(ch, m->fp); done: m->f = f; + if (m->f & F_PROGRESS) fprogress_update(&m->ff, n); return (n); } @@ -197,9 +202,18 @@ static void textwrite(msgcanon *m, const void *bp, size_t n) } static size_t binreadembed(msgcanon *m, void *bp) - { return (chunk_read(m->e, bp)); } +{ + size_t n = chunk_read(m->e, bp); + if (m->f & F_PROGRESS) fprogress_update(&m->ff, n); + return (n); +} + static size_t binreaddetach(msgcanon *m, void *bp) - { return (fread(bp, 1, MSGBUFSZ - 1, m->fp)); } +{ + size_t n = fread(bp, 1, MSGBUFSZ - 1, m->fp); + if (m->f & F_PROGRESS) fprogress_update(&m->ff, n); + return (n); +} static void binwriteembed(msgcanon *m, const void *bp, size_t n) { chunk_write(m->e, bp, n); } @@ -208,18 +222,25 @@ static void nullwrite(msgcanon *m, const void *bp, size_t n) { ; } static void mcsetup_readfile(msgcanon *m, unsigned f, const char *fn) { - m->f = F_DETACH | (f & F_BINARY); + m->f = F_DETACH | (f & (F_BINARY | F_PROGRESS)); if (!fn || strcmp(fn, "-") == 0) { m->fp = stdin; m->f |= F_NOCLOSE; } else if ((m->fp = fopen(fn, (f & F_BINARY) ? "rb" : "r")) == 0) die(EXIT_FAILURE, "couldn't open file `%s': %s", fn, strerror(errno)); + if (m->f & F_PROGRESS) { + if (fprogress_init(&m->ff, fn, m->fp)) { + die(EXIT_FAILURE, "failed to initialize progress indicator: %s", + strerror(errno)); + } + } m->read = (f & F_BINARY) ? binreaddetach : textread; } static void mcsetup_writenull(msgcanon *m) { m->write = nullwrite; } -static void mcsetup_read(msgcanon *m, unsigned f, enc **ee, const char *dfn) +static void mcsetup_read(msgcanon *m, unsigned f, enc **ee, + const char *fn, const char *dfn) { enc *e = *ee; @@ -232,6 +253,12 @@ static void mcsetup_read(msgcanon *m, unsigned f, enc **ee, const char *dfn) *ee = 0; m->fp = e->fp; m->read = binreadembed; + if (m->f & F_PROGRESS) { + if (fprogress_init(&m->ff, fn, m->fp)) { + die(EXIT_FAILURE, "failed to initialize progress indicator: %s", + strerror(errno)); + } + } } else { m->read = binreaddetach; if (!dfn || strcmp(dfn, "-") == 0) @@ -240,6 +267,12 @@ static void mcsetup_read(msgcanon *m, unsigned f, enc **ee, const char *dfn) die(EXIT_FAILURE, "can't open `%s': %s", dfn, strerror(errno)); else m->f &= ~F_NOCLOSE; + if (m->f & F_PROGRESS) { + if (fprogress_init(&m->ff, dfn, m->fp)) { + die(EXIT_FAILURE, "failed to initialize progress indicator: %s", + strerror(errno)); + } + } } } else { m->read = textread; @@ -249,12 +282,26 @@ static void mcsetup_read(msgcanon *m, unsigned f, enc **ee, const char *dfn) m->fp = e->fp; e->ops->destroy(e); *ee = 0; - } else if (!dfn || strcmp(dfn, "-") == 0) - m->fp = stdin; - else if ((m->fp = fopen(dfn, "r")) == 0) - die(EXIT_FAILURE, "can't read file `%s': %s", dfn, strerror(errno)); - else - m->f &= ~F_NOCLOSE; + if (m->f & F_PROGRESS) { + if (fprogress_init(&m->ff, fn, m->fp)) { + die(EXIT_FAILURE, "failed to initialize progress indicator: %s", + strerror(errno)); + } + } + } else { + if (!dfn || strcmp(dfn, "-") == 0) + m->fp = stdin; + else if ((m->fp = fopen(dfn, "r")) == 0) + die(EXIT_FAILURE, "can't read file `%s': %s", dfn, strerror(errno)); + else + m->f &= ~F_NOCLOSE; + if (m->f & F_PROGRESS) { + if (fprogress_init(&m->ff, dfn, m->fp)) { + die(EXIT_FAILURE, "failed to initialize progress indicator: %s", + strerror(errno)); + } + } + } } } @@ -293,6 +340,7 @@ static void mc_endread(msgcanon *m, const encops *eops, enc **ee) if (ferror(m->fp) || fclose(m->fp)) die(EXIT_FAILURE, "error closing message file: %s", strerror(errno)); } + if (m->f & F_PROGRESS) fprogress_done(&m->ff); } static void mc_endwrite(msgcanon *m, const encops *eops, enc **ee) @@ -453,11 +501,12 @@ static int sign(int argc, char *argv[]) { "key", OPTF_ARGREQ, 0, 'k' }, { "format", OPTF_ARGREQ, 0, 'f' }, { "output", OPTF_ARGREQ, 0, 'o' }, + { "progress", 0, 0, 'p' }, { "text", 0, 0, 't' }, { "nocheck", 0, 0, 'C' }, { 0, 0, 0, 0 } }; - i = mdwopt(argc, argv, "k:f:o:abdtC", opt, 0, 0, 0); + i = mdwopt(argc, argv, "k:f:o:abdptC", opt, 0, 0, 0); if (i < 0) break; switch (i) { case 'k': kn = optarg; break; @@ -468,6 +517,7 @@ static int sign(int argc, char *argv[]) case 'b': f |= F_BINARY; break; case 'd': f |= F_DETACH; break; case 'C': f |= F_NOCHECK; break; + case 'p': f |= F_PROGRESS; break; default: f |= F_BOGUS; break; } } @@ -574,12 +624,13 @@ static void vrfchoke(const char *m, void *p) static int verify(int argc, char *argv[]) { - const char *ef = "binary", *of = 0, *dfn = 0, *kn = 0, *err; + const char *ef = "binary", *of = 0, *fn, *dfn = 0, *kn = 0, *err; vrfctx v = { 0, 0, 1 }; key_file kf; key *k, *kk = 0; sigmsg s; FILE *fp, *ofp = 0, *rfp = 0; + fprogress ff; struct tm *tm; int i; char bb[MSGBUFSZ]; @@ -598,6 +649,7 @@ static int verify(int argc, char *argv[]) { "key", OPTF_ARGREQ, 0, 'k' }, { "format", OPTF_ARGREQ, 0, 'f' }, { "output", OPTF_ARGREQ, 0, 'o' }, + { "progress", 0, 0, 'p' }, { "quiet", 0, 0, 'q' }, { "utc", 0, 0, 'u' }, { "fresh-time", 0, 0, 't' }, @@ -606,7 +658,7 @@ static int verify(int argc, char *argv[]) { "nocheck", 0, 0, 'C' }, { 0, 0, 0, 0 } }; - i = mdwopt(argc, argv, "k:f:o:abqt:uvC", opt, 0, 0, 0); + i = mdwopt(argc, argv, "k:f:o:abpqt:uvC", opt, 0, 0, 0); if (i < 0) break; switch (i) { case 'a': ef = "pem"; break; @@ -623,6 +675,7 @@ static int verify(int argc, char *argv[]) break; case 'q': if (v.verb > 0) v.verb--; break; case 'v': if (v.verb < 10) v.verb++; break; + case 'p': v.f |= F_PROGRESS; break; default: v.f |= F_BOGUS; break; } } @@ -632,16 +685,13 @@ static int verify(int argc, char *argv[]) if ((eo = getenc(ef)) == 0) die(EXIT_FAILURE, "encoding `%s' not found", ef); - if (optind >= argc) - fp = stdin; - else if (strcmp(argv[optind], "-") == 0) { + fn = optind < argc ? argv[optind++] : "-"; + if (strcmp(fn, "-") == 0) fp = stdin; - optind++; - } else if ((fp = fopen(argv[optind], eo->rmode)) == 0) { + else if ((fp = fopen(fn, eo->rmode)) == 0) { die(EXIT_FAILURE, "couldn't open file `%s': %s", - argv[optind], strerror(errno)); - } else - optind++; + fn, strerror(errno)); + } if (key_open(&kf, keyring, KOPEN_READ, key_moan, 0)) die(EXIT_FAILURE, "can't open keyring `%s'", keyring); @@ -692,7 +742,7 @@ static int verify(int argc, char *argv[]) sig_readsig(e, &s); if (optind < argc) dfn = argv[optind++]; - mcsetup_read(&mc_in, v.f, &e, dfn); + mcsetup_read(&mc_in, v.f, &e, fn, dfn); if (!of && (v.f & F_DETACH)) { rfp = ofp = 0; @@ -756,13 +806,18 @@ static int verify(int argc, char *argv[]) of, strerror(errno)); } rewind(rfp); + if (v.f & F_PROGRESS) fprogress_init(&ff, "copying buffer", rfp); if (v.verb && ofp == stdout) printf("DATA\n"); for (;;) { n = fread(bb, 1, sizeof(bb), rfp); if (!n) break; - if (fwrite(bb, 1, n, ofp) < n) + if (v.f & F_PROGRESS) fprogress_update(&ff, n); + if (fwrite(bb, 1, n, ofp) < n) { + if (v.f & F_PROGRESS) fprogress_done(&ff); die(EXIT_FAILURE, "error writing output: %s", strerror(errno)); + } } + if (v.f & F_PROGRESS) fprogress_done(&ff); if (ferror(rfp) || fclose(rfp)) die(EXIT_FAILURE, "error unbuffering output: %s", strerror(errno)); } @@ -787,7 +842,7 @@ static int verify(int argc, char *argv[]) static int format(int argc, char *argv[]) { const char *ief = "binary", *oef = "binary"; - const char *dfn = 0, *of = 0, *mf = 0; + const char *fn, *dfn = 0, *of = 0, *mf = 0; sigmsg s; FILE *fp, *ofp = 0, *mfp = 0; int i; @@ -811,9 +866,10 @@ static int format(int argc, char *argv[]) { "format-out", OPTF_ARGREQ, 0, 'F' }, { "message", OPTF_ARGREQ, 0, 'm' }, { "output", OPTF_ARGREQ, 0, 'o' }, + { "progress", 0, 0, 'p' }, { 0, 0, 0, 0 } }; - i = mdwopt(argc, argv, "f:F:m:o:aADE", opt, 0, 0, 0); + i = mdwopt(argc, argv, "f:F:m:o:apADE", opt, 0, 0, 0); if (i < 0) break; switch (i) { case 'a': ief = "pem"; break; @@ -824,6 +880,7 @@ static int format(int argc, char *argv[]) case 'E': f &= ~F_DETACH; fm |= F_DETACH; break; case 'm': mf = optarg; break; case 'o': of = optarg; break; + case 'p': f |= F_PROGRESS; break; default: f |= F_BOGUS; break; } } @@ -836,16 +893,13 @@ static int format(int argc, char *argv[]) if ((oeo = getenc(oef)) == 0) die(EXIT_FAILURE, "encoding `%s' not found", oef); - if (optind >= argc) - fp = stdin; - else if (strcmp(argv[optind], "-") == 0) { + fn = optind < argc ? argv[optind++] : "-"; + if (strcmp(fn, "-") == 0) fp = stdin; - optind++; - } else if ((fp = fopen(argv[optind], ieo->rmode)) == 0) { + else if ((fp = fopen(fn, ieo->rmode)) == 0) { die(EXIT_FAILURE, "couldn't open file `%s': %s", - argv[optind], strerror(errno)); - } else - optind++; + fn, strerror(errno)); + } if (optind < argc) dfn = argv[optind++]; @@ -859,7 +913,7 @@ static int format(int argc, char *argv[]) if (((s.f ^ v.f) & v.m) != 0) moan("boundary string inconsistent with contents (ignoring)"); - mcsetup_read(&mc_in, s.f, &ie, dfn); + mcsetup_read(&mc_in, s.f, &ie, fn, dfn); /* --- Prepare the output stuff --- */ @@ -1058,7 +1112,7 @@ static cmd cmdtab[] = { CMD_ENCODE, CMD_DECODE, { "sign", sign, - "sign [-adtC] [-k TAG] [-f FORMAT] [-o OUTPUT] [FILE]", "\ + "sign [-adptC] [-k TAG] [-f FORMAT] [-o OUTPUT] [FILE]", "\ Options:\n\ \n\ -a, --armour Same as `-f pem'.\n\ @@ -1067,11 +1121,12 @@ Options:\n\ -f, --format=FORMAT Encode as FORMAT.\n\ -k, --key=TAG Use public encryption key named by TAG.\n\ -o, --output=FILE Write output to FILE.\n\ +-p, --progress Show progress on large files.\n\ -t, --text Canonify input message as a text file.\n\ -C, --nocheck Don't check the private key.\n\ " }, { "verify", verify, - "verify [-abquvC] [-f FORMAT] [-k TAG] [-o OUTPUT]\n\t\ + "verify [-abpquvC] [-f FORMAT] [-k TAG] [-o OUTPUT]\n\t\ [FILE [MESSAGE]]", "\ Options:\n\ \n\ @@ -1080,6 +1135,7 @@ Options:\n\ -f, --format=FORMAT Decode as FORMAT.\n\ -k, --key=TAG Require that the message be signed by key TAG.\n\ -o, --output=FILE Write message to FILE.\n\ +-p, --progress Show progress on large files.\n\ -q, --quiet Produce fewer messages.\n\ -t, --freshtime=TIME Only accept signatures made after this time.\n\ -u, --utc Show dates in UTC rather than local time.\n\ @@ -1095,7 +1151,7 @@ Options:\n\ -u, --utc Show dates in UTC rather than local time.\n\ "}, { "format", format, - "format [-auADE] [-f FORMAT] [-F format] [-m FILE] [-o FILE]\n\t\ + "format [-apuADE] [-f FORMAT] [-F format] [-m FILE] [-o FILE]\n\t\ [FILE [MESSAGE]]", "\ Options:\n\ \n\ @@ -1107,6 +1163,7 @@ Options:\n\ -F, --format-out=FORMAT Encode output as FORMAT.\n\ -m, --message=FILE Write message to FILE.\n\ -o, --output=FILE Write new signature to FILE.\n\ +-p, --progress Show progress on large files.\n\ "}, { 0, 0, 0 } }; /* " Emacs seems confused. */