* (c) 2000 Straylight/Edgeware
*/
-/*----- Licensing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of Catacomb.
*
* 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,
/*----- Header files ------------------------------------------------------*/
+#define _FILE_OFFSET_BITS 64
+
#include "config.h"
#include <ctype.h>
if (fp && !bin)
bwrite(b, fp);
}
-
+
/*----- Static variables --------------------------------------------------*/
static const char *keyring = "keyring";
/*----- Other shared functions --------------------------------------------*/
-/* --- @keyreport@ --- *
- *
- * Arguments: @const char *file@ = filename containing the error
- * @int line@ = line number in file
- * @const char *err@ = error text message
- * @void *p@ = unimportant pointer
- *
- * Returns: ---
- *
- * Use: Reports errors during the opening of a key file.
- */
-
-static void keyreport(const char *file, int line, const char *err, void *p)
-{
- moan("error in keyring `%s' at line `%s': %s", file, line, err);
-}
-
/* --- @fhash@ --- *
*
* Arguments: @const gchash *c@ = pointer to hash class
+ * @unsigned f@ = flags
* @const char *file@ = file to hash
* @void *b@ = pointer to output buffer
*
* Use: Hashes a file.
*/
-static int fhash(const gchash *c, const char *file, void *b)
+#define FHF_PROGRESS 256u
+
+static int fhash(const gchash *c, unsigned f, const char *file, void *b)
{
FILE *fp = fopen(file, "rb");
+ fprogress ff;
ghash *h = GH_INIT(c);
char buf[4096];
size_t sz;
if (!fp)
return (-1);
- while ((sz = fread(buf, 1, sizeof(buf), fp)) > 0)
+ if (f & FHF_PROGRESS) {
+ if (fprogress_init(&ff, file, fp)) return (-1);
+ }
+ while ((sz = fread(buf, 1, sizeof(buf), fp)) > 0) {
GH_HASH(h, buf, sz);
+ if (f & FHF_PROGRESS) fprogress_update(&ff, sz);
+ }
if (ferror(fp))
rc = -1;
+ if (f & FHF_PROGRESS) fprogress_done(&ff);
GH_DONE(h, b);
GH_DESTROY(h);
fclose(fp);
if (!sz)
break;
}
-}
+}
/*----- Signature generation ----------------------------------------------*/
#define f_raw 1u
#define f_bin 2u
#define f_bogus 4u
+#define f_nocheck 8u
unsigned f = 0;
const char *ki = "dsig";
{ "null", 0, 0, '0' },
{ "binary", 0, 0, 'b' },
{ "verbose", 0, 0, 'v' },
+ { "progress", 0, 0, 'p' },
{ "quiet", 0, 0, 'q' },
{ "comment", OPTF_ARGREQ, 0, 'c' },
{ "file", OPTF_ARGREQ, 0, 'f' },
{ "output", OPTF_ARGREQ, 0, 'o' },
{ "key", OPTF_ARGREQ, 0, 'k' },
{ "expire", OPTF_ARGREQ, 0, 'e' },
+ { "nocheck", OPTF_ARGREQ, 0, 'C' },
{ 0, 0, 0, 0 }
};
- int i = mdwopt(argc, argv, "+0vqb" "c:" "f:o:" "k:e:", opts, 0, 0, 0);
+ int i = mdwopt(argc, argv, "+0vpqbC" "c:" "f:o:" "k:e:", opts, 0, 0, 0);
if (i < 0)
break;
switch (i) {
case 'v':
verb++;
break;
+ case 'p':
+ f |= FHF_PROGRESS;
+ break;
case 'q':
if (verb > 0)
verb--;
break;
+ case 'C':
+ f |= f_nocheck;
+ break;
case 'c':
c = optarg;
break;
/* --- Locate the signing key --- */
- if (key_open(&kf, keyring, KOPEN_WRITE, keyreport, 0))
+ if (key_open(&kf, keyring, KOPEN_WRITE, key_moan, 0))
die(EXIT_FAILURE, "couldn't open keyring `%s'", keyring);
if ((k = key_bytag(&kf, ki)) == 0)
die(EXIT_FAILURE, "couldn't find key `%s'", ki);
/* --- Check the key --- */
- if ((err = s->ops->check(s)) != 0)
+ if (!(f & f_nocheck) && (err = s->ops->check(s)) != 0)
moan("key `%s' fails check: %s", d.buf, err);
/* --- Open files --- */
- if (!ifile)
+ if (!ifile || strcmp(ifile, "-") == 0)
ifp = stdin;
else if ((ifp = fopen(ifile, (f & f_raw) ? "rb" : "r")) == 0) {
die(EXIT_FAILURE, "couldn't open input file `%s': %s",
ifile, strerror(errno));
}
- if (!ofile)
+ if (!ofile || strcmp(ofile, "-") == 0)
ofp = stdout;
else if ((ofp = fopen(ofile, (f & f_bin) ? "wb" : "w")) == 0) {
die(EXIT_FAILURE, "couldn't open output file `%s': %s",
binit(&b); b.tag = T_IDENT;
dstr_putf(&b.d, "%s, Catacomb version " VERSION, QUIS);
bemit(&b, ofp, 0, f & f_bin);
-
+
breset(&b); b.tag = T_KEYID; b.k = k->id;
bemit(&b, ofp, 0, f & f_bin);
break;
b.tag = T_FILE;
DENSURE(&b.b, GH_CLASS(s->h)->hashsz);
- if (fhash(GH_CLASS(s->h), b.d.buf, b.b.buf)) {
+ if (fhash(GH_CLASS(s->h), f, b.d.buf, b.b.buf)) {
moan("Error reading `%s': %s", b.d.buf, strerror(errno));
f |= f_bogus;
} else {
#undef f_raw
#undef f_bin
#undef f_bogus
+#undef f_nocheck
}
/*----- Signature verification --------------------------------------------*/
#define f_bogus 1u
#define f_bin 2u
#define f_ok 4u
+#define f_nocheck 8u
unsigned f = 0;
unsigned verb = 1;
for (;;) {
static struct option opts[] = {
{ "verbose", 0, 0, 'v' },
+ { "progress", 0, 0, 'p' },
{ "quiet", 0, 0, 'q' },
+ { "nocheck", 0, 0, 'C' },
{ 0, 0, 0, 0 }
};
- int i = mdwopt(argc, argv, "+vq", opts, 0, 0, 0);
+ int i = mdwopt(argc, argv, "+vpqC", opts, 0, 0, 0);
if (i < 0)
break;
switch (i) {
case 'v':
verb++;
break;
+ case 'p':
+ f |= FHF_PROGRESS;
+ break;
case 'q':
if (verb)
verb--;
break;
+ case 'C':
+ f |= f_nocheck;
+ break;
default:
f |= f_bogus;
break;
argc -= optind;
argv += optind;
if ((f & f_bogus) || argc > 1)
- die(EXIT_FAILURE, "Usage: verify [-qv] [FILE]");
+ die(EXIT_FAILURE, "Usage: verify [-qvC] [FILE]");
/* --- Open the key file, and start reading the input file --- */
- if (key_open(&kf, keyring, KOPEN_READ, keyreport, 0))
+ if (key_open(&kf, keyring, KOPEN_READ, key_moan, 0))
die(EXIT_FAILURE, "couldn't open keyring `%s'\n", keyring);
if (argc < 1)
fp = stdin;
}
s = getsig(k, "dsig", 0);
- if (verb && (err = s->ops->check(s)) != 0)
+ if (!(f & f_nocheck) && verb && (err = s->ops->check(s)) != 0)
printf("WARN public key fails check: %s", err);
for (;;) {
case T_FILE:
DRESET(&d);
DENSURE(&d, GH_CLASS(s->h)->hashsz);
- if (fhash(GH_CLASS(s->h), b.d.buf, d.buf)) {
+ if (fhash(GH_CLASS(s->h), f, b.d.buf, d.buf)) {
if (verb > 1) {
printf("BAD error reading file `%s': %s\n",
b.d.buf, strerror(errno));
#undef f_bogus
#undef f_bin
#undef f_ok
+#undef f_nocheck
}
/*----- Main code ---------------------------------------------------------*/
{ "help", cmd_help, "help [COMMAND...]" },
{ "show", cmd_show, "show [ITEM...]" },
{ "sign", sign,
- "sign [-0bqv] [-c COMMENT] [-k TAG] [-e EXPIRE]\n\t\
+ "sign [-0bpqvC] [-c COMMENT] [-k TAG] [-e EXPIRE]\n\t\
[-f FILE] [-o OUTPUT]",
"\
Options:\n\
-b, --binary Produce a binary output file.\n\
-q, --quiet Produce fewer messages while working.\n\
-v, --verbose Produce more messages while working.\n\
+-p, --progress Show progress on large files.\n\
+-C, --nocheck Don't check the private key.\n\
-c, --comment=COMMENT Include COMMENT in the output file.\n\
-f, --file=FILE Read filenames to hash from FILE.\n\
-o, --output=FILE Write the signed result to FILE.\n\
-e, --expire=TIME The signature should expire after TIME.\n\
" },
{ "verify", verify,
- "verify [-qv] [FILE]", "\
+ "verify [-pqvC] [FILE]", "\
Options:\n\
\n\
-q, --quiet Produce fewer messages while working.\n\
-v, --verbose Produce more messages while working.\n\
+-p, --progress Show progress on large files.\n\
+-C, --nocheck Don't check the public key.\n\
" },
{ 0, 0, 0 }
};