|
Packit Service |
7500fa |
#include "EXTERN.h"
|
|
Packit Service |
7500fa |
#include "perl.h"
|
|
Packit Service |
7500fa |
#include "XSUB.h"
|
|
Packit Service |
7500fa |
#include "UUID.h"
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#if defined __BEOS__ || defined __HAIKU__
|
|
Packit Service |
7500fa |
# undef bool
|
|
Packit Service |
7500fa |
# include <OS.h>
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#ifdef USE_ITHREADS
|
|
Packit Service |
7500fa |
# define DU_THREADSAFE 1
|
|
Packit Service |
7500fa |
#else
|
|
Packit Service |
7500fa |
# define DU_THREADSAFE 0
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
# define pPTBL pTHX
|
|
Packit Service |
7500fa |
# define pPTBL_ pTHX_
|
|
Packit Service |
7500fa |
# define aPTBL aTHX
|
|
Packit Service |
7500fa |
# define aPTBL_ aTHX_
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
# define PTABLE_VAL_FREE(V) ((void) (V))
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
# include "ptable.h"
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
# define ptable_store(T, K, V) ptable_store(aTHX_ (T), (K), (V))
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static ptable *instances;
|
|
Packit Service |
7500fa |
static perl_mutex instances_mutex;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void inc(pTHX_ ptable_ent *ent, void *ud) {
|
|
Packit Service |
7500fa |
UV count = PTR2UV(ent->val);
|
|
Packit Service |
7500fa |
PERL_UNUSED_VAR(ud);
|
|
Packit Service |
7500fa |
ptable_store(instances, ent->key, (void *)++count);
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static perl_uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
|
|
Packit Service |
7500fa |
0x6ba7b810,
|
|
Packit Service |
7500fa |
0x9dad,
|
|
Packit Service |
7500fa |
0x11d1,
|
|
Packit Service |
7500fa |
0x80, 0xb4, { 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static perl_uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */
|
|
Packit Service |
7500fa |
0x6ba7b811,
|
|
Packit Service |
7500fa |
0x9dad,
|
|
Packit Service |
7500fa |
0x11d1,
|
|
Packit Service |
7500fa |
0x80, 0xb4, { 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static perl_uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */
|
|
Packit Service |
7500fa |
0x6ba7b812,
|
|
Packit Service |
7500fa |
0x9dad,
|
|
Packit Service |
7500fa |
0x11d1,
|
|
Packit Service |
7500fa |
0x80, 0xb4, { 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static perl_uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */
|
|
Packit Service |
7500fa |
0x6ba7b814,
|
|
Packit Service |
7500fa |
0x9dad,
|
|
Packit Service |
7500fa |
0x11d1,
|
|
Packit Service |
7500fa |
0x80, 0xb4, { 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void format_uuid_v1(
|
|
Packit Service |
7500fa |
perl_uuid_t *uuid,
|
|
Packit Service |
7500fa |
unsigned16 clock_seq,
|
|
Packit Service |
7500fa |
perl_uuid_time_t timestamp,
|
|
Packit Service |
7500fa |
uuid_node_t node
|
|
Packit Service |
7500fa |
) {
|
|
Packit Service |
7500fa |
uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF);
|
|
Packit Service |
7500fa |
uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF);
|
|
Packit Service |
7500fa |
uuid->time_hi_and_version = (unsigned short)((timestamp >> 48) &
|
|
Packit Service |
7500fa |
0x0FFF);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
uuid->time_hi_and_version |= (1 << 12);
|
|
Packit Service |
7500fa |
uuid->clock_seq_low = clock_seq & 0xFF;
|
|
Packit Service |
7500fa |
uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8;
|
|
Packit Service |
7500fa |
uuid->clock_seq_hi_and_reserved |= 0x80;
|
|
Packit Service |
7500fa |
memcpy(&uuid->node, &node, sizeof uuid->node);
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void get_current_time(perl_uuid_time_t * timestamp) {
|
|
Packit Service |
7500fa |
perl_uuid_time_t time_now;
|
|
Packit Service |
7500fa |
static perl_uuid_time_t time_last;
|
|
Packit Service |
7500fa |
static unsigned16 uuids_this_tick;
|
|
Packit Service |
7500fa |
static int inited = 0;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if (!inited) {
|
|
Packit Service |
7500fa |
get_system_time(&time_last);
|
|
Packit Service |
7500fa |
uuids_this_tick = UUIDS_PER_TICK;
|
|
Packit Service |
7500fa |
inited = 1;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
while (1) {
|
|
Packit Service |
7500fa |
get_system_time(&time_now);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if (time_last != time_now) {
|
|
Packit Service |
7500fa |
uuids_this_tick = 0;
|
|
Packit Service |
7500fa |
time_last = time_now;
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
if (uuids_this_tick < UUIDS_PER_TICK) {
|
|
Packit Service |
7500fa |
uuids_this_tick++;
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
*timestamp = time_now + uuids_this_tick;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static unsigned16 true_random(void) {
|
|
Packit Service |
7500fa |
static int inited = 0;
|
|
Packit Service |
7500fa |
perl_uuid_time_t time_now;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if (!inited) {
|
|
Packit Service |
7500fa |
get_system_time(&time_now);
|
|
Packit Service |
7500fa |
time_now = time_now/UUIDS_PER_TICK;
|
|
Packit Service |
7500fa |
srand((unsigned int)(((time_now >> 32) ^ time_now)&0xffffffff));
|
|
Packit Service |
7500fa |
inited = 1;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
return (rand());
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void format_uuid_v3(
|
|
Packit Service |
7500fa |
perl_uuid_t *uuid,
|
|
Packit Service |
7500fa |
unsigned char hash[16]
|
|
Packit Service |
7500fa |
) {
|
|
Packit Service |
7500fa |
memcpy(uuid, hash, sizeof(perl_uuid_t));
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
uuid->time_low = ntohl(uuid->time_low);
|
|
Packit Service |
7500fa |
uuid->time_mid = ntohs(uuid->time_mid);
|
|
Packit Service |
7500fa |
uuid->time_hi_and_version = ntohs(uuid->time_hi_and_version);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
uuid->time_hi_and_version &= 0x0FFF;
|
|
Packit Service |
7500fa |
uuid->time_hi_and_version |= (3 << 12);
|
|
Packit Service |
7500fa |
uuid->clock_seq_hi_and_reserved &= 0x3F;
|
|
Packit Service |
7500fa |
uuid->clock_seq_hi_and_reserved |= 0x80;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void get_system_time(perl_uuid_time_t *perl_uuid_time) {
|
|
Packit Service |
7500fa |
#if defined __cygwin__ || defined __MINGW32__ || defined WIN32
|
|
Packit Service |
7500fa |
/* ULARGE_INTEGER time; */
|
|
Packit Service |
7500fa |
LARGE_INTEGER time;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
/* use QeryPerformanceCounter for +ms resolution - as per Paul Stodghill
|
|
Packit Service |
7500fa |
GetSystemTimeAsFileTime((FILETIME *)&time); */
|
|
Packit Service |
7500fa |
QueryPerformanceCounter(&time);
|
|
Packit Service |
7500fa |
time.QuadPart +=
|
|
Packit Service |
7500fa |
(unsigned __int64) (1000*1000*10) *
|
|
Packit Service |
7500fa |
(unsigned __int64) (60 * 60 * 24) *
|
|
Packit Service |
7500fa |
(unsigned __int64) (17+30+31+365*18+5);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
*perl_uuid_time = time.QuadPart;
|
|
Packit Service |
7500fa |
#else
|
|
Packit Service |
7500fa |
struct timeval tp;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
gettimeofday(&tp, (struct timezone *)0);
|
|
Packit Service |
7500fa |
*perl_uuid_time = (tp.tv_sec * I64(10000000)) + (tp.tv_usec * I64(10)) +
|
|
Packit Service |
7500fa |
I64(0x01B21DD213814000);
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void get_random_info(unsigned char seed[16]) {
|
|
Packit Service |
7500fa |
SV* ctx;
|
|
Packit Service |
7500fa |
#if defined __cygwin__ || defined __MINGW32__ || defined __MSWin32__
|
|
Packit Service |
7500fa |
typedef struct {
|
|
Packit Service |
7500fa |
MEMORYSTATUS m;
|
|
Packit Service |
7500fa |
SYSTEM_INFO s;
|
|
Packit Service |
7500fa |
FILETIME t;
|
|
Packit Service |
7500fa |
LARGE_INTEGER pc;
|
|
Packit Service |
7500fa |
DWORD tc;
|
|
Packit Service |
7500fa |
DWORD l;
|
|
Packit Service |
7500fa |
char hostname[MAX_COMPUTERNAME_LENGTH + 1];
|
|
Packit Service |
7500fa |
} randomness;
|
|
Packit Service |
7500fa |
#else
|
|
Packit Service |
7500fa |
typedef struct {
|
|
Packit Service |
7500fa |
#if defined __BEOS__ || defined __HAIKU__
|
|
Packit Service |
7500fa |
system_info sys_info;
|
|
Packit Service |
7500fa |
#else
|
|
Packit Service |
7500fa |
long hostid;
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
struct timeval t;
|
|
Packit Service |
7500fa |
char hostname[257];
|
|
Packit Service |
7500fa |
} randomness;
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
randomness r;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#if defined __cygwin__ || defined __MINGW32__ || defined __MSWin32__
|
|
Packit Service |
7500fa |
GlobalMemoryStatus(&r.m);
|
|
Packit Service |
7500fa |
GetSystemInfo(&r.s);
|
|
Packit Service |
7500fa |
GetSystemTimeAsFileTime(&r.t);
|
|
Packit Service |
7500fa |
QueryPerformanceCounter(&r.pc);
|
|
Packit Service |
7500fa |
r.tc = GetTickCount();
|
|
Packit Service |
7500fa |
r.l = MAX_COMPUTERNAME_LENGTH + 1;
|
|
Packit Service |
7500fa |
GetComputerName(r.hostname, &r.l );
|
|
Packit Service |
7500fa |
#else
|
|
Packit Service |
7500fa |
# if defined __BEOS__ || defined __HAIKU__
|
|
Packit Service |
7500fa |
get_system_info(&r.sys_info);
|
|
Packit Service |
7500fa |
# elif !defined(__ANDROID__)
|
|
Packit Service |
7500fa |
r.hostid = gethostid();
|
|
Packit Service |
7500fa |
# endif
|
|
Packit Service |
7500fa |
gettimeofday(&r.t, (struct timezone *)0);
|
|
Packit Service |
7500fa |
gethostname(r.hostname, 256);
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
ctx = MD5Init();
|
|
Packit Service |
7500fa |
MD5Update(ctx, sv_2mortal(newSVpv((char*)&r, sizeof(randomness))));
|
|
Packit Service |
7500fa |
MD5Final(seed, ctx);
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static SV* make_ret(const perl_uuid_t u, int type) {
|
|
Packit Service |
7500fa |
char buf[BUFSIZ];
|
|
Packit Service |
7500fa |
const unsigned char *from;
|
|
Packit Service |
7500fa |
unsigned char *to;
|
|
Packit Service |
7500fa |
STRLEN len;
|
|
Packit Service |
7500fa |
int i;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
memset(buf, 0x00, BUFSIZ);
|
|
Packit Service |
7500fa |
switch(type) {
|
|
Packit Service |
7500fa |
case F_BIN:
|
|
Packit Service |
7500fa |
memcpy(buf, &u, sizeof(perl_uuid_t));
|
|
Packit Service |
7500fa |
len = sizeof(perl_uuid_t);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
case F_STR:
|
|
Packit Service |
7500fa |
sprintf(buf, "%8.8X-%4.4X-%4.4X-%2.2X%2.2X-", (unsigned int)u.time_low, u.time_mid,
|
|
Packit Service |
7500fa |
u.time_hi_and_version, u.clock_seq_hi_and_reserved, u.clock_seq_low);
|
|
Packit Service |
7500fa |
for(i = 0; i < 6; i++ )
|
|
Packit Service |
7500fa |
sprintf(buf+strlen(buf), "%2.2X", u.node[i]);
|
|
Packit Service |
7500fa |
len = strlen(buf);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
case F_HEX:
|
|
Packit Service |
7500fa |
sprintf(buf, "0x%8.8X%4.4X%4.4X%2.2X%2.2X", (unsigned int)u.time_low, u.time_mid,
|
|
Packit Service |
7500fa |
u.time_hi_and_version, u.clock_seq_hi_and_reserved, u.clock_seq_low);
|
|
Packit Service |
7500fa |
for(i = 0; i < 6; i++ )
|
|
Packit Service |
7500fa |
sprintf(buf+strlen(buf), "%2.2X", u.node[i]);
|
|
Packit Service |
7500fa |
len = strlen(buf);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
case F_B64:
|
|
Packit Service |
7500fa |
for(from = (const unsigned char*)&u, to = (unsigned char*)buf, i = sizeof(u); i > 0; i -= 3, from += 3) {
|
|
Packit Service |
7500fa |
*to++ = base64[from[0]>>2];
|
|
Packit Service |
7500fa |
switch(i) {
|
|
Packit Service |
7500fa |
case 1:
|
|
Packit Service |
7500fa |
*to++ = base64[(from[0]&0x03)<<4];
|
|
Packit Service |
7500fa |
*to++ = '=';
|
|
Packit Service |
7500fa |
*to++ = '=';
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
case 2:
|
|
Packit Service |
7500fa |
*to++ = base64[((from[0]&0x03)<<4) | ((from[1]&0xF0)>>4)];
|
|
Packit Service |
7500fa |
*to++ = base64[(from[1]&0x0F)<<2];
|
|
Packit Service |
7500fa |
*to++ = '=';
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
default:
|
|
Packit Service |
7500fa |
*to++ = base64[((from[0]&0x03)<<4) | ((from[1]&0xF0)>>4)];
|
|
Packit Service |
7500fa |
*to++ = base64[((from[1]&0x0F)<<2) | ((from[2]&0xC0)>>6)];
|
|
Packit Service |
7500fa |
*to++ = base64[(from[2]&0x3F)];
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
len = strlen(buf);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
default:
|
|
Packit Service |
7500fa |
croak("invalid type: %d\n", type);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
return sv_2mortal(newSVpv(buf,len));
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static SV* MD5Init() {
|
|
Packit Service |
7500fa |
SV* res;
|
|
Packit Service |
7500fa |
int rcount;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
dSP;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
ENTER; SAVETMPS;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PUSHMARK(SP);
|
|
Packit Service |
7500fa |
XPUSHs(sv_2mortal(newSVpv("Digest::MD5", 0)));
|
|
Packit Service |
7500fa |
PUTBACK;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
rcount = call_method("new", G_SCALAR);
|
|
Packit Service |
7500fa |
SPAGAIN;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if ( rcount != 1 )
|
|
Packit Service |
7500fa |
croak("couldn't construct new Digest::MD5 object");
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
res = newSVsv(POPs);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PUTBACK;
|
|
Packit Service |
7500fa |
FREETMPS;
|
|
Packit Service |
7500fa |
LEAVE;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
return res;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void MD5Update( SV* ctx, SV* data ) {
|
|
Packit Service |
7500fa |
dSP;
|
|
Packit Service |
7500fa |
ENTER; SAVETMPS;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PUSHMARK(SP);
|
|
Packit Service |
7500fa |
XPUSHs(ctx);
|
|
Packit Service |
7500fa |
XPUSHs(data);
|
|
Packit Service |
7500fa |
PUTBACK;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
call_method("add", G_DISCARD);
|
|
Packit Service |
7500fa |
SPAGAIN;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PUTBACK;
|
|
Packit Service |
7500fa |
FREETMPS;
|
|
Packit Service |
7500fa |
LEAVE;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
static void MD5Final( unsigned char hash[16], SV* ctx ) {
|
|
Packit Service |
7500fa |
int rcount;
|
|
Packit Service |
7500fa |
char* tmp;
|
|
Packit Service |
7500fa |
STRLEN len;
|
|
Packit Service |
7500fa |
SV* retval;
|
|
Packit Service |
7500fa |
dSP;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
ENTER; SAVETMPS;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PUSHMARK(SP);
|
|
Packit Service |
7500fa |
XPUSHs(sv_2mortal(ctx));
|
|
Packit Service |
7500fa |
PUTBACK;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
rcount = call_method("digest", G_SCALAR);
|
|
Packit Service |
7500fa |
SPAGAIN;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if ( rcount != 1 )
|
|
Packit Service |
7500fa |
croak("Digest::MD5->digest hasn't returned a scalar");
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
retval = POPs;
|
|
Packit Service |
7500fa |
tmp = SvPV(retval, len);
|
|
Packit Service |
7500fa |
if ( len != 16 )
|
|
Packit Service |
7500fa |
croak("Digest::MD5->digest returned not 16 bytes");
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
memcpy(hash, tmp, len);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PUTBACK;
|
|
Packit Service |
7500fa |
FREETMPS;
|
|
Packit Service |
7500fa |
LEAVE;
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
MODULE = Data::UUID PACKAGE = Data::UUID
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
PROTOTYPES: DISABLE
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
uuid_context_t*
|
|
Packit Service |
7500fa |
new(class)
|
|
Packit Service |
7500fa |
PREINIT:
|
|
Packit Service |
7500fa |
FILE *fd;
|
|
Packit Service |
7500fa |
unsigned char seed[16];
|
|
Packit Service |
7500fa |
perl_uuid_time_t timestamp;
|
|
Packit Service |
7500fa |
mode_t mask;
|
|
Packit Service |
7500fa |
UV one = 1;
|
|
Packit Service |
7500fa |
CODE:
|
|
Packit Service |
7500fa |
RETVAL = (uuid_context_t *)PerlMemShared_malloc(sizeof(uuid_context_t));
|
|
Packit Service |
7500fa |
if ((fd = fopen(UUID_STATE_NV_STORE, "rb"))) {
|
|
Packit Service |
7500fa |
fread(&(RETVAL->state), sizeof(uuid_state_t), 1, fd);
|
|
Packit Service |
7500fa |
fclose(fd);
|
|
Packit Service |
7500fa |
get_current_time(×tamp);
|
|
Packit Service |
7500fa |
RETVAL->next_save = timestamp;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
if ((fd = fopen(UUID_NODEID_NV_STORE, "rb"))) {
|
|
Packit Service |
7500fa |
pid_t *hate = (pid_t *) &(RETVAL->nodeid);
|
|
Packit Service |
7500fa |
fread(&(RETVAL->nodeid), sizeof(uuid_node_t), 1, fd );
|
|
Packit Service |
7500fa |
fclose(fd);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
*hate += getpid();
|
|
Packit Service |
7500fa |
} else {
|
|
Packit Service |
7500fa |
get_random_info(seed);
|
|
Packit Service |
7500fa |
seed[0] |= 0x80;
|
|
Packit Service |
7500fa |
memcpy(&(RETVAL->nodeid), seed, sizeof(uuid_node_t));
|
|
Packit Service |
7500fa |
mask = umask(_DEFAULT_UMASK);
|
|
Packit Service |
7500fa |
if ((fd = fopen(UUID_NODEID_NV_STORE, "wb"))) {
|
|
Packit Service |
7500fa |
fwrite(&(RETVAL->nodeid), sizeof(uuid_node_t), 1, fd);
|
|
Packit Service |
7500fa |
fclose(fd);
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
umask(mask);
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
errno = 0;
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
MUTEX_LOCK(&instances_mutex);
|
|
Packit Service |
7500fa |
ptable_store(instances, RETVAL, INT2PTR(void *, one));
|
|
Packit Service |
7500fa |
MUTEX_UNLOCK(&instances_mutex);
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
OUTPUT:
|
|
Packit Service |
7500fa |
RETVAL
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
void
|
|
Packit Service |
7500fa |
create(self)
|
|
Packit Service |
7500fa |
uuid_context_t *self;
|
|
Packit Service |
7500fa |
ALIAS:
|
|
Packit Service |
7500fa |
Data::UUID::create_bin = F_BIN
|
|
Packit Service |
7500fa |
Data::UUID::create_str = F_STR
|
|
Packit Service |
7500fa |
Data::UUID::create_hex = F_HEX
|
|
Packit Service |
7500fa |
Data::UUID::create_b64 = F_B64
|
|
Packit Service |
7500fa |
PREINIT:
|
|
Packit Service |
7500fa |
perl_uuid_time_t timestamp;
|
|
Packit Service |
7500fa |
unsigned16 clockseq;
|
|
Packit Service |
7500fa |
perl_uuid_t uuid;
|
|
Packit Service |
7500fa |
FILE *fd;
|
|
Packit Service |
7500fa |
mode_t mask;
|
|
Packit Service |
7500fa |
PPCODE:
|
|
Packit Service |
7500fa |
clockseq = self->state.cs;
|
|
Packit Service |
7500fa |
get_current_time(×tamp);
|
|
Packit Service |
7500fa |
if ( self->state.ts == I64(0) ||
|
|
Packit Service |
7500fa |
memcmp(&(self->nodeid), &(self->state.node), sizeof(uuid_node_t)))
|
|
Packit Service |
7500fa |
clockseq = true_random();
|
|
Packit Service |
7500fa |
else if (timestamp <= self->state.ts)
|
|
Packit Service |
7500fa |
clockseq++;
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
format_uuid_v1(&uuid, clockseq, timestamp, self->nodeid);
|
|
Packit Service |
7500fa |
self->state.node = self->nodeid;
|
|
Packit Service |
7500fa |
self->state.ts = timestamp;
|
|
Packit Service |
7500fa |
self->state.cs = clockseq;
|
|
Packit Service |
7500fa |
if (timestamp > self->next_save ) {
|
|
Packit Service |
7500fa |
mask = umask(_DEFAULT_UMASK);
|
|
Packit Service |
7500fa |
if((fd = fopen(UUID_STATE_NV_STORE, "wb"))) {
|
|
Packit Service |
7500fa |
LOCK(fd);
|
|
Packit Service |
7500fa |
fwrite(&(self->state), sizeof(uuid_state_t), 1, fd);
|
|
Packit Service |
7500fa |
UNLOCK(fd);
|
|
Packit Service |
7500fa |
fclose(fd);
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
umask(mask);
|
|
Packit Service |
7500fa |
self->next_save = timestamp + (10 * 10 * 1000 * 1000);
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
ST(0) = make_ret(uuid, ix);
|
|
Packit Service |
7500fa |
XSRETURN(1);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
void
|
|
Packit Service |
7500fa |
create_from_name(self,nsid,name)
|
|
Packit Service |
7500fa |
uuid_context_t *self;
|
|
Packit Service |
7500fa |
perl_uuid_t *nsid;
|
|
Packit Service |
7500fa |
SV *name;
|
|
Packit Service |
7500fa |
ALIAS:
|
|
Packit Service |
7500fa |
Data::UUID::create_from_name_bin = F_BIN
|
|
Packit Service |
7500fa |
Data::UUID::create_from_name_str = F_STR
|
|
Packit Service |
7500fa |
Data::UUID::create_from_name_hex = F_HEX
|
|
Packit Service |
7500fa |
Data::UUID::create_from_name_b64 = F_B64
|
|
Packit Service |
7500fa |
PREINIT:
|
|
Packit Service |
7500fa |
SV *ctx;
|
|
Packit Service |
7500fa |
unsigned char hash[16];
|
|
Packit Service |
7500fa |
perl_uuid_t net_nsid;
|
|
Packit Service |
7500fa |
perl_uuid_t uuid;
|
|
Packit Service |
7500fa |
PPCODE:
|
|
Packit Service |
7500fa |
net_nsid = *nsid;
|
|
Packit Service |
7500fa |
net_nsid.time_low = htonl(net_nsid.time_low);
|
|
Packit Service |
7500fa |
net_nsid.time_mid = htons(net_nsid.time_mid);
|
|
Packit Service |
7500fa |
net_nsid.time_hi_and_version = htons(net_nsid.time_hi_and_version);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
ctx = MD5Init();
|
|
Packit Service |
7500fa |
MD5Update(ctx, newSVpv((char*)&net_nsid, sizeof(perl_uuid_t)));
|
|
Packit Service |
7500fa |
MD5Update(ctx, name);
|
|
Packit Service |
7500fa |
MD5Final(hash, ctx);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
format_uuid_v3(&uuid, hash);
|
|
Packit Service |
7500fa |
ST(0) = make_ret(uuid, ix);
|
|
Packit Service |
7500fa |
XSRETURN(1);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
int
|
|
Packit Service |
7500fa |
compare(self,u1,u2)
|
|
Packit Service |
7500fa |
uuid_context_t *self;
|
|
Packit Service |
7500fa |
perl_uuid_t *u1;
|
|
Packit Service |
7500fa |
perl_uuid_t *u2;
|
|
Packit Service |
7500fa |
PREINIT:
|
|
Packit Service |
7500fa |
int i;
|
|
Packit Service |
7500fa |
CODE:
|
|
Packit Service |
7500fa |
RETVAL = 0;
|
|
Packit Service |
7500fa |
CHECK(u1->time_low, u2->time_low);
|
|
Packit Service |
7500fa |
CHECK(u1->time_mid, u2->time_mid);
|
|
Packit Service |
7500fa |
CHECK(u1->time_hi_and_version, u2->time_hi_and_version);
|
|
Packit Service |
7500fa |
CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved);
|
|
Packit Service |
7500fa |
CHECK(u1->clock_seq_low, u2->clock_seq_low);
|
|
Packit Service |
7500fa |
for (i = 0; i < 6; i++) {
|
|
Packit Service |
7500fa |
if (u1->node[i] < u2->node[i])
|
|
Packit Service |
7500fa |
RETVAL = -1;
|
|
Packit Service |
7500fa |
if (u1->node[i] > u2->node[i])
|
|
Packit Service |
7500fa |
RETVAL = 1;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
OUTPUT:
|
|
Packit Service |
7500fa |
RETVAL
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
void
|
|
Packit Service |
7500fa |
to_string(self,uuid)
|
|
Packit Service |
7500fa |
uuid_context_t *self;
|
|
Packit Service |
7500fa |
perl_uuid_t *uuid;
|
|
Packit Service |
7500fa |
ALIAS:
|
|
Packit Service |
7500fa |
Data::UUID::to_hexstring = F_HEX
|
|
Packit Service |
7500fa |
Data::UUID::to_b64string = F_B64
|
|
Packit Service |
7500fa |
PPCODE:
|
|
Packit Service |
7500fa |
ST(0) = make_ret(*uuid, ix ? ix : F_STR);
|
|
Packit Service |
7500fa |
XSRETURN(1);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
void
|
|
Packit Service |
7500fa |
from_string(self,str)
|
|
Packit Service |
7500fa |
uuid_context_t *self;
|
|
Packit Service |
7500fa |
char *str;
|
|
Packit Service |
7500fa |
ALIAS:
|
|
Packit Service |
7500fa |
Data::UUID::from_hexstring = F_HEX
|
|
Packit Service |
7500fa |
Data::UUID::from_b64string = F_B64
|
|
Packit Service |
7500fa |
PREINIT:
|
|
Packit Service |
7500fa |
perl_uuid_t uuid;
|
|
Packit Service |
7500fa |
char *from, *to;
|
|
Packit Service |
7500fa |
int c;
|
|
Packit Service |
7500fa |
unsigned int i;
|
|
Packit Service |
7500fa |
unsigned char buf[4];
|
|
Packit Service |
7500fa |
PPCODE:
|
|
Packit Service |
7500fa |
switch(ix) {
|
|
Packit Service |
7500fa |
case F_BIN:
|
|
Packit Service |
7500fa |
case F_STR:
|
|
Packit Service |
7500fa |
case F_HEX:
|
|
Packit Service |
7500fa |
from = str;
|
|
Packit Service |
7500fa |
memset(&uuid, 0x00, sizeof(perl_uuid_t));
|
|
Packit Service |
7500fa |
if ( from[0] == '0' && from[1] == 'x' )
|
|
Packit Service |
7500fa |
from += 2;
|
|
Packit Service |
7500fa |
for (i = 0; i < sizeof(perl_uuid_t); i++) {
|
|
Packit Service |
7500fa |
if (*from == '-')
|
|
Packit Service |
7500fa |
from++;
|
|
Packit Service |
7500fa |
if (sscanf(from, "%2x", &c) != 1)
|
|
Packit Service |
7500fa |
croak("from_string(%s) failed...\n", str);
|
|
Packit Service |
7500fa |
((unsigned char*)&uuid)[i] = (unsigned char)c;
|
|
Packit Service |
7500fa |
from += 2;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
uuid.time_low = ntohl(uuid.time_low);
|
|
Packit Service |
7500fa |
uuid.time_mid = ntohs(uuid.time_mid);
|
|
Packit Service |
7500fa |
uuid.time_hi_and_version = ntohs(uuid.time_hi_and_version);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
case F_B64:
|
|
Packit Service |
7500fa |
from = str; to = (char*)&uui;;
|
|
Packit Service |
7500fa |
while(from < (str + strlen(str))) {
|
|
Packit Service |
7500fa |
i = 0; memset(buf, 254, 4);
|
|
Packit Service |
7500fa |
do {
|
|
Packit Service |
7500fa |
c = index64[(int)*from++];
|
|
Packit Service |
7500fa |
if (c != 255) buf[i++] = (unsigned char)c;
|
|
Packit Service |
7500fa |
if (from == (str + strlen(str)))
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
} while (i < 4);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if (buf[0] == 254 || buf[1] == 254)
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
*to++ = (buf[0] << 2) | ((buf[1] & 0x30) >> 4);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if (buf[2] == 254) break;
|
|
Packit Service |
7500fa |
*to++ = ((buf[1] & 0x0F) << 4) | ((buf[2] & 0x3C) >> 2);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
if (buf[3] == 254) break;
|
|
Packit Service |
7500fa |
*to++ = ((buf[2] & 0x03) << 6) | buf[3];
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
default:
|
|
Packit Service |
7500fa |
croak("invalid type %d\n", ix);
|
|
Packit Service |
7500fa |
break;
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
ST(0) = make_ret(uuid, F_BIN);
|
|
Packit Service |
7500fa |
XSRETURN(1);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
void
|
|
Packit Service |
7500fa |
CLONE(klass)
|
|
Packit Service |
7500fa |
CODE:
|
|
Packit Service |
7500fa |
MUTEX_LOCK(&instances_mutex);
|
|
Packit Service |
7500fa |
ptable_walk(instances, inc, instances);
|
|
Packit Service |
7500fa |
MUTEX_UNLOCK(&instances_mutex);
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
void
|
|
Packit Service |
7500fa |
DESTROY(self)
|
|
Packit Service |
7500fa |
uuid_context_t *self;
|
|
Packit Service |
7500fa |
PREINIT:
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
UV count;
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
FILE *fd;
|
|
Packit Service |
7500fa |
CODE:
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
MUTEX_LOCK(&instances_mutex);
|
|
Packit Service |
7500fa |
count = PTR2UV(ptable_fetch(instances, self));
|
|
Packit Service |
7500fa |
count--;
|
|
Packit Service |
7500fa |
ptable_store(instances, self, (void *)count);
|
|
Packit Service |
7500fa |
MUTEX_UNLOCK(&instances_mutex);
|
|
Packit Service |
7500fa |
if (count == 0) {
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
if ((fd = fopen(UUID_STATE_NV_STORE, "wb"))) {
|
|
Packit Service |
7500fa |
LOCK(fd);
|
|
Packit Service |
7500fa |
fwrite(&(self->state), sizeof(uuid_state_t), 1, fd);
|
|
Packit Service |
7500fa |
UNLOCK(fd);
|
|
Packit Service |
7500fa |
fclose(fd);
|
|
Packit Service |
7500fa |
};
|
|
Packit Service |
7500fa |
PerlMemShared_free(self);
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
}
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
|
|
Packit Service |
7500fa |
BOOT:
|
|
Packit Service |
7500fa |
{
|
|
Packit Service |
7500fa |
HV *stash = gv_stashpv("Data::UUID", 0);
|
|
Packit Service |
7500fa |
STRLEN len = sizeof(perl_uuid_t);
|
|
Packit Service |
7500fa |
#if DU_THREADSAFE
|
|
Packit Service |
7500fa |
instances = ptable_new();
|
|
Packit Service |
7500fa |
MUTEX_INIT(&instances_mutex);
|
|
Packit Service |
7500fa |
#endif
|
|
Packit Service |
7500fa |
newCONSTSUB(stash, "NameSpace_DNS", newSVpv((char *)&NameSpace_DNS, len));
|
|
Packit Service |
7500fa |
newCONSTSUB(stash, "NameSpace_URL", newSVpv((char *)&NameSpace_URL, len));
|
|
Packit Service |
7500fa |
newCONSTSUB(stash, "NameSpace_OID", newSVpv((char *)&NameSpace_OID, len));
|
|
Packit Service |
7500fa |
newCONSTSUB(stash, "NameSpace_X500", newSVpv((char *)&NameSpace_X500, len));
|
|
Packit Service |
7500fa |
}
|