Index: ossp-pkg/as/as-gui/as_uuid.cpp RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/as_uuid.cpp,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/as_uuid.cpp,v' 2>/dev/null --- 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 -#include -#include -#include -#include -#include -#include +#include #include "as_uuid.h" +#include "as_rand.h" -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -#ifdef TIME_WITH_SYS_TIME -#include -#endif /* TIME_WITH_SYS_TIME */ -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif /* HAVE_SYS_SOCKIO_H */ -#ifdef HAVE_NET_IF_H -#include -#endif /* HAVE_NET_IF_H */ -#ifdef HAVE_NETINET_IN_H -#include -#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 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 Index: ossp-pkg/as/as-gui/as_uuid.h RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/as_uuid.h,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/as_uuid.h,v' 2>/dev/null --- as_uuid.h 2003/01/22 11:37:22 1.2 +++ as_uuid.h 2003/01/22 18:59:46 1.3 @@ -32,12 +32,14 @@ #ifndef UUIDGEN_H #define UUIDGEN_H -#include "as_gui.h" +#include #ifdef HAVE_CONFIG_H #include "ac_config.h" #endif +namespace AS { + #ifdef HAVE_CONFIG_H #if (SIZEOF_CHAR == 1) typedef unsigned char __u8; @@ -109,32 +111,28 @@ #endif // HAVE_CONFIG_H -typedef unsigned char uuid_t[16]; - -struct uuid { - __u32 time_low; - __u16 time_mid; - __u16 time_hi_and_version; - __u16 clock_seq; - __u8 node[6]; -}; - +// +// A DCE standard UUID, can generate (multiple) +// IDs and format them for a printed output +// class Uuid { +private: + std::string m_Fmtstr; // Human readable format + __u32 time_low; // + __u16 time_mid; // Fields according to + __u16 time_hi_and_version; // the IETF specification + __u16 clock_seq; // draft-mealling-uuid-urn-00 + __u8 node[6]; // + public: - void genTime(uuid_t); - void genRand(uuid_t); - void genId(uuid_t); - - void packId(const uuid *, uuid_t); - void unpackId(const uuid_t, uuid *); - void unparseId(const uuid_t, char *); + void genId(void); // Generate an UUID + void setString(void); // Sets the formatted representation + std::string getString(void); // Return a formatted representation private: - int getRandfd(void); - void getRandbytes(void *, int); - int getNodeid(unsigned char *); - int getClock(__u32 *, __u32 *, __u16 *); + void setId(const unsigned char *); // Helper method to set data members }; +} #endif // UUIDGEN_H