/*----- Header files ------------------------------------------------------*/
+#define _FILE_OFFSET_BITS 64
+
#include "config.h"
#include <ctype.h>
/* --- @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);
{ "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' },
{ "nocheck", OPTF_ARGREQ, 0, 'C' },
{ 0, 0, 0, 0 }
};
- int i = mdwopt(argc, argv, "+0vqbC" "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;
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 {
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, "+vqC", 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--;
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));
{ "help", cmd_help, "help [COMMAND...]" },
{ "show", cmd_show, "show [ITEM...]" },
{ "sign", sign,
- "sign [-0bqvC] [-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\
-e, --expire=TIME The signature should expire after TIME.\n\
" },
{ "verify", verify,
- "verify [-qvC] [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 }