--- /dev/null
+.TH uuidgen 1 "Tue Sep 23 09:54:24 UTC 2014"
+.SH NAME
+
+uuidgen - command line utility for generating uuids
+
+.SH SYNOPSIS
+
+uuidgen [-tvnqODUX]
+
+uuidgen [-n ns | -UXD] name ...
+
+.SH DESCRIPTION
+
+This program generates uuids and writes their canonical string representation
+to stdout.
+
+.SH OPTIONS
+
+.TP
+.BI \-r
+Generate a version 4 random uuid.
+.TP
+.BI \-t
+Generate a version 1 timestamp based uuid
+.TP
+.B \-n " namespace | oid | dns | x500 | url"
+set the namespace for version 3 or version 5 uuids
+.TP
+.B \-q num
+Specify how many uuids to generate for version 1 and 4 uuids. UUIDs will
+be output one per line on stdout.
+.TP
+.B \-h
+Write a help message to stdout and exit.
+
+.SH DIAGNOSTICS
+
+The program will exit 0 on success, and non zero on failure. Running
+witht the \-h or \-V switches will write the appropriate message
+to stdout and exit successfully.
+
+Errors will generate a message to stderr and nothing to stdout, as
+well as exiting non-zero.
+
+.SH BUGS
+
+.SH AUTHOR
+
+Nathan Wagner
+.I
+<nw@hydaspes.if.org>
+
+.SH COPYRIGHT
+
+None. Program is in the public domain.
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "pduuid.h"
+
+void print_help() {
+ printf("uuidgen [-rthV]\n");
+}
+void print_version() {
+ printf("uuidgen version 1.0\n");
+}
+
+int main(int ac, char *av[]) {
+ pd_uuid_t u; /* generated uuid */
+ pd_uuid_t nsuuid; /* namespace uuid */
+ pd_uuid_t *nsid = 0; /* pointer to namespace uuid */
+ char *ns; /* literal ns id string */
+
+ struct pd_uuid_state s;
+ char uuid[PD_UUID_STRLEN+1];
+ int q = 1;
+ int opt;
+ int mode = 4;
+ int i;
+
+ /*
+ * V = version
+ * h = help
+ * q = quantity
+ *
+ * t = time, v1
+ * T = time with random mac
+ * r = random, v4
+ * m = md5 ns, v3
+ * s = sha1 ns, v5
+ * v2 isn't used
+ * v = set version
+ *
+ * n = namespace
+ * D = DNS ns
+ * U = URL ns
+ * O = OID ns
+ * X = X.500 ns
+ */
+
+ while ((opt = getopt(ac, av, "Vhq:tTrmsv:n:DUOX")) != -1) {
+ switch (opt) {
+ case 'n':
+ ns = optarg;
+ if (mode != 3 && mode != 5) mode = 5;
+ break;
+ case 'D':
+ nsid = &pd_uuid_ns_dns;
+ break;
+ case 'U':
+ nsid = &pd_uuid_ns_url;
+ break;
+ case 'O':
+ nsid = &pd_uuid_ns_oid;
+ break;
+ case 'X':
+ nsid = &pd_uuid_ns_x500;
+ break;
+ case 'r':
+ mode = 4;
+ break;
+ case 't':
+ mode = 1;
+ break;
+ case 'm':
+ mode = 3;
+ break;
+ case 's':
+ mode = 5;
+ break;
+ case 'T':
+ mode = -1;
+ break;
+ case 'h':
+ print_help();
+ exit(EXIT_SUCCESS);
+ break;
+ case 'v':
+ mode = atoi(optarg);
+ break;
+ case 'V':
+ print_version();
+ exit(EXIT_SUCCESS);
+ break;
+ case 'q':
+ q = atoi(optarg);
+ break;
+ default:
+ fprintf(stderr,
+ "uuidgen: unknown option '%c'\n",
+ opt);
+ print_help();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ pd_uuid_init_state(&s);
+
+ if (mode == 3 || mode == 5) {
+ /* TODO warn if q != 1 */
+ int len;
+ if (!nsid) {
+ if (!strcmp(ns, "dns")) {
+ nsid = &pd_uuid_ns_dns;
+ } else if (!strcmp(ns, "url")) {
+ nsid = &pd_uuid_ns_url;
+ } else if (!strcmp(ns, "oid")) {
+ nsid = &pd_uuid_ns_oid;
+ } else if (!strcmp(ns, "x500")) {
+ nsid = &pd_uuid_ns_x500;
+ } else {
+ nsid = &nsuuid;
+ if (pd_uuid_set_string(nsid, ns) != 0) {
+ fprintf(stderr, "malformed ns uuid: %s\n", ns);
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ for (i = optind; i < ac; i++) {
+ len = strlen(av[i]);
+ if (mode == 3) {
+ pd_uuid_get_string(nsid, uuid);
+ pd_uuid_make_v3(0, &u, nsid, av[i], len);
+ } else {
+ pd_uuid_make_v5(&s, &u, nsid, av[i], len);
+ }
+ pd_uuid_get_string(&u, uuid);
+ printf("%s\n", uuid);
+ }
+ exit(EXIT_SUCCESS);
+ }
+
+ while (q--) {
+ switch (mode) {
+ case -1:
+ pd_uuid_make_v1mc(&s, &u);
+ break;
+ case 1:
+ pd_uuid_make_v1(&s, &u);
+ break;
+ case 4:
+ pd_uuid_make_v4(&s, &u);
+ break;
+ default:
+ fprintf(stderr,
+ "uuidgen: unknown uuid version '%d'\n",
+ mode);
+ exit(EXIT_FAILURE);
+ }
+ pd_uuid_get_string(&u, uuid);
+ printf("%s\n", uuid);
+ }
+
+ return 0;
+
+}