--- as_uuid.cpp 2003/01/22 11:37:22 1.6
+++ as_uuid.cpp 2003/01/22 18:59:46 1.7
@@ -29,336 +29,89 @@
// as_uuidgen.cpp: ISO C++ implementation
//
-/*
- * as_uuidgen.c --- generate a DCE-compatible uuid
- *
- * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
- *
- * This file may be redistributed under the terms of the GNU
- * Library General Public License.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
+#include <string>
#include "as_uuid.h"
+#include "as_rand.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#endif /* TIME_WITH_SYS_TIME */
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif /* HAVE_SYS_SOCKIO_H */
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif /* HAVE_NET_IF_H */
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
-
-#ifndef max
-/* Define a general use max macro */
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif /* max */
-
-#ifdef HAVE_NET_IF_H
-/* Define the size of a interface address */
-#define ifreq_size(i) max(sizeof(struct ifreq), sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
-#endif /* HAVE_NET_IF_H */
+namespace AS {
-int Uuid::getRandfd(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.
- */
-void Uuid::getRandbytes(void *buf, int nbytes)
-{
- int i, fd = getRandfd();
- int lose_counter = 0;
- char *cp = (char *) buf;
-
- if (fd >= 0) {
- while (nbytes > 0) {
- i = read(fd, cp, nbytes);
- if ((i < 0) &&
- ((errno == EINTR) || (errno == EAGAIN)))
- continue;
- if (i <= 0) {
- if (lose_counter++ == 8)
- 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;
-}
-
-/*
- * Get the ethernet hardware address, if we can find it...
- */
-int Uuid::getNodeid(unsigned char *node_id)
-{
-#if 0 // FIXME: Fix this broken code some other day
-#ifdef HAVE_NET_IF_H
- int sd;
- struct ifreq ifr, *ifrp;
- struct ifconf ifc;
- char buf[1024];
- int n, i;
- unsigned char *a;
-
- sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
- if (sd < 0) {
- return -1;
- }
- memset(buf, 0, sizeof(buf));
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
- if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
- close(sd);
- return -1;
- }
- n = ifc.ifc_len;
- for (i = 0; i < n; i+= ifreq_size(ifr)) {
- ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
- strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
-#ifdef HAVE_SIOCGIFHWADDR
- if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
- continue;
- a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
-#else
-#ifdef HAVE_SIOCGENADDR
- if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
- continue;
- a = (unsigned char *) ifr.ifr_enaddr;
-#else
- /*
- * Broken! We don't have a way of getting the hardware
- * address, so just return without doing anything else
- */
- close(sd);
- return 0;
-#endif /* SIOCGENADDR */
-#endif /* SIOCGIFHWADDR */
- if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
- continue;
- if (node_id) {
- memcpy(node_id, a, 6);
- close(sd);
- return 1;
- }
- }
- close(sd);
-#endif
- return 0;
-#endif // FIXME: Fix this broken code some other day
-}
-
-/* Assume that the gettimeofday() has microsecond granularity */
-#define MAX_ADJUSTMENT 10
-
-int Uuid::getClock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
+//
+// Generate a DCE standard UUID
+//
+void Uuid::genId(void)
{
- 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)) {
- getRandbytes(&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;
-}
+ Rand Temprand; // For random numbers
+ unsigned char szChardata[16]; // Intermediate data
-void Uuid::genTime(uuid_t out)
-{
- static unsigned char node_id[6];
- static int has_init = 0;
- uuid uu;
- __u32 clock_mid;
-
- if (!has_init) {
- if (getNodeid(node_id) <= 0) {
- getRandbytes(node_id, 6);
- /*
- * Set multicast bit, to prevent conflicts
- * with IEEE 802 addresses obtained from
- * network cards
- */
- node_id[0] |= 0x80;
- }
- has_init = 1;
- }
- getClock(&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);
- packId(&uu, out);
+ // Generate random data and fill in our UUID member fields with it
+ Temprand.genData(szChardata, sizeof(szChardata));
+ setId(szChardata);
+ setString(); // Uses field from internal data
+
+ // Since we don't just want random data, lets take some clock sequences also
+ this->clock_seq = (this->clock_seq & 0x3FFF) | 0x8000;
+ this->time_hi_and_version = (this->time_hi_and_version & 0x0FFF) | 0x4000;
}
-void Uuid::genRand(uuid_t out)
+//
+// Helper method to set the UUID private member data
+//
+void Uuid::setId(const unsigned char *pkucData)
{
- uuid_t buf;
- uuid uu;
+ const __u8 *pOctet = pkucData;
+ __u32 Tmpdat;
- getRandbytes(buf, sizeof(buf));
- unpackId(buf, &uu);
+ Tmpdat = *pOctet++; // Tmpdat is our iterator
- uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
- uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
- packId(&uu, out);
-}
+ // Copy data chunks one octet at a time
+ Tmpdat = (Tmpdat << 8) | *pOctet++;
+ Tmpdat = (Tmpdat << 8) | *pOctet++;
+ Tmpdat = (Tmpdat << 8) | *pOctet++;
+ this->time_low = Tmpdat;
-/*
- * 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::genId(uuid_t out)
-{
- if (getRandfd() >= 0)
- genRand(out);
- else
- genTime(out);
-}
+ Tmpdat = *pOctet++;
+ Tmpdat = (Tmpdat << 8) | *pOctet++;
+ this->time_mid = Tmpdat;
-void Uuid::packId(const uuid *uu, uuid_t ptr)
-{
- __u32 tmp;
- unsigned char *out = ptr;
+ Tmpdat = *pOctet++;
+ Tmpdat = (Tmpdat << 8) | *pOctet++;
+ this->time_hi_and_version = Tmpdat;
- 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;
+ Tmpdat = *pOctet++;
+ Tmpdat = (Tmpdat << 8) | *pOctet++;
+ this->clock_seq = Tmpdat;
- memcpy(out+10, uu->node, 6);
+ // Put in the MAC address
+ memcpy(this->node, pOctet, 6);
}
-void Uuid::unpackId(const uuid_t in, uuid *uu)
+//
+// Returns a formatted representation of a DCE standard UUID
+//
+std::string Uuid::getString(void)
{
- 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);
+// // Copy to outbound string and benefit from auto dealloc
+// auto_ptr<char> szOut(new char[48]);
+ return m_Fmtstr;
}
-void Uuid::unparseId(const uuid_t uu, char *out)
+//
+// Helper method to set the private formatted
+// representation of a DCE standard UUID
+//
+void Uuid::setString(void)
{
- uuid uuid;
+ char szTemp[48]; // To perform intermediate manipulation
- unpackId(uu, &uuid);
- sprintf(out,
+ sprintf(szTemp, // The DCE standard UUID format
"%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]);
+ this->time_low, this->time_mid, this->time_hi_and_version,
+ this->clock_seq >> 8, this->clock_seq & 0xFF,
+ node[0], node[1], node[2],
+ node[3], node[4], node[5]);
+
+ m_Fmtstr = szTemp; // Finally copy the temporary to our object
}
+} // namespace AS
|