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) |
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 GUID_ENCODING_LENGTH 32 |
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.
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.
salt | The additional random values to add to the generator. | |
salt_len | The length of the additional random values. |
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.
salt | The additional random values to add to the generator. | |
salt_len | The length of the additional random values. |
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 | ) |
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.
guid | A pointer to an existing guid data structure. The existing value will be replaced with a new value. |
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.
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 | ) |
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.
guid | The guid to print. |
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)
guid | The guid to print. | |
buff | The buffer to print it into. |
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.