procmgmt: $(DIR_roken) config
+${COMPILE_PART1} procmgmt ${COMPILE_PART2}
-opr: config $(DIR_roken)
+opr: config hcrypto $(DIR_roken)
+${COMPILE_PART1} opr ${COMPILE_PART2}
util: opr $(DIR_roken) procmgmt hcrypto lwp_depinstall rx_depinstall
LDFLAGS_hcrypto="-L\$(TOP_LIBDIR)"
AC_SUBST(LIB_hcrypto)
AC_SUBST(LDFLAGS_hcrypto)
+
+dnl Check for UUID library
+AC_CHECK_HEADERS([uuid/uuid.h])
+AC_CHECK_LIB(uuid, uuid_generate, LIBS_uuid="-luuid")
+AC_CHECK_FUNCS([uuid_generate])
])
+
AC_DEFUN([SUMMARY], [
# Print a configuration summary
echo
include @TOP_OBJDIR@/src/config/Makefile.config
include @TOP_OBJDIR@/src/config/Makefile.shared
-objects = assert.o casestrcpy.o rbtree.o
+objects = assert.o casestrcpy.o rbtree.o uuid.o
HEADERS = $(TOP_INCDIR)/afs/opr.h \
$(TOP_INCDIR)/afs/opr_assert.h \
$(TOP_INCDIR)/opr/jhash.h \
$(TOP_INCDIR)/opr/queue.h \
$(TOP_INCDIR)/opr/rbtree.h \
- $(TOP_INCDIR)/opr/time.h
+ $(TOP_INCDIR)/opr/time.h \
+ $(TOP_INCDIR)/opr/uuid.h
all: $(HEADERS) $(TOP_LIBDIR)/libopr.a
$(TOP_INCDIR)/opr/time.h: ${srcdir}/opr_time.h
$(INSTALL_DATA) $? $@
+$(TOP_INCDIR)/opr/uuid.h: ${srcdir}/uuid.h
+ $(INSTALL_DATA) $? $@
+
clean:
rm -f $(objects) libopr.a
$(DESTDIR)\include\opr\jhash.h \
$(DESTDIR)\include\opr\queue.h \
$(DESTDIR)\include\opr\rbtree.h \
- $(DESTDIR)\include\opr\time.h
+ $(DESTDIR)\include\opr\time.h \
+ $(DESTDIR)\include\opr\uuid.h
$(DESTDIR)\include\opr\time.h: opr_time.h
$(COPY) $** $@
$(OUT)\assert.obj \
$(OUT)\casestrcpy.obj \
$(OUT)\rbtree.obj \
+ $(OUT)\uuid.obj \
$(OUT)\AFS_component_version_number.obj
$(LIBOBJS): $(INCFILES)
--- /dev/null
+/*
+ * Copyright (c) 2012 Your File System Inc. All rights reserved.
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+#include <roken.h>
+
+#ifdef HAVE_UUID_UUID_H
+# include <uuid/uuid.h>
+#endif
+
+#ifdef AFS_NT40_ENV
+# include <rpc.h>
+#endif
+
+#include <hcrypto/rand.h>
+
+#include "uuid.h"
+#include "jhash.h"
+
+static const opr_uuid_t nilUid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+void
+opr_uuid_create(opr_uuid_t *uuid)
+{
+#if defined (AFS_NT40_ENV)
+ struct opr_uuid_unpacked raw;
+
+ UuidCreate((UUID *) &raw);
+ opr_uuid_pack(uuid, &raw);
+
+#elif !defined(KERNEL) && defined(HAVE_UUID_GENERATE)
+
+ uuid_generate(uuid->data);
+
+#else
+ RAND_bytes(uuid->data, 16);
+
+ uuid->data[6] = (uuid->data[6] & 0x0F) | 0x40; /* verison is 4 */
+ uuid->data[8] = (uuid->data[8] & 0x3F) | 0x80; /* variant is DCE */
+#endif
+}
+
+int
+opr_uuid_isNil(const opr_uuid_t *uuid)
+{
+ return opr_uuid_equal(uuid, &nilUid);
+}
+
+int
+opr_uuid_equal(const opr_uuid_t *uuid1, const opr_uuid_t *uuid2)
+{
+ return memcmp(uuid1, uuid2, sizeof(opr_uuid_t)) == 0;
+}
+
+int
+opr_uuid_hash(const opr_uuid_t *uuid)
+{
+ /* uuid->data is a (unsigned char *), so there's every danger that this
+ * may cause an unaligned access on some platforms */
+ return opr_jhash((const afs_uint32 *)uuid->data, 4, 0);
+}
+
+#if !defined(KERNEL)
+void
+opr_uuid_toString(const opr_uuid_t *uuid, char **string)
+{
+ unsigned const char *p;
+
+ p = uuid->data;
+ asprintf(string,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
+ "%02x%02x%02x%02x%02x%02x",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
+ p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
+}
+
+void
+opr_uuid_freeString(char *string)
+{
+ free(string);
+}
+
+int
+opr_uuid_fromString(opr_uuid_t *uuid, const char *string)
+{
+ unsigned int i[16];
+ int items, c;
+
+ /* XXX - Traditionally, AFS has printed UUIDs as
+ * 00000000-0000-00-00-00000000. We should perhaps also accept
+ * that format here
+ */
+ items = sscanf(string,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
+ "%02x%02x%02x%02x%02x%02x",
+ &i[0], &i[1], &i[2], &i[3], &i[4], &i[5],
+ &i[6], &i[7], &i[8], &i[9], &i[10], &i[11],
+ &i[12], &i[13], &i[14], &i[15]);
+ if (items !=16) {
+ /* Originally, AFS's printed UUIDs would take the form
+ * 00000000-0000-0000-00-00-00000000. Also handle this. */
+ items = sscanf(string,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x-"
+ "%02x%02x%02x%02x%02x%02x",
+ &i[0], &i[1], &i[2], &i[3], &i[4], &i[5],
+ &i[6], &i[7], &i[8], &i[9], &i[10], &i[11],
+ &i[12], &i[13], &i[14], &i[15]);
+ }
+ if (items !=16)
+ return EINVAL;
+
+ for (c=0; c<16; c++)
+ uuid->data[c] = i[c];
+
+ return 0;
+}
+
+void
+opr_uuid_pack(opr_uuid_t *uuid, const struct opr_uuid_unpacked *raw)
+{
+ afs_uint32 intval;
+ unsigned short shortval;
+
+ intval = htonl(raw->time_low);
+ memcpy(&uuid->data[0], &intval, sizeof(uint32_t));
+
+ shortval = htons(raw->time_mid);
+ memcpy(&uuid->data[4], &shortval, sizeof(uint16_t));
+
+ shortval = htons(raw->time_hi_and_version);
+ memcpy(&uuid->data[6], &shortval, sizeof(uint16_t));
+
+ uuid->data[8] = raw->clock_seq_hi_and_reserved;
+ uuid->data[9] = raw->clock_seq_low;
+
+ memcpy(&uuid->data[10], &raw->node, 6);
+}
+
+void
+opr_uuid_unpack(const opr_uuid_t *uuid, struct opr_uuid_unpacked *raw)
+{
+ afs_uint32 intval;
+ unsigned short shortval;
+
+ memcpy(&intval, &uuid->data[0], sizeof(uint32_t));
+ raw->time_low = ntohl(intval);
+
+ memcpy(&shortval, &uuid->data[4], sizeof(uint16_t));
+ raw->time_mid = ntohs(shortval);
+
+ memcpy(&shortval, &uuid->data[6], sizeof(uint16_t));
+ raw->time_hi_and_version = ntohs(shortval);
+
+ raw->clock_seq_hi_and_reserved = uuid->data[8];
+ raw->clock_seq_low = uuid->data[9];
+
+ memcpy(&raw->node, &uuid->data[10], 6);
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2012 Your File System Inc. All rights reserved.
+ */
+
+#ifndef OPENAFS_OPR_UUID_H
+#define OPENAFS_OPR_UUID_H 1
+
+struct opr_uuid {
+ unsigned char data[16];
+};
+
+struct opr_uuid_unpacked {
+ afs_uint32 time_low;
+ unsigned short time_mid;
+ unsigned short time_hi_and_version;
+ char clock_seq_hi_and_reserved;
+ char clock_seq_low;
+ char node[6];
+};
+
+typedef struct opr_uuid opr_uuid_t;
+typedef opr_uuid_t opr_uuid; /* For XDR */
+
+extern void opr_uuid_create(opr_uuid_t *uuid);
+extern int opr_uuid_isNil(const opr_uuid_t *uuid);
+extern int opr_uuid_equal(const opr_uuid_t *uuid1, const opr_uuid_t *uuid2);
+extern int opr_uuid_hash(const opr_uuid_t *uuid);
+
+#if !defined(KERNEL)
+extern void opr_uuid_toString(const opr_uuid_t *uuid, char **string);
+extern void opr_uuid_freeString(char *string);
+extern int opr_uuid_fromString(opr_uuid_t *uuid, const char *string);
+#endif
+
+extern void opr_uuid_pack(opr_uuid_t *uuid, const struct opr_uuid_unpacked *raw);
+extern void opr_uuid_unpack(const opr_uuid_t *uuid, struct opr_uuid_unpacked *raw);
+
+#endif
opr/queues
opr/rbtree
opr/time
+opr/uuid
ptserver/pt_util
ptserver/pts-man
rx/event
LIBS=../tap/libtap.a $(abs_top_builddir)/lib/libopr.a
-tests = jhash-t queues-t rbtree-t time-t
+tests = jhash-t queues-t rbtree-t time-t uuid-t
all check test tests: $(tests)
time-t: time-t.o
$(AFS_LDRULE) time-t.o ../tap/libtap.a $(XLIBS)
+uuid-t: uuid-t.o
+ $(AFS_LDRULE) uuid-t.o ../tap/libtap.a $(LIBS) $(LIB_hcrypto) $(XLIBS)
+
clean distclean:
$(RM) -f $(tests) *.o core
--- /dev/null
+/*
+ * Copyright (c) 2012 Your File System Inc. All rights reserved.
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+#include <roken.h>
+
+#include <opr/uuid.h>
+
+#include <tests/tap/basic.h>
+
+int
+main(int argc, char **argv)
+{
+ opr_uuid_t uuidA = {{0x4F, 0x44, 0x94, 0x47, 0x76, 0xBA, 0x47, 0x2C,
+ 0x97, 0x1A, 0x86, 0x6B, 0xC0, 0x10, 0x1A, 0x4B}};
+ opr_uuid_t uuidB = {{0x5D, 0x2A, 0x39, 0x36, 0x94, 0xB2, 0x48, 0x90,
+ 0xA8, 0xD2, 0x7F, 0xBC, 0x1B, 0x29, 0xDA, 0x9B}};
+ opr_uuid_t uuidC;
+ char *str;
+ int version;
+ struct opr_uuid_unpacked raw;
+
+ memset(&uuidC, 0, sizeof(opr_uuid_t));
+
+ ok(opr_uuid_isNil(&uuidC), "opr_uuid_isNil(nilUuid) works");
+ ok(!opr_uuid_isNil(&uuidA), "opr_uuid_isNil(uuid) works");
+
+ ok(opr_uuid_equal(&uuidA, &uuidA), "opr_uuid_equal(A, A) works");
+ ok(!opr_uuid_equal(&uuidA, &uuidB), "opr_uuid_equal(A, B) works");
+ ok(!opr_uuid_equal(&uuidA, &uuidC), "opr_uuid_equal(A, nilUid) works");
+
+ is_int(1187447773, opr_uuid_hash(&uuidA), "opr_uuid_hash(A) works");
+ is_int(1251907497, opr_uuid_hash(&uuidB), "opr_uuid_hash(B) works");
+
+ opr_uuid_toString(&uuidA, &str);
+ is_string("4f449447-76ba-472c-971a-866bc0101a4b", str,
+ "opr_uuid_toString(uuidA) works");
+ opr_uuid_freeString(str);
+
+ is_int(0, opr_uuid_fromString(&uuidC, "4F449447-76BA-472C-971A-866BC0101A4B"),
+ "opr_uuid_fromString works with conventional UUID");
+ ok(opr_uuid_equal(&uuidA, &uuidC), " ... and UUID is correct");
+
+ memset(&uuidC, 0, sizeof(opr_uuid_t));
+ is_int(0, opr_uuid_fromString(&uuidC, "4F449447-76BA-472C-97-1A-866BC0101A4B"),
+ "opr_uuid_fromString works with AFS style UUID");
+ ok(opr_uuid_equal(&uuidA, &uuidC), " ... and UUID is correct");
+
+ memset(&uuidC, 0, sizeof(opr_uuid_t));
+ opr_uuid_create(&uuidC);
+ ok(!opr_uuid_isNil(&uuidC), "opr_uuid_create makes non-nil UUID");
+ is_int(0x80, uuidC.data[8] & 0xB0, "variant is DCE as expected");
+ version = (uuidC.data[6] & 0xF0) >> 4;
+ ok(version >=1 && version <=5, "version %d is in expected range", version);
+
+ opr_uuid_unpack(&uuidB, &raw);
+ opr_uuid_pack(&uuidC, &raw);
+ ok(opr_uuid_equal(&uuidB, &uuidC),
+ "opr_uuid_pack(opr_uuid_unpack()) works as expected");
+
+ return 0;
+}