* (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,
/*----- Header files ------------------------------------------------------*/
+#define _FILE_OFFSET_BITS 64
+
#include <errno.h>
#include <stdio.h>
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);
/* --- 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@ --- *
*
enc *e = eo->initenc(fp, msg);
e->ops = eo;
e->fp = fp;
- return (e);
+ return (e);
}
/* --- @initdec@ --- *
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];
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;
}
}
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;
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;
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;
}
}
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;
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 -------------------------------------------------*/