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
));