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.
Files | |
file | guid.h |
globally unique ID User API | |
Data Structures | |
union | _GUID |
Defines | |
#define | GUID_DATA_SIZE 16 |
#define | GUID_ENCODING_LENGTH 32 |
Typedefs | |
typedef _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) |
|
The type used to store guids |
|
number of characters needed to encode a guid as a string not including the null terminator. |
|
Given two GUIDs, return TRUE if they are non-NULL and equal. Return FALSE, otherwise. Definition at line 649 of file guid.c. 00650 { 00651 if (guid_1 && guid_2) 00652 return (memcmp(guid_1, guid_2, GUID_DATA_SIZE) == 0); 00653 else 00654 return FALSE; 00655 }
|
|
Given a GUID *, hash it to a guint Definition at line 674 of file guid.c. 00675 { 00676 const GUID *guid = ptr; 00677 00678 if (!guid) 00679 { 00680 PERR ("received NULL guid pointer."); 00681 return 0; 00682 } 00683 00684 if (sizeof(guint) <= sizeof(guid->data)) 00685 { 00686 return (*((guint *) guid->data)); 00687 } 00688 else 00689 { 00690 guint hash = 0; 00691 unsigned int i, j; 00692 00693 for (i = 0, j = 0; i < sizeof(guint); i++, j++) { 00694 if (j == GUID_DATA_SIZE) j = 0; 00695 00696 hash <<= 4; 00697 hash |= guid->data[j]; 00698 } 00699 00700 return hash; 00701 } 00702 }
|
|
Initialize the id generator with a variety of random sources.
Definition at line 327 of file guid.c. 00328 { 00329 size_t bytes = 0; 00330 00331 /* Not needed; taken care of on first malloc. 00332 * guid_memchunk_init(); */ 00333 00334 md5_init_ctx(&guid_context); 00335 00336 /* entropy pool */ 00337 bytes += init_from_file ("/dev/urandom", 512); 00338 00339 /* files */ 00340 { 00341 const char * files[] = 00342 { "/etc/passwd", 00343 "/proc/loadavg", 00344 "/proc/meminfo", 00345 "/proc/net/dev", 00346 "/proc/rtc", 00347 "/proc/self/environ", 00348 "/proc/self/stat", 00349 "/proc/stat", 00350 "/proc/uptime", 00351 NULL 00352 }; 00353 int i; 00354 00355 for (i = 0; files[i] != NULL; i++) 00356 bytes += init_from_file(files[i], BLOCKSIZE); 00357 } 00358 00359 /* directories */ 00360 { 00361 const char * dirname; 00362 const char * dirs[] = 00363 { 00364 "/proc", 00365 P_tmpdir, 00366 "/var/lock", 00367 "/var/log", 00368 "/var/mail", 00369 "/var/spool/mail", 00370 "/var/run", 00371 NULL 00372 }; 00373 int i; 00374 00375 for (i = 0; dirs[i] != NULL; i++) 00376 bytes += init_from_dir(dirs[i], 32); 00377 00378 dirname = g_get_home_dir(); 00379 if (dirname != NULL) 00380 bytes += init_from_dir(dirname, 32); 00381 } 00382 00383 /* process and parent ids */ 00384 { 00385 pid_t pid; 00386 00387 pid = getpid(); 00388 md5_process_bytes(&pid, sizeof(pid), &guid_context); 00389 bytes += sizeof(pid); 00390 00391 #ifdef HAVE_GETPPID 00392 pid = getppid(); 00393 md5_process_bytes(&pid, sizeof(pid), &guid_context); 00394 bytes += sizeof(pid); 00395 #endif 00396 } 00397 00398 /* user info */ 00399 { 00400 #ifdef HAVE_GETUID 00401 uid_t uid; 00402 gid_t gid; 00403 char *s; 00404 00405 s = getlogin(); 00406 if (s != NULL) 00407 { 00408 md5_process_bytes(s, strlen(s), &guid_context); 00409 bytes += strlen(s); 00410 } 00411 00412 uid = getuid(); 00413 md5_process_bytes(&uid, sizeof(uid), &guid_context); 00414 bytes += sizeof(uid); 00415 00416 gid = getgid(); 00417 md5_process_bytes(&gid, sizeof(gid), &guid_context); 00418 bytes += sizeof(gid); 00419 #endif 00420 } 00421 00422 /* host info */ 00423 { 00424 #ifdef HAVE_GETHOSTNAME 00425 char string[1024]; 00426 00427 memset(string, 0, sizeof(string)); 00428 gethostname(string, sizeof(string)); 00429 md5_process_bytes(string, sizeof(string), &guid_context); 00430 bytes += sizeof(string); 00431 #endif 00432 } 00433 00434 /* plain old random */ 00435 { 00436 int n, i; 00437 00438 srand((unsigned int) time(NULL)); 00439 00440 for (i = 0; i < 32; i++) 00441 { 00442 n = rand(); 00443 00444 md5_process_bytes(&n, sizeof(n), &guid_context); 00445 bytes += sizeof(n); 00446 } 00447 } 00448 00449 /* time in secs and clock ticks */ 00450 bytes += init_from_time(); 00451 00452 PINFO ("got %llu bytes", (unsigned long long int) bytes); 00453 00454 if (bytes < THRESHOLD) 00455 PWARN("only got %llu bytes.\n" 00456 "The identifiers might not be very random.\n", 00457 (unsigned long long int)bytes); 00458 00459 guid_initialized = TRUE; 00460 }
|
|
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.
Definition at line 471 of file guid.c. 00472 { 00473 md5_init_ctx(&guid_context); 00474 00475 md5_process_bytes(salt, salt_len, &guid_context); 00476 00477 guid_initialized = TRUE; 00478 }
|
|
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.
Definition at line 463 of file guid.c. 00464 { 00465 guid_init(); 00466 00467 md5_process_bytes(salt, salt_len, &guid_context); 00468 }
|
|
Efficiently allocate & free memory for GUIDs Definition at line 104 of file guid.c. 00105 { 00106 if (!guid_memchunk) guid_memchunk_init(); 00107 return g_chunk_new (GUID, guid_memchunk); 00108 }
|
|
Generate a new id. If no initialization function has been called, guid_init() will be called before the id is created.
Definition at line 491 of file guid.c. 00492 { 00493 static int counter = 0; 00494 struct md5_ctx ctx; 00495 00496 if (guid == NULL) 00497 return; 00498 00499 if (!guid_initialized) 00500 guid_init(); 00501 00502 /* make the id */ 00503 ctx = guid_context; 00504 md5_finish_ctx(&ctx, guid->data); 00505 00506 /* update the global context */ 00507 init_from_time(); 00508 00509 /* Make it a little extra salty. I think init_from_time was buggy, 00510 * or something, since duplicate id's actually happened. Or something 00511 * like that. I think this is because init_from_time kept returning 00512 * the same values too many times in a row. So we'll do some 'block 00513 * chaining', and feed in the old guid as new random data. 00514 * 00515 * Anyway, I think the whole fact that I saw a bunch of duplicate 00516 * id's at one point, but can't reproduce the bug is rather alarming. 00517 * Something must be broken somewhere, and merely adding more salt 00518 * is just hiding the problem, not fixing it. 00519 */ 00520 init_from_int (433781*counter); 00521 init_from_buff (guid->data, GUID_DATA_SIZE); 00522 00523 if (counter == 0) 00524 { 00525 FILE *fp; 00526 00527 fp = fopen ("/dev/urandom", "r"); 00528 if (fp == NULL) 00529 return; 00530 00531 init_from_stream(fp, 32); 00532 00533 fclose(fp); 00534 00535 counter = GUID_PERIOD; 00536 } 00537 00538 counter--; 00539 }
|
|
Generate a new id. If no initialization function has been called, guid_init() will be called before the id is created.
Definition at line 542 of file guid.c.
|
|
Returns a GUID which is guaranteed to never reference any entity. Definition at line 122 of file guid.c. 00123 { 00124 static int null_inited = 0; 00125 static GUID null_guid; 00126 00127 if (!null_inited) 00128 { 00129 int i; 00130 char *tmp = "NULLGUID.EMPTY."; 00131 00132 /* 16th space for '\O' */ 00133 for (i = 0; i < GUID_DATA_SIZE; i++) 00134 null_guid.data[i] = tmp[i]; 00135 00136 null_inited = 1; 00137 } 00138 00139 return &null_guid; 00140 }
|
|
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 481 of file guid.c.
|
|
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.
Definition at line 610 of file guid.c. 00611 { 00612 #ifdef G_THREADS_ENABLED 00613 static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT; 00614 gchar *string; 00615 00616 string = g_static_private_get (&guid_buffer_key); 00617 if (string == NULL) { 00618 string = malloc(GUID_ENCODING_LENGTH+1); 00619 g_static_private_set (&guid_buffer_key, string, g_free); 00620 } 00621 #else 00622 static char string[64]; 00623 #endif 00624 00625 encode_md5_data(guid->data, string); 00626 string[GUID_ENCODING_LENGTH] = '\0'; 00627 00628 return string; 00629 }
|
|
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)
|
|
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. |