GUID
[Class: Getting and setting entity values.]


Data Structures

union  _GUID

Files

file  guid.h
 globally unique ID User API

Defines

#define GUID_DATA_SIZE   16
#define GUID_ENCODING_LENGTH   32

Typedefs

typedef union _GUID GUID

Functions

void guid_init (void)
void guid_init_with_salt (const void *salt, size_t salt_len)
void guid_init_only_salt (const void *salt, size_t salt_len)
void guid_shutdown (void)
void guid_new (GUID *guid)
GUID guid_new_return (void)
const GUID * guid_null (void)
GUID * guid_malloc (void)
void guid_free (GUID *guid)
const gchar * guid_to_string (const GUID *guid)
gchar * guid_to_string_buff (const GUID *guid, gchar *buff)
gboolean string_to_guid (const gchar *string, GUID *guid)
gboolean guid_equal (const GUID *guid_1, const GUID *guid_2)
gint guid_compare (const GUID *g1, const GUID *g2)
guint guid_hash_to_guint (gconstpointer ptr)
GHashTable * guid_hash_table_new (void)

Detailed Description

Globally Unique ID's provide a way to uniquely identify some thing. A GUID is a unique, cryptographically random 128-bit value. The identifier is so random that it is safe to assume that there is no other such item on the planet Earth, and indeed, not even in the Galaxy or beyond.

QOF GUID's can be used independently of any other subsystem in QOF. In particular, they do not require the use of other parts of the object subsystem. New GUID's are usually created by initialising a new entity using qof_instance_init, rather than calling GUID functions directly.


Define Documentation

#define GUID_DATA_SIZE   16

The type used to store guids

Definition at line 52 of file guid.h.

#define GUID_ENCODING_LENGTH   32

number of characters needed to encode a guid as a string not including the null terminator.

Definition at line 64 of file guid.h.


Function Documentation

gboolean guid_equal ( const GUID *  guid_1,
const GUID *  guid_2 
)

Given two GUIDs, return TRUE if they are non-NULL and equal. Return FALSE, otherwise.

Definition at line 609 of file guid.c.

00610 {
00611     if (guid_1 && guid_2)
00612         return (memcmp (guid_1, guid_2, GUID_DATA_SIZE) == 0);
00613     else
00614         return FALSE;
00615 }

guint guid_hash_to_guint ( gconstpointer  ptr  ) 

Given a GUID *, hash it to a guint

Definition at line 634 of file guid.c.

00635 {
00636     const GUID *guid = ptr;
00637     guint hash = 0;
00638     unsigned int i, j;
00639 
00640     if (!guid)
00641     {
00642         PERR ("received NULL guid pointer.");
00643         return 0;
00644     }
00645 
00646     for (i = 0, j = 0; i < sizeof (guint); i++, j++)
00647     {
00648         if (j == GUID_DATA_SIZE)
00649             j = 0;
00650         
00651         hash <<= 4;
00652         hash |= guid->data[j];
00653     }
00654     
00655     return hash;
00656 }

void guid_init ( void   ) 

Initialize the id generator with a variety of random sources.

Note:
Only one of guid_init(), guid_init_with_salt() and guid_init_only_salt() should be called. Calling any initialization function a second time will reset the generator and erase the effect of the first call.

Definition at line 285 of file guid.c.

