Catcrypt tools: Roll out progress indicator stuff from hashsum.
[u/mdw/catacomb] / cc-enc.c
index 17c0a56..2b8b0fd 100644 (file)
--- a/cc-enc.c
+++ b/cc-enc.c
@@ -7,7 +7,7 @@
  * (c) 2004 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,
@@ -29,6 +29,8 @@
 
 /*----- Header files ------------------------------------------------------*/
 
+#define _FILE_OFFSET_BITS 64
+
 #include <errno.h>
 #include <stdio.h>
 
@@ -55,7 +57,7 @@ static enc *bin_decinit(FILE *fp, encbdryp *func, void *p)
 static int bin_read(enc *e, void *p, size_t sz)
 {
   size_t n;
-  
+
   if (!sz) return (0);
   n = fread(p, 1, sz, e->fp);
   if (!n || ferror(e->fp)) return (-1);
@@ -268,18 +270,18 @@ static void pem_destroy(enc *e)
 /* --- Encoder table --- */
 
 const encops enctab[] = {
-  { "binary", "rb", "wb",
+  { "binary", "rb", "wb", 1, 1,
     bin_encinit, bin_decinit,
     bin_read, bin_write,
     bin_done, bin_done,
     bin_destroy },
-  { "pem", "r", "w",
+  { "pem", "r", "w", 3, 4,
     pem_encinit, pem_decinit,
     pem_read, pem_write,
     pem_encdone, pem_decdone,
     pem_destroy },
   { 0 }
-};  
+};
 
 /* --- @getenc@ --- *
  *
@@ -319,7 +321,7 @@ enc *initenc(const encops *eo, FILE *fp, const char *msg)
   enc *e = eo->initenc(fp, msg);
   e->ops = eo;
   e->fp = fp;
-  return (e);  
+  return (e);
 }
 
 /* --- @initdec@ --- *
@@ -358,11 +360,12 @@ void freeenc(enc *e) { e->ops->destroy(e); }
 
 int cmd_encode(int argc, char *argv[])
 {
-  const char *of = 0;
+  const char *fn, *of = 0;
   FILE *ofp = 0;
   FILE *fp = 0;
   const char *ef = "binary";
   const char *bd = "MESSAGE";
+  fprogress ff;
   int i;
   size_t n;
   char buf[4096];
@@ -371,20 +374,23 @@ int cmd_encode(int argc, char *argv[])
   enc *e;
 
 #define f_bogus 1u
+#define f_progress 2u
 
   for (;;) {
     static const struct option opt[] = {
-      { "format",      OPTF_ARGREQ,    0,      'f' },
-      { "boundary",    OPTF_ARGREQ,    0,      'b' },
-      { "output",      OPTF_ARGREQ,    0,      'o' },
+      { "format",      OPTF_ARGREQ,    0,      'f' },
+      { "boundary",    OPTF_ARGREQ,    0,      'b' },
+      { "output",      OPTF_ARGREQ,    0,      'o' },
+      { "progress",    0,              0,      'p' },
       { 0,             0,              0,      0 }
     };
-    i = mdwopt(argc, argv, "f:b:o:", opt, 0, 0, 0);
+    i = mdwopt(argc, argv, "f:b:o:p", opt, 0, 0, 0);
     if (i < 0) break;
     switch (i) {
       case 'f': ef = optarg; break;
       case 'b': bd = optarg; break;
       case 'o': of = optarg; break;
+      case 'p': f |= f_progress; break;
       default: f |= f_bogus; break;
     }
   }
@@ -394,16 +400,13 @@ int cmd_encode(int argc, char *argv[])
   if ((eo = getenc(ef)) == 0)
     die(EXIT_FAILURE, "encoding `%s' not found", ef);
 
-  if (optind == argc)
+  fn = optind < argc ? argv[optind++] : "-";
+  if (strcmp(fn, "-") == 0)
     fp = stdin;
-  else if (strcmp(argv[optind], "-") == 0) {
-    fp = stdin;
-    optind++;
-  } else if ((fp = fopen(argv[optind], "rb")) == 0) {
+  else if ((fp = fopen(fn, "rb")) == 0) {
     die(EXIT_FAILURE, "couldn't open file `%s': %s",
-       argv[optind], strerror(errno));
-  } else
-    optind++;
+       fn, strerror(errno));
+  }
 
   if (!of || strcmp(of, "-") == 0)
     ofp = stdout;
@@ -414,25 +417,38 @@ int cmd_encode(int argc, char *argv[])
 
   e = initenc(eo, ofp, bd);
 
+  if (f & f_progress) {
+    if (fprogress_init(&ff, fn, fp)) {
+      die(EXIT_FAILURE, "failed to initialize progress display: %s",
+         strerror(errno));
+    }
+  }
+
   do {
     n = fread(buf, 1, sizeof(buf), fp);
-    if (e->ops->write(e, buf, n))
+    if (f & f_progress) fprogress_update(&ff, n);
+    if (e->ops->write(e, buf, n)) {
+      if (f & f_progress) fprogress_done(&ff);
       die(EXIT_FAILURE, "error writing output: %s", strerror(errno));
+    }
   } while (n == sizeof(buf));
+  if (f & f_progress) fprogress_done(&ff);
   e->ops->encdone(e);
   freeenc(e);
   return (0);
 
 #undef f_bogus
+#undef f_progress
 }
 
 int cmd_decode(int argc, char *argv[])
 {
-  const char *of = 0;
+  const char *fn, *of = 0;
   FILE *ofp = 0;
   FILE *fp = 0;
   const char *ef = "binary";
   const char *bd = 0;
+  fprogress ff;
   int i;
   char buf[4096];
   unsigned f = 0;
@@ -440,20 +456,23 @@ int cmd_decode(int argc, char *argv[])
   enc *e;
 
 #define f_bogus 1u
+#define f_progress 2u
 
   for (;;) {
     static const struct option opt[] = {
-      { "format",      OPTF_ARGREQ,    0,      'f' },
-      { "boundary",    OPTF_ARGREQ,    0,      'b' },
-      { "output",      OPTF_ARGREQ,    0,      'o' },
+      { "format",      OPTF_ARGREQ,    0,      'f' },
+      { "boundary",    OPTF_ARGREQ,    0,      'b' },
+      { "output",      OPTF_ARGREQ,    0,      'o' },
+      { "progress",    0,              0,      'p' },
       { 0,             0,              0,      0 }
     };
-    i = mdwopt(argc, argv, "f:b:o:", opt, 0, 0, 0);
+    i = mdwopt(argc, argv, "f:b:o:p", opt, 0, 0, 0);
     if (i < 0) break;
     switch (i) {
       case 'f': ef = optarg; break;
       case 'b': bd = optarg; break;
       case 'o': of = optarg; break;
+      case 'p': f |= f_progress; break;
       default: f |= f_bogus; break;
     }
   }
@@ -463,16 +482,13 @@ int cmd_decode(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 (!of || strcmp(of, "-") == 0)
     ofp = stdout;
@@ -483,17 +499,32 @@ int cmd_decode(int argc, char *argv[])
 
   e = initdec(eo, fp, checkbdry, (/*unconst*/ void *)bd);
 
+  if (f & f_progress) {
+    if (fprogress_init(&ff, fn, fp)) {
+      die(EXIT_FAILURE, "failed to initialize progress display: %s",
+         strerror(errno));
+    }
+  }
+
   do {
-    if ((i = e->ops->read(e, buf, sizeof(buf))) < 0)
+    if ((i = e->ops->read(e, buf, sizeof(buf))) < 0) {
+      if (f & f_progress) fprogress_done(&ff);
       die(EXIT_FAILURE, "error reading input: %s", strerror(errno));
-    if (fwrite(buf, 1, i, ofp) < i)
+    }
+    if (f & f_progress)
+      fprogress_update(&ff, i*e->ops->ncook/e->ops->nraw);
+    if (fwrite(buf, 1, i, ofp) < i) {
+      if (f & f_progress) fprogress_done(&ff);
       die(EXIT_FAILURE, "error writing output: %s", strerror(errno));
+    }
   } while (i == sizeof(buf));
   e->ops->decdone(e);
+  if (f & f_progress) fprogress_done(&ff);
   freeenc(e);
   return (0);
 
 #undef f_bogus
+#undef f_progress
 }
 
 /*----- That's all, folks -------------------------------------------------*/