diff options
-rw-r--r-- | bin/uuidgen/Makefile | 6 | ||||
-rw-r--r-- | bin/uuidgen/uuidgen.1 | 71 | ||||
-rw-r--r-- | bin/uuidgen/uuidgen.c | 113 | ||||
-rw-r--r-- | lib/libc/sys/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/sys/uuidgen.2 | 83 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/kern/init_sysent.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_uuid.c | 222 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 3 | ||||
-rw-r--r-- | sys/sys/syscall.h | 5 | ||||
-rw-r--r-- | sys/sys/syscall.mk | 5 | ||||
-rw-r--r-- | sys/sys/sysproto.h | 7 | ||||
-rw-r--r-- | sys/sys/uuid.h | 70 | ||||
-rw-r--r-- | usr.bin/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/uuidgen/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/uuidgen/uuidgen.1 | 71 | ||||
-rw-r--r-- | usr.bin/uuidgen/uuidgen.c | 113 |
17 files changed, 774 insertions, 8 deletions
diff --git a/bin/uuidgen/Makefile b/bin/uuidgen/Makefile new file mode 100644 index 0000000..81459e2 --- /dev/null +++ b/bin/uuidgen/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= uuidgen +WARNS?= 4 + +.include <bsd.prog.mk> diff --git a/bin/uuidgen/uuidgen.1 b/bin/uuidgen/uuidgen.1 new file mode 100644 index 0000000..d61f848 --- /dev/null +++ b/bin/uuidgen/uuidgen.1 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2002 Marcel Moolenaar +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 23, 2002 +.Dt UUIDGEN 1 +.Os +.Sh NAME +.Nm uuidgen +.Nd generate universally unique identifiers +.Sh SYNOPSIS +.Nm +.Op Fl 1 +.Op Fl n Ar count +.Sh DESCRIPTION +The +.Nm +utility by default generates a single universally unique identifier (UUID), +also known as a globally unique identifier (GUID). The UUID is written to +stdout. The following options can be used to change the number of identifiers +and the method used: +.Bl -tag -width indent +.It Fl 1 +This option only has effect if multiple identifiers are to be generated and +instructs +.Nm +to not generate them in batch, but one at a time. +.It Fl n +This option controls the number of identifiers generated. By default, multiple +identifiers are generated in batch. +.El +.Pp +Batched generation yields a dense set of identifiers in such a way that there +is no identifier that is larger than the smallest identifier in the set and +smaller than the largest identifier in the set and that is not already in the +set. +.Pp +When generating the identifiers one at a time, the identifiers will be close +to each other, but operating system latency and processing time will be +reflected in the distance between two successive identifiers. +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr uuidgen 2 +.Sh HISTORY +The +.Nm +command first appeared in +.Fx 5.0 . diff --git a/bin/uuidgen/uuidgen.c b/bin/uuidgen/uuidgen.c new file mode 100644 index 0000000..59fd446 --- /dev/null +++ b/bin/uuidgen/uuidgen.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2002 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/endian.h> +#include <sys/uuid.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static void +usage(void) +{ + (void)fprintf(stderr, "usage: uuidgen [-1] [-n count]\n"); + exit(1); +} + +static void +uuid_print(uuid_t *uuid) +{ + printf("%08x-%04x-%04x-%02x%02x-", uuid->time_low, uuid->time_mid, + uuid->time_hi_and_version, uuid->clock_seq_hi_and_reserved, + uuid->clock_seq_low); + printf("%02x%02x%02x%02x%02x%02x\n", uuid->node[0], uuid->node[1], + uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); +} + +int +main(int argc, char *argv[]) +{ + uuid_t *store, *uuid; + char *p; + int ch, count, i, iterate; + + count = -1; /* no count yet */ + iterate = 0; /* not one at a time */ + while ((ch = getopt(argc, argv, "1n:")) != -1) + switch (ch) { + case '1': + iterate = 1; + break; + case 'n': + if (count > 0) + usage(); + count = strtol(optarg, &p, 10); + if (*p != 0 || count < 1) + usage(); + break; + default: + usage(); + } + argv += optind; + argc -= optind; + + if (argc) + usage(); + + if (count == -1) + count = 1; + + store = (uuid_t*)malloc(sizeof(uuid_t) * count); + if (store == NULL) + err(1, "malloc()"); + + if (!iterate) { + /* Get them all in a single batch */ + if (uuidgen(store, count) != 0) + err(1, "uuidgen()"); + } else { + uuid = store; + for (i = 0; i < count; i++) { + if (uuidgen(uuid++, 1) != 0) + err(1, "uuidgen()"); + } + } + + uuid = store; + while (count--) + uuid_print(uuid++); + + free(store); + return (0); +} diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 5f78b60..5133fff 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -81,7 +81,7 @@ MAN+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \ sigstack.2 sigsuspend.2 socket.2 socketpair.2 stat.2 statfs.2 \ swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \ truncate.2 umask.2 undelete.2 \ - unlink.2 utimes.2 vfork.2 wait.2 write.2 + unlink.2 utimes.2 uuidgen.2 vfork.2 wait.2 write.2 .if !defined(NO_P1003_1B) MAN+= sched_get_priority_max.2 sched_setparam.2 \ sched_setscheduler.2 sched_yield.2 diff --git a/lib/libc/sys/uuidgen.2 b/lib/libc/sys/uuidgen.2 new file mode 100644 index 0000000..9d6a522 --- /dev/null +++ b/lib/libc/sys/uuidgen.2 @@ -0,0 +1,83 @@ +.\" Copyright (c) 2002 Marcel Moolenaar +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 26, 2002 +.Dt UUIDGEN 2 +.Os +.Sh NAME +.Nm uuidgen +.Nd generate universally unique identifiers +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/uuid.h +.Ft int +.Fn uuidgen "uuid_t *store" "int count" +.Sh DESCRIPTION +The +.Nm +system call generates +.Fa count +universally unique identifiers (UUIDs) and writes them to the buffer +pointed to by +.Fa store . +The identifiers are generated according to the syntax and semantics of the +DCE version 1 variant of universally unique identifiers. When no IEEE 802 +address is available for the node field a random multicast address is +generated for each call. +.Pp +When multiple identifiers are requested, the +.Nm +system call will generate identifiers that are adjacent in time. +.Pp +Universally unique identifiers, also known as globally unique identifiers, +are normally represented as: +.Bd -literal -offset indent +63d81915-7140-11d6-903d-00022d09712b +.Ed +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The +.Nm +system call can fail with: +.Bl -tag -width Er +.It Bq Er EFAULT +The buffer pointed to by +.Fa store +could not be written to for any or all identifiers. +.It Bq Er EINVAL +The +.Fa count +parameter is less than 1 or larger than the hard upper limit of 2048. +.El +.Sh SEE ALSO +.Xr uuidgen 1 +.Sh HISTORY +The +.Nm +system call first appeared in +.Fx 5.0 . diff --git a/sys/conf/files b/sys/conf/files index 7a67183..6e3e365 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -863,6 +863,7 @@ kern/kern_sysctl.c standard kern/kern_tc.c standard kern/kern_time.c standard kern/kern_timeout.c standard +kern/kern_uuid.c standard kern/kern_xxx.c standard kern/link_elf.c standard kern/md5c.c standard diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 567ce4b..2dc7bc3 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.111 2002/05/05 23:37:44 mux Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.112 2002/05/28 05:58:06 marcel Exp */ #include "opt_compat.h" @@ -414,4 +414,5 @@ struct sysent sysent[] = { { 0, (sy_call_t *)nosys }, /* 389 = __mac_set_file */ { AS(kenv_args), (sy_call_t *)kenv }, /* 390 = kenv */ { AS(lchflags_args), (sy_call_t *)lchflags }, /* 391 = lchflags */ + { AS(uuidgen_args), (sy_call_t *)uuidgen }, /* 392 = uuidgen */ }; diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c new file mode 100644 index 0000000..ba5faa5 --- /dev/null +++ b/sys/kern/kern_uuid.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2002 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/endian.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/sbuf.h> +#include <sys/socket.h> +#include <sys/sysproto.h> +#include <sys/uuid.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> + +/* + * See also: + * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt + * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm + * + * Note that the generator state is itself an UUID, but the time and clock + * sequence fields are written in the native byte order. + */ + +CTASSERT(sizeof(struct uuid) == 16); + +/* We use an alternative, more convenient representation in the generator. */ +struct uuid_private { + union { + uint64_t ll; /* internal. */ + struct { + uint32_t low; + uint16_t mid; + uint16_t hi; + } x; + } time; + uint16_t seq; /* Big-endian. */ + uint16_t node[UUID_NODE_LEN>>1]; +}; + +CTASSERT(sizeof(struct uuid_private) == 16); + +static struct uuid_private uuid_last; + +static struct mtx uuid_mutex; +MTX_SYSINIT(uuid_lock, &uuid_mutex, "UUID generator mutex lock", MTX_DEF); + +/* + * Return the first MAC address we encounter or, if none was found, + * construct a sufficiently random multicast address. We don't try + * to return the same MAC address as previously returned. We always + * generate a new multicast address if no MAC address exists in the + * system. + * It would be nice to know if 'ifnet' or any of its sub-structures + * has been changed in any way. If not, we could simply skip the + * scan and safely return the MAC address we returned before. + */ +static void +uuid_node(uint16_t *node) +{ + struct ifnet *ifp; + struct ifaddr *ifa; + struct sockaddr_dl *sdl; + int i; + + /* XXX: lock ifnet. */ + TAILQ_FOREACH(ifp, &ifnet, if_link) { + /* Walk the address list */ + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + sdl = (struct sockaddr_dl*)ifa->ifa_addr; + if (sdl != NULL && sdl->sdl_family == AF_LINK && + sdl->sdl_type == IFT_ETHER) { + /* Got a MAC address. */ + bcopy(LLADDR(sdl), node, UUID_NODE_LEN); + /* XXX: unlock ifnet. */ + return; + } + } + } + /* XXX: unlock ifnet. */ + + for (i = 0; i < (UUID_NODE_LEN>>1); i++) + node[i] = (uint16_t)arc4random(); + *((uint8_t*)node) |= 0x80; +} + +/* + * Get the current time as a 60 bit count of 100-nanosecond intervals + * since 00:00:00.00, October 15,1582. We apply a magic offset to convert + * the Unix time since 00:00:00.00, Januari 1, 1970 to the date of the + * Gregorian reform to the Christian calendar. + */ +static uint64_t +uuid_time(void) +{ + struct bintime bt; + uint64_t time = 0x01B21DD213814000LL; + + bintime(&bt); + time += (uint64_t)bt.sec * 10000000LL; + time += (10000000LL * (uint32_t)(bt.frac >> 32)) >> 32; + return (time & ((1LL << 60) - 1LL)); +} + +#ifndef _SYS_SYSPROTO_H_ +struct uuidgen_args { + struct uuid *store; + int count; +}; +#endif + +int uuidgen(struct thread *td, struct uuidgen_args *uap) +{ + struct uuid_private uuid; + uint64_t time; + int error; + + /* + * Limit the number of UUIDs that can be created at the same time + * to some arbitrary number. This isn't really necessary, but I + * like to have some sort of upper-bound that's less than 2G :-) + * XXX needs to be tunable. + */ + if (uap->count < 1 || uap->count > 2048) + return (EINVAL); + + /* XXX: pre-validate accessibility to the whole of the UUID store? */ + + mtx_lock(&uuid_mutex); + + uuid_node(uuid.node); + time = uuid_time(); + + if (uuid_last.time.ll == 0LL || uuid_last.node[0] != uuid.node[0] || + uuid_last.node[1] != uuid.node[1] || + uuid_last.node[2] != uuid.node[2]) + uuid.seq = (uint16_t)arc4random() & 0x3fff; + else if (uuid_last.time.ll >= time) + uuid.seq = (uuid_last.seq + 1) & 0x3fff; + else + uuid.seq = uuid_last.seq; + + uuid_last = uuid; + uuid_last.time.ll = (time + uap->count - 1) & ((1LL << 60) - 1LL); + + mtx_unlock(&uuid_mutex); + + /* Set sequence and variant and deal with byte order. */ + uuid.seq = htobe16(uuid.seq | 0x8000); + + /* XXX: this should copyout larger chunks at a time. */ + do { + /* Set time and version (=1) and deal with byte order. */ + uuid.time.x.low = (uint32_t)time; + uuid.time.x.mid = (uint16_t)(time >> 32); + uuid.time.x.hi = ((uint16_t)(time >> 48) & 0xfff) | (1 << 12); + error = copyout(&uuid, uap->store, sizeof(uuid)); + uap->store++; + uap->count--; + time++; + } while (uap->count > 0 && !error); + + return (error); +} + +int +snprintf_uuid(char *buf, size_t sz, struct uuid *uuid) +{ + struct uuid_private *id; + int cnt; + + id = (struct uuid_private *)uuid; + cnt = snprintf(buf, sz, "%08x-%04x-%04x-%04x-%04x%04x%04x", + id->time.x.low, id->time.x.mid, id->time.x.hi, be16toh(id->seq), + be16toh(id->node[0]), be16toh(id->node[1]), be16toh(id->node[2])); + return (cnt); +} + +int +printf_uuid(struct uuid *uuid) +{ + char buf[38]; + + snprintf_uuid(buf, sizeof(buf), uuid); + return (printf("%s", buf)); +} + +int +sbuf_printf_uuid(struct sbuf *sb, struct uuid *uuid) +{ + char buf[38]; + + snprintf_uuid(buf, sizeof(buf), uuid); + return (sbuf_printf(sb, "%s", buf)); +} diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 7b0b49e..c555aca 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.111 2002/05/05 23:37:44 mux Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.112 2002/05/28 05:58:06 marcel Exp */ char *syscallnames[] = { @@ -399,4 +399,5 @@ char *syscallnames[] = { "#389", /* 389 = __mac_set_file */ "kenv", /* 390 = kenv */ "lchflags", /* 391 = lchflags */ + "uuidgen", /* 392 = uuidgen */ }; diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 31c0c9a..6fd04f3 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.111 2002/05/05 23:37:44 mux Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.112 2002/05/28 05:58:06 marcel Exp */ #define SYS_syscall 0 @@ -305,4 +305,5 @@ #define SYS_kse_yield 383 #define SYS_kenv 390 #define SYS_lchflags 391 -#define SYS_MAXSYSCALL 392 +#define SYS_uuidgen 392 +#define SYS_MAXSYSCALL 393 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index d269daf..193e7cc 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: src/sys/kern/syscalls.master,v 1.111 2002/05/05 23:37:44 mux Exp +# created from FreeBSD: src/sys/kern/syscalls.master,v 1.112 2002/05/28 05:58:06 marcel Exp MIASM = \ syscall.o \ exit.o \ @@ -254,4 +254,5 @@ MIASM = \ thread_wakeup.o \ kse_yield.o \ kenv.o \ - lchflags.o + lchflags.o \ + uuidgen.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 011dc92..57c6b7f 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.111 2002/05/05 23:37:44 mux Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.112 2002/05/28 05:58:06 marcel Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -1115,6 +1115,10 @@ struct lchflags_args { char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; }; +struct uuidgen_args { + char store_l_[PADL_(struct uuid *)]; struct uuid * store; char store_r_[PADR_(struct uuid *)]; + char count_l_[PADL_(int)]; int count; char count_r_[PADR_(int)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_exit(struct thread *, struct sys_exit_args *); int fork(struct thread *, struct fork_args *); @@ -1366,6 +1370,7 @@ int thread_wakeup(struct thread *, struct thread_wakeup_args *); int kse_yield(struct thread *, struct kse_yield_args *); int kenv(struct thread *, struct kenv_args *); int lchflags(struct thread *, struct lchflags_args *); +int uuidgen(struct thread *, struct uuidgen_args *); #ifdef COMPAT_43 diff --git a/sys/sys/uuid.h b/sys/sys/uuid.h new file mode 100644 index 0000000..155f909 --- /dev/null +++ b/sys/sys/uuid.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2002 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_UUID_H_ +#define _SYS_UUID_H_ + +/* Length of a node address (an IEEE 802 address). */ +#define _UUID_NODE_LEN 6 + +/* + * See also: + * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt + * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm + * + * A DCE 1.1 compatible source representation of UUIDs. + */ +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[_UUID_NODE_LEN]; +}; + +#ifdef _KERNEL + +#define UUID_NODE_LEN _UUID_NODE_LEN + +struct sbuf; + +int snprintf_uuid(char *, size_t, struct uuid *); +int printf_uuid(struct uuid *); +int sbuf_printf_uuid(struct sbuf *, struct uuid *); + +#else /* _KERNEL */ + +/* XXX namespace pollution? */ +typedef struct uuid uuid_t; + +int uuidgen(struct uuid *, int); + +#endif /* _KERNEL */ + +#endif /* _SYS_UUID_H_ */ diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 892eb41..f49bbbc 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -178,6 +178,7 @@ SUBDIR= apply \ users \ uudecode \ uuencode \ + uuidgen \ vgrind \ vi \ vis \ diff --git a/usr.bin/uuidgen/Makefile b/usr.bin/uuidgen/Makefile new file mode 100644 index 0000000..81459e2 --- /dev/null +++ b/usr.bin/uuidgen/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= uuidgen +WARNS?= 4 + +.include <bsd.prog.mk> diff --git a/usr.bin/uuidgen/uuidgen.1 b/usr.bin/uuidgen/uuidgen.1 new file mode 100644 index 0000000..d61f848 --- /dev/null +++ b/usr.bin/uuidgen/uuidgen.1 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2002 Marcel Moolenaar +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 23, 2002 +.Dt UUIDGEN 1 +.Os +.Sh NAME +.Nm uuidgen +.Nd generate universally unique identifiers +.Sh SYNOPSIS +.Nm +.Op Fl 1 +.Op Fl n Ar count +.Sh DESCRIPTION +The +.Nm +utility by default generates a single universally unique identifier (UUID), +also known as a globally unique identifier (GUID). The UUID is written to +stdout. The following options can be used to change the number of identifiers +and the method used: +.Bl -tag -width indent +.It Fl 1 +This option only has effect if multiple identifiers are to be generated and +instructs +.Nm +to not generate them in batch, but one at a time. +.It Fl n +This option controls the number of identifiers generated. By default, multiple +identifiers are generated in batch. +.El +.Pp +Batched generation yields a dense set of identifiers in such a way that there +is no identifier that is larger than the smallest identifier in the set and +smaller than the largest identifier in the set and that is not already in the +set. +.Pp +When generating the identifiers one at a time, the identifiers will be close +to each other, but operating system latency and processing time will be +reflected in the distance between two successive identifiers. +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr uuidgen 2 +.Sh HISTORY +The +.Nm +command first appeared in +.Fx 5.0 . diff --git a/usr.bin/uuidgen/uuidgen.c b/usr.bin/uuidgen/uuidgen.c new file mode 100644 index 0000000..59fd446 --- /dev/null +++ b/usr.bin/uuidgen/uuidgen.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2002 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/endian.h> +#include <sys/uuid.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static void +usage(void) +{ + (void)fprintf(stderr, "usage: uuidgen [-1] [-n count]\n"); + exit(1); +} + +static void +uuid_print(uuid_t *uuid) +{ + printf("%08x-%04x-%04x-%02x%02x-", uuid->time_low, uuid->time_mid, + uuid->time_hi_and_version, uuid->clock_seq_hi_and_reserved, + uuid->clock_seq_low); + printf("%02x%02x%02x%02x%02x%02x\n", uuid->node[0], uuid->node[1], + uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); +} + +int +main(int argc, char *argv[]) +{ + uuid_t *store, *uuid; + char *p; + int ch, count, i, iterate; + + count = -1; /* no count yet */ + iterate = 0; /* not one at a time */ + while ((ch = getopt(argc, argv, "1n:")) != -1) + switch (ch) { + case '1': + iterate = 1; + break; + case 'n': + if (count > 0) + usage(); + count = strtol(optarg, &p, 10); + if (*p != 0 || count < 1) + usage(); + break; + default: + usage(); + } + argv += optind; + argc -= optind; + + if (argc) + usage(); + + if (count == -1) + count = 1; + + store = (uuid_t*)malloc(sizeof(uuid_t) * count); + if (store == NULL) + err(1, "malloc()"); + + if (!iterate) { + /* Get them all in a single batch */ + if (uuidgen(store, count) != 0) + err(1, "uuidgen()"); + } else { + uuid = store; + for (i = 0; i < count; i++) { + if (uuidgen(uuid++, 1) != 0) + err(1, "uuidgen()"); + } + } + + uuid = store; + while (count--) + uuid_print(uuid++); + + free(store); + return (0); +} |