00286 {
00287     size_t bytes = 0;
00288 
00289     /* Not needed; taken care of on first malloc.
00290      * guid_memchunk_init(); */
00291 
00292     md5_init_ctx (&guid_context);
00293 
00294     /* entropy pool */
00295     bytes += init_from_file ("/dev/urandom", 512);
00296 
00297     /* files */
00298     {
00299         const char *files[] = { "/etc/passwd",
00300             "/proc/loadavg",
00301             "/proc/meminfo",
00302             "/proc/net/dev",
00303             "/proc/rtc",
00304             "/proc/self/environ",
00305             "/proc/self/stat",
00306             "/proc/stat",
00307             "/proc/uptime",
00308             NULL
00309         };
00310         int i;
00311 
00312         for (i = 0; files[i] != NULL; i++)
00313             bytes += init_from_file (files[i], BLOCKSIZE);
00314     }
00315 
00316     /* directories */
00317     {
00318         const char *dirname;
00319         const char *dirs[] = {
00320             "/proc",
00321             P_tmpdir,
00322             "/var/lock",
00323             "/var/log",
00324             "/var/mail",
00325             "/var/spool/mail",
00326             "/var/run",
00327             NULL
00328         };
00329         int i;
00330 
00331         for (i = 0; dirs[i] != NULL; i++)
00332             bytes += init_from_dir (dirs[i], 32);
00333 
00334         dirname = g_get_home_dir ();
00335         if (dirname != NULL)
00336             bytes += init_from_dir (dirname, 32);
00337     }
00338 
00339     /* process and parent ids */
00340     {
00341         pid_t pid;
00342 
00343         pid = getpid ();
00344         md5_process_bytes (&pid, sizeof (pid), &guid_context);
00345         bytes += sizeof (pid);
00346 
00347 #ifdef HAVE_GETPPID
00348         pid = getppid ();
00349         md5_process_bytes (&pid, sizeof (pid), &guid_context);
00350         bytes += sizeof (pid);
00351 #endif
00352     }
00353 
00354     /* user info */
00355     {
00356 #ifdef HAVE_GETUID
00357         uid_t uid;
00358         gid_t gid;
00359         char *s;
00360 
00361         s = getlogin ();
00362         if (s != NULL)
00363         {
00364             md5_process_bytes (s, strlen (s), &guid_context);
00365             bytes += strlen (s);
00366         }
00367 
00368         uid = getuid ();
00369         md5_process_bytes (&uid, sizeof (uid), &guid_context);
00370         bytes += sizeof (uid);
00371 
00372         gid = getgid ();
00373         md5_process_bytes (&gid, sizeof (gid), &guid_context);
00374         bytes += sizeof (gid);
00375 #endif
00376     }
00377 
00378     /* host info */
00379     {
00380 #ifdef HAVE_GETHOSTNAME
00381         char string[1024];
00382 
00383         memset (string, 0, sizeof (string));
00384         gethostname (string, sizeof (string));
00385         md5_process_bytes (string, sizeof (string), &guid_context);
00386         bytes += sizeof (string);
00387 #endif
00388     }
00389 
00390     /* plain old random */
00391     {
00392         int n, i;
00393 
00394         srand ((unsigned int) time (NULL));
00395 
00396         for (i = 0; i < 32; i++)
00397         {
00398             n = rand ();
00399 
00400             md5_process_bytes (&n, sizeof (n), &guid_context);
00401             bytes += sizeof (n);
00402         }
00403     }
00404 
00405     /* time in secs and clock ticks */
00406     bytes += init_from_time ();
00407 
00408     PINFO ("got %llu bytes", (unsigned long long int) bytes);
00409 
00410     if (bytes < THRESHOLD)
00411         PWARN ("only got %llu bytes.\n"
00412             "The identifiers might not be very random.\n",
00413             (unsigned long long int) bytes);
00414 
00415     guid_initialized = TRUE;
00416 }

void guid_init_only_salt ( const void *  salt,
size_t  salt_len 
)

Initialize the id generator with the data given in the salt argument, but not with any other source. Calling this function with a specific argument will reliably produce a specific sequence of ids.

Parameters:
salt The additional random values to add to the generator.
salt_len The length of the additional random values.
Note:
Only one of guid_init(), guid_init_with_salt() and guid_init_only_salt() should be called. Calling any initialization function a second time will reset the generator and erase the effect of the first call.

Definition at line 427 of file guid.c.

00428 {
00429     md5_init_ctx (&guid_context);
00430 
00431     md5_process_bytes (salt, salt_len, &guid_context);
00432 
00433     guid_initialized = TRUE;
00434 }

void guid_init_with_salt ( const void *  salt,
size_t  salt_len 
)

Initialize the id generator with a variety of random sources. and with the data given in the salt argument. This argument can be used to add additional randomness to the generated ids.

Parameters:
salt The additional random values to add to the generator.
salt_len The length of the additional random values.
Note:
Only one of guid_init(), guid_init_with_salt() and guid_init_only_salt() should be called. Calling any initialization function a second time will reset the generator and erase the effect of the first call.

Definition at line 419 of file guid.c.

00420 {
00421     guid_init ();
00422 
00423     md5_process_bytes (salt, salt_len, &guid_context);
00424 }

GUID* guid_malloc ( void   ) 

Efficiently allocate & free memory for GUIDs

Definition at line 64 of file guid.c.

00065 {
00066     return g_slice_new (GUID);
00067 }

void guid_new ( GUID *  guid  ) 

Generate a new id. If no initialization function has been called, guid_init() will be called before the id is created.

Parameters:
guid A pointer to an existing guid data structure. The existing value will be replaced with a new value.
This routine uses the md5 algorithm to build strong random guids. Note that while guid's are generated randomly, the odds of this routine returning a non-unique id are astronomically small. (Literally astronomically: If you had Cray's on every solar system in the universe running for the entire age of the universe, you'd still have less than a one-in-a-million chance of coming up with a duplicate id. 2^128 == 10^38 is a really really big number.)

Definition at line 444 of file guid.c.

