8 #include <mLib/alloc.h>
9 #include <mLib/base64.h>
10 #include <mLib/dstr.h>
12 #include <mLib/mdwopt.h>
13 #include <mLib/quis.h>
14 #include <mLib/report.h>
16 #include <catacomb/rand.h>
17 #include <catacomb/noise.h>
21 void (*out)(size_t, unsigned);
26 static void format_base64(size_t n, unsigned line)
28 unsigned char buf[CHUNK];
44 rand_get(RAND_GLOBAL, buf, nn);
45 base64_encode(&b, buf, nn, &d);
50 base64_encode(&b, 0, 0, &d);
52 while (d.len && d.buf[d.len - 1] == '=')
59 static void file_fix(char *p, size_t n)
62 if (*p == '/') *p = '%';
67 static void format_file64(size_t n, unsigned line)
69 unsigned char buf[CHUNK];
80 rand_get(RAND_GLOBAL, buf, nn);
81 base64_encode(&b, buf, nn, &d);
82 file_fix(d.buf, d.len);
87 base64_encode(&b, 0, 0, &d);
88 file_fix(d.buf, d.len);
89 while (d.len && d.buf[d.len - 1] == '=')
95 static void format_hex(size_t n, unsigned line)
97 unsigned char buf[CHUNK];
113 rand_get(RAND_GLOBAL, buf, nn);
114 hex_encode(&h, buf, nn, &d);
119 hex_encode(&h, 0, 0, &d);
124 static void format_raw(size_t n, unsigned line)
126 unsigned char buf[CHUNK];
131 rand_get(RAND_GLOBAL, buf, nn);
132 fwrite(buf, 1, nn, stdout);
137 static const struct format fmt[] = {
138 { "base64", format_base64 },
139 { "file64", format_file64 },
140 { "hex", format_hex },
141 { "raw", format_raw },
145 static int uarg(const char *p, const char *what)
150 x = strtoul(p, &q, 0);
151 if (*q || errno || x > INT_MAX) die(EXIT_FAILURE, "bad %s", what);
155 static void version(FILE *fp)
157 pquis(stderr, "$, version " VERSION "\n");
160 static void usage(FILE *fp)
162 pquis(stderr, "Usage: $ [-y] [-l LEN] [-f FORMAT] [BITS]\n");
165 static void help(FILE *fp)
171 Generates a random string, and prints it to standard output.\n\
175 -h, --help Print this help message.\n\
176 -v, --version Print program version number.\n\
177 -u, --usage Print short usage summary.\n\
179 -y, --bytes Output length is bytes, not bits.\n\
180 -l, --line=LENGTH For textual output, limit line length to LENGTH.\n\
181 -f, --format=FORMAT Select output format: base64, file64, hex, raw.\n\
185 int main(int argc, char *argv[])
191 const struct format *ff = &fmt[0];
197 static const struct option opt[] = {
198 { "help", 0, 0, 'h' },
199 { "version", 0, 0, 'v' },
200 { "usage", 0, 0, 'u' },
202 { "format", OPTF_ARGREQ, 0, 'f' },
203 { "line", OPTF_ARGREQ, 0, 'l' },
204 { "bytes", 0, 0, 'y' },
209 i = mdwopt(argc, argv, "hvuf:l:y", opt, 0, 0, 0);
226 len = uarg(optarg, "line length");
231 for (i = 0; fmt[i].name; i++) {
232 if (strncmp(fmt[i].name, optarg, n) != 0)
234 if (!fmt[i].name[n]) {
239 die(EXIT_FAILURE, "ambiguous format name `%s'", optarg);
243 die(EXIT_FAILURE, "unknown format name `%s'", optarg);
253 if (f & f_bogus && argc > 1) {
257 n = argc == 1 ? uarg(argv[0], "bit count") : 128;
258 if (!n || n % mul) die(EXIT_FAILURE, "bad bit count");
260 rand_noisesrc(RAND_GLOBAL, &noise_source);
261 rand_seed(RAND_GLOBAL, 160);
264 die(EXIT_FAILURE, "output error: %s", strerror(errno));