xref: /minix/external/bsd/bind/dist/bin/tools/genrandom.c (revision 9f7f0ad0)
1 /*	$NetBSD: genrandom.c,v 1.7 2014/12/10 04:37:54 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 2000-2003  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: genrandom.c,v 1.7 2010/05/17 23:51:04 tbox Exp  */
21 
22 /*! \file */
23 #include <config.h>
24 
25 #include <isc/commandline.h>
26 #include <isc/print.h>
27 #include <isc/stdlib.h>
28 #include <isc/util.h>
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 const char *program = "genrandom";
34 
35 ISC_PLATFORM_NORETURN_PRE static void
36 usage(void) ISC_PLATFORM_NORETURN_POST;
37 
38 static void
39 usage(void) {
40 	fprintf(stderr, "usage: %s [-n 2..9] k file\n", program);
41 	exit(1);
42 }
43 
44 static void
45 generate(char *filename, unsigned int bytes) {
46 	FILE *fp;
47 
48 	fp = fopen(filename, "w");
49 	if (fp == NULL) {
50 		printf("failed to open %s\n", filename);
51 		exit(1);
52 	}
53 
54 	while (bytes > 0) {
55 #ifndef HAVE_ARC4RANDOM
56 		unsigned short int x = (rand() & 0xFFFF);
57 #else
58 		unsigned short int x = (arc4random() & 0xFFFF);
59 #endif
60 		unsigned char c = x & 0xFF;
61 		if (putc(c, fp) == EOF) {
62 			printf("error writing to %s\n", filename);
63 			exit(1);
64 		}
65 		c = x >> 8;
66 		if (putc(c, fp) == EOF) {
67 			printf("error writing to %s\n", filename);
68 			exit(1);
69 		}
70 		bytes -= 2;
71 	}
72 	fclose(fp);
73 }
74 
75 int
76 main(int argc, char **argv) {
77 	unsigned int bytes;
78 	unsigned int k;
79 	char *endp;
80 	int c, i, n = 1;
81 	size_t len;
82 	char *name;
83 
84 	isc_commandline_errprint = ISC_FALSE;
85 
86 	while ((c = isc_commandline_parse(argc, argv, "hn:")) != EOF) {
87 		switch (c) {
88 		case 'n':
89 			n = strtol(isc_commandline_argument, &endp, 10);
90 			if ((*endp != 0) || (n <= 1) || (n > 9))
91 				usage();
92 			break;
93 
94 		case '?':
95 			if (isc_commandline_option != '?')
96 				fprintf(stderr, "%s: invalid argument -%c\n",
97 					program, isc_commandline_option);
98 			/* FALLTHROUGH */
99 		case 'h':
100 			usage();
101 
102 		default:
103 			fprintf(stderr, "%s: unhandled option -%c\n",
104 				program, isc_commandline_option);
105 			exit(1);
106 		}
107 	}
108 
109 	if (isc_commandline_index + 2 != argc)
110 		usage();
111 
112 	k = strtoul(argv[isc_commandline_index++], &endp, 10);
113 	if (*endp != 0)
114 		usage();
115 	bytes = k << 10;
116 
117 #ifndef HAVE_ARC4RANDOM
118 	srand(0x12345678);
119 #endif
120 	if (n == 1) {
121 		generate(argv[isc_commandline_index], bytes);
122 		return (0);
123 	}
124 
125 	len = strlen(argv[isc_commandline_index]);
126 	INSIST((len + 2) > len);
127 	len += 2;
128 	name = (char *) malloc(len);
129 	if (name == NULL) {
130 		perror("malloc");
131 		exit(1);
132 	}
133 
134 	for (i = 1; i <= n; i++) {
135 		snprintf(name, len, "%s%d", argv[isc_commandline_index], i);
136 		generate(name, bytes);
137 	}
138 	free(name);
139 
140 	return (0);
141 }
142