9 const struct option opts[] = {
10 { "seed", required_argument, 0, 's' },
11 { "verify", no_argument, 0, 'v' },
12 { "create", no_argument, 0, 'c' },
13 { "help", no_argument, 0, 'h' },
14 { "version", no_argument, 0, 'V' },
18 static void help(void) {
19 printf("vbig - create or verify a large but pseudo-random file\n"
22 " vbig [--seed SEED] --verify|--create PATH SIZE\n");
31 int main(int argc, char **argv) {
32 const char *seed = "hexapodia as the key insight";
33 mode_type mode = NONE;
35 while((n = getopt_long(argc, argv, "+s:vchV", opts, 0)) >= 0) {
37 case 's': seed = optarg; break;
38 case 'v': mode = VERIFY; break;
39 case 'c': mode = CREATE; break;
40 case 'h': help(); exit(0);
41 case 'V': puts(VERSION); exit(0);
43 fprintf(stderr, "ERROR: unknown option\n");
48 fprintf(stderr, "ERROR: must specify one of --verify or --create\n");
51 if(optind + 2 != argc) {
52 fprintf(stderr, "ERROR: must specify a path and size\n");
55 const char *path = argv[optind];
58 long long size = strtoll(argv[optind + 1], &end, 10);
60 fprintf(stderr, "ERROR: invalid size: %s\n", strerror(errno));
63 if(end == argv[optind + 1]) {
64 fprintf(stderr, "ERROR: invalid size\n");
69 else if(!strcmp(end, "M"))
71 else if(!strcmp(end, "G"))
72 size *= 1024 * 1024 * 1024;
74 fprintf(stderr, "ERROR: invalid size\n");
77 Arcfour rng(seed, strlen(seed));
78 FILE *fp = fopen(path, mode == VERIFY ? "rb" : "wb");
80 fprintf(stderr, "ERROR: %s: %s\n", path, strerror(errno));
83 char generated[4096], input[4096];
86 size_t bytesGenerated = (remain > sizeof generated
89 rng.stream(generated, bytesGenerated);
91 fwrite(generated, 1, bytesGenerated, fp);
93 fprintf(stderr, "ERROR: %s: %s\n", path, strerror(errno));
97 size_t bytesRead = fread(input, 1, bytesGenerated, fp);
99 fprintf(stderr, "ERROR: %s: %s\n", path, strerror(errno));
102 if(bytesRead < bytesGenerated) {
103 fprintf(stderr, "ERROR: %s: truncated at %lld/%lld bytes\n",
104 path, (size - remain + bytesRead), size);
107 if(memcmp(generated, input, bytesGenerated)) {
108 for(size_t n = 0; n < bytesGenerated; ++n)
109 if(generated[n] != input[n]){
110 fprintf(stderr, "ERROR: %s corrupted at %lld/%lld bytes (expected %d got %d)\n",
111 path, size - remain + n, size,
112 (unsigned char)generated[n], (unsigned char)input[n]);
117 remain -= bytesGenerated;
119 if(mode == VERIFY && getc(fp) != EOF) {
120 fprintf(stderr, "ERROR: %s: extended beyond %lld bytes\n",
125 fprintf(stderr, "ERROR: %s: %s\n", path, strerror(errno));