Bring uuidgen(3) into libc and implement the uuidgen() system call.
authorMatthew Dillon <dillon@dragonflybsd.org>
Sat, 16 Jun 2007 19:57:14 +0000 (19:57 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sat, 16 Jun 2007 19:57:14 +0000 (19:57 +0000)
Obtained-from: FreeBSD / Marcel Moolenaar

18 files changed:
include/Makefile
include/uuid.h [new file with mode: 0644]
lib/libc/Makefile.inc
lib/libc/sys/uuidgen.2 [new file with mode: 0644]
lib/libc/uuid/Makefile.inc [new file with mode: 0644]
lib/libc/uuid/Symbol.map [new file with mode: 0644]
lib/libc/uuid/uuid.3 [new file with mode: 0644]
lib/libc/uuid/uuid_compare.c [new file with mode: 0644]
lib/libc/uuid/uuid_create.c [new file with mode: 0644]
lib/libc/uuid/uuid_create_nil.c [new file with mode: 0644]
lib/libc/uuid/uuid_equal.c [new file with mode: 0644]
lib/libc/uuid/uuid_from_string.c [new file with mode: 0644]
lib/libc/uuid/uuid_hash.c [new file with mode: 0644]
lib/libc/uuid/uuid_is_nil.c [new file with mode: 0644]
lib/libc/uuid/uuid_to_string.c [new file with mode: 0644]
sys/kern/kern_uuid.c
sys/sys/kern_syscall.h
sys/sys/uuid.h

index db74c77..8c0bdf9 100644 (file)
@@ -1,6 +1,6 @@
 #      @(#)Makefile    8.2 (Berkeley) 1/4/94
 # $FreeBSD: src/include/Makefile,v 1.109.2.27 2003/01/24 05:12:29 sam Exp $
-# $DragonFly: src/include/Makefile,v 1.33 2007/01/19 07:23:39 dillon Exp $
+# $DragonFly: src/include/Makefile,v 1.34 2007/06/16 19:57:11 dillon Exp $
 #
 # Doing a make install builds /usr/include
 #
@@ -21,8 +21,8 @@ INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h ctype.h db.h \
        search.h setjmp.h sgtty.h \
        signal.h stab.h stdarg.h stdbool.h stddef.h stdint.h stdio.h stdlib.h \
        string.h stringlist.h strings.h struct.h sysexits.h tar.h time.h \
-       timers.h ttyent.h unistd.h ulimit.h utime.h utmp.h vis.h wchar.h \
-       wctype.h
+       timers.h ttyent.h unistd.h ulimit.h utime.h utmp.h uuid.h vis.h \
+       wchar.h wctype.h
 
 MHDRS= float.h floatingpoint.h varargs.h
 
diff --git a/include/uuid.h b/include/uuid.h
new file mode 100644 (file)
index 0000000..bbaefa9
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/include/uuid.h,v 1.3 2005/01/03 02:56:15 marcel Exp $
+ * $DragonFly: src/include/uuid.h,v 1.1 2007/06/16 19:57:11 dillon Exp $
+ */
+
+#ifndef _UUID_H_
+#define        _UUID_H_
+
+#include <sys/types.h>
+#include <sys/uuid.h>
+
+/*
+ * This implementation mostly conforms to the DCE 1.1 specification.
+ * See Also:
+ *     uuidgen(1), uuidgen(2), uuid(3)
+ */
+
+/* Status codes returned by the functions. */
+#define        uuid_s_ok                       0
+#define        uuid_s_bad_version              1
+#define        uuid_s_invalid_string_uuid      2
+#define        uuid_s_no_memory                3
+
+__BEGIN_DECLS
+int32_t        uuid_compare(const uuid_t *, const uuid_t *, uint32_t *);
+void   uuid_create(uuid_t *, uint32_t *);
+void   uuid_create_nil(uuid_t *, uint32_t *);
+int32_t        uuid_equal(const uuid_t *, const uuid_t *, uint32_t *);
+void   uuid_from_string(const char *, uuid_t *, uint32_t *);
+uint16_t uuid_hash(const uuid_t *, uint32_t *);
+int32_t        uuid_is_nil(const uuid_t *, uint32_t *);
+void   uuid_to_string(const uuid_t *, char **, uint32_t *);
+__END_DECLS
+
+#endif /* _UUID_H_ */
index 0b65f07..f96f150 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/lib/libc/Makefile.inc,v 1.5 1999/08/27 23:58:06 peter Exp $
-# $DragonFly: src/lib/libc/Makefile.inc,v 1.5 2006/08/19 09:14:27 swildner Exp $
+# $DragonFly: src/lib/libc/Makefile.inc,v 1.6 2007/06/16 19:57:12 dillon Exp $
 #
 # This file contains make rules that are shared by libc and libc_r.
 #
@@ -39,6 +39,7 @@ NOASM=
 .include "${.CURDIR}/../libc/string/Makefile.inc"
 .include "${.CURDIR}/../libc/sys/Makefile.inc"
 .include "${.CURDIR}/../libc/rpc/Makefile.inc"
+.include "${.CURDIR}/../libc/uuid/Makefile.inc"
 .include "${.CURDIR}/../libc/xdr/Makefile.inc"
 .if !defined(NO_YP_LIBC)
 CFLAGS+= -DYP
diff --git a/lib/libc/sys/uuidgen.2 b/lib/libc/sys/uuidgen.2
new file mode 100644 (file)
index 0000000..f1644b6
--- /dev/null
@@ -0,0 +1,143 @@
+.\" 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: src/lib/libc/sys/uuidgen.2,v 1.8 2005/07/31 03:30:44 keramida Exp $
+.\" $DragonFly: src/lib/libc/sys/uuidgen.2,v 1.1 2007/06/16 19:57:13 dillon Exp $
+.\"
+.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 "struct uuid *store" "int count"
+.Sh DESCRIPTION
+The
+.Fn uuidgen
+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.
+See below for a more in-depth description of the identifiers.
+When no IEEE 802
+address is available for the node field, a random multicast address is
+generated for each invocation of the system call.
+According to the algorithm of generating time-based UUIDs, this will also
+force a new random clock sequence, thereby increasing the likelihood for
+the identifier to be unique.
+.Pp
+When multiple identifiers are to be generated, the
+.Fn uuidgen
+system call will generate a set of identifiers that is dense 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
+Universally unique identifiers, also known as globally unique identifiers
+(GUIDs), have a binary representation of 128-bits.
+The grouping and meaning of these bits is described by the following
+structure and its description of the fields that follow it:
+.Bd -literal
+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];
+};
+.Ed
+.Bl -tag -width ".Va clock_seq_hi_and_reserved"
+.It Va time_low
+The least significant 32 bits of a 60-bit timestamp.
+This field is stored in the native byte-order.
+.It Va time_mid
+The least significant 16 bits of the most significant 28 bits of the 60-bit
+timestamp.
+This field is stored in the native byte-order.
+.It Va time_hi_and_version
+The most significant 12 bits of the 60-bit timestamp multiplexed with a 4-bit
+version number.
+The version number is stored in the most significant 4 bits of the 16-bit
+field.
+This field is stored in the native byte-order.
+.It Va clock_seq_hi_and_reserved
+The most significant 6 bits of a 14-bit sequence number multiplexed with a
+2-bit variant value.
+Note that the width of the variant value is determined by the variant itself.
+Identifiers generated by the
+.Fn uuidgen
+system call have variant value 10b.
+the variant value is stored in the most significant bits of the field.
+.It Va clock_seq_low
+The least significant 8 bits of a 14-bit sequence number.
+.It Va node
+The 6-byte IEEE 802 (MAC) address of one of the interfaces of the node.
+If no such interface exists, a random multi-cast address is used instead.
+.El
+.Pp
+The binary representation is sensitive to byte ordering.
+Any multi-byte field is to be stored in the local or native byte-order and
+identifiers must be converted when transmitted to hosts that do not agree
+on the byte-order.
+The specification does not however document what this means in concrete
+terms and is otherwise beyond the scope of this system call.
+.Sh RETURN VALUES
+.Rv -std
+.Sh ERRORS
+The
+.Fn uuidgen
+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
+argument is less than 1 or larger than the hard upper limit of 2048.
+.El
+.Sh SEE ALSO
+.Xr uuidgen 1 ,
+.Xr uuid 3
+.Sh STANDARDS
+The identifiers are represented and generated in conformance with the DCE 1.1
+RPC specification.
+The
+.Fn uuidgen
+system call is itself not part of the specification.
+.Sh HISTORY
+The
+.Fn uuidgen
+system call first appeared in
+.Fx 5.0 .
diff --git a/lib/libc/uuid/Makefile.inc b/lib/libc/uuid/Makefile.inc
new file mode 100644 (file)
index 0000000..343b7c4
--- /dev/null
@@ -0,0 +1,20 @@
+# $FreeBSD: src/lib/libc/uuid/Makefile.inc,v 1.4 2006/03/13 01:15:01 deischen Exp $
+# $DragonFly: src/lib/libc/uuid/Makefile.inc,v 1.1 2007/06/16 19:57:14 dillon Exp $
+
+# DCE 1.1 UUID implementation sources
+
+.PATH: ${.CURDIR}/uuid
+
+SRCS+= uuid_compare.c uuid_create.c uuid_create_nil.c uuid_equal.c \
+       uuid_from_string.c uuid_hash.c uuid_is_nil.c uuid_to_string.c
+SYM_MAPS+=     ${.CURDIR}/uuid/Symbol.map
+
+MAN+=  uuid.3
+MLINKS+=uuid.3 uuid_compare.3
+MLINKS+=uuid.3 uuid_create.3
+MLINKS+=uuid.3 uuid_create_nil.3
+MLINKS+=uuid.3 uuid_equal.3
+MLINKS+=uuid.3 uuid_from_string.3
+MLINKS+=uuid.3 uuid_hash.3
+MLINKS+=uuid.3 uuid_is_nil.3
+MLINKS+=uuid.3 uuid_to_string.3
diff --git a/lib/libc/uuid/Symbol.map b/lib/libc/uuid/Symbol.map
new file mode 100644 (file)
index 0000000..3360f1a
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * $FreeBSD: src/lib/libc/uuid/Symbol.map,v 1.2 2007/04/29 14:05:20 deischen Exp $
+ * $DragonFly: src/lib/libc/uuid/Symbol.map,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+FBSD_1.0 {
+       uuid_to_string;
+       uuid_is_nil;
+       uuid_hash;
+       uuid_from_string;
+       uuid_equal;
+       uuid_create_nil;
+       uuid_create;
+       uuid_compare;
+};
diff --git a/lib/libc/uuid/uuid.3 b/lib/libc/uuid/uuid.3
new file mode 100644 (file)
index 0000000..d0039da
--- /dev/null
@@ -0,0 +1,101 @@
+.\" Copyright (c) 2002 Marcel Moolenaar
+.\" Copyright (c) 2002 Hiten Mahesh Pandya
+.\" 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: src/lib/libc/uuid/uuid.3,v 1.6 2005/11/24 07:04:20 ru Exp $
+.\" $DragonFly: src/lib/libc/uuid/uuid.3,v 1.1 2007/06/16 19:57:14 dillon Exp $
+.\"
+.Dd January 3, 2005
+.Dt UUID 3
+.Os
+.Sh NAME
+.Nm uuid_compare , uuid_create , uuid_create_nil , uuid_equal ,
+.Nm uuid_from_string , uuid_hash , uuid_is_nil , uuid_to_string
+.Nd DCE 1.1 compliant UUID functions
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In uuid.h
+.Ft int32_t
+.Fn uuid_compare "const uuid_t *uuid1" "const uuid_t *uuid2" "uint32_t *status"
+.Ft void
+.Fn uuid_create "uuid_t *uuid" "uint32_t *status"
+.Ft void
+.Fn uuid_create_nil "uuid_t *uuid" "uint32_t *status"
+.Ft int32_t
+.Fn uuid_equal "const uuid_t *uuid1" "const uuid_t *uuid2" "uint32_t *status"
+.Ft void
+.Fn uuid_from_string "const char *str" "uuid_t *uuid" "uint32_t *status"
+.Ft uint16_t
+.Fn uuid_hash "const uuid_t *uuid" "uint32_t *status"
+.Ft int32_t
+.Fn uuid_is_nil "const uuid_t *uuid" "uint32_t *status"
+.Ft void
+.Fn uuid_to_string "const uuid_t *uuid" "char **str" "uint32_t *status"
+.Sh DESCRIPTION
+The family of DCE 1.1 compliant UUID functions allow applications to operate
+on universally unique identifiers, or UUIDs.
+The
+.Fn uuid_create
+and
+.Fn uuid_create_nil
+functions create UUIDs.
+The
+.Fn uuid_compare ,
+.Fn uuid_equal
+and
+.Fn uuid_is_nil
+functions can be used to test UUIDs.
+To convert from the binary representation to the string representation or
+vice versa, use
+.Fn uuid_to_string
+or
+.Fn uuid_from_string
+respectively.
+A 16-bit hash value can be obtained by calling
+.Fn uuid_hash .
+.Sh RETURN VALUES
+The successful or unsuccessful completion of the function is returned in
+the
+.Fa status
+argument.
+Possible values are:
+.Pp
+.Bl -tag -width ".Dv uuid_s_invalid_string_uuid"
+.It Dv uuid_s_ok
+The function completed successfully.
+.It Dv uuid_s_bad_version
+The UUID does not have a known version.
+.It Dv uuid_s_invalid_string_uuid
+The string representation of an UUID is not valid.
+.It Dv uuid_s_no_memory
+The meaning of the code escaped the writers mind.
+.El
+.Sh SEE ALSO
+.Xr uuidgen 1 ,
+.Xr uuidgen 2
+.Sh STANDARDS
+The UUID functions conform to the DCE 1.1 RPC specification.
+.Sh BUGS
+This manpage can be improved.
diff --git a/lib/libc/uuid/uuid_compare.c b/lib/libc/uuid/uuid_compare.c
new file mode 100644 (file)
index 0000000..5d2559c
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_compare.c,v 1.6 2007/04/05 02:07:33 delphij Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_compare.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <string.h>
+#include <uuid.h>
+
+/* A macro used to improve the readability of uuid_compare(). */
+#define DIFF_RETURN(a, b, field)       do {                    \
+       if ((a)->field != (b)->field)                           \
+               return (((a)->field < (b)->field) ? -1 : 1);    \
+} while (0)
+
+/*
+ * uuid_compare() - compare two UUIDs.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_compare.htm
+ *
+ * NOTE: Either UUID can be NULL, meaning a nil UUID. nil UUIDs are smaller
+ *      than any non-nil UUID.
+ */
+int32_t
+uuid_compare(const uuid_t *a, const uuid_t *b, uint32_t *status)
+{
+       int     res;
+
+       if (status != NULL)
+               *status = uuid_s_ok;
+
+       /* Deal with NULL or equal pointers. */
+       if (a == b)
+               return (0);
+       if (a == NULL)
+               return ((uuid_is_nil(b, NULL)) ? 0 : -1);
+       if (b == NULL)
+               return ((uuid_is_nil(a, NULL)) ? 0 : 1);
+
+       /* We have to compare the hard way. */
+       DIFF_RETURN(a, b, time_low);
+       DIFF_RETURN(a, b, time_mid);
+       DIFF_RETURN(a, b, time_hi_and_version);
+       DIFF_RETURN(a, b, clock_seq_hi_and_reserved);
+       DIFF_RETURN(a, b, clock_seq_low);
+
+       res = memcmp(a->node, b->node, sizeof(a->node));
+       if (res)
+               return ((res < 0) ? -1 : 1);
+       return (0);
+}
+
+#undef DIFF_RETURN
diff --git a/lib/libc/uuid/uuid_create.c b/lib/libc/uuid/uuid_create.c
new file mode 100644 (file)
index 0000000..0a0c201
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_create.c,v 1.2 2003/08/08 19:18:43 marcel Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_create.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <uuid.h>
+
+/*
+ * uuid_create() - create an UUID.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_create.htm
+ */
+void
+uuid_create(uuid_t *u, uint32_t *status)
+{
+
+       if (status)
+               *status = uuid_s_ok;
+
+       uuidgen(u, 1);
+}
diff --git a/lib/libc/uuid/uuid_create_nil.c b/lib/libc/uuid/uuid_create_nil.c
new file mode 100644 (file)
index 0000000..8b41ee5
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_create_nil.c,v 1.2 2003/08/08 19:18:43 marcel Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_create_nil.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <strings.h>
+#include <uuid.h>
+
+/*
+ * uuid_create_nil() - create a nil UUID.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_create_nil.htm
+ */
+void
+uuid_create_nil(uuid_t *u, uint32_t *status)
+{
+
+       if (status)
+               *status = uuid_s_ok;
+
+       bzero(u, sizeof(*u));
+}
diff --git a/lib/libc/uuid/uuid_equal.c b/lib/libc/uuid/uuid_equal.c
new file mode 100644 (file)
index 0000000..9383399
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_equal.c,v 1.3 2005/01/03 02:56:15 marcel Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_equal.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <string.h>
+#include <uuid.h>
+
+/*
+ * uuid_equal() - compare for equality.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_equal.htm
+ */
+int32_t
+uuid_equal(const uuid_t *a, const uuid_t *b, uint32_t *status)
+{
+
+       if (status != NULL)
+               *status = uuid_s_ok;
+
+       /* Deal with equal or NULL pointers. */
+       if (a == b)
+               return (1);
+       if (a == NULL)
+               return (uuid_is_nil(b, NULL));
+       if (b == NULL)
+               return (uuid_is_nil(a, NULL));
+
+       /* Do a byte for byte comparison. */
+       return ((memcmp(a, b, sizeof(uuid_t))) ? 0 : 1);
+}
diff --git a/lib/libc/uuid/uuid_from_string.c b/lib/libc/uuid/uuid_from_string.c
new file mode 100644 (file)
index 0000000..020d96f
--- /dev/null
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_from_string.c,v 1.2 2003/08/08 19:18:43 marcel Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_from_string.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <uuid.h>
+
+/*
+ * uuid_from_string() - convert a string representation of an UUID into
+ *                     a binary representation.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_from_string.htm
+ *
+ * NOTE: The sequence field is in big-endian, while the time fields are in
+ *      native byte order.
+ */
+void
+uuid_from_string(const char *s, uuid_t *u, uint32_t *status)
+{
+       int n;
+
+       /* Short-circuit 2 special cases: NULL pointer and empty string. */
+       if (s == NULL || *s == '\0') {
+               uuid_create_nil(u, status);
+               return;
+       }
+
+       /* Assume the worst. */
+       if (status != NULL)
+               *status = uuid_s_invalid_string_uuid;
+
+       /* The UUID string representation has a fixed length. */
+       if (strlen(s) != 36)
+               return;
+
+       /*
+        * We only work with "new" UUIDs. New UUIDs have the form:
+        *      01234567-89ab-cdef-0123-456789abcdef
+        * The so called "old" UUIDs, which we don't support, have the form:
+        *      0123456789ab.cd.ef.01.23.45.67.89.ab
+        */
+       if (s[8] != '-')
+               return;
+
+       n = sscanf(s,
+           "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
+           &u->time_low, &u->time_mid, &u->time_hi_and_version,
+           &u->clock_seq_hi_and_reserved, &u->clock_seq_low, &u->node[0],
+           &u->node[1], &u->node[2], &u->node[3], &u->node[4], &u->node[5]);
+
+       /* Make sure we have all conversions. */
+       if (n != 11)
+               return;
+
+       /* We have a successful scan. Check semantics... */
+       n = u->clock_seq_hi_and_reserved;
+       if ((n & 0x80) != 0x00 &&                       /* variant 0? */
+           (n & 0xc0) != 0x80 &&                       /* variant 1? */
+           (n & 0xe0) != 0xc0) {                       /* variant 2? */
+               if (status != NULL)
+                       *status = uuid_s_bad_version;
+       } else {
+               if (status != NULL)
+                       *status = uuid_s_ok;
+       }
+}
diff --git a/lib/libc/uuid/uuid_hash.c b/lib/libc/uuid/uuid_hash.c
new file mode 100644 (file)
index 0000000..602c10a
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_hash.c,v 1.3 2005/01/03 02:56:15 marcel Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_hash.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <uuid.h>
+
+/*
+ * uuid_hash() - generate a hash value.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_hash.htm
+ */
+uint16_t
+uuid_hash(const uuid_t *u, uint32_t *status)
+{
+
+       if (status)
+               *status = uuid_s_ok;
+
+       /*
+        * Use the most frequently changing bits in the UUID as the hash
+        * value. This should yield a good enough distribution...
+        */
+       return ((u) ? u->time_low & 0xffff : 0);
+}
diff --git a/lib/libc/uuid/uuid_is_nil.c b/lib/libc/uuid/uuid_is_nil.c
new file mode 100644 (file)
index 0000000..4796407
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_is_nil.c,v 1.4 2005/05/11 13:18:10 delphij Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_is_nil.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <uuid.h>
+
+/*
+ * uuid_is_nil() - return whether the UUID is a nil UUID.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_is_nil.htm
+ */
+int32_t
+uuid_is_nil(const uuid_t *u, uint32_t *status)
+{
+       const uint32_t *p;
+
+       if (status)
+               *status = uuid_s_ok;
+
+       if (!u)
+               return (1);
+
+       /*
+        * Pick the largest type that has equivalent alignment constraints
+        * as an UUID and use it to test if the UUID consists of all zeroes.
+        */
+       p = (const uint32_t*)u;
+       return ((p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0) ? 1 : 0);
+}
diff --git a/lib/libc/uuid/uuid_to_string.c b/lib/libc/uuid/uuid_to_string.c
new file mode 100644 (file)
index 0000000..32e166e
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: src/lib/libc/uuid/uuid_to_string.c,v 1.3 2005/01/03 02:56:15 marcel Exp $
+ * $DragonFly: src/lib/libc/uuid/uuid_to_string.c,v 1.1 2007/06/16 19:57:14 dillon Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <uuid.h>
+
+/*
+ * uuid_to_string() - Convert a binary UUID into a string representation.
+ * See also:
+ *     http://www.opengroup.org/onlinepubs/009629399/uuid_to_string.htm
+ *
+ * NOTE: The references given above do not have a status code for when
+ *      the string could not be allocated. The status code has been
+ *      taken from the Hewlett-Packard implementation.
+ */
+void
+uuid_to_string(const uuid_t *u, char **s, uint32_t *status)
+{
+       uuid_t nil;
+
+       if (status != NULL)
+               *status = uuid_s_ok;
+
+       /* Why allow a NULL-pointer here? */
+       if (s == 0)
+               return;
+
+       if (u == NULL) {
+               u = &nil;
+               uuid_create_nil(&nil, NULL);
+       }
+
+       asprintf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+           u->time_low, u->time_mid, u->time_hi_and_version,
+           u->clock_seq_hi_and_reserved, u->clock_seq_low, u->node[0],
+           u->node[1], u->node[2], u->node[3], u->node[4], u->node[5]);
+
+       if (*s == NULL && status != NULL)
+               *status = uuid_s_no_memory;
+}
index 70794fe..d6e849b 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_uuid.c,v 1.13 2007/04/23 12:53:00 pjd Exp $
- * $DragonFly: src/sys/kern/kern_uuid.c,v 1.1 2007/06/16 18:55:27 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_uuid.c,v 1.2 2007/06/16 19:57:10 dillon Exp $
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
+#include <sys/kern_syscall.h>
+#include <sys/random.h>
 #include <sys/sbuf.h>
 #include <sys/socket.h>
 #include <sys/sysproto.h>
 #include <sys/uuid.h>
