X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=internal.c;h=c911099ff6bee130f9daf05e7730cec1c72f060d;hb=89078e281093c442c5275050cad8867abc6885bf;hp=0fe696278a5b45993994c3bfedc5d9dd1b4454aa;hpb=c7e13d717c38e528ae241bf5facb51bca63f323c;p=uuid diff --git a/internal.c b/internal.c index 0fe6962..c911099 100644 --- a/internal.c +++ b/internal.c @@ -17,6 +17,7 @@ #include #include #include +#include #endif #ifdef __APPLE__ @@ -126,11 +127,12 @@ static int release_global_lock(void *data) { static uint64_t current_time(void) { uint64_t now; struct timeval tv; + static int seq = 0; /* TODO is this BSD specific? */ gettimeofday(&tv, 0); - now = (tv.tv_sec * 10000000ULL + tv.tv_usec * 10ULL) + GREGORIAN; + now = (tv.tv_sec * 10000000ULL + tv.tv_usec * 10ULL + seq++ % 10) + GREGORIAN; return now; } @@ -186,7 +188,6 @@ static uint64_t current_node(struct pd_uuid_state *st) { continue; } if (ioctl(s, SIOCGIFHWADDR, req) == 0) { - int j; data = (unsigned char *)req->ifr_hwaddr.sa_data; node = data[0]; node = node << 8; node += data[1]; @@ -194,10 +195,12 @@ static uint64_t current_node(struct pd_uuid_state *st) { node = node << 8; node += data[3]; node = node << 8; node += data[4]; node = node << 8; node += data[5]; + close(s); return node; } } } + close(s); } #endif @@ -272,11 +275,19 @@ static uint16_t random_clock_sequence(struct pd_uuid_state *s) { } static int read_state(struct pd_uuid_state *s) { + uint64_t node; + s->available = 0; s->node = 0LL; s->clock_sequence = 0; s->timestamp = 0LL; + node = current_node(s); + + if (!s->available || s->node != node) { + s->clock_sequence = random_clock_sequence(s); + } + return 0; } @@ -295,6 +306,30 @@ static unsigned long get_bytes(void *buf, unsigned long n, void *state) { return i; } +int pd_uuid_init(struct pd_uuid_state *s, int flags) { + if (!s) return 0; + + s->get_lock = obtain_global_lock; + s->release_lock = release_global_lock; + s->lock_data = 0; + + if (flags & 0x1) { + s->read_state = 0; + s->save_state = 0; + s->node = current_node(s); + } else { + s->read_state = read_state; + s->save_state = 0; + } + + s->random_bytes = get_bytes; + s->rng_state = 0; + + s->available = 0; + + return 1; +} + int pd_uuid_init_state(struct pd_uuid_state *s) { if (!s) return 0; @@ -316,7 +351,6 @@ int pd_uuid_init_state(struct pd_uuid_state *s) { int pd_uuid_make_v1(struct pd_uuid_state *s, pd_uuid_t *uuid) { struct pd_uuid_state ls; uint64_t now; - uint64_t node; int err; if (!s) { @@ -339,12 +373,6 @@ int pd_uuid_make_v1(struct pd_uuid_state *s, pd_uuid_t *uuid) { } now = current_time(); - node = current_node(s); - - if (!s->available || s->node != node) { - s->clock_sequence = random_clock_sequence(s); - } - s->node = node; if (s->available && s->timestamp > now) { s->clock_sequence++; @@ -371,30 +399,60 @@ int pd_uuid_make_v1(struct pd_uuid_state *s, pd_uuid_t *uuid) { return 1; } -int pd_uuid_make_v1mc(struct pd_uuid_state *ps, pd_uuid_t *uuid) { - struct pd_uuid_state s; +int pd_uuid_make_v1mc(struct pd_uuid_state *s, pd_uuid_t *uuid) { + struct pd_uuid_state ls; uint64_t now; uint64_t node; + int err; + + if (!s) { + s = &ls; + pd_uuid_init_state(s); + } + + if (s->get_lock) { + if ((err = s->get_lock(s->lock_data)) != 0) { + /* TODO set uuid to nil ? */ + /* be cute and have an "error" uuid? */ + return 0; + } + } + + if (s->read_state) { + if ((err = s->read_state(s)) != 0) { + return 0; + } + } - obtain_global_lock(0); - read_state(&s); now = current_time(); - node = random_mc_mac(&s); - if (!s.available) { - s.clock_sequence = random_clock_sequence(&s); + node = random_mc_mac(s); + + if (!s->available || s->node != node) { + s->clock_sequence = random_clock_sequence(s); } + s->node = node; - if (s.available && s.timestamp > now) { - s.clock_sequence++; + if (s->available && s->timestamp > now) { + s->clock_sequence++; } else { - s.timestamp = now; + s->timestamp = now; } - save_state(&s); - release_global_lock(0); - s.node = node; + if (s->save_state) { + if ((err = s->save_state(s)) != 0) { + return 0; + } + } - format_uuid(uuid, &s, 1); + if (s->release_lock) { + if ((err = s->release_lock(s->lock_data)) != 0) { + /* TODO set uuid to nil ? */ + /* be cute and have an "error" uuid? */ + return 0; + } + } + + format_uuid(uuid, s, 1); return 1; } @@ -458,3 +516,48 @@ int pd_uuid_set_string(pd_uuid_t *uuid, char *s) { } return 1; } + +/* pre-defined namespace uuids */ + +pd_uuid_t pd_uuid_ns_dns = { + { + 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + } +}; + +pd_uuid_t pd_uuid_ns_url = { + { + 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + } +}; + +pd_uuid_t pd_uuid_ns_oid = { + { + 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + } +}; + +pd_uuid_t pd_uuid_ns_x500 = { + { + 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + } +}; + +int pd_uuid_copy(pd_uuid_t *src, pd_uuid_t *dst) { + if (src && dst) { + memcpy(dst->data, src->data, 16); + return 1; + } + return 0; +} + +int pd_uuid_cmp(pd_uuid_t *a, pd_uuid_t *b) { + if (a && b) { + return memcmp(a, b, 16); + } + return 1; +}