diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | bcb704366cb5e333a626c18c308c7e0448a8e69f (patch) | |
tree | f0d6ab7d78ecdd9207cf46536376b44b91a1ca71 /krfb/srvloc/uuid.cpp | |
download | tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.tar.gz tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krfb/srvloc/uuid.cpp')
-rw-r--r-- | krfb/srvloc/uuid.cpp | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/krfb/srvloc/uuid.cpp b/krfb/srvloc/uuid.cpp new file mode 100644 index 00000000..61f78d86 --- /dev/null +++ b/krfb/srvloc/uuid.cpp @@ -0,0 +1,245 @@ +/* + * libuuid - library for generating UUIDs + * + * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. + * Copyright (C) 2002 Tim Jansen + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU + * Library General Public License. + * %End-Header% + * + * 2002-12-15, tim@tjansen.de: + * merged all *.c files, + * replaced all function that are not needed to generate a time uuid, + * added createUUID() + */ + +#include "uuid.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> + +#ifndef _SVID_SOURCE +#define _SVID_SOURCE +#endif + +#include <fcntl.h> +#include <errno.h> +#ifdef HAVE_SRANDOM +#define srand(x) srandom(x) +#define rand() random() +#endif + +typedef unsigned char uuid_t[16]; +typedef unsigned char __u8; +typedef unsigned short __u16; +typedef unsigned int __u32; + + +struct uuid { + __u32 time_low; + __u16 time_mid; + __u16 time_hi_and_version; + __u16 clock_seq; + __u8 node[6]; +}; + +void uuid_unpack(const uuid_t in, struct uuid *uu) +{ + const __u8 *ptr = in; + __u32 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = tmp; + + memcpy(uu->node, ptr, 6); +} + +static int get_random_fd(void) +{ + struct timeval tv; + static int fd = -2; + int i; + + if (fd == -2) { + gettimeofday(&tv, 0); + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + fd = open("/dev/random", O_RDONLY | O_NONBLOCK); + srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); + } + /* Crank the random number generator a few times */ + gettimeofday(&tv, 0); + for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) + rand(); + return fd; +} + + +/* + * Generate a series of random bytes. Use /dev/urandom if possible, + * and if not, use srandom/random. + */ +static void get_random_bytes(void *buf, int nbytes) +{ + int i, fd = get_random_fd(); + int lose_counter = 0; + char *cp = (char *) buf; + + if (fd >= 0) { + while (nbytes > 0) { + i = read(fd, cp, nbytes); + if (i <= 0) { + if (lose_counter++ > 16) + break; + continue; + } + nbytes -= i; + cp += i; + lose_counter = 0; + } + } + + /* XXX put something better here if no /dev/random! */ + for (i = 0; i < nbytes; i++) + *cp++ = rand() & 0xFF; + return; +} + + +/* Assume that the gettimeofday() has microsecond granularity */ +#define MAX_ADJUSTMENT 10 + +static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq) +{ + static int adjustment = 0; + static struct timeval last = {0, 0}; + static __u16 clock_seq; + struct timeval tv; + unsigned long long clock_reg; + +try_again: + gettimeofday(&tv, 0); + if ((last.tv_sec == 0) && (last.tv_usec == 0)) { + get_random_bytes(&clock_seq, sizeof(clock_seq)); + clock_seq &= 0x1FFF; + last = tv; + last.tv_sec--; + } + if ((tv.tv_sec < last.tv_sec) || + ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec < last.tv_usec))) { + clock_seq = (clock_seq+1) & 0x1FFF; + adjustment = 0; + last = tv; + } else if ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec == last.tv_usec)) { + if (adjustment >= MAX_ADJUSTMENT) + goto try_again; + adjustment++; + } else { + adjustment = 0; + last = tv; + } + + clock_reg = tv.tv_usec*10 + adjustment; + clock_reg += ((unsigned long long) tv.tv_sec)*10000000; + clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000; + + *clock_high = clock_reg >> 32; + *clock_low = clock_reg; + *ret_clock_seq = clock_seq; + return 0; +} + +static void uuid_pack(const struct uuid *uu, uuid_t ptr) +{ + __u32 tmp; + unsigned char *out = ptr; + + tmp = uu->time_low; + out[3] = (unsigned char) tmp; + tmp >>= 8; + out[2] = (unsigned char) tmp; + tmp >>= 8; + out[1] = (unsigned char) tmp; + tmp >>= 8; + out[0] = (unsigned char) tmp; + + tmp = uu->time_mid; + out[5] = (unsigned char) tmp; + tmp >>= 8; + out[4] = (unsigned char) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (unsigned char) tmp; + tmp >>= 8; + out[6] = (unsigned char) tmp; + + tmp = uu->clock_seq; + out[9] = (unsigned char) tmp; + tmp >>= 8; + out[8] = (unsigned char) tmp; + + memcpy(out+10, uu->node, 6); +} + +static void uuid_generate_time(uuid_t out) +{ + static unsigned char node_id[6]; + struct uuid uu; + __u32 clock_mid; + + get_random_bytes(node_id, 6); + get_clock(&clock_mid, &uu.time_low, &uu.clock_seq); + uu.clock_seq |= 0x8000; + uu.time_mid = (__u16) clock_mid; + uu.time_hi_and_version = (clock_mid >> 16) | 0x1000; + memcpy(uu.node, node_id, 6); + uuid_pack(&uu, out); +} + +static void uuid_unparse(const uuid_t uu, char *out) +{ + struct uuid uuid; + + uuid_unpack(uu, &uuid); + sprintf(out, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, + uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, + uuid.node[0], uuid.node[1], uuid.node[2], + uuid.node[3], uuid.node[4], uuid.node[5]); +} + +QString createUUID() { + char s[37]; + uuid_t uu; + uuid_generate_time(uu); + uuid_unparse(uu, s); + return QString(s); +} + |