+#include <net/if_var.h>
 
 /*
  * See also:
@@ -60,49 +63,28 @@ struct uuid_private {
        uint16_t        node[UUID_NODE_LEN>>1];
 };
 
-#if 0  /* NOT YET */
-
 static struct uuid_private uuid_last;
 
-static struct mtx uuid_mutex;
-MTX_SYSINIT(uuid_lock, &uuid_mutex, "UUID generator mutex lock", MTX_DEF);
+static struct lock uuid_lock;
+
+static
+void
+uuid_lock_init(void *arg __unused)
+{
+       lockinit(&uuid_lock, "uuid", 0, 0);
+}
+SYSINIT(uuid_lock, SI_BOOT1_POST, SI_ORDER_ANY, uuid_lock_init, NULL);
 
 /*
- * 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.
+ * Ask the network subsystem for a real MAC address from any of the
+ * system interfaces.  If we can't find one, generate a random multicast
+ * MAC address.
  */
 static void
 uuid_node(uint16_t *node)
 {
-       struct ifnet *ifp;
-       struct ifaddr *ifa;
-       struct sockaddr_dl *sdl;
-       int i;
-
-       IFNET_RLOCK();
-       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);
-                               IFNET_RUNLOCK();
-                               return;
-                       }
-               }
-       }
-       IFNET_RUNLOCK();
-
-       for (i = 0; i < (UUID_NODE_LEN>>1); i++)
-               node[i] = (uint16_t)arc4random();
+       if (if_getanyethermac(node, UUID_NODE_LEN) != 0)
+               read_random(node, UUID_NODE_LEN);
        *((uint8_t*)node) |= 0x01;
 }
 
