+ /* --- Seeding --- */
+
+ case 'A': {
+ const struct seedalg *ss;
+ if (strcmp(optarg, "list") == 0) {
+ printf("Seed algorithms:\n");
+ for (ss = seedtab; ss->p; ss++)
+ printf(" %s\n", ss->p);
+ exit(0);
+ }
+ if (seed) die(EXIT_FAILURE, "seed already set -- put -A first");
+ sa = 0;
+ for (ss = seedtab; ss->p; ss++) {
+ if (strcmp(optarg, ss->p) == 0)
+ sa = ss;
+ }
+ if (!sa)
+ die(EXIT_FAILURE, "seed algorithm `%s' not known", optarg);
+ } break;
+
+ case 's': {
+ base64_ctx b;
+ dstr d = DSTR_INIT;
+ if (seed) die(EXIT_FAILURE, "seed already set");
+ base64_init(&b);
+ base64_decode(&b, optarg, strlen(optarg), &d);
+ base64_decode(&b, 0, 0, &d);
+ k.r = sa->gen(d.buf, d.len);
+ seed = optarg;
+ dstr_destroy(&d);
+ } break;
+
+ case 'n': {
+ base64_ctx b;
+ dstr d = DSTR_INIT;
+ char *p;
+ unsigned n = strtoul(optarg, &p, 0);
+ if (n == 0 || *p != 0 || n % 8 != 0)
+ die(EXIT_FAILURE, "bad seed length `%s'", optarg);
+ if (seed) die(EXIT_FAILURE, "seed already set");
+ n /= 8;
+ p = xmalloc(n);
+ rand_get(RAND_GLOBAL, p, n);
+ base64_init(&b);
+ base64_encode(&b, p, n, &d);
+ base64_encode(&b, 0, 0, &d);
+ seed = d.buf;
+ k.r = sa->gen(p, n);
+ } break;
+