[cig-commits] r7514 - in cs/cigma/branches/cigma-0.9: . build src
tests
luis at geodynamics.org
luis at geodynamics.org
Tue Jun 26 10:10:19 PDT 2007
Author: luis
Date: 2007-06-26 10:10:18 -0700 (Tue, 26 Jun 2007)
New Revision: 7514
Added:
cs/cigma/branches/cigma-0.9/src/uuid.c
cs/cigma/branches/cigma-0.9/src/uuid.h
cs/cigma/branches/cigma-0.9/src/uuid_mac.c
cs/cigma/branches/cigma-0.9/src/uuid_mac.h
cs/cigma/branches/cigma-0.9/src/uuid_md5.c
cs/cigma/branches/cigma-0.9/src/uuid_md5.h
cs/cigma/branches/cigma-0.9/src/uuid_prng.c
cs/cigma/branches/cigma-0.9/src/uuid_prng.h
cs/cigma/branches/cigma-0.9/src/uuid_ui64.c
cs/cigma/branches/cigma-0.9/src/uuid_ui64.h
cs/cigma/branches/cigma-0.9/tests/test_uuid.c
Modified:
cs/cigma/branches/cigma-0.9/Makefile.am
cs/cigma/branches/cigma-0.9/build/Makefile
cs/cigma/branches/cigma-0.9/configure.ac
cs/cigma/branches/cigma-0.9/src/Makefile.am
cs/cigma/branches/cigma-0.9/src/README
Log:
darcs patches:
* Added OSSP uuid source (version 0.9.0)
* Added another acknowledgement to src/README
* Added test for uuid functions
* Added autoconf checks for compiling uuid (which requires a config.h)
* Updated build makefile
* Updated build makefile
* Updated src/Makefile.am to build both static & shared libraries
* Updated top level Makefile.am with appropriate SUBDIRS
* Use linker for building cigma and test programs
Modified: cs/cigma/branches/cigma-0.9/Makefile.am
===================================================================
--- cs/cigma/branches/cigma-0.9/Makefile.am 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/Makefile.am 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1 @@
+SUBDIRS = src bin tests
Modified: cs/cigma/branches/cigma-0.9/build/Makefile
===================================================================
--- cs/cigma/branches/cigma-0.9/build/Makefile 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/build/Makefile 2007-06-26 17:10:18 UTC (rev 7514)
@@ -13,12 +13,14 @@
CC = gcc
LD = gcc
+WARNINGS = -Wall
+OPTIMIZE =
DEBUGFLAGS = -g -DNDEBUG
-OPTIMIZE =
-CFLAGS = -Wall $(OPTIMIZE) $(DEBUGFLAGS)
+CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUGFLAGS)
-LIBS = -lm -lhdf5 -lpthread -ldl
-DC3D_LIBS = -lgfortran
+LIBS = -lhdf5 -lpthread -ldl -lm
+DC3D_LIBS = -lgfortran
+CIGMA_LIBS = -lcigma $(LIBS)
STATICLIBS = libcigma.a
STATICLIBS += $(HDF5_HOME)/lib/libhdf5.a
@@ -36,12 +38,13 @@
###############################################################################
-LIBRARIES = -L. -L$(HDF5_HOME)/lib
+LIBRARIES = -L. -L$(CIGMA)/build -L$(HDF5_HOME)/lib
CFLAGS += $(LIBRARIES)
LDFLAGS += $(LIBRARIES)
LDFLAGS += -Wl,--rpath -Wl,.
+LDFLAGS += -Wl,--rpath -Wl,$(CIGMA)/build
LDFLAGS += -Wl,--rpath -Wl,$(HDF5_HOME)/lib
###############################################################################
@@ -64,12 +67,6 @@
$(CIGMA)/src/tet4.o \
$(CIGMA)/src/hex8.o
-EXTOBJS = \
- $(CIGMA)/src/argtable2.o \
- $(CIGMA)/src/hash.o \
- $(CIGMA)/src/iniparser.o \
- $(CIGMA)/src/sqlite3.o
-
ARGOBJS = \
$(CIGMA)/src/arg_end.o \
$(CIGMA)/src/arg_rem.o \
@@ -79,25 +76,48 @@
$(CIGMA)/src/arg_dbl.o \
$(CIGMA)/src/arg_file.o
+UUIDOBJS = \
+ $(CIGMA)/src/uuid_md5.o \
+ $(CIGMA)/src/uuid_prng.o \
+ $(CIGMA)/src/uuid_mac.o \
+ $(CIGMA)/src/uuid_ui64.o
+
+EXTOBJS = \
+ $(CIGMA)/src/hash.o \
+ $(CIGMA)/src/iniparser.o \
+ $(CIGMA)/src/sqlite3.o \
+ $(CIGMA)/src/argtable2.o $(ARGOBJS) \
+ $(CIGMA)/src/uuid.o $(UUIDOBJS)
+
CMDOBJS = \
$(CIGMA)/bin/cigma-cube.o
-ALLOBJS = $(OBJS) $(ELTOBJS) $(ARGOBJS) $(EXTOBJS)
+ALLOBJS = $(OBJS) $(ELTOBJS) $(EXTOBJS)
###############################################################################
-all: $(TARGETS)
+TESTS = \
+ $(CIGMA)/tests/test_uuid
-cigma: $(CIGMA)/bin/cigma.c libcigma.a libcigma.so $(CMDOBJS)
- $(CC) -static $(CFLAGS) $< $(CMDOBJS) $(STATICLIBS) -o $@
+###############################################################################
+all: $(TARGETS) $(TESTS)
+
libcigma.a: $(ALLOBJS)
ar rcs $@ $^
libcigma.so: $(ALLOBJS)
$(LD) -shared $(LDFLAGS) -o $@ $^
+cigma: $(CIGMA)/bin/cigma.c libcigma.a $(CMDOBJS)
+ $(LD) -static $(CFLAGS) $< $(CMDOBJS) $(STATICLIBS) -o $@
+test_%: test_%.c libcigma.so
+ $(LD) $(LDFLAGS) $(CIGMA_LIBS) $^ -o $@
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
$(CIGMA)/src/hash.o: $(CIGMA)/src/hash.c
$(CC) -Wall -c $< -o $@
@@ -113,8 +133,7 @@
$(CIGMA)/benchmarks/disloc3d/dc3d.o: $(CIGMA)/fields/disloc3d/dc3d.f
$(FC) -Wall -c $< -o $@
-.c.o:
- $(CC) $(CFLAGS) -c $< -o $@
+###############################################################################
clean:
rm -f $(ALLOBJS) $(CMDOBJS)
Modified: cs/cigma/branches/cigma-0.9/configure.ac
===================================================================
--- cs/cigma/branches/cigma-0.9/configure.ac 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/configure.ac 2007-06-26 17:10:18 UTC (rev 7514)
@@ -61,6 +61,16 @@
#AM_CONDITIONAL(USE_ARGREX, test "$SYS_REGEX" = "1")
#AM_CONDITIONAL(USE_ARGDATE, test "$SYS_STRPTIME" = "1")
+AC_CHECK_SIZEOF(char, 1)
+AC_CHECK_SIZEOF(unsigned char, 1)
+AC_CHECK_SIZEOF(short, 2)
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned long, 4)
+AC_CHECK_SIZEOF(long long, 8)
+AC_CHECK_SIZEOF(unsigned long long, 8)
+
# Detection complete
AC_CONFIG_FILES([Makefile
Modified: cs/cigma/branches/cigma-0.9/src/Makefile.am
===================================================================
--- cs/cigma/branches/cigma-0.9/src/Makefile.am 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/Makefile.am 2007-06-26 17:10:18 UTC (rev 7514)
@@ -1,12 +1,46 @@
-lib_LTLIBRARIES = libcigma.la
+lib_LTLIBRARIES = libcigma.la libcigma.a
-libargtable2_la_SOURCES = \
- argtable2.c \
+libcigma_la_SOURCES = \
+ $(cigma_sources) \
+ $(argtable2_sources) \
+ $(uuid_sources) \
+ $(extra_sources)
+
+cigma_sources = \
+ array.c \
+ attr.c \
+ cube.c \
+ dataset.c \
+ det.c \
+ fe.c \
+ field.c \
+ io.c \
+ mesh.c \
+ points.c \
+ rule.c \
+ split.c \
+ hex8.c \
+ tet4.c
+
+argtable2_sources = \
+ arg_dbl.c \
arg_end.c \
+ arg_file.c \
+ arg_int.c \
+ arg_lit.c \
arg_rem.c \
- arg_lit.c \
- arg_int.c \
- arg_dbl.c \
arg_str.c \
- arg_file.c
+ argtable2.c
+uuid_sources = \
+ uuid.c \
+ uuid_mac.c \
+ uuid_md5.c \
+ uuid_prng.c \
+ uuid_ui64.c
+
+extra_sources = \
+ hash.c \
+ iniparser.c \
+ sqlite3.c
+
Modified: cs/cigma/branches/cigma-0.9/src/README
===================================================================
--- cs/cigma/branches/cigma-0.9/src/README 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/README 2007-06-26 17:10:18 UTC (rev 7514)
@@ -7,3 +7,4 @@
- sqlite3.c and sqlite3.h from http://www.sqlite.org/
- argtable2.[ch], and arg_*.c from http://argtable.sf.net/
- iniparser.[ch] from http://ndevilla.free.fr/iniparser/
+ - uuid*.[ch] from http://www.ossp.org/pkg/lib/uuid/
Added: cs/cigma/branches/cigma-0.9/src/uuid.c
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid.c 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid.c 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,759 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid.c: library API implementation
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include "config.h"
+#include "uuid.h"
+#include "uuid_md5.h"
+#include "uuid_prng.h"
+#include "uuid_mac.h"
+#include "uuid_ui64.h"
+
+/* determine types of 8-bit size */
+#if SIZEOF_CHAR == 1
+typedef char uuid_int8_t;
+#else
+#error uexpected: sizeof(char) != 1 !?
+#endif
+#if SIZEOF_UNSIGNED_CHAR == 1
+typedef unsigned char uuid_uint8_t;
+#else
+#error uexpected: sizeof(unsigned char) != 1 !?
+#endif
+
+/* determine types of 16-bit size */
+#if SIZEOF_SHORT == 2
+typedef short uuid_int16_t;
+#elif SIZEOF_INT == 2
+typedef int uuid_int16_t;
+#elif SIZEOF_LONG == 2
+typedef long uuid_int16_t;
+#else
+#error unexpected: no type found for uuid_int16_t
+#endif
+#if SIZEOF_UNSIGNED_SHORT == 2
+typedef unsigned short uuid_uint16_t;
+#elif SIZEOF_UNSIGNED_INT == 2
+typedef unsigned int uuid_uint16_t;
+#elif SIZEOF_UNSIGNED_LONG == 2
+typedef unsigned long uuid_uint16_t;
+#else
+#error unexpected: no type found for uuid_uint16_t
+#endif
+
+/* determine types of 32-bit size */
+#if SIZEOF_SHORT == 4
+typedef short uuid_int32_t;
+#elif SIZEOF_INT == 4
+typedef int uuid_int32_t;
+#elif SIZEOF_LONG == 4
+typedef long uuid_int32_t;
+#elif SIZEOF_LONG_LONG == 4
+typedef long long uuid_int32_t;
+#else
+#error unexpected: no type found for uuid_int32_t
+#endif
+#if SIZEOF_UNSIGNED_SHORT == 4
+typedef unsigned short uuid_uint32_t;
+#elif SIZEOF_UNSIGNED_INT == 4
+typedef unsigned int uuid_uint32_t;
+#elif SIZEOF_UNSIGNED_LONG == 4
+typedef unsigned long uuid_uint32_t;
+#elif SIZEOF_UNSIGNED_LONG_LONG == 4
+typedef unsigned long long uuid_uint32_t;
+#else
+#error unexpected: no type found for uuid_uint32_t
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+/* UUID binary representation according to UUID standards */
+typedef struct {
+ uuid_uint32_t time_low;
+ uuid_uint16_t time_mid;
+ uuid_uint16_t time_hi_and_version;
+ uuid_uint8_t clock_seq_hi_and_reserved;
+ uuid_uint8_t clock_seq_low;
+ uuid_uint8_t node[6];
+} uuid_obj_t;
+
+/* abstract data type (ADT) of API */
+struct uuid_st {
+ uuid_obj_t obj; /* inlined UUID object */
+ prng_t *prng; /* RPNG sub-object */
+ md5_t *md5; /* MD5 sub-object */
+ uuid_uint8_t mac[6]; /* pre-determined MAC address */
+ struct timeval time_last; /* last retrieved timestamp */
+ unsigned long time_seq; /* last timestamp sequence counter */
+};
+
+/* create UUID object */
+uuid_rc_t uuid_create(uuid_t **uuid)
+{
+ /* argument sanity check */
+ if (uuid == NULL)
+ return UUID_RC_ARG;
+
+ /* allocate UUID object */
+ if ((*uuid = (uuid_t *)malloc(sizeof(uuid_t))) == NULL)
+ return UUID_RC_MEM;
+
+ /* set UUID object initially to "nil UUID" */
+ uuid_nil(*uuid);
+
+ /* create PRNG and MD5 sub-objects */
+ if (prng_create(&(*uuid)->prng) != PRNG_RC_OK)
+ return UUID_RC_INT;
+ if (md5_create(&(*uuid)->md5) != MD5_RC_OK)
+ return UUID_RC_INT;
+
+ /* resolve MAC address for insertion into node field of UUIDs */
+ if (!mac_address((unsigned char *)((*uuid)->mac), sizeof((*uuid)->mac))) {
+ memset((*uuid)->mac, '\0', sizeof((*uuid)->mac));
+ (*uuid)->mac[0] = 0x80;
+ }
+
+ /* initialize time attributes */
+ (*uuid)->time_last.tv_sec = 0;
+ (*uuid)->time_last.tv_usec = 0;
+ (*uuid)->time_seq = 0;
+
+ return UUID_RC_OK;
+}
+
+/* destroy UUID object */
+uuid_rc_t uuid_destroy(uuid_t *uuid)
+{
+ /* argument sanity check */
+ if (uuid == NULL)
+ return UUID_RC_ARG;
+
+ /* destroy PRNG and MD5 sub-objects */
+ prng_destroy(uuid->prng);
+ md5_destroy(uuid->md5);
+
+ /* free UUID object */
+ free(uuid);
+
+ return UUID_RC_OK;
+}
+
+/* set UUID object to represents 'nil UUID' */
+uuid_rc_t uuid_nil(uuid_t *uuid)
+{
+ /* argument sanity check */
+ if (uuid == NULL)
+ return UUID_RC_ARG;
+
+ /* clear all octets to create "nil UUID" */
+ memset((void *)&(uuid->obj), '\0', sizeof(uuid->obj));
+
+ return UUID_RC_OK;
+}
+
+/* compare UUID objects */
+uuid_rc_t uuid_compare(uuid_t *uuid1, uuid_t *uuid2, int *result)
+{
+ int r;
+
+ /* argument sanity check */
+ if (result == NULL)
+ return UUID_RC_ARG;
+
+ /* convinience macro for setting result */
+# define RESULT(r) \
+ do { \
+ *result = (r); \
+ goto result_exit; \
+ } while (0)
+
+ /* special cases: NULL or equal UUIDs */
+ if (uuid1 == uuid2)
+ RESULT(0);
+ if (uuid1 == NULL && uuid2 == NULL)
+ RESULT(0);
+ if (uuid1 == NULL)
+ RESULT((uuid_isnil(uuid2, &r), r) ? 0 : -1);
+ if (uuid2 == NULL)
+ RESULT((uuid_isnil(uuid1, &r), r) ? 0 : 1);
+
+ /* standard cases: regular different UUIDs */
+ if (uuid1->obj.time_low != uuid2->obj.time_low)
+ RESULT((uuid1->obj.time_low < uuid2->obj.time_low) ? -1 : 1);
+ if ((r = (int)uuid1->obj.time_mid
+ - (int)uuid2->obj.time_mid) != 0)
+ RESULT((r < 0) ? -1 : 1);
+ if ((r = (int)uuid1->obj.time_hi_and_version
+ - (int)uuid2->obj.time_hi_and_version) != 0)
+ RESULT((r < 0) ? -1 : 1);
+ if ((r = (int)uuid1->obj.clock_seq_hi_and_reserved
+ - (int)uuid2->obj.clock_seq_hi_and_reserved) != 0)
+ RESULT((r < 0) ? -1 : 1);
+ if ((r = (int)uuid1->obj.clock_seq_low
+ - (int)uuid2->obj.clock_seq_low) != 0)
+ RESULT((r < 0) ? -1 : 1);
+ if ((r = memcmp(uuid1->obj.node, uuid2->obj.node, sizeof(uuid1->obj.node))) != 0)
+ RESULT((r < 0) ? -1 : 1);
+
+ /* default case: the keys are equal */
+ *result = 0;
+
+ result_exit:
+ return UUID_RC_OK;
+}
+
+/* check whether UUID object represents 'nil UUID' */
+uuid_rc_t uuid_isnil(uuid_t *uuid, int *result)
+{
+ const unsigned char *ucp;
+ int i;
+
+ /* sanity check argument(s) */
+ if (uuid == NULL || result == NULL)
+ return UUID_RC_ARG;
+
+ /* a "nil UUID" is defined as all octets zero, so check for this case */
+ *result = TRUE;
+ for (i = 0, ucp = (unsigned char *)&(uuid->obj); i < UUID_LEN_BIN; i++) {
+ if (*ucp++ != '\0') {
+ *result = FALSE;
+ break;
+ }
+ }
+
+ return UUID_RC_OK;
+}
+
+/* unpack UUID binary presentation into UUID object
+ (allows in-place operation for internal efficiency!) */
+uuid_rc_t uuid_unpack(uuid_t *uuid, const void *buf)
+{
+ const uuid_uint8_t *in;
+ uuid_uint32_t tmp32;
+ uuid_uint16_t tmp16;
+ int i;
+
+ /* sanity check argument(s) */
+ if (uuid == NULL || buf == NULL)
+ return UUID_RC_ARG;
+
+ /* treat input buffer as octet stream */
+ in = (const uuid_uint8_t *)buf;
+
+ /* unpack "time_low" field */
+ tmp32 = *in++;
+ tmp32 = (tmp32 << 8) | *in++;
+ tmp32 = (tmp32 << 8) | *in++;
+ tmp32 = (tmp32 << 8) | *in++;
+ uuid->obj.time_low = tmp32;
+
+ /* unpack "time_mid" field */
+ tmp16 = *in++;
+ tmp16 = (tmp16 << 8) | *in++;
+ uuid->obj.time_mid = tmp16;
+
+ /* unpack "time_hi_and_version" field */
+ tmp16 = *in++;
+ tmp16 = (tmp16 << 8) | *in++;
+ uuid->obj.time_hi_and_version = tmp16;
+
+ /* unpack "clock_seq_hi_and_reserved" field */
+ uuid->obj.clock_seq_hi_and_reserved = *in++;
+
+ /* unpack "clock_seq_low" field */
+ uuid->obj.clock_seq_low = *in++;
+
+ /* unpack "node" field */
+ for (i = 0; i < sizeof(uuid->obj.node); i++)
+ uuid->obj.node[i] = *in++;
+
+ return UUID_RC_OK;
+}
+
+/* pack UUID object into binary representation
+ (allows in-place operation for internal efficiency!) */
+uuid_rc_t uuid_pack(uuid_t *uuid, void **buf)
+{
+ uuid_uint8_t *out;
+ uuid_uint32_t tmp32;
+ uuid_uint16_t tmp16;
+ int i;
+
+ /* sanity check argument(s) */
+ if (uuid == NULL || buf == NULL)
+ return UUID_RC_ARG;
+
+ /* optionally allocate octet buffer */
+ if (*buf == NULL)
+ if ((*buf = malloc(sizeof(uuid_t))) == NULL)
+ return UUID_RC_MEM;
+
+ /* treat output buffer as octet stream */
+ out = (uuid_uint8_t *)(*buf);
+
+ /* pack "time_low" field */
+ tmp32 = uuid->obj.time_low;
+ out[3] = (uuid_uint8_t)(tmp32 & 0xff); tmp32 >>= 8;
+ out[2] = (uuid_uint8_t)(tmp32 & 0xff); tmp32 >>= 8;
+ out[1] = (uuid_uint8_t)(tmp32 & 0xff); tmp32 >>= 8;
+ out[0] = (uuid_uint8_t)(tmp32 & 0xff);
+
+ /* pack "time_mid" field */
+ tmp16 = uuid->obj.time_mid;
+ out[5] = (uuid_uint8_t)(tmp16 & 0xff); tmp16 >>= 8;
+ out[4] = (uuid_uint8_t)(tmp16 & 0xff);
+
+ /* pack "time_hi_and_version" field */
+ tmp16 = uuid->obj.time_hi_and_version;
+ out[7] = (uuid_uint8_t)(tmp16 & 0xff); tmp16 >>= 8;
+ out[6] = (uuid_uint8_t)(tmp16 & 0xff);
+
+ /* pack "clock_seq_hi_and_reserved" field */
+ out[8] = uuid->obj.clock_seq_hi_and_reserved;
+
+ /* pack "clock_seq_low" field */
+ out[9] = uuid->obj.clock_seq_low;
+
+ /* pack "node" field */
+ for (i = 0; i < sizeof(uuid->obj.node); i++)
+ out[10+i] = uuid->obj.node[i];
+
+ return UUID_RC_OK;
+}
+
+/* INTERNAL: check for valid UUID string representation syntax */
+static int uuid_isstr(const char *str)
+{
+ int i;
+ const char *cp;
+
+ /* example reference:
+ f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+ 012345678901234567890123456789012345
+ 0 1 2 3 */
+ if (str == NULL)
+ return FALSE;
+ if (strlen(str) != UUID_LEN_STR)
+ return FALSE;
+ for (i = 0, cp = str; i <= UUID_LEN_STR; i++, cp++) {
+ if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
+ if (*cp == '-')
+ continue;
+ else
+ return FALSE;
+ }
+ if (i == UUID_LEN_STR)
+ if (*cp == '\0')
+ continue;
+ if (!isxdigit((int)(*cp)))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* parse string representation into UUID object */
+uuid_rc_t uuid_parse(uuid_t *uuid, const char *str)
+{
+ uuid_uint16_t tmp16;
+ const char *cp;
+ char hexbuf[3];
+ int i;
+
+ /* sanity check argument(s) */
+ if (uuid == NULL || str == NULL)
+ return UUID_RC_ARG;
+
+ /* check for correct UUID string representation syntax */
+ if (!uuid_isstr(str))
+ return UUID_RC_ARG;
+
+ /* parse hex values of "time" parts */
+ uuid->obj.time_low = (uuid_uint32_t)strtoul(str, NULL, 16);
+ uuid->obj.time_mid = (uuid_uint16_t)strtoul(str+9, NULL, 16);
+ uuid->obj.time_hi_and_version = (uuid_uint16_t)strtoul(str+14, NULL, 16);
+
+ /* parse hex values of "clock" parts */
+ tmp16 = (uuid_uint16_t)strtoul(str+19, NULL, 16);
+ uuid->obj.clock_seq_low = (uuid_uint8_t)(tmp16 & 0xff); tmp16 >>= 8;
+ uuid->obj.clock_seq_hi_and_reserved = (uuid_uint8_t)(tmp16 & 0xff);
+
+ /* parse hex values of "node" part */
+ cp = str+24;
+ hexbuf[2] = '\0';
+ for (i = 0; i < sizeof(uuid->obj.node); i++) {
+ hexbuf[0] = *cp++;
+ hexbuf[1] = *cp++;
+ uuid->obj.node[i] = strtoul(hexbuf, NULL, 16);
+ }
+
+ return UUID_RC_OK;
+}
+
+/* format UUID object into string representation */
+uuid_rc_t uuid_format(uuid_t *uuid, char **str)
+{
+ /* sanity check argument(s) */
+ if (uuid == NULL || str == NULL)
+ return UUID_RC_ARG;
+
+ /* optionally allocate string buffer */
+ if (*str == NULL)
+ if ((*str = (char *)malloc(UUID_LEN_STR+1)) == NULL)
+ return UUID_RC_MEM;
+
+ /* format UUID into string representation */
+ sprintf(*str,
+ "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (unsigned long)uuid->obj.time_low,
+ (unsigned int)uuid->obj.time_mid,
+ (unsigned int)uuid->obj.time_hi_and_version,
+ (unsigned int)uuid->obj.clock_seq_hi_and_reserved,
+ (unsigned int)uuid->obj.clock_seq_low,
+ (unsigned int)uuid->obj.node[0],
+ (unsigned int)uuid->obj.node[1],
+ (unsigned int)uuid->obj.node[2],
+ (unsigned int)uuid->obj.node[3],
+ (unsigned int)uuid->obj.node[4],
+ (unsigned int)uuid->obj.node[5]);
+
+ return UUID_RC_OK;
+}
+
+/* INTERNAL: brand UUID with version and variant */
+static void uuid_brand(uuid_t *uuid, int version)
+{
+ /* set version (as given) */
+ uuid->obj.time_hi_and_version &= 0x0fff;
+ uuid->obj.time_hi_and_version |= (((uuid_uint16_t)version & 0x0fff) << 12);
+
+ /* set variant (always DCE 1.1 only) */
+ uuid->obj.clock_seq_hi_and_reserved &= ~((0x03) << 6);
+ uuid->obj.clock_seq_hi_and_reserved |= (0x02 << 6);
+ return;
+}
+
+/* maximum number of 100ns ticks of the actual resolution of system clock
+ (which in our case is 1us (= 1000ns) because we use gettimeofday(2) */
+#define UUIDS_PER_TICK 10
+
+/* INTERNAL: generate UUID version 1: time, clock and node based */
+static uuid_rc_t uuid_generate_v1(uuid_t *uuid, unsigned int mode, va_list ap)
+{
+ struct timeval time_now;
+#ifdef HAVE_NANOSLEEP
+ struct timespec ts;
+#else
+ struct timeval tv;
+#endif
+ ui64_t t;
+ ui64_t offset;
+ ui64_t ov;
+ uuid_uint16_t clck;
+
+ /*
+ * GENERATE TIME
+ */
+
+ /* determine current system time and sequence counter */
+ while (1) {
+ /* determine current system time */
+ if (gettimeofday(&time_now, NULL) == -1)
+ return UUID_RC_SYS;
+
+ /* check whether system time changed since last retrieve */
+ if (!( time_now.tv_sec == uuid->time_last.tv_sec
+ && time_now.tv_usec == uuid->time_last.tv_usec))
+ /* reset time sequence counter */
+ uuid->time_seq = 0;
+
+ /* until we are out of UUIDs per tick, increment
+ the time/tick sequence counter and continue */
+ if (uuid->time_seq < UUIDS_PER_TICK) {
+ uuid->time_seq++;
+ break;
+ }
+
+ /* stall the UUID generation until the system clock (which
+ has a gettimeofday(2) resolution of 1us) catches up */
+#ifdef HAVE_NANOSLEEP
+ /* sleep for 500ns (1/2us) */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 500;
+ nanosleep(&ts, NULL);
+#else
+ /* sleep for 1000ns (1us) */
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+ select(0, NULL, NULL, NULL, &tv);
+#endif
+ }
+
+ /* convert from timeval (sec,usec) to OSSP ui64 (100*nsec) format */
+ t = ui64_n2i(time_now.tv_sec);
+ t = ui64_muln(t, 1000000, NULL);
+ t = ui64_addn(t, time_now.tv_usec, NULL);
+ t = ui64_muln(t, 10, NULL);
+
+ /* adjust for offset between UUID and Unix Epoch time through adding
+ the magic offset 01B21DD213814000 from draft-leach-uuids-guids-01.
+ (UUID UTC base time is October 15, 1582
+ Unix UTC base time is January 1, 1970) */
+ offset = ui64_s2i("01B21DD213814000", NULL, 16);
+ t = ui64_add(t, offset, NULL);
+
+ /* compensate for low resolution system clock by adding
+ the time/tick sequence counter */
+ if (uuid->time_seq > 0)
+ t = ui64_addn(t, uuid->time_seq, NULL);
+
+ /* store the 60 LSB of the time in the UUID */
+ t = ui64_rol(t, 16, &ov);
+ uuid->obj.time_hi_and_version =
+ (uuid_uint16_t)(ui64_i2n(ov) & 0x00000fff); /* 12 of 16 bit only! */
+ t = ui64_rol(t, 16, &ov);
+ uuid->obj.time_mid =
+ (uuid_uint16_t)(ui64_i2n(ov) & 0x0000ffff); /* all 16 bit */
+ t = ui64_rol(t, 32, &ov);
+ uuid->obj.time_low =
+ (uuid_uint32_t)(ui64_i2n(ov) & 0xffffffff); /* all 32 bit */
+
+ /*
+ * GENERATE CLOCK
+ */
+
+ /* retrieve current clock sequence */
+ clck = ((uuid->obj.clock_seq_hi_and_reserved & ~((0x03) << 6)) << 8)
+ + uuid->obj.clock_seq_low;
+
+ /* generate new random clock sequence (initially or if the
+ time has stepped backwards) or else just increase it */
+ if ( clck == 0
+ || ( time_now.tv_sec < uuid->time_last.tv_sec
+ || ( time_now.tv_sec == uuid->time_last.tv_sec
+ && time_now.tv_usec < uuid->time_last.tv_usec)))
+ prng_data(uuid->prng, (void *)&clck, sizeof(clck));
+ else
+ clck++;
+ clck &= ~((0x03) << 6);
+
+ /* store back new clock sequence */
+ uuid->obj.clock_seq_hi_and_reserved =
+ (uuid->obj.clock_seq_hi_and_reserved & ((0x03) << 6))
+ | (uuid_uint8_t)((clck >> 8) & 0xff);
+ uuid->obj.clock_seq_low =
+ (uuid_uint8_t)(clck & 0xff);
+
+ /*
+ * GENERATE NODE
+ */
+
+ if ((mode & UUID_MCASTRND) || (uuid->mac[0] & 0x80)) {
+ /* use random multi-cast MAC address */
+ prng_data(uuid->prng, (void *)&(uuid->obj.node), sizeof(uuid->obj.node));
+ uuid->obj.node[0] |= 0x80;
+ }
+ else {
+ /* use real regular MAC address */
+ memcpy(uuid->obj.node, uuid->mac, sizeof(uuid->mac));
+ }
+
+ /*
+ * FINISH
+ */
+
+ /* remember current system time for next iteration */
+ uuid->time_last.tv_sec = time_now.tv_sec;
+ uuid->time_last.tv_usec = time_now.tv_usec;
+
+ /* brand with version and variant */
+ uuid_brand(uuid, 1);
+
+ return UUID_RC_OK;
+}
+
+/* INTERNAL: UUID Namespace Ids as pre-defined by draft-leach-uuids-guids-01.txt
+ (defined here as network byte ordered octet stream for direct MD5 feeding) */
+static struct {
+ char *name;
+ uuid_uint8_t uuid[UUID_LEN_BIN];
+} uuid_ns_table[] = {
+ { "DNS", /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
+ { 0x6b,0xa7,0xb8,0x10,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8 } },
+ { "URL", /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */
+ { 0x6b,0xa7,0xb8,0x11,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8 } },
+ { "OID", /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */
+ { 0x6b,0xa7,0xb8,0x12,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8 } },
+ { "X500", /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */
+ { 0x6b,0xa7,0xb8,0x14,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8 } }
+};
+
+/* INTERNAL: generate UUID version 3: name based */
+static uuid_rc_t uuid_generate_v3(uuid_t *uuid, unsigned int mode, va_list ap)
+{
+ char *str;
+ char *ns;
+ void *uuid_octets;
+ uuid_t *uuid_object;
+ uuid_rc_t rc;
+ int i;
+
+ /* determine namespace UUID name and argument name string */
+ if ((ns = (char *)va_arg(ap, char *)) == NULL)
+ return UUID_RC_ARG;
+ if ((str = (char *)va_arg(ap, char *)) == NULL)
+ return UUID_RC_ARG;
+
+ /* initialize MD5 context */
+ if (md5_init(uuid->md5) != MD5_RC_OK)
+ return UUID_RC_MEM;
+
+ /* load the namespace UUID into MD5 context */
+ if (uuid_isstr(ns)) {
+ /* custom namespace via UUID string representation */
+ if ((rc = uuid_create(&uuid_object)) != UUID_RC_OK)
+ return rc;
+ if ((rc = uuid_parse(uuid_object, ns)) != UUID_RC_OK)
+ return rc;
+ uuid_octets = (void *)&(uuid_object->obj);
+ uuid_pack(uuid_object, &uuid_octets);
+ md5_update(uuid->md5, uuid_octets, UUID_LEN_BIN);
+ uuid_destroy(uuid_object);
+ }
+ else {
+ /* standard namespace via UUID namespace id */
+ uuid_octets = NULL;
+ for (i = 0; i < sizeof(uuid_ns_table)/sizeof(uuid_ns_table[0]); i++) {
+ if (strcmp(uuid_ns_table[i].name, ns) == 0) {
+ uuid_octets = uuid_ns_table[i].uuid;
+ break;
+ }
+ }
+ if (uuid_octets == NULL)
+ return UUID_RC_ARG;
+ md5_update(uuid->md5, uuid_octets, UUID_LEN_BIN);
+ }
+
+ /* load the argument name string into MD5 context */
+ md5_update(uuid->md5, str, strlen(str));
+
+ /* store MD5 result into UUID
+ (requires MD5_LEN_BIN space, UUID_LEN_BIN space is available,
+ and both are equal in size, so we are safe!) */
+ uuid_octets = (void *)&(uuid->obj);
+ md5_store(uuid->md5, &uuid_octets, NULL);
+
+ /* fulfill requirement of standard and convert UUID data into
+ local/host byte order (this uses fact that uuid_unpack() is
+ able to operate in-place!) */
+ uuid_unpack(uuid, (void *)&(uuid->obj));
+
+ /* brand UUID with version and variant */
+ uuid_brand(uuid, 3);
+
+ return UUID_RC_OK;
+}
+
+/* INTERNAL: generate UUID version 4: random number based */
+static uuid_rc_t uuid_generate_v4(uuid_t *uuid, unsigned int mode, va_list ap)
+{
+ /* fill UUID with random data */
+ prng_data(uuid->prng, (void *)&(uuid->obj), sizeof(uuid->obj));
+
+ /* brand UUID with version and variant */
+ uuid_brand(uuid, 4);
+
+ return UUID_RC_OK;
+}
+
+/* generate UUID */
+uuid_rc_t uuid_generate(uuid_t *uuid, unsigned int mode, ...)
+{
+ va_list ap;
+ uuid_rc_t rc;
+
+ /* sanity check argument(s) */
+ if (uuid == NULL)
+ return UUID_RC_ARG;
+
+ /* dispatch into version dependent generation functions */
+ va_start(ap, mode);
+ if (mode & UUID_VERSION1)
+ rc = uuid_generate_v1(uuid, mode, ap);
+ else if (mode & UUID_VERSION3)
+ rc = uuid_generate_v3(uuid, mode, ap);
+ else if (mode & UUID_VERSION4)
+ rc = uuid_generate_v4(uuid, mode, ap);
+ else
+ rc = UUID_RC_ARG;
+ va_end(ap);
+
+ return rc;
+}
+
+/* dump UUID object as descriptive text */
+uuid_rc_t uuid_dump(uuid_t *uuid, char **str)
+{
+ /* sanity check argument(s) */
+ if (uuid == NULL || str == NULL)
+ return UUID_RC_ARG;
+ /* FIXME */
+ return UUID_RC_OK;
+}
+
+/* translate UUID API error code into corresponding error string */
+char *uuid_error(uuid_rc_t rc)
+{
+ char *str;
+
+ switch (rc) {
+ case UUID_RC_OK: str = "everything ok"; break;
+ case UUID_RC_ARG: str = "invalid argument"; break;
+ case UUID_RC_MEM: str = "out of memory"; break;
+ case UUID_RC_SYS: str = "system error"; break;
+ default: str = NULL; break;
+ }
+ return str;
+}
+
Added: cs/cigma/branches/cigma-0.9/src/uuid.h
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid.h 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid.h 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,120 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid.h: library API definition
+*/
+
+#ifndef __UUID_H__
+#define __UUID_H__
+
+/*
+ * UUID Binary Representation:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 0| time_low |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 1| time_mid | time_hi_and_version |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 2|clk_seq_hi_res | clk_seq_low | node (0-1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 3| node (2-5) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * UUID ASCII String Representation:
+ *
+ * uuid = <time_low> "-" <time_mid> "-"
+ * <time_high_and_version> "-"
+ * <clock_seq_and_reserved>
+ * <clock_seq_low> "-" <node>
+ * time_low = 4*<hexOctet>
+ * time_mid = 2*<hexOctet>
+ * time_high_and_version = 2*<hexOctet>
+ * clock_seq_and_reserved = <hexOctet>
+ * clock_seq_low = <hexOctet>
+ * node = 6*<hexOctet>
+ * hexOctet = <hexDigit> <hexDigit>
+ * hexDigit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
+ * |"a"|"b"|"c"|"d"|"e"|"f"
+ * |"A"|"B"|"C"|"D"|"E"|"F"
+ *
+ * Example string representation of a UUID:
+ *
+ * "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
+ */
+
+/* encoding octet stream lengths */
+#define UUID_LEN_BIN (128 / 8 /*bytes*/)
+#define UUID_LEN_STR (128 / 4 /*nibbles*/ + 4 /*hyphens*/)
+
+/* return codes */
+typedef enum {
+ UUID_RC_OK = 0,
+ UUID_RC_ARG = 1,
+ UUID_RC_MEM = 2,
+ UUID_RC_SYS = 3,
+ UUID_RC_INT = 4
+} uuid_rc_t;
+
+/* generation mode flags */
+enum {
+ UUID_VERSION1 = (1 << 0),
+ UUID_VERSION3 = (1 << 1),
+ UUID_VERSION4 = (1 << 2),
+ UUID_MCASTRND = (1 << 3)
+};
+
+/* abstract data type */
+struct uuid_st;
+typedef struct uuid_st uuid_t;
+
+/* object handling */
+extern uuid_rc_t uuid_create (uuid_t **uuid);
+extern uuid_rc_t uuid_destroy (uuid_t *uuid);
+extern uuid_rc_t uuid_nil (uuid_t *uuid);
+
+/* UUID comparison */
+extern uuid_rc_t uuid_compare (uuid_t *uuid, uuid_t *uuid2, int *result);
+extern uuid_rc_t uuid_isnil (uuid_t *uuid, int *result);
+
+/* binary representation handling */
+extern uuid_rc_t uuid_unpack (uuid_t *uuid, const void *buf);
+extern uuid_rc_t uuid_pack (uuid_t *uuid, void **buf);
+
+/* string representation handling */
+extern uuid_rc_t uuid_parse (uuid_t *uuid, const char *str);
+extern uuid_rc_t uuid_format (uuid_t *uuid, char **str);
+
+/* UUID generation and dumping */
+extern uuid_rc_t uuid_generate (uuid_t *uuid, unsigned int mode, ...);
+extern uuid_rc_t uuid_dump (uuid_t *uuid, char **str);
+
+/* error handling */
+extern char *uuid_error (uuid_rc_t rc);
+
+#endif /* __UUID_H__ */
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_mac.c
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_mac.c 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_mac.c 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,178 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid_mac.c: Media Access Control (MAC) resolver implementation
+*/
+
+#include "config.h"
+#include "uuid_mac.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NET_IF_DL_H
+#include <net/if_dl.h>
+#endif
+#ifdef HAVE_NET_IF_ARP_H
+#include <net/if_arp.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+/* return the Media Access Control (MAC) address of
+ the FIRST network interface card (NIC) */
+int mac_address(unsigned char *data_ptr, size_t data_len)
+{
+ /* sanity check arguments */
+ if (data_ptr == NULL || data_len < MAC_LEN)
+ return FALSE;
+
+#if defined(HAVE_IFADDRS_H) && defined(HAVE_NET_IF_DL_H) && defined(HAVE_GETIFADDRS)
+ /* use getifaddrs(3) on BSD class platforms (xxxBSD, MacOS X, etc) */
+ {
+ struct ifaddrs *ifap;
+ struct ifaddrs *ifap_head;
+ const struct sockaddr_dl *sdl;
+ unsigned char *ucp;
+ int i;
+
+ if (getifaddrs(&ifap_head) < 0)
+ return FALSE;
+ for (ifap = ifap_head; ifap != NULL; ifap = ifap->ifa_next) {
+ if (ifap->ifa_addr != NULL && ifap->ifa_addr->sa_family == AF_LINK) {
+ sdl = (const struct sockaddr_dl *)ifap->ifa_addr;
+ ucp = (unsigned char *)(sdl->sdl_data + sdl->sdl_nlen);
+ if (ucp != NULL && sdl->sdl_alen > 0) {
+ for (i = 0; i < MAC_LEN && i < sdl->sdl_alen; i++, ucp++)
+ data_ptr[i] = (unsigned char)(*ucp & 0xff);
+ freeifaddrs(ifap_head);
+ return TRUE;
+ }
+ }
+ }
+ freeifaddrs(ifap_head);
+ }
+#endif
+
+#if defined(HAVE_NET_IF_H) && defined(SIOCGIFHWADDR)
+ /* use SIOCGIFHWADDR ioctl(2) on Linux class platforms */
+ {
+ struct ifreq ifr;
+ struct sockaddr *sa;
+ int s;
+ int i;
+
+ if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+ return FALSE;
+ sprintf(ifr.ifr_name, "eth0");
+ if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+ close(s);
+ return FALSE;
+ }
+ sa = (struct sockaddr *)&ifr.ifr_addr;
+ for (i = 0; i < MAC_LEN; i++)
+ data_ptr[i] = (unsigned char)(sa->sa_data[i] & 0xff);
+ close(s);
+ return TRUE;
+ }
+#endif
+
+#if defined(SIOCGARP)
+ /* use SIOCGARP ioctl(2) on SVR4 class platforms (Solaris, etc) */
+ {
+ char hostname[MAXHOSTNAMELEN];
+ struct hostent *he;
+ struct arpreq ar;
+ struct sockaddr_in *sa;
+ int s;
+ int i;
+
+ if (gethostname(hostname, sizeof(hostname)) < 0)
+ return FALSE;
+ if ((he = gethostbyname(hostname)) == NULL)
+ return FALSE;
+ if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ return FALSE;
+ memset(&ar, '\0', sizeof(ar));
+ sa = (struct sockaddr_in *)((void *)&(ar.arp_pa));
+ sa->sin_family = AF_INET;
+ memcpy(&(sa->sin_addr), *(he->h_addr_list), sizeof(struct in_addr));
+ if (ioctl(s, SIOCGARP, &ar) < 0) {
+ close(s);
+ return FALSE;
+ }
+ for (i = 0; i < MAC_LEN; i++)
+ data_ptr[i] = (unsigned char)(ar.arp_ha.sa_data[i] & 0xff);
+ close(s);
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_mac.h
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_mac.h 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_mac.h 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,40 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid_mac.h: Media Access Control (MAC) resolver API definition
+*/
+
+#ifndef __UUID_MAC_H__
+#define __UUID_MAC_H__
+
+#include <string.h> /* size_t */
+
+#define MAC_LEN 6
+
+extern int mac_address(unsigned char *data_ptr, size_t data_len);
+
+#endif /* __UUID_MAC_H__ */
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_md5.c
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_md5.c 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_md5.c 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,456 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid_md5.c: MD5 API implementation
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "uuid_md5.h"
+
+/*
+ * This is a RFC 1321 compliant Message Digest 5 (MD5) algorithm
+ * implementation. It is directly derived from the RSA code published in
+ * RFC 1321 with just the following functionality preserving changes:
+ * - converted function definitions from K&R to ANSI C
+ * - included contents of the "global.h" and "md5.h" headers
+ * - moved the SXX defines into the MD5Transform function
+ * - replaced MD5_memcpy() with memcpy(3) and MD5_memset() with memset(3)
+ * - renamed "index" variables to "idx" to avoid namespace conflicts
+ * - reformatted C style to conform with OSSP C style
+ * - added own OSSP style frontend API
+ */
+
+/*
+** ==== BEGIN RFC 1321 CODE ====
+*/
+
+/*
+ * RSA Data Security, Inc., MD5 message-digest algorithm
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
+ * All rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+static void MD5Init (MD5_CTX *_ctx);
+static void MD5Update (MD5_CTX *_ctx, unsigned char *, unsigned int);
+static void MD5Final (unsigned char [16], MD5_CTX *);
+
+static void MD5Transform (UINT4 [4], unsigned char [64]);
+static void Encode (unsigned char *, UINT4 *, unsigned int);
+static void Decode (UINT4 *, unsigned char *, unsigned int);
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ Rotation is separate from addition to prevent recomputation. */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+}
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+}
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+}
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+}
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+static void MD5Init(
+ MD5_CTX *context)
+{
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants. */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context. */
+static void MD5Update(
+ MD5_CTX *context, /* context */
+ unsigned char *input, /* input block */
+ unsigned int inputLen) /* length of input block */
+{
+ unsigned int i, idx, partLen;
+
+ /* Compute number of bytes mod 64 */
+ idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - idx;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
+ MD5Transform(context->state, context->buffer);
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+ idx = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i], inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context. */
+static void MD5Final(
+ unsigned char digest[16], /* message digest */
+ MD5_CTX *context) /* context */
+{
+ unsigned char bits[8];
+ unsigned int idx, padLen;
+
+ /* Save number of bits */
+ Encode(bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+ MD5Update(context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update(context, bits, 8);
+
+ /* Store state in digest */
+ Encode(digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+static void MD5Transform(
+ UINT4 state[4],
+ unsigned char block[64])
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode(x, block, 64);
+
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information. */
+ memset((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char).
+ Assumes len is a multiple of 4. */
+static void Encode(
+ unsigned char *output,
+ UINT4 *input,
+ unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)( input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4).
+ Assumes len is a multiple of 4. */
+static void Decode(
+ UINT4 *output,
+ unsigned char *input,
+ unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ( (UINT4)input[j])
+ | (((UINT4)input[j+1]) << 8 )
+ | (((UINT4)input[j+2]) << 16)
+ | (((UINT4)input[j+3]) << 24);
+}
+
+/*
+** ==== END RFC 1321 CODE ====
+*/
+
+struct md5_st {
+ MD5_CTX ctx;
+};
+
+md5_rc_t md5_create(md5_t **md5)
+{
+ if (md5 == NULL)
+ return MD5_RC_ARG;
+ if ((*md5 = (md5_t *)malloc(sizeof(md5_t))) == NULL)
+ return MD5_RC_MEM;
+ MD5Init(&((*md5)->ctx));
+ return MD5_RC_OK;
+}
+
+md5_rc_t md5_init(md5_t *md5)
+{
+ if (md5 == NULL)
+ return MD5_RC_ARG;
+ MD5Init(&(md5->ctx));
+ return MD5_RC_OK;
+}
+
+md5_rc_t md5_update(md5_t *md5, const void *data_ptr, size_t data_len)
+{
+ if (md5 == NULL)
+ return MD5_RC_ARG;
+ MD5Update(&(md5->ctx), (unsigned char *)data_ptr, (unsigned int)data_len);
+ return MD5_RC_OK;
+}
+
+md5_rc_t md5_store(md5_t *md5, void **data_ptr, size_t *data_len)
+{
+ MD5_CTX ctx;
+
+ if (md5 == NULL || data_ptr == NULL)
+ return MD5_RC_ARG;
+ if (*data_ptr == NULL) {
+ if ((*data_ptr = malloc(MD5_LEN_BIN)) == NULL)
+ return MD5_RC_MEM;
+ if (data_len != NULL)
+ *data_len = MD5_LEN_BIN;
+ }
+ else {
+ if (data_len != NULL) {
+ if (*data_len < MD5_LEN_BIN)
+ return MD5_RC_MEM;
+ *data_len = MD5_LEN_BIN;
+ }
+ }
+ memcpy((void *)(&ctx), (void *)(&(md5->ctx)), sizeof(MD5_CTX));
+ MD5Final((unsigned char *)(*data_ptr), &(md5->ctx));
+ memcpy((void *)(&(md5->ctx)), (void *)(&ctx), sizeof(MD5_CTX));
+ return MD5_RC_OK;
+}
+
+md5_rc_t md5_format(md5_t *md5, char **data_ptr, size_t *data_len)
+{
+ static const char hex[] = "0123456789abcdef";
+ unsigned char buf[MD5_LEN_BIN];
+ unsigned char *bufptr;
+ size_t buflen;
+ md5_rc_t rc;
+ int i;
+
+ if (md5 == NULL || data_ptr == NULL)
+ return MD5_RC_ARG;
+ if (*data_ptr == NULL) {
+ if ((*data_ptr = malloc(MD5_LEN_STR+1)) == NULL)
+ return MD5_RC_MEM;
+ if (data_len != NULL)
+ *data_len = MD5_LEN_STR+1;
+ }
+ else {
+ if (data_len != NULL) {
+ if (*data_len < MD5_LEN_STR+1)
+ return MD5_RC_MEM;
+ *data_len = MD5_LEN_STR+1;
+ }
+ }
+
+ bufptr = buf;
+ buflen = sizeof(buf);
+ if ((rc = md5_store(md5, (void *)(&bufptr), &buflen)) != MD5_RC_OK)
+ return rc;
+
+ for (i = 0; i < buflen; i++) {
+ (*data_ptr)[(i*2)+0] = hex[(int)(bufptr[i] >> 4)];
+ (*data_ptr)[(i*2)+1] = hex[(int)(bufptr[i] & 0x0f)];
+ }
+ (*data_ptr)[(i*2)] = '\0';
+ return MD5_RC_OK;
+}
+
+md5_rc_t md5_destroy(md5_t *md5)
+{
+ if (md5 == NULL)
+ return MD5_RC_ARG;
+ free(md5);
+ return MD5_RC_OK;
+}
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_md5.h
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_md5.h 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_md5.h 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,75 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid_md5.h: MD5 API definition
+*/
+
+#ifndef __MD5_H___
+#define __MD5_H___
+
+#include <string.h> /* size_t */
+
+#define MD5_PREFIX uuid_
+
+/* embedding support */
+#ifdef MD5_PREFIX
+#if defined(__STDC__) || defined(__cplusplus)
+#define __MD5_CONCAT(x,y) x ## y
+#define MD5_CONCAT(x,y) __MD5_CONCAT(x,y)
+#else
+#define __MD5_CONCAT(x) x
+#define MD5_CONCAT(x,y) __MD5_CONCAT(x)y
+#endif
+#define md5_st MD5_CONCAT(MD5_PREFIX,md5_st)
+#define md5_t MD5_CONCAT(MD5_PREFIX,md5_t)
+#define md5_create MD5_CONCAT(MD5_PREFIX,md5_create)
+#define md5_update MD5_CONCAT(MD5_PREFIX,md5_update)
+#define md5_store MD5_CONCAT(MD5_PREFIX,md5_store)
+#define md5_format MD5_CONCAT(MD5_PREFIX,md5_format)
+#define md5_destroy MD5_CONCAT(MD5_PREFIX,md5_destroy)
+#endif
+
+struct md5_st;
+typedef struct md5_st md5_t;
+
+#define MD5_LEN_BIN 16
+#define MD5_LEN_STR 32
+
+typedef enum {
+ MD5_RC_OK = 0,
+ MD5_RC_ARG = 1,
+ MD5_RC_MEM = 2
+} md5_rc_t;
+
+extern md5_rc_t md5_create (md5_t **md5);
+extern md5_rc_t md5_init (md5_t *md5);
+extern md5_rc_t md5_update (md5_t *md5, const void *data_ptr, size_t data_len);
+extern md5_rc_t md5_store (md5_t *md5, void **data_ptr, size_t *data_len);
+extern md5_rc_t md5_format (md5_t *md5, char **data_ptr, size_t *data_len);
+extern md5_rc_t md5_destroy (md5_t *md5);
+
+#endif /* __MD5_H___ */
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_prng.c
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_prng.c 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_prng.c 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,132 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid_prng.c: PRNG API implementation
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+#include "uuid_prng.h"
+
+struct prng_st {
+ int devfd;
+};
+
+prng_rc_t prng_create(prng_t **prng)
+{
+ int fd = -1;
+ struct timeval tv;
+ pid_t pid;
+ size_t i;
+
+ /* sanity check argument(s) */
+ if (prng == NULL)
+ return PRNG_RC_ARG;
+
+ /* allocate object */
+ if ((*prng = (prng_t *)malloc(sizeof(prng_t))) == NULL)
+ return PRNG_RC_MEM;
+
+ /* try to open the system PRNG device */
+ (*prng)->devfd = -1;
+ if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
+ fd = open("/dev/random", O_RDONLY|O_NONBLOCK);
+ if (fd != -1) {
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ (*prng)->devfd = fd;
+ }
+
+ /* seed the C library PRNG once */
+ gettimeofday(&tv, NULL);
+ pid = getpid();
+ srand((unsigned int)(
+ ((unsigned int)pid << 16)
+ ^ (unsigned int)pid
+ ^ (unsigned int)tv.tv_sec
+ ^ (unsigned int)tv.tv_usec));
+
+ /* crank the PRNG a few times */
+ gettimeofday(&tv, NULL);
+ for (i = (unsigned int)(tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
+ (void)rand();
+
+ return PRNG_RC_OK;
+}
+
+prng_rc_t prng_data(prng_t *prng, void *data_ptr, size_t data_len)
+{
+ size_t n;
+ unsigned char *p;
+ int cnt;
+ int i;
+
+ /* sanity check argument(s) */
+ if (prng == NULL || data_len == 0)
+ return PRNG_RC_ARG;
+
+ /* try to gather data from the system PRNG device */
+ if (prng->devfd != -1) {
+ p = data_ptr;
+ n = data_len;
+ cnt = 0;
+ while (n > 0) {
+ i = read(prng->devfd, (void *)p, n);
+ if (i <= 0) {
+ if (cnt++ > 16)
+ break;
+ continue;
+ }
+ n -= i;
+ p += i;
+ cnt = 0;
+ }
+ }
+
+ /* always also apply the weaker PRNG. In case the stronger PRNG device
+ based source failed, this is the only remaining randomness, of course */
+ for (p = data_ptr, n = 0; n < data_len; n++)
+ *p++ ^= (unsigned char)(((unsigned int)rand() >> 7) & 0xFF);
+
+ return PRNG_RC_OK;
+}
+
+prng_rc_t prng_destroy(prng_t *prng)
+{
+ /* sanity check argument(s) */
+ if (prng == NULL)
+ return PRNG_RC_ARG;
+
+ /* free object */
+ free(prng);
+
+ return PRNG_RC_OK;
+}
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_prng.h
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_prng.h 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_prng.h 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,67 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** uuid_prng.h: PRNG API definition
+*/
+
+#ifndef __PRNG_H___
+#define __PRNG_H___
+
+#include <string.h> /* size_t */
+
+#define PRNG_PREFIX uuid_
+
+/* embedding support */
+#ifdef PRNG_PREFIX
+#if defined(__STDC__) || defined(__cplusplus)
+#define __PRNG_CONCAT(x,y) x ## y
+#define PRNG_CONCAT(x,y) __PRNG_CONCAT(x,y)
+#else
+#define __PRNG_CONCAT(x) x
+#define PRNG_CONCAT(x,y) __PRNG_CONCAT(x)y
+#endif
+#define prng_st PRNG_CONCAT(PRNG_PREFIX,prng_st)
+#define prng_t PRNG_CONCAT(PRNG_PREFIX,prng_t)
+#define prng_create PRNG_CONCAT(PRNG_PREFIX,prng_create)
+#define prng_data PRNG_CONCAT(PRNG_PREFIX,prng_data)
+#define prng_destroy PRNG_CONCAT(PRNG_PREFIX,prng_destroy)
+#endif
+
+struct prng_st;
+typedef struct prng_st prng_t;
+
+typedef enum {
+ PRNG_RC_OK = 0,
+ PRNG_RC_ARG = 1,
+ PRNG_RC_MEM = 2
+} prng_rc_t;
+
+extern prng_rc_t prng_create (prng_t **prng);
+extern prng_rc_t prng_data (prng_t *prng, void *data_ptr, size_t data_len);
+extern prng_rc_t prng_destroy (prng_t *prng);
+
+#endif /* __PRNG_H___ */
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_ui64.c
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_ui64.c 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_ui64.c 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,582 @@
+/*
+** OSSP ui64 - 64-Bit Arithmetic
+** Copyright (c) 2002-2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP ui64, a 64-bit arithmetic library
+** which can be found at http://www.ossp.org/pkg/lib/ui64/.
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** ui64.c: implementation of 64-bit unsigned integer arithmetic
+*/
+
+#include <string.h>
+#include <ctype.h>
+
+#include "uuid_ui64.h"
+
+#define UI64_BASE 256 /* 2^8 */
+#define UI64_DIGITS 8 /* 8*8 = 64 bit */
+#define UIXX_T(n) struct { unsigned char x[n]; }
+
+/* fill an ui64_t with a sequence of a particular digit */
+#define ui64_fill(__x, __n) \
+ do { int __i; \
+ for (__i = 0; __i < UI64_DIGITS; __i++) \
+ (__x).x[__i] = (__n); \
+ } while(0)
+
+/* the value zero */
+ui64_t ui64_zero(void)
+{
+ ui64_t z;
+
+ ui64_fill(z, 0);
+ return z;
+}
+
+/* the maximum value */
+ui64_t ui64_max(void)
+{
+ ui64_t z;
+
+ ui64_fill(z, UI64_BASE-1);
+ return z;
+}
+
+/* convert ISO-C "unsigned long" into internal format */
+ui64_t ui64_n2i(unsigned long n)
+{
+ ui64_t z;
+ int i;
+
+ i = 0;
+ do {
+ z.x[i++] = (n % UI64_BASE);
+ } while ((n /= UI64_BASE) > 0 && i < UI64_DIGITS);
+ for ( ; i < UI64_DIGITS; i++)
+ z.x[i] = 0;
+ return z;
+}
+
+/* convert internal format into ISO-C "unsigned long";
+ truncates if sizeof(unsigned long) is less than UI64_DIGITS! */
+unsigned long ui64_i2n(ui64_t x)
+{
+ unsigned long n;
+ int i;
+
+ n = 0;
+ i = (int)sizeof(n);
+ if (i > UI64_DIGITS)
+ i = UI64_DIGITS;
+ while (--i >= 0) {
+ n = (n * UI64_BASE) + x.x[i];
+ }
+ return n;
+}
+
+/* convert string representation of arbitrary base into internal format */
+ui64_t ui64_s2i(const char *str, char **end, int base)
+{
+ ui64_t z;
+ const char *cp;
+ int carry;
+ static char map[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 0...9 */
+ 36, 36, 36, 36, 36, 36, 36, /* illegal chars */
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, /* A...M */
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, /* N...Z */
+ 36, 36, 36, 36, 36, 36, /* illegal chars */
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, /* a...m */
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 /* m...z */
+ };
+
+ ui64_fill(z, 0);
+ if (str == NULL || (base < 2 || base > 36))
+ return z;
+ cp = str;
+ while (*cp != '\0' && isspace((int)(*cp)))
+ cp++;
+ while ( *cp != '\0'
+ && isalnum((int)(*cp))
+ && map[(int)(*cp)-'0'] < base) {
+ z = ui64_muln(z, base, &carry);
+ if (carry)
+ break;
+ z = ui64_addn(z, map[(int)(*cp)-'0'], &carry);
+ if (carry)
+ break;
+ cp++;
+ }
+ if (end != NULL)
+ *end = (char *)cp;
+ return z;
+}
+
+/* convert internal format into string representation of arbitrary base */
+char *ui64_i2s(ui64_t x, char *str, size_t len, int base)
+{
+ static char map[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char c;
+ int r;
+ int n;
+ int i, j;
+
+ if (str == NULL || len < 2 || (base < 2 || base > 36))
+ return NULL;
+ n = ui64_len(x);
+ i = 0;
+ do {
+ x = ui64_divn(x, base, &r);
+ str[i++] = map[r];
+ while (n > 1 && x.x[n-1] == 0)
+ n--;
+ } while (i < (len-1) && (n > 1 || x.x[0] != 0));
+ str[i] = '\0';
+ for (j = 0; j < --i; j++) {
+ c = str[j];
+ str[j] = str[i];
+ str[i] = c;
+ }
+ return str;
+}
+
+/* addition of two ui64_t */
+ui64_t ui64_add(ui64_t x, ui64_t y, ui64_t *ov)
+{
+ ui64_t z;
+ int carry;
+ int i;
+
+ carry = 0;
+ for (i = 0; i < UI64_DIGITS; i++) {
+ carry += (x.x[i] + y.x[i]);
+ z.x[i] = (carry % UI64_BASE);
+ carry /= UI64_BASE;
+ }
+ if (ov != NULL)
+ *ov = ui64_n2i((unsigned long)carry);
+ return z;
+}
+
+/* addition of an ui64_t and a single digit */
+ui64_t ui64_addn(ui64_t x, int y, int *ov)
+{
+ ui64_t z;
+ int i;
+
+ for (i = 0; i < UI64_DIGITS; i++) {
+ y += x.x[i];
+ z.x[i] = (y % UI64_BASE);
+ y /= UI64_BASE;
+ }
+ if (ov != NULL)
+ *ov = y;
+ return z;
+}
+
+/* subtraction of two ui64_t */
+ui64_t ui64_sub(ui64_t x, ui64_t y, ui64_t *ov)
+{
+ ui64_t z;
+ int borrow;
+ int i;
+ int d;
+
+ borrow = 0;
+ for (i = 0; i < UI64_DIGITS; i++) {
+ d = ((x.x[i] + UI64_BASE) - borrow - y.x[i]);
+ z.x[i] = (d % UI64_BASE);
+ borrow = (1 - (d/UI64_BASE));
+ }
+ if (ov != NULL)
+ *ov = ui64_n2i((unsigned long)borrow);
+ return z;
+}
+
+/* subtraction of an ui64_t and a single digit */
+ui64_t ui64_subn(ui64_t x, int y, int *ov)
+{
+ ui64_t z;
+ int i;
+ int d;
+
+ for (i = 0; i < UI64_DIGITS; i++) {
+ d = (x.x[i] + UI64_BASE) - y;
+ z.x[i] = (d % UI64_BASE);
+ y = (1 - (d/UI64_BASE));
+ }
+ if (ov != NULL)
+ *ov = y;
+ return z;
+}
+
+/*
+ 7 3 2
+ * 9 4 2 8
+ ---------
+ 5 8 5 6
+ + 1 4 6 4
+ + 2 9 2 8
+ + 6 5 8 8
+ ---------------
+ = 6 9 0 1 2 9 6
+*/
+
+ui64_t ui64_mul(ui64_t x, ui64_t y, ui64_t *ov)
+{
+ UIXX_T(UI64_DIGITS+UI64_DIGITS) zx;
+ ui64_t z;
+ int carry;
+ int i, j;
+
+ /* clear temporary result buffer */
+ for (i = 0; i < (UI64_DIGITS+UI64_DIGITS); i++)
+ zx.x[i] = 0;
+
+ /* perform multiplication operation */
+ for (i = 0; i < UI64_DIGITS; i++) {
+ /* calculate partial product and immediately add to z */
+ carry = 0;
+ for (j = 0; j < UI64_DIGITS; j++) {
+ carry += (x.x[i] * y.x[j]) + zx.x[i+j];
+ zx.x[i+j] = (carry % UI64_BASE);
+ carry /= UI64_BASE;
+ }
+ /* add carry to remaining digits in z */
+ for ( ; j < UI64_DIGITS + UI64_DIGITS - i; j++) {
+ carry += zx.x[i+j];
+ zx.x[i+j] = (carry % UI64_BASE);
+ carry /= UI64_BASE;
+ }
+ }
+
+ /* provide result by splitting zx into z and ov */
+ memcpy(z.x, zx.x, UI64_DIGITS);
+ if (ov != NULL)
+ memcpy((*ov).x, &zx.x[UI64_DIGITS], UI64_DIGITS);
+
+ return z;
+}
+
+ui64_t ui64_muln(ui64_t x, int y, int *ov)
+{
+ ui64_t z;
+ int carry;
+ int i;
+
+ carry = 0;
+ for (i = 0; i < UI64_DIGITS; i++) {
+ carry += (x.x[i] * y);
+ z.x[i] = (carry % UI64_BASE);
+ carry /= UI64_BASE;
+ }
+ if (ov != NULL)
+ *ov = carry;
+ return z;
+}
+
+/*
+ = 2078 [q]
+ 0615367 [x] : 296 [y]
+ -0592 [dq]
+ -----
+ = 0233
+ -0000 [dq]
+ -----
+ = 2336
+ -2072 [dq]
+ -----
+ = 2647
+ -2308 [dq]
+ -----
+ = 279 [r]
+ */
+ui64_t ui64_div(ui64_t x, ui64_t y, ui64_t *ov)
+{
+ ui64_t q;
+ ui64_t r;
+ int i;
+ int n, m;
+ int ovn;
+
+ /* determine actual number of involved digits */
+ n = ui64_len(x);
+ m = ui64_len(y);
+
+ if (m == 1) {
+ /* simple case #1: reduceable to ui64_divn() */
+ if (y.x[0] == 0) {
+ /* error case: division by zero! */
+ ui64_fill(q, 0);
+ ui64_fill(r, 0);
+ }
+ else {
+ q = ui64_divn(x, y.x[0], &ovn);
+ ui64_fill(r, 0);
+ r.x[0] = (unsigned char)ovn;
+ }
+
+ } else if (n < m) {
+ /* simple case #2: everything is in the remainder */
+ ui64_fill(q, 0);
+ r = x;
+
+ } else { /* n >= m, m > 1 */
+ /* standard case: x[0..n] / y[0..m] */
+ UIXX_T(UI64_DIGITS+1) rx;
+ UIXX_T(UI64_DIGITS+1) dq;
+ ui64_t t;
+ int km;
+ int k;
+ int qk;
+ unsigned long y2;
+ unsigned long r3;
+ int borrow;
+ int d;
+
+ /* rx is x with a leading zero in order to make
+ sure that n > m and not just n >= m */
+ memcpy(rx.x, x.x, UI64_DIGITS);
+ rx.x[UI64_DIGITS] = 0;
+
+ for (k = n - m; k >= 0; k--) {
+ /* efficiently compute qk by guessing
+ qk := rx[k+m-2...k+m]/y[m-2...m-1] */
+ km = k + m;
+ y2 = (y.x[m-1]*UI64_BASE) + y.x[m-2];
+ r3 = (rx.x[km]*(UI64_BASE*UI64_BASE)) +
+ (rx.x[km-1]*UI64_BASE) + rx.x[km-2];
+ qk = r3 / y2;
+ if (qk >= UI64_BASE)
+ qk = UI64_BASE - 1;
+
+ /* dq := y*qk (post-adjust qk if guessed incorrectly) */
+ t = ui64_muln(y, qk, &ovn);
+ memcpy(dq.x, t.x, UI64_DIGITS);
+ dq.x[m] = (unsigned char)ovn;
+ for (i = m; i > 0; i--)
+ if (rx.x[i+k] != dq.x[i])
+ break;
+ if (rx.x[i+k] < dq.x[i]) {
+ t = ui64_muln(y, --qk, &ovn);
+ memcpy(dq.x, t.x, UI64_DIGITS);
+ dq.x[m] = (unsigned char)ovn;
+ }
+
+ /* store qk */
+ q.x[k] = (unsigned char)qk;
+
+ /* rx := rx - dq*(b^k) */
+ borrow = 0;
+ for (i = 0; i < m+1; i++) {
+ d = ((rx.x[k+i] + UI64_BASE) - borrow - dq.x[i]);
+ rx.x[k+i] = (d % UI64_BASE);
+ borrow = (1 - (d/UI64_BASE));
+ }
+ }
+ memcpy(r.x, rx.x, m);
+
+ /* fill out results with leading zeros */
+ for (i = n-m+1; i < UI64_DIGITS; i++)
+ q.x[i] = 0;
+ for (i = m; i < UI64_DIGITS; i++)
+ r.x[i] = 0;
+ }
+
+ /* provide results */
+ if (ov != NULL)
+ *ov = r;
+ return q;
+}
+
+ui64_t ui64_divn(ui64_t x, int y, int *ov)
+{
+ ui64_t z;
+ unsigned int carry;
+ int i;
+
+ carry = 0;
+ for (i = (UI64_DIGITS - 1); i >= 0; i--) {
+ carry = (carry * UI64_BASE) + x.x[i];
+ z.x[i] = (carry / y);
+ carry %= y;
+ }
+ if (ov != NULL)
+ *ov = carry;
+ return z;
+}
+
+ui64_t ui64_and(ui64_t x, ui64_t y)
+{
+ ui64_t z;
+ int i;
+
+ for (i = 0; i < UI64_DIGITS; i++)
+ z.x[i] = (x.x[i] & y.x[i]);
+ return z;
+}
+
+ui64_t ui64_or(ui64_t x, ui64_t y)
+{
+ ui64_t z;
+ int i;
+
+ for (i = 0; i < UI64_DIGITS; i++)
+ z.x[i] = (x.x[i] | y.x[i]);
+ return z;
+}
+
+ui64_t ui64_xor(ui64_t x, ui64_t y)
+{
+ ui64_t z;
+ int i;
+
+ for (i = 0; i < UI64_DIGITS; i++)
+ z.x[i] = ((x.x[i] & ~(y.x[i])) | (~(x.x[i]) & (y.x[i])));
+ return z;
+}
+
+ui64_t ui64_not(ui64_t x)
+{
+ ui64_t z;
+ int i;
+
+ for (i = 0; i < UI64_DIGITS; i++)
+ z.x[i] = ~(x.x[i]);
+ return z;
+}
+
+ui64_t ui64_rol(ui64_t x, int s, ui64_t *ov)
+{
+ UIXX_T(UI64_DIGITS+UI64_DIGITS) zx;
+ ui64_t z;
+ int i;
+ int carry;
+
+ if (s <= 0) {
+ /* no shift at all */
+ if (ov != NULL)
+ *ov = ui64_zero();
+ return x;
+ }
+ else if (s > 64) {
+ /* too large shift */
+ if (ov != NULL)
+ *ov = ui64_zero();
+ return ui64_zero();
+ }
+ else if (s == 64) {
+ /* maximum shift */
+ if (ov != NULL)
+ *ov = x;
+ return ui64_zero();
+ }
+ else { /* regular shift */
+ /* shift (logically) left by s/8 bytes */
+ for (i = 0; i < UI64_DIGITS+UI64_DIGITS; i++)
+ zx.x[i] = 0;
+ for (i = 0; i < UI64_DIGITS; i++)
+ zx.x[i+(s/8)] = x.x[i];
+ /* shift (logically) left by remaining s%8 bits */
+ s %= 8;
+ if (s > 0) {
+ carry = 0;
+ for (i = 0; i < UI64_DIGITS+UI64_DIGITS; i++) {
+ carry += (zx.x[i] * (1 << s));
+ zx.x[i] = (carry % UI64_BASE);
+ carry /= UI64_BASE;
+ }
+ }
+ memcpy(z.x, zx.x, UI64_DIGITS);
+ if (ov != NULL)
+ memcpy((*ov).x, &zx.x[UI64_DIGITS], UI64_DIGITS);
+ }
+ return z;
+}
+
+ui64_t ui64_ror(ui64_t x, int s, ui64_t *ov)
+{
+ UIXX_T(UI64_DIGITS+UI64_DIGITS) zx;
+ ui64_t z;
+ int i;
+ int carry;
+
+ if (s <= 0) {
+ /* no shift at all */
+ if (ov != NULL)
+ *ov = ui64_zero();
+ return x;
+ }
+ else if (s > 64) {
+ /* too large shift */
+ if (ov != NULL)
+ *ov = ui64_zero();
+ return ui64_zero();
+ }
+ else if (s == 64) {
+ /* maximum shift */
+ if (ov != NULL)
+ *ov = x;
+ return ui64_zero();
+ }
+ else { /* regular shift */
+ /* shift (logically) right by s/8 bytes */
+ for (i = 0; i < UI64_DIGITS+UI64_DIGITS; i++)
+ zx.x[i] = 0;
+ for (i = 0; i < UI64_DIGITS; i++)
+ zx.x[UI64_DIGITS+i-(s/8)] = x.x[i];
+ /* shift (logically) right by remaining s%8 bits */
+ s %= 8;
+ if (s > 0) {
+ carry = 0;
+ for (i = (UI64_DIGITS+UI64_DIGITS - 1); i >= 0; i--) {
+ carry = (carry * UI64_BASE) + zx.x[i];
+ zx.x[i] = (carry / (1 << s));
+ carry %= (1 << s);
+ }
+ }
+ memcpy(z.x, &zx.x[UI64_DIGITS], UI64_DIGITS);
+ if (ov != NULL)
+ memcpy((*ov).x, zx.x, UI64_DIGITS);
+ }
+ return z;
+}
+
+int ui64_cmp(ui64_t x, ui64_t y)
+{
+ int i;
+
+ i = UI64_DIGITS - 1;
+ while (i > 0 && x.x[i] == y.x[i])
+ i--;
+ return (x.x[i] - y.x[i]);
+}
+
+int ui64_len(ui64_t x)
+{
+ int i;
+
+ for (i = UI64_DIGITS; i > 1 && x.x[i-1] == 0; i--)
+ ;
+ return i;
+}
+
Added: cs/cigma/branches/cigma-0.9/src/uuid_ui64.h
===================================================================
--- cs/cigma/branches/cigma-0.9/src/uuid_ui64.h 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/src/uuid_ui64.h 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,113 @@
+/*
+** OSSP ui64 - 64-Bit Arithmetic
+** Copyright (c) 2002-2004 Ralf S. Engelschall <rse at engelschall.com>
+** Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP ui64, a 64-bit arithmetic library
+** which can be found at http://www.ossp.org/pkg/lib/ui64/.
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** 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.
+**
+** ui64.h: API declaration
+*/
+
+#ifndef __UI64_H__
+#define __UI64_H__
+
+#include <string.h>
+
+#define UI64_PREFIX uuid_
+
+/* embedding support */
+#ifdef UI64_PREFIX
+#if defined(__STDC__) || defined(__cplusplus)
+#define __UI64_CONCAT(x,y) x ## y
+#define UI64_CONCAT(x,y) __UI64_CONCAT(x,y)
+#else
+#define __UI64_CONCAT(x) x
+#define UI64_CONCAT(x,y) __UI64_CONCAT(x)y
+#endif
+#define ui64_t UI64_CONCAT(UI64_PREFIX,ui64_t)
+#define ui64_zero UI64_CONCAT(UI64_PREFIX,ui64_zero)
+#define ui64_max UI64_CONCAT(UI64_PREFIX,ui64_max)
+#define ui64_n2i UI64_CONCAT(UI64_PREFIX,ui64_n2i)
+#define ui64_i2n UI64_CONCAT(UI64_PREFIX,ui64_i2n)
+#define ui64_s2i UI64_CONCAT(UI64_PREFIX,ui64_s2i)
+#define ui64_i2s UI64_CONCAT(UI64_PREFIX,ui64_i2s)
+#define ui64_add UI64_CONCAT(UI64_PREFIX,ui64_add)
+#define ui64_addn UI64_CONCAT(UI64_PREFIX,ui64_addn)
+#define ui64_sub UI64_CONCAT(UI64_PREFIX,ui64_sub)
+#define ui64_subn UI64_CONCAT(UI64_PREFIX,ui64_subn)
+#define ui64_mul UI64_CONCAT(UI64_PREFIX,ui64_mul)
+#define ui64_muln UI64_CONCAT(UI64_PREFIX,ui64_muln)
+#define ui64_div UI64_CONCAT(UI64_PREFIX,ui64_div)
+#define ui64_divn UI64_CONCAT(UI64_PREFIX,ui64_divn)
+#define ui64_and UI64_CONCAT(UI64_PREFIX,ui64_and)
+#define ui64_or UI64_CONCAT(UI64_PREFIX,ui64_or)
+#define ui64_xor UI64_CONCAT(UI64_PREFIX,ui64_xor)
+#define ui64_not UI64_CONCAT(UI64_PREFIX,ui64_not)
+#define ui64_rol UI64_CONCAT(UI64_PREFIX,ui64_rol)
+#define ui64_ror UI64_CONCAT(UI64_PREFIX,ui64_ror)
+#define ui64_len UI64_CONCAT(UI64_PREFIX,ui64_len)
+#define ui64_cmp UI64_CONCAT(UI64_PREFIX,ui64_cmp)
+#endif
+
+typedef struct {
+ unsigned char x[8]; /* x_0, ..., x_7 */
+} ui64_t;
+
+#define ui64_cons(x7,x6,x5,x4,x3,x2,x1,x0) \
+ { { 0x##x0, 0x##x1, 0x##x2, 0x##x3, 0x##x4, 0x##x5, 0x##x6, 0x##x7 } }
+
+/* particular values */
+extern ui64_t ui64_zero (void);
+extern ui64_t ui64_max (void);
+
+/* import and export via ISO-C "unsigned long" */
+extern ui64_t ui64_n2i (unsigned long n);
+extern unsigned long ui64_i2n (ui64_t x);
+
+/* import and export via ISO-C string of arbitrary base */
+extern ui64_t ui64_s2i (const char *str, char **end, int base);
+extern char * ui64_i2s (ui64_t x, char *str, size_t len, int base);
+
+/* arithmetical operations */
+extern ui64_t ui64_add (ui64_t x, ui64_t y, ui64_t *ov);
+extern ui64_t ui64_addn (ui64_t x, int y, int *ov);
+extern ui64_t ui64_sub (ui64_t x, ui64_t y, ui64_t *ov);
+extern ui64_t ui64_subn (ui64_t x, int y, int *ov);
+extern ui64_t ui64_mul (ui64_t x, ui64_t y, ui64_t *ov);
+extern ui64_t ui64_muln (ui64_t x, int y, int *ov);
+extern ui64_t ui64_div (ui64_t x, ui64_t y, ui64_t *ov);
+extern ui64_t ui64_divn (ui64_t x, int y, int *ov);
+
+/* bit operations */
+extern ui64_t ui64_and (ui64_t x, ui64_t y);
+extern ui64_t ui64_or (ui64_t x, ui64_t y);
+extern ui64_t ui64_xor (ui64_t x, ui64_t y);
+extern ui64_t ui64_not (ui64_t x);
+extern ui64_t ui64_rol (ui64_t x, int s, ui64_t *ov);
+extern ui64_t ui64_ror (ui64_t x, int s, ui64_t *ov);
+
+/* other operations */
+extern int ui64_len (ui64_t x);
+extern int ui64_cmp (ui64_t x, ui64_t y);
+
+#endif /* __UI64_H__ */
+
Added: cs/cigma/branches/cigma-0.9/tests/test_uuid.c
===================================================================
--- cs/cigma/branches/cigma-0.9/tests/test_uuid.c 2007-06-26 17:08:43 UTC (rev 7513)
+++ cs/cigma/branches/cigma-0.9/tests/test_uuid.c 2007-06-26 17:10:18 UTC (rev 7514)
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../src/uuid.h"
+
+/* error handler */
+static void error(int ec, const char *str, ...)
+{
+ va_list ap;
+
+ va_start(ap, str);
+ fprintf(stderr, "test_uuid: ");
+ vfprintf(stderr, str, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(ec);
+}
+
+int main(int argc, char *argv[])
+{
+ uuid_t *uuid;
+ uuid_rc_t rc;
+
+ FILE *fp;
+ char *cp;
+ void *vp;
+ int raw;
+
+ raw = 0;
+ fp = stdout;
+
+ rc = uuid_create(&uuid);
+ if (rc != UUID_RC_OK)
+ error(1, "uuid_create: %s", uuid_error(rc));
+
+ rc = uuid_nil(uuid);
+ if (rc != UUID_RC_OK)
+ error(1, "uuid_nil: %s", uuid_error(rc));
+
+ rc = uuid_generate(uuid, UUID_VERSION4);
+ if (rc != UUID_RC_OK)
+ error(1, "uuid_generate: %s", uuid_error(rc));
+
+ if (raw)
+ {
+ vp = NULL;
+ rc = uuid_pack(uuid, &vp);
+ if (rc != UUID_RC_OK)
+ error(1, "uuid_pack: %s", uuid_error(rc));
+ fwrite(vp, UUID_LEN_BIN, 1, fp);
+ free(vp);
+ }
+ else
+ {
+ cp = NULL;
+ rc = uuid_format(uuid, &cp);
+ if (rc != UUID_RC_OK)
+ error(1, "uuid_format: %s", uuid_error(rc));
+ fprintf(fp, "%s\n", cp);
+ free(cp);
+ }
+
+ rc = uuid_destroy(uuid);
+ if (rc != UUID_RC_OK)
+ error(1, "uuid_destroy: %s", uuid_error(rc));
+
+ if (fp != stdout)
+ fclose(fp);
+
+ return 0;
+}
More information about the cig-commits
mailing list