@@ -115,13 +97,13 @@ uuid_node(uint16_t *node)
 static uint64_t
 uuid_time(void)
 {
-       struct bintime bt;
+       struct timespec ts;
        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));
+       nanotime(&ts);
+       time += ts.tv_sec * 10000000LL;         /* 100 ns increments */
+       time += ts.tv_nsec / 100;               /* 100 ns increments */
+       return (time & ((1LL << 60) - 1LL));    /* limit to 60 bits */
 }
 
 struct uuid *
@@ -131,24 +113,26 @@ kern_uuidgen(struct uuid *store, size_t count)
        uint64_t time;
        size_t n;
 
-       mtx_lock(&uuid_mutex);
+       lockmgr(&uuid_lock, LK_EXCLUSIVE | LK_RETRY);
 
        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_last.node[2] != uuid.node[2]) {
+               read_random(&uuid.seq, sizeof(uuid.seq));
+               uuid.seq &= 0x3fff;
+       } else if (uuid_last.time.ll >= time) {
                uuid.seq = (uuid_last.seq + 1) & 0x3fff;
-       else
+       } else {
                uuid.seq = uuid_last.seq;
+       }
 
        uuid_last = uuid;
        uuid_last.time.ll = (time + count - 1) & ((1LL << 60) - 1LL);
 
