]> git.ipfire.org Git - thirdparty/util-linux.git/blame_incremental - misc-utils/uuidgen.c
lib/path: avoid double free() for cpusets
[thirdparty/util-linux.git] / misc-utils / uuidgen.c
... / ...
CommitLineData
1/*
2 * gen_uuid.c --- generate a DCE-compatible uuid
3 *
4 * Copyright (C) 1999, Andreas Dilger and Theodore Ts'o
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the
8 * GNU General Public License.
9 * %End-Header%
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <getopt.h>
15
16#include "uuid.h"
17#include "nls.h"
18#include "c.h"
19#include "closestream.h"
20#include "strutils.h"
21#include "optutils.h"
22#include "xalloc.h"
23
24static void __attribute__((__noreturn__)) usage(void)
25{
26 FILE *out = stdout;
27 fputs(USAGE_HEADER, out);
28 fprintf(out,
29 _(" %s [options]\n"), program_invocation_short_name);
30
31 fputs(USAGE_SEPARATOR, out);
32 fputs(_("Create a new UUID value.\n"), out);
33
34 fputs(USAGE_OPTIONS, out);
35 fputs(_(" -r, --random generate random-based uuid\n"), out);
36 fputs(_(" -t, --time generate time-based uuid\n"), out);
37 fputs(_(" -n, --namespace <ns> generate hash-based uuid in this namespace\n"), out);
38 fprintf(out, _(" available namespaces: %s\n"), "@dns @url @oid @x500");
39 fputs(_(" -N, --name <name> generate hash-based uuid from this name\n"), out);
40 fputs(_(" -m, --md5 generate md5 hash\n"), out);
41 fputs(_(" -C, --count <num> generate more uuids in loop\n"), out);
42 fputs(_(" -s, --sha1 generate sha1 hash\n"), out);
43 fputs(_(" -6, --time-v6 generate time-based v6 uuid\n"), out);
44 fputs(_(" -7, --time-v7 generate time-based v7 uuid\n"), out);
45 fputs(_(" -x, --hex interpret name as hex string\n"), out);
46 fputs(USAGE_SEPARATOR, out);
47 fprintf(out, USAGE_HELP_OPTIONS(21));
48 fprintf(out, USAGE_MAN_TAIL("uuidgen(1)"));
49 exit(EXIT_SUCCESS);
50}
51
52static char *unhex(const char *value, size_t *valuelen)
53{
54 char c, *value2;
55 unsigned n, x;
56
57 if (*valuelen % 2 != 0) {
58badstring:
59 warnx(_("not a valid hex string"));
60 errtryhelp(EXIT_FAILURE);
61 }
62
63 value2 = xmalloc(*valuelen / 2 + 1);
64
65 for (x = n = 0; n < *valuelen; n++) {
66 c = value[n];
67 if ('0' <= c && c <= '9')
68 x += c - '0';
69 else if (('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))
70 x += (c - 'A' + 10) & 0xf;
71 else
72 goto badstring;
73
74 if (n % 2 == 0)
75 x *= 16;
76 else {
77 value2[n / 2] = x;
78 x = 0;
79 }
80 }
81 value2[n / 2] = '\0';
82
83 *valuelen = (n / 2);
84
85 return value2;
86}
87
88int
89main (int argc, char *argv[])
90{
91 int c;
92 int do_type = 0, is_hex = 0;
93 char str[UUID_STR_LEN];
94 char *namespace = NULL, *name = NULL;
95 size_t namelen = 0;
96 uuid_t ns, uu;
97 unsigned int count = 1, i;
98
99 static const struct option longopts[] = {
100 {"random", no_argument, NULL, 'r'},
101 {"time", no_argument, NULL, 't'},
102 {"version", no_argument, NULL, 'V'},
103 {"help", no_argument, NULL, 'h'},
104 {"namespace", required_argument, NULL, 'n'},
105 {"name", required_argument, NULL, 'N'},
106 {"md5", no_argument, NULL, 'm'},
107 {"count", required_argument, NULL, 'C'},
108 {"sha1", no_argument, NULL, 's'},
109 {"time-v6", no_argument, NULL, '6'},
110 {"time-v7", no_argument, NULL, '7'},
111 {"hex", no_argument, NULL, 'x'},
112 {NULL, 0, NULL, 0}
113 };
114
115 static const ul_excl_t excl[] = {
116 { '6', '7', 'm', 'r', 's', 't' },
117 { 'C', 'm', 's' },
118 { 'N', 'r', 't' },
119 { 'n', 'r', 't' },
120 { 0 }
121 };
122 int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
123
124 setlocale(LC_ALL, "");
125 bindtextdomain(PACKAGE, LOCALEDIR);
126 textdomain(PACKAGE);
127 close_stdout_atexit();
128
129 while ((c = getopt_long(argc, argv, "C:rtVhn:N:msx67", longopts, NULL)) != -1) {
130
131 err_exclusive_options(c, longopts, excl, excl_st);
132
133 switch (c) {
134 case 't':
135 do_type = UUID_TYPE_DCE_TIME;
136 break;
137 case 'r':
138 do_type = UUID_TYPE_DCE_RANDOM;
139 break;
140 case 'n':
141 namespace = optarg;
142 break;
143 case 'N':
144 name = optarg;
145 break;
146 case 'm':
147 do_type = UUID_TYPE_DCE_MD5;
148 break;
149 case 'C':
150 count = strtou32_or_err(optarg, _("invalid count argument"));
151 break;
152 case 's':
153 do_type = UUID_TYPE_DCE_SHA1;
154 break;
155 case 'x':
156 is_hex = 1;
157 break;
158 case '6':
159 do_type = UUID_TYPE_DCE_TIME_V6;
160 break;
161 case '7':
162 do_type = UUID_TYPE_DCE_TIME_V7;
163 break;
164
165 case 'h':
166 usage();
167 case 'V':
168 print_version(EXIT_SUCCESS);
169 default:
170 errtryhelp(EXIT_FAILURE);
171 }
172 }
173
174 if (namespace) {
175 if (!name) {
176 warnx(_("--namespace requires --name argument"));
177 errtryhelp(EXIT_FAILURE);
178 }
179 if (do_type != UUID_TYPE_DCE_MD5 && do_type != UUID_TYPE_DCE_SHA1) {
180 warnx(_("--namespace requires --md5 or --sha1"));
181 errtryhelp(EXIT_FAILURE);
182 }
183 } else {
184 if (name) {
185 warnx(_("--name requires --namespace argument"));
186 errtryhelp(EXIT_FAILURE);
187 }
188 if (do_type == UUID_TYPE_DCE_MD5 || do_type == UUID_TYPE_DCE_SHA1) {
189 warnx(_("--md5 or --sha1 requires --namespace argument"));
190 errtryhelp(EXIT_FAILURE);
191 }
192 }
193
194 if (name) {
195 namelen = strlen(name);
196 if (is_hex)
197 name = unhex(name, &namelen);
198 }
199
200 for (i = 0; i < count; i++) {
201 switch (do_type) {
202 case UUID_TYPE_DCE_TIME:
203 uuid_generate_time(uu);
204 break;
205 case UUID_TYPE_DCE_TIME_V6:
206 uuid_generate_time_v6(uu);
207 break;
208 case UUID_TYPE_DCE_TIME_V7:
209 uuid_generate_time_v7(uu);
210 break;
211 case UUID_TYPE_DCE_RANDOM:
212 uuid_generate_random(uu);
213 break;
214 case UUID_TYPE_DCE_MD5:
215 case UUID_TYPE_DCE_SHA1:
216 if (namespace[0] == '@' && namespace[1] != '\0') {
217 const uuid_t *uuidptr;
218
219 uuidptr = uuid_get_template(&namespace[1]);
220 if (uuidptr == NULL) {
221 warnx(_("unknown namespace alias: '%s'"), namespace);
222 errtryhelp(EXIT_FAILURE);
223 }
224 memcpy(ns, *uuidptr, sizeof(ns));
225 } else {
226 if (uuid_parse(namespace, ns) != 0) {
227 warnx(_("invalid uuid for namespace: '%s'"), namespace);
228 errtryhelp(EXIT_FAILURE);
229 }
230 }
231 if (do_type == UUID_TYPE_DCE_MD5)
232 uuid_generate_md5(uu, ns, name, namelen);
233 else
234 uuid_generate_sha1(uu, ns, name, namelen);
235 break;
236 default:
237 uuid_generate(uu);
238 break;
239 }
240
241 uuid_unparse(uu, str);
242
243 printf("%s\n", str);
244 }
245
246 if (is_hex)
247 free(name);
248
249 return EXIT_SUCCESS;
250}