X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=vbig.cc;h=a243fb7262602703b2eeed2038866778039c9f19;hb=393a419e4e8e6523166dedf482bc714fe9d8c16b;hp=5dcb42136e25000db7ba623d15b97a6ec2f76011;hpb=a84c6ce20e8e19b4c07424a2082c6eea2f15596b;p=vbig.git diff --git a/vbig.cc b/vbig.cc index 5dcb421..a243fb7 100644 --- a/vbig.cc +++ b/vbig.cc @@ -1,6 +1,7 @@ /* * This file is part of vbig. - * Copyright (C) 2011 Richard Kettlewell + * Copyright (C) 2011, 2013 Richard Kettlewell + * Copyright (C) 2013 Ian Jackson * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +42,7 @@ const struct option opts[] = { { "create", no_argument, 0, 'c' }, { "flush", no_argument, 0, 'f' }, { "entire", no_argument, 0, 'e' }, + { "progress", no_argument, 0, 'p' }, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { 0, 0, 0, 0 }, @@ -51,18 +53,20 @@ static void help(void) { printf("vbig - create or verify a large but pseudo-random file\n" "\n" "Usage:\n" - " vbig [--seed SEED] --verify|--create PATH [SIZE]\n" + " vbig [OPTIONS] [--both|--verify|--create] PATH] [SIZE]\n" "\n" "Options:\n" - " --seed, -s Specify random seed as string\n" - " --seed-file, -S Read random seed from (start of) this file\n" + " --seed, -s Specify random seed as string\n" + " --seed-file, -S Read random seed from (start of) this file\n" " --seed-length, -L Set (maximum) seed length to read from file\n" - " --verify, -v Verify that PATH contains the expected contents\n" - " --create, -c Create PATH with psuedo-random contents\n" - " --flush, -f Flush cache\n" - " --entire, -e Write until full; read until EOF\n" - " --help, -h Display usage message\n" - " --version, -V Display version string\n"); + " --verify, -v Verify that PATH contains the expected contents\n" + " --create, -c Create PATH with psuedo-random contents\n" + " --both, -b Do both create and verify (default)\n" + " --flush, -f Flush cache\n" + " --entire, -e Write until full; read until EOF\n" + " --progress, -p Show progress as we go\n" + " --help, -h Display usage message\n" + " --version, -V Display version string\n"); } // Possible modes of operation @@ -72,9 +76,12 @@ enum mode_type { BOTH }; +static void clearprogress(); + // Report an error and exit static void fatal(int errno_value, const char *fmt, ...) { va_list ap; + clearprogress(); fprintf(stderr, "ERROR: "); va_start(ap, fmt); vfprintf(stderr, fmt, ap); @@ -123,13 +130,14 @@ static const char *seedpath; static const char *path; static bool entireopt = false; static bool flush = false; +static bool progress = false; static long long size; int main(int argc, char **argv) { mode_type mode = BOTH; int n; char *ep; - while((n = getopt_long(argc, argv, "+s:S:L:vcefhV", opts, 0)) >= 0) { + while((n = getopt_long(argc, argv, "+s:S:L:vcepfhV", opts, 0)) >= 0) { switch(n) { case 's': seed = optarg; seedlen = strlen(optarg); break; case 'S': seedpath = optarg; break; @@ -141,6 +149,7 @@ int main(int argc, char **argv) { case 'v': mode = VERIFY; break; case 'c': mode = CREATE; break; case 'e': entireopt = true; break; + case 'p': progress = true; break; case 'f': flush = true; break; case 'h': help(); exit(0); case 'V': puts(VERSION); exit(0); @@ -163,6 +172,14 @@ int main(int argc, char **argv) { } if(seed && seedpath) fatal(0, "both --seed and --seed-file specified"); + if(mode == BOTH && !seed && !seedpath) { +#ifdef HAVE_RANDOM_DEVICE + seedpath = RANDOM_DEVICE; +#else + fatal(0, "no --seed or --seed-file specified in --both mode" + " and random device not supported on this system"); +#endif + } if(seedpath) { if(!seedlen) seedlen = DEFAULT_SEED_LENGTH; @@ -199,7 +216,7 @@ int main(int argc, char **argv) { else if(*end) fatal(0, "invalid size"); } else if(entireopt) { - size = LONG_LONG_MAX; + size = LLONG_MAX; } else { struct stat sb; if(stat(path, &sb) < 0) @@ -216,6 +233,37 @@ int main(int argc, char **argv) { return 0; } +static void flushstdout() { + if(ferror(stdout) || fflush(stdout)) + fatal(errno, "flush stdout"); +} + +static void clearprogress() { + if (!progress) return; + printf(" %-10s %*s \r", "", (int)sizeof(long long)*4, ""); + flushstdout(); +} + +static void showprogress(long long amount, const char *show) { + if (!progress) return; + + static int counter; + if (counter++ < 1000) return; + counter = 0; + + int triples = sizeof(amount); + char rawbuf[triples*3 + 1]; + char outbuf[triples*4 + 1]; + snprintf(rawbuf, sizeof(rawbuf), "% *lld", (int)sizeof(rawbuf)-1, amount); + for (int i=0; i> 20, done >> 30, show); - if(ferror(stdout) || fflush(stdout)) - fatal(errno, "flush stdout"); + flushstdout(); } return done; }