Many files:

* gen_uuid.c (get_random_bytes): Use a while loop when reading from
  	/dev/urandom so that if we get interrupted while reading the right
  	thing happens.
  	(uuid_generate_random): Add new function which uses the new UUID
  	format which uses 122 random bits to form the 128-bit UUID.
  	(uuid_generate): Rename the old uuid_generate to be
  	uuid_generate_time, and create a new uuid_generate function which
  	calls either uuid_generate_random or uuid_genereate_time depending on
  	whether /dev/urandom is present.
  uuid_generate.3.in: Update to reflect changesin uuid_generate and its
  	two new variants.
  tst_uuid.c: Updated to test new uuid_generate functions, and to
  	reflect new semantics of uuid_compare.  Added tests to make sure the
  	UUID type and variant created by UUID generate is correct.
  uuid_time.c (uuid_variant, uuid_type): Added new functions to return
  	the UUID variant and type information.  The debugging program now
  	prints the UUID variant and type, and warns if the unparsed time
  	information is likely to be incorrect.
  uuid_parse.3.in, libuuid.3.in: Miscellaneous text cleanups.
uuidgen.1.in:
  Miscellaneous text cleanups.
bitmap-optimize
Theodore Ts'o 1999-06-18 00:32:03 +00:00
parent ffd3af5874
commit b19d1a959e
10 changed files with 258 additions and 24 deletions

View File

@ -1,3 +1,33 @@
1999-05-17 <tytso@rsts-11.mit.edu>
* gen_uuid.c (get_random_bytes): Use a while loop when reading
from /dev/urandom so that if we get interrupted while
reading the right thing happens.
(uuid_generate_random): Add new function which uses the
new UUID format which uses 122 random bits to form the
128-bit UUID.
(uuid_generate): Rename the old uuid_generate to be
uuid_generate_time, and create a new uuid_generate
function which calls either uuid_generate_random or
uuid_genereate_time depending on whether /dev/urandom is
present.
* uuid_generate.3.in: Update to reflect changesin uuid_generate
and its two new variants.
* tst_uuid.c: Updated to test new uuid_generate functions, and to
reflect new semantics of uuid_compare. Added tests to
make sure the UUID type and variant created by UUID
generate is correct.
* uuid_time.c (uuid_variant, uuid_type): Added new functions to
return the UUID variant and type information. The
debugging program now prints the UUID variant and type,
and warns if the unparsed time information is likely to be
incorrect.
* uuid_parse.3.in, libuuid.3.in: Miscellaneous text cleanups.
1999-05-03 <tytso@rsts-11.mit.edu>
* compare.c (uuid_compare): Change sense of uuid_compare so that

View File

@ -144,6 +144,9 @@ clean::
$(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/*
$(RM) -f ../libuuid.a ../libuuid_p.a tst_uuid uuid_time $(SMANPAGES)
check:: tst_uuid
LD_LIBRARY_PATH=$(LIB) ./tst_uuid
mostlyclean:: clean
distclean:: clean
$(RM) -f .depend Makefile

View File

@ -17,6 +17,7 @@
#endif
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
@ -54,17 +55,26 @@ static void get_random_bytes(void *buf, int nbytes)
fd = open("/dev/urandom", O_RDONLY);
srand((getpid() << 16) ^ getuid() ^ time(0));
}
if (fd > 0) {
i = read(fd, cp, nbytes);
if (i == nbytes)
return;
if (i > 0) {
if (fd >= 0) {
while (nbytes > 0) {
i = read(fd, cp, nbytes);
if (i < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
break;
}
nbytes -= i;
cp += i;
}
}
if (nbytes == 0)
return;
/* XXX put something better here if no /dev/random! */
for (i=0; i < nbytes; i++)
*cp++ = rand() & 0xFF;
return;
}
/*
@ -184,7 +194,7 @@ try_again:
return 0;
}
void uuid_generate(uuid_t out)
void uuid_generate_time(uuid_t out)
{
static unsigned char node_id[6];
static int has_init = 0;
@ -210,3 +220,39 @@ void uuid_generate(uuid_t out)
memcpy(uu.node, node_id, 6);
uuid_pack(&uu, out);
}
void uuid_generate_random(uuid_t out)
{
uuid_t buf;
struct uuid uu;
get_random_bytes(buf, sizeof(buf));
uuid_unpack(buf, &uu);
uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
uuid_pack(&uu, out);
}
/*
* This is the generic front-end to uuid_generate_random and
* uuid_generate_time. It uses uuid_generate_random only if
* /dev/urandom is available, since otherwise we won't have
* high-quality randomness.
*/
void uuid_generate(uuid_t out)
{
static int has_random = -1;
if (has_random < 0) {
if (access("/dev/urandom", R_OK) == 0)
has_random = 1;
else
has_random = 0;
}
if (has_random)
uuid_generate_random(out);
else
uuid_generate_time(out);
}