00445 {
00446     static int counter = 0;
00447     struct md5_ctx ctx;
00448 
00449     if (guid == NULL)
00450         return;
00451 
00452     if (!guid_initialized)
00453         guid_init ();
00454 
00455     /* make the id */
00456     ctx = guid_context;
00457     md5_finish_ctx (&ctx, guid->data);
00458 
00459     /* update the global context */
00460     init_from_time ();
00461 
00462     /* Make it a little extra salty.  I think init_from_time was buggy,
00463      * or something, since duplicate id's actually happened. Or something
00464      * like that.  I think this is because init_from_time kept returning
00465      * the same values too many times in a row.  So we'll do some 'block
00466      * chaining', and feed in the old guid as new random data.
00467      *
00468      * Anyway, I think the whole fact that I saw a bunch of duplicate 
00469      * id's at one point, but can't reproduce the bug is rather alarming.
00470      * Something must be broken somewhere, and merely adding more salt
00471      * is just hiding the problem, not fixing it.
00472      */
00473     init_from_int (433781 * counter);
00474     init_from_buff (guid->data, GUID_DATA_SIZE);
00475 
00476     if (counter == 0)
00477     {
00478         FILE *fp;
00479 
00480         fp = fopen ("/dev/urandom", "r");
00481         if (fp == NULL)
00482             return;
00483 
00484         init_from_stream (fp, 32);
00485 
00486         fclose (fp);
00487 
00488         counter = GUID_PERIOD;
00489     }
00490 
00491     counter--;
00492 }

GUID guid_new_return ( void   ) 

Generate a new id. If no initialization function has been called, guid_init() will be called before the id is created.

Returns:
guid A data structure containing a newly allocated GUID. Caller is responsible for calling guid_free().

Definition at line 495 of file guid.c.

00496 {
00497     GUID guid;
00498 
00499     guid_new (&guid);
00500 
00501     return guid;
00502 }

const GUID* guid_null ( void   ) 

Returns a GUID which is guaranteed to never reference any entity.

Definition at line 79 of file guid.c.

00080 {
00081     static int null_inited = 0;
00082     static GUID null_guid;
00083 
00084     if (!null_inited)
00085     {
00086         int i;
00087         char *tmp = "NULLGUID.EMPTY.";
00088 
00089         /* 16th space for '\O' */
00090         for (i = 0; i < GUID_DATA_SIZE; i++)
00091             null_guid.data[i] = tmp[i];
00092 
00093         null_inited = 1;
00094     }
00095 
00096     return &null_guid;
00097 }

void guid_shutdown ( void   ) 

Release the memory chunk associated with gui storage. Use this only when shutting down the program, as it invalidates *all* GUIDs at once.

Definition at line 437 of file guid.c.

00438 {
00439 }

const gchar* guid_to_string ( const GUID *  guid  ) 

The guid_to_string() routine returns a null-terminated string encoding of the id. String encodings of identifiers are hex numbers printed only with the characters '0' through '9' and 'a' through 'f'. The encoding will always be GUID_ENCODING_LENGTH characters long.

XXX This routine is not thread safe and is deprecated. Please use the routine guid_to_string_buff() instead.

Parameters:
guid The guid to print.
Returns:
A pointer to the starting character of the string. The returned memory is owned by this routine and may not be freed by the caller.

Definition at line 568 of file guid.c.

00569 {
00570 #ifdef G_THREADS_ENABLED
00571     static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT;
00572     gchar *string;
00573 
00574     string = g_static_private_get (&guid_buffer_key);
00575     if (string == NULL)
00576     {
00577         string = malloc (GUID_ENCODING_LENGTH + 1);
00578         g_static_private_set (&guid_buffer_key, string, g_free);
00579     }
00580 #else
00581     static char string[64];
00582 #endif
00583 
00584     encode_md5_data (guid->data, string);
00585     string[GUID_ENCODING_LENGTH] = '\0';
00586 
00587     return string;
00588 }

gchar* guid_to_string_buff ( const GUID *  guid,
gchar *  buff 
)

The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory pointed at by buff. The buffer must be at least GUID_ENCODING_LENGTH+1 characters long. This routine is handy for avoiding a malloc/free cycle. It returns a pointer to the >>end<< of what was written. (i.e. it can be used like 'stpcpy' during string concatenation)

Parameters:
guid The guid to print.
buff The buffer to print it into.
Returns:
A pointer to the terminating null character of the string.

gboolean string_to_guid ( const gchar *  string,
GUID *  guid 
)

Given a string, decode the id into the guid if guid is non-NULL. The function returns TRUE if the string was a valid 32 character hexadecimal number. This function accepts both upper and lower case hex digits. If the return value is FALSE, the effect on guid is undefined.


Generated on Sat Aug 15 15:46:31 2009 for QOF by  doxygen 1.5.9