-       mtx_unlock(&uuid_mutex);
+       lockmgr(&uuid_lock, LK_RELEASE);
 
        /* Set sequence and variant and deal with byte order. */
        uuid.seq = htobe16(uuid.seq | 0x8000);
@@ -165,14 +149,13 @@ kern_uuidgen(struct uuid *store, size_t count)
        return (store);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct uuidgen_args {
-       struct uuid *store;
-       int     count;
-};
-#endif
+/*
+ * uuidgen(struct uuid *store, int count)
+ *
+ * Generate an array of new UUIDs
+ */
 int
-uuidgen(struct thread *td, struct uuidgen_args *uap)
+sys_uuidgen(struct uuidgen_args *uap)
 {
        struct uuid *store;
        size_t count;
@@ -188,15 +171,13 @@ uuidgen(struct thread *td, struct uuidgen_args *uap)
                return (EINVAL);
 
        count = uap->count;
-       store = malloc(count * sizeof(struct uuid), M_TEMP, M_WAITOK);
+       store = kmalloc(count * sizeof(struct uuid), M_TEMP, M_WAITOK);
        kern_uuidgen(store, count);
        error = copyout(store, uap->store, count * sizeof(struct uuid));
-       free(store, M_TEMP);
+       kfree(store, M_TEMP);
        return (error);
 }
 
-#endif /* NOT YET */
-
 int
 snprintf_uuid(char *buf, size_t sz, struct uuid *uuid)
 {
index 04c8a42..0a7c288 100644 (file)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/kern_syscall.h,v 1.36 2007/05/09 00:53:35 dillon Exp $
+ * $DragonFly: src/sys/sys/kern_syscall.h,v 1.37 2007/06/16 19:57:08 dillon Exp $
  */
 
 #ifndef _SYS_KERN_SYSCALL_H_
@@ -63,6 +63,7 @@ struct vmspace;
 struct vnode;
 struct file;
 struct ucred;
+struct uuid;
 
 /*
  * Prototypes for syscalls in kern/kern_descrip.c
@@ -158,6 +159,7 @@ int kern_symlink(struct nlookupdata *nd, char *path, int mode);
 int kern_truncate(struct nlookupdata *nd, off_t length);
 int kern_unlink(struct nlookupdata *nd);
 int kern_utimes(struct nlookupdata *nd, struct timeval *tptr);
+struct uuid *kern_uuidgen(struct uuid *store, size_t count);
 
 /*
  * Prototypes for syscalls in kern/vfs_cache.c
index 559b1ad..386b1a1 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/uuid.h,v 1.6 2005/10/07 13:37:10 marcel Exp $
- * $DragonFly: src/sys/sys/uuid.h,v 1.1 2007/06/16 18:55:24 dillon Exp $
+ * $DragonFly: src/sys/sys/uuid.h,v 1.2 2007/06/16 19:57:08 dillon Exp $
  */
 
 #ifndef _SYS_UUID_H_
@@ -57,9 +57,7 @@ struct uuid {
 
 struct sbuf;
 
-#if 0
 struct uuid *kern_uuidgen(struct uuid *, size_t);
-#endif
 
 int snprintf_uuid(char *, size_t, struct uuid *);
 int printf_uuid(struct uuid *);