View File

@ -12,6 +12,8 @@ libuuid \- DCE compatible Universally Unique Identifier library
.nf
.B #include <uuid/uuid.h>
.sp
cc
.I file.c
.B \-luuid
.SH DESCRIPTION
The

View File

@ -24,22 +24,71 @@ main(int argc, char **argv)
unsigned char *cp;
int i;
int failed = 0;
int type, variant;
uuid_generate(buf);
uuid_unparse(buf, str);
printf("UUID string = %s\n", str);
printf("UUID generate = %s\n", str);
printf("UUID: ");
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
printf("%02x", *cp++);
}
printf("\n");
type = uuid_type(buf); variant = uuid_variant(buf);
printf("UUID type = %d, UUID variant = %d\n", type, variant);
if (variant != UUID_VARIANT_DCE) {
printf("Incorrect UUID Variant; was expecting DCE!\n");
failed++;
}
printf("\n");
uuid_generate_random(buf);
uuid_unparse(buf, str);
printf("UUID random string = %s\n", str);
printf("UUID: ");
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
printf("%02x", *cp++);
}
printf("\n");
type = uuid_type(buf); variant = uuid_variant(buf);
printf("UUID type = %d, UUID variant = %d\n", type, variant);
if (variant != UUID_VARIANT_DCE) {
printf("Incorrect UUID Variant; was expecting DCE!\n");
failed++;
}
if (type != 4) {
printf("Incorrect UUID type; was expecting "
"4 (random type)!\n");
failed++;
}
printf("\n");
uuid_generate_time(buf);
uuid_unparse(buf, str);
printf("UUID string = %s\n", str);
printf("UUID time: ");
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
printf("%02x", *cp++);
}
printf("\n");
type = uuid_type(buf); variant = uuid_variant(buf);
printf("UUID type = %d, UUID variant = %d\n", type, variant);
if (variant != UUID_VARIANT_DCE) {
printf("Incorrect UUID Variant; was expecting DCE!\n");
failed++;
}
if (type != 1) {
printf("Incorrect UUID type; was expecting "
"1 (time-based type)!\\n");
failed++;
}
tv.tv_sec = 0;
tv.tv_usec = 0;
time_reg = uuid_time(buf, &tv);
printf("UUID time is: (%d, %d): %s\n", tv.tv_sec, tv.tv_usec,
ctime(&time_reg));
uuid_parse(str, tst);
if (uuid_compare(buf, tst))
if (!uuid_compare(buf, tst))
printf("UUID parse and compare succeeded.\n");
else {
printf("UUID parse and compare failed!\n");
@ -53,7 +102,7 @@ main(int argc, char **argv)
failed++;
}
uuid_copy(buf, tst);
if (uuid_compare(buf, tst))
if (!uuid_compare(buf, tst))
printf("UUID copy and compare succeeded.\n");
else {
printf("UUID copy and compare failed!\n");

View File

@ -15,6 +15,12 @@
typedef unsigned char uuid_t[16];
/* UUID Variant definitions */
#define UUID_VARIANT_NCS 0
#define UUID_VARIANT_DCE 1
#define UUID_VARIANT_MICROSOFT 2
#define UUID_VARIANT_OTHER 3
/* clear.c */
void uuid_clear(uuid_t uu);
@ -38,5 +44,5 @@ void uuid_unparse(uuid_t uu, char *out);
/* uuid_time.c */
time_t uuid_time(uuid_t uu, struct timeval *ret_tv);
int uuid_type(uuid_t uu);
int uuid_variant(uuid_t uu);

View File

@ -13,16 +13,42 @@ uuid_generate \- create a new unique UUID value
.B #include <uuid/uuid.h>
.sp
.BI "void uuid_generate(uuid_t " out );
.BI "void uuid_generate_random(uuid_t " out );
.BI "void uuid_generate_time(uuid_t " out );
.fi
.SH DESCRIPTION
The
.B uuid_generate
function creates a new universally unique identifier. Depending on
compile\- and run\-time availability, the UUID will be based on the
local ethernet MAC address (if available), random data from /dev/urandom
or a pseudo\-random generator
.BR rand "(3) or " random "(3),"
and the current time.
function creates a new universally unique identifier (UUID). The uuid will
be generated based on high-quality randomness from
.IR /dev/urandom ,
if available. If it is not available, then
.B uuid_generate
will use an alternative algorithm which uses the current time, the
local ethernet MAC address (if available), and random data generated
using a pseudo-random generator.
.sp
The
.B uuid_generate_random
function forces the use of the all-random UUID format, even if
a high-quality random number generator (i.e.,
.IR /dev/urandom )
is not available, in which case a pseudo-random
generator will be subsituted. Note that the use of a pseudo-random
generator may compromise the uniqueness of UUID's
generated in this fashion.
.sp
The
.B uuid_generate_time
function forces the use of the alternative algorithm which uses the
current time and the local ethernet MAC address (if available).
This algorithm used to be the default one used to generate UUID, but
because of the use of the ethernet MAC address, it can leak
information about when and where the UUID was generated. This can cause
privacy problems in some applications, so the
.B uuid_generate
function only uses this algorithm if a high-quality source of
randomness is not available.
.sp
The UUID is 16 bytes (128 bits) long, which gives approximately 3.4x10^38
unique values (there are approximately 10^80 elemntary particles in

View File

@ -17,7 +17,7 @@ uuid_parse \- convert an input UUID string into the libuuid internal format
.SH DESCRIPTION
The
.B uuid_parse
function converts the supplied UUID string given by
function converts the UUID string given by
.I in
into the internal
.B uuid_t

View File

@ -1,7 +1,9 @@
/*
* uuid_time.c --- Interpret the time field from a uuid
*
* Copyright (C) 1998 Theodore Ts'o.
* uuid_time.c --- Interpret the time field from a uuid. This program
* violates the UUID abstraction barrier by reaching into the guts
* of a UUID and interpreting it.
*
* Copyright (C) 1998, 1999 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
@ -41,13 +43,54 @@ time_t uuid_time(uuid_t uu, struct timeval *ret_tv)
return tv.tv_sec;
}
int uuid_type(uuid_t uu)
{
struct uuid uuid;
uuid_unpack(uu, &uuid);
return ((uuid.time_hi_and_version >> 12) & 0xF);
}
int uuid_variant(uuid_t uu)
{
struct uuid uuid;
int var;
uuid_unpack(uu, &uuid);
var = uuid.clock_seq;
if ((var & 0x8000) == 0)
return UUID_VARIANT_NCS;
if ((var & 0x4000) == 0)
return UUID_VARIANT_DCE;
if ((var & 0x2000) == 0)
return UUID_VARIANT_MICROSOFT;
return UUID_VARIANT_OTHER;
}
#ifdef DEBUG
const char *variant_string(int variant)
{
switch (variant) {
case UUID_VARIANT_NCS:
return "NCS";
case UUID_VARIANT_DCE:
return "DCE";
case UUID_VARIANT_MICROSOFT:
return "Microsoft";
default:
return "Other";
}
}
int
main(int argc, char **argv)
{
uuid_t buf;
time_t time_reg;
struct timeval tv;
int type, variant;
if (argc != 2) {
fprintf(stderr, "Usage: %s uuid\n", argv[0]);
@ -57,8 +100,37 @@ main(int argc, char **argv)
fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
exit(1);
}
variant = uuid_variant(buf);
type = uuid_type(buf);
time_reg = uuid_time(buf, &tv);
printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
if (variant != UUID_VARIANT_DCE) {
printf("Warning: This program only knows how to interpret "
"DCE UUIDs.\n\tThe rest of the output is likely "
"to be incorrect!!\n");
}
printf("UUID type is %d", type);
switch (type) {
case 1:
printf(" (time based)\n");
break;
case 2:
printf(" (DCE)\n");
break;
case 3:
printf(" (name-based)\n");
break;
case 4:
printf(" (random)\n");
break;
default:
printf("\n");
}
if (type != 1) {
printf("Warning: not a time-based UUID, so UUID time "
"decoding will likely not work!\n");
}
printf("UUID time is: (%d, %d): %s\n", tv.tv_sec, tv.tv_usec,
ctime(&time_reg));

View File

@ -5,9 +5,9 @@
.\" This file may be copied under the terms of the GNU Public License.
.\"
.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
.TH UUIDGEN "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@"
.TH UUIDGEN 1 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@"
.SH NAME
uuidgen \- command\-line utility to create a new unique UUID value
uuidgen \- command\-line utility to create a new UUID value
.SH SYNOPSIS
.nf
.B uuidgen
@ -15,7 +15,7 @@ uuidgen \- command\-line utility to create a new unique UUID value
.SH DESCRIPTION
The
.B uuidgen
program creates a new universally unique identifier using the
program creates a new universally unique identifier (UUID) using the
.BR libuuid "(3) functions " uuid_generate "(3) and " uuid_unparse "(3)."
The new UUID can reasonably be considered unique among all UUIDs created
on the local system, and among UUIDs created on other systems in the past