2 * gen_uuid.c --- generate a DCE-compatible uuid
4 * Copyright (C) 1999, Andreas Dilger and Theodore Ts'o
7 * This file may be redistributed under the terms of the GNU Public
19 #include "closestream.h"
23 static void __attribute__((__noreturn__
)) usage(void)
26 fputs(USAGE_HEADER
, out
);
28 _(" %s [options]\n"), program_invocation_short_name
);
30 fputs(USAGE_SEPARATOR
, out
);
31 fputs(_("Create a new UUID value.\n"), out
);
33 fputs(USAGE_OPTIONS
, out
);
34 fputs(_(" -r, --random generate random-based uuid\n"), out
);
35 fputs(_(" -t, --time generate time-based uuid\n"), out
);
36 fputs(_(" -n, --namespace <ns> generate hash-based uuid in this namespace\n"), out
);
37 printf(_(" available namespaces: %s\n"), "@dns @url @oid @x500");
38 fputs(_(" -N, --name <name> generate hash-based uuid from this name\n"), out
);
39 fputs(_(" -m, --md5 generate md5 hash\n"), out
);
40 fputs(_(" -C, --count <num> generate more uuids in loop\n"), out
);
41 fputs(_(" -s, --sha1 generate sha1 hash\n"), out
);
42 fputs(_(" -x, --hex interpret name as hex string\n"), out
);
43 fputs(USAGE_SEPARATOR
, out
);
44 printf(USAGE_HELP_OPTIONS(21));
45 printf(USAGE_MAN_TAIL("uuidgen(1)"));
49 static char *unhex(const char *value
, size_t *valuelen
)
54 if (*valuelen
% 2 != 0) {
56 warnx(_("not a valid hex string"));
57 errtryhelp(EXIT_FAILURE
);
60 value2
= malloc(*valuelen
/ 2 + 1);
62 for (x
= n
= 0; n
< *valuelen
; n
++) {
64 if ('0' <= c
&& c
<= '9')
66 else if (('a' <= c
&& c
<= 'f') || ('A' <= c
&& c
<= 'F'))
67 x
+= (c
- 'A' + 10) & 0xf;
86 main (int argc
, char *argv
[])
89 int do_type
= 0, is_hex
= 0;
90 char str
[UUID_STR_LEN
];
91 char *namespace = NULL
, *name
= NULL
;
94 unsigned int count
= 1, i
;
96 static const struct option longopts
[] = {
97 {"random", no_argument
, NULL
, 'r'},
98 {"time", no_argument
, NULL
, 't'},
99 {"version", no_argument
, NULL
, 'V'},
100 {"help", no_argument
, NULL
, 'h'},
101 {"namespace", required_argument
, NULL
, 'n'},
102 {"name", required_argument
, NULL
, 'N'},
103 {"md5", no_argument
, NULL
, 'm'},
104 {"count", required_argument
, NULL
, 'C'},
105 {"sha1", no_argument
, NULL
, 's'},
106 {"hex", no_argument
, NULL
, 'x'},
110 static const ul_excl_t excl
[] = {
113 { 'm', 'r', 's', 't' },
117 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
119 setlocale(LC_ALL
, "");
120 bindtextdomain(PACKAGE
, LOCALEDIR
);
122 close_stdout_atexit();
124 while ((c
= getopt_long(argc
, argv
, "C:rtVhn:N:msx", longopts
, NULL
)) != -1) {
126 err_exclusive_options(c
, longopts
, excl
, excl_st
);
130 do_type
= UUID_TYPE_DCE_TIME
;
133 do_type
= UUID_TYPE_DCE_RANDOM
;
142 do_type
= UUID_TYPE_DCE_MD5
;
145 count
= strtou32_or_err(optarg
, _("invalid count argument"));
148 do_type
= UUID_TYPE_DCE_SHA1
;
157 print_version(EXIT_SUCCESS
);
159 errtryhelp(EXIT_FAILURE
);
165 warnx(_("--namespace requires --name argument"));
166 errtryhelp(EXIT_FAILURE
);
168 if (do_type
!= UUID_TYPE_DCE_MD5
&& do_type
!= UUID_TYPE_DCE_SHA1
) {
169 warnx(_("--namespace requires --md5 or --sha1"));
170 errtryhelp(EXIT_FAILURE
);
174 warnx(_("--name requires --namespace argument"));
175 errtryhelp(EXIT_FAILURE
);
177 if (do_type
== UUID_TYPE_DCE_MD5
|| do_type
== UUID_TYPE_DCE_SHA1
) {
178 warnx(_("--md5 or --sha1 requires --namespace argument"));
179 errtryhelp(EXIT_FAILURE
);
184 namelen
= strlen(name
);
186 name
= unhex(name
, &namelen
);
189 for (i
= 0; i
< count
; i
++) {
191 case UUID_TYPE_DCE_TIME
:
192 uuid_generate_time(uu
);
194 case UUID_TYPE_DCE_RANDOM
:
195 uuid_generate_random(uu
);
197 case UUID_TYPE_DCE_MD5
:
198 case UUID_TYPE_DCE_SHA1
:
199 if (namespace[0] == '@' && namespace[1] != '\0') {
200 const uuid_t
*uuidptr
;
202 uuidptr
= uuid_get_template(&namespace[1]);
203 if (uuidptr
== NULL
) {
204 warnx(_("unknown namespace alias: '%s'"), namespace);
205 errtryhelp(EXIT_FAILURE
);
207 memcpy(ns
, *uuidptr
, sizeof(ns
));
209 if (uuid_parse(namespace, ns
) != 0) {
210 warnx(_("invalid uuid for namespace: '%s'"), namespace);
211 errtryhelp(EXIT_FAILURE
);
214 if (do_type
== UUID_TYPE_DCE_MD5
)
215 uuid_generate_md5(uu
, ns
, name
, namelen
);
217 uuid_generate_sha1(uu
, ns
, name
, namelen
);
224 uuid_unparse(uu
, str
);