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"
24 static void __attribute__((__noreturn__
)) usage(void)
27 fputs(USAGE_HEADER
, out
);
29 _(" %s [options]\n"), program_invocation_short_name
);
31 fputs(USAGE_SEPARATOR
, out
);
32 fputs(_("Create a new UUID value.\n"), out
);
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(_(" -x, --hex interpret name as hex string\n"), out
);
44 fputs(USAGE_SEPARATOR
, out
);
45 fprintf(out
, USAGE_HELP_OPTIONS(21));
46 fprintf(out
, USAGE_MAN_TAIL("uuidgen(1)"));
50 static char *unhex(const char *value
, size_t *valuelen
)
55 if (*valuelen
% 2 != 0) {
57 warnx(_("not a valid hex string"));
58 errtryhelp(EXIT_FAILURE
);
61 value2
= xmalloc(*valuelen
/ 2 + 1);
63 for (x
= n
= 0; n
< *valuelen
; n
++) {
65 if ('0' <= c
&& c
<= '9')
67 else if (('a' <= c
&& c
<= 'f') || ('A' <= c
&& c
<= 'F'))
68 x
+= (c
- 'A' + 10) & 0xf;
87 main (int argc
, char *argv
[])
90 int do_type
= 0, is_hex
= 0;
91 char str
[UUID_STR_LEN
];
92 char *namespace = NULL
, *name
= NULL
;
95 unsigned int count
= 1, i
;
97 static const struct option longopts
[] = {
98 {"random", no_argument
, NULL
, 'r'},
99 {"time", no_argument
, NULL
, 't'},
100 {"version", no_argument
, NULL
, 'V'},
101 {"help", no_argument
, NULL
, 'h'},
102 {"namespace", required_argument
, NULL
, 'n'},
103 {"name", required_argument
, NULL
, 'N'},
104 {"md5", no_argument
, NULL
, 'm'},
105 {"count", required_argument
, NULL
, 'C'},
106 {"sha1", no_argument
, NULL
, 's'},
107 {"hex", no_argument
, NULL
, 'x'},
111 static const ul_excl_t excl
[] = {
114 { 'm', 'r', 's', 't' },
118 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
120 setlocale(LC_ALL
, "");
121 bindtextdomain(PACKAGE
, LOCALEDIR
);
123 close_stdout_atexit();
125 while ((c
= getopt_long(argc
, argv
, "C:rtVhn:N:msx", longopts
, NULL
)) != -1) {
127 err_exclusive_options(c
, longopts
, excl
, excl_st
);
131 do_type
= UUID_TYPE_DCE_TIME
;
134 do_type
= UUID_TYPE_DCE_RANDOM
;
143 do_type
= UUID_TYPE_DCE_MD5
;
146 count
= strtou32_or_err(optarg
, _("invalid count argument"));
149 do_type
= UUID_TYPE_DCE_SHA1
;
158 print_version(EXIT_SUCCESS
);
160 errtryhelp(EXIT_FAILURE
);
166 warnx(_("--namespace requires --name argument"));
167 errtryhelp(EXIT_FAILURE
);
169 if (do_type
!= UUID_TYPE_DCE_MD5
&& do_type
!= UUID_TYPE_DCE_SHA1
) {
170 warnx(_("--namespace requires --md5 or --sha1"));
171 errtryhelp(EXIT_FAILURE
);
175 warnx(_("--name requires --namespace argument"));
176 errtryhelp(EXIT_FAILURE
);
178 if (do_type
== UUID_TYPE_DCE_MD5
|| do_type
== UUID_TYPE_DCE_SHA1
) {
179 warnx(_("--md5 or --sha1 requires --namespace argument"));
180 errtryhelp(EXIT_FAILURE
);
185 namelen
= strlen(name
);
187 name
= unhex(name
, &namelen
);
190 for (i
= 0; i
< count
; i
++) {
192 case UUID_TYPE_DCE_TIME
:
193 uuid_generate_time(uu
);
195 case UUID_TYPE_DCE_RANDOM
:
196 uuid_generate_random(uu
);
198 case UUID_TYPE_DCE_MD5
:
199 case UUID_TYPE_DCE_SHA1
:
200 if (namespace[0] == '@' && namespace[1] != '\0') {
201 const uuid_t
*uuidptr
;
203 uuidptr
= uuid_get_template(&namespace[1]);
204 if (uuidptr
== NULL
) {
205 warnx(_("unknown namespace alias: '%s'"), namespace);
206 errtryhelp(EXIT_FAILURE
);
208 memcpy(ns
, *uuidptr
, sizeof(ns
));
210 if (uuid_parse(namespace, ns
) != 0) {
211 warnx(_("invalid uuid for namespace: '%s'"), namespace);
212 errtryhelp(EXIT_FAILURE
);
215 if (do_type
== UUID_TYPE_DCE_MD5
)
216 uuid_generate_md5(uu
, ns
, name
, namelen
);
218 uuid_generate_sha1(uu
, ns
, name
, namelen
);
225 uuid_unparse(uu
, str
);