Data Structures | |
| union | GNC_INTERNAL_GUID |
Files | |
| file | guid.h |
| globally unique ID User API | |
Defines | |
| #define | GUID_DATA_SIZE 16 |
| #define | GNC_TYPE_GUID (gnc_guid_get_type()) |
| #define | GNC_VALUE_HOLDS_GUID(value) G_VALUE_HOLDS(value, GNC_TYPE_GUID) |
| #define | GUID_ENCODING_LENGTH 32 |
Typedefs | |
| typedef union GNC_INTERNAL_GUID | GUID |
Functions | |
| GType | gnc_guid_get_type (void) |
| G_CONST_RETURN GUID * | gnc_value_get_guid (const GValue *value) |
| 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) |
| GUID * | guid_copy (const 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 |
| G_CONST_RETURN GUID* gnc_value_get_guid | ( | const GValue * | value | ) |
gnc_value_get_guid
| value | a GValue whose value we want to get. |
Definition at line 75 of file guid.c.
00076 { 00077 GUID *val; 00078 00079 g_return_val_if_fail (value && G_IS_VALUE (value), NULL); 00080 g_return_val_if_fail (GNC_VALUE_HOLDS_GUID (value), NULL); 00081 00082 val = (GUID*) g_value_get_boxed (value); 00083 00084 return val; 00085 }
| 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 658 of file guid.c.
00659 { 00660 if (guid_1 && guid_2) 00661 return (memcmp(guid_1, guid_2, GUID_DATA_SIZE) == 0); 00662 else 00663 return FALSE; 00664 }
| guint guid_hash_to_guint | ( | gconstpointer | ptr | ) |
Given a GUID *, hash it to a guint
Definition at line 683 of file guid.c.
00684 { 00685 const GUID *guid = ptr; 00686 00687 if (!guid) 00688 { 00689 PERR ("received NULL guid pointer."); 00690 return 0; 00691 } 00692 00693 if (sizeof(guint) <= sizeof(guid->data)) 00694 { 00695 const guint* ptr_data = (const guint *) guid->data; 00696 return (*ptr_data); 00697 } 00698 else 00699 { 00700 guint hash = 0; 00701 unsigned int i, j; 00702 00703 for (i = 0, j = 0; i < sizeof(guint); i++, j++) 00704 { 00705 if (j == GUID_DATA_SIZE) j = 0; 00706 00707 hash <<= 4; 00708 hash |= guid->data[j]; 00709 } 00710 00711 return hash; 00712 } 00713 }
| void guid_init | ( | void | ) |
Initialize the id generator with a variety of random sources.
Definition at line 326 of file guid.c.
00327 { 00328 size_t bytes = 0; 00329 00330 /* Not needed; taken care of on first malloc. 00331 * guid_memchunk_init(); */ 00332 00333 md5_init_ctx(&guid_context); 00334 00335 /* entropy pool */ 00336 bytes += init_from_file ("/dev/urandom", 512); 00337 00338 /* files */ 00339 { 00340 const char * files[] = 00341 { 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 #ifdef HAVE_UNISTD_H 00386 pid_t pid; 00387 00388 pid = getpid(); 00389 md5_process_bytes(&pid, sizeof(pid), &guid_context); 00390 bytes += sizeof(pid); 00391 00392 #ifdef HAVE_GETPPID 00393 pid = getppid(); 00394 md5_process_bytes(&pid, sizeof(pid), &guid_context); 00395 bytes += sizeof(pid); 00396 #endif 00397 #endif 00398 } 00399 00400 /* user info */ 00401 { 00402 #ifdef HAVE_GETUID 00403 uid_t uid; 00404 gid_t gid; 00405 char *s; 00406 00407 s = getlogin(); 00408 if (s != NULL) 00409 { 00410 md5_process_bytes(s, strlen(s), &guid_context); 00411 bytes += strlen(s); 00412 } 00413 00414 uid = getuid(); 00415 md5_process_bytes(&uid, sizeof(uid), &guid_context); 00416 bytes += sizeof(uid); 00417 00418 gid = getgid(); 00419 md5_process_bytes(&gid, sizeof(gid), &guid_context); 00420 bytes += sizeof(gid); 00421 #endif 00422 } 00423 00424 /* host info */ 00425 { 00426 #ifdef HAVE_GETHOSTNAME 00427 char string[1024]; 00428 00429 memset(string, 0, sizeof(string)); 00430 gethostname(string, sizeof(string)); 00431 md5_process_bytes(string, sizeof(string), &guid_context); 00432 bytes += sizeof(string); 00433 #endif 00434 } 00435 00436 /* plain old random */ 00437 { 00438 int n, i; 00439 00440 srand((unsigned int) time(NULL)); 00441 00442 for (i = 0; i < 32; i++) 00443 { 00444 n = rand(); 00445 00446 md5_process_bytes(&n, sizeof(n), &guid_context); 00447 bytes += sizeof(n); 00448 } 00449 } 00450 00451 /* time in secs and clock ticks */ 00452 bytes += init_from_time(); 00453 00454 #ifdef HAVE_SCANF_LLD 00455 PINFO ("got %llu bytes", (unsigned long long int) bytes); 00456 00457 if (bytes < THRESHOLD) 00458 PWARN("only got %llu bytes.\n" 00459 "The identifiers might not be very random.\n", 00460 (unsigned long long int)bytes); 00461 #else 00462 PINFO ("got %lu bytes", (unsigned long int) bytes); 00463 00464 if (bytes < THRESHOLD) 00465 PWARN("only got %lu bytes.\n" 00466 "The identifiers might not be very random.\n", 00467 (unsigned long int)bytes); 00468 #endif 00469 00470 guid_initialized = TRUE; 00471 }
| 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 482 of file guid.c.
00483 { 00484 md5_init_ctx(&guid_context); 00485 00486 md5_process_bytes(salt, salt_len, &guid_context); 00487 00488 guid_initialized = TRUE; 00489 }
| 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 474 of file guid.c.
00475 { 00476 guid_init(); 00477 00478 md5_process_bytes(salt, salt_len, &guid_context); 00479 }
| 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 499 of file guid.c.
00500 { 00501 static int counter = 0; 00502 struct md5_ctx ctx; 00503 00504 if (guid == NULL) 00505 return; 00506 00507 if (!guid_initialized) 00508 guid_init(); 00509 00510 /* make the id */ 00511 ctx = guid_context; 00512 md5_finish_ctx(&ctx, guid->data); 00513 00514 /* update the global context */ 00515 init_from_time(); 00516 00517 /* Make it a little extra salty. I think init_from_time was buggy, 00518 * or something, since duplicate id's actually happened. Or something 00519 * like that. I think this is because init_from_time kept returning 00520 * the same values too many times in a row. So we'll do some 'block 00521 * chaining', and feed in the old guid as new random data. 00522 * 00523 * Anyway, I think the whole fact that I saw a bunch of duplicate 00524 * id's at one point, but can't reproduce the bug is rather alarming. 00525 * Something must be broken somewhere, and merely adding more salt 00526 * is just hiding the problem, not fixing it. 00527 */ 00528 init_from_int (433781 * counter); 00529 init_from_buff (guid->data, GUID_DATA_SIZE); 00530 00531 if (counter == 0) 00532 { 00533 FILE *fp; 00534 00535 fp = g_fopen ("/dev/urandom", "r"); 00536 if (fp == NULL) 00537 return; 00538 00539 init_from_stream(fp, 32); 00540 00541 fclose(fp); 00542 00543 counter = GUID_PERIOD; 00544 } 00545 00546 counter--; 00547 }
| 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 550 of file guid.c.
00551 { 00552 GUID guid; 00553 00554 guid_new (&guid); 00555 00556 return guid; 00557 }
| const GUID* guid_null | ( | void | ) |
Returns a GUID which is guaranteed to never reference any entity.
Definition at line 117 of file guid.c.
00118 { 00119 static int null_inited = 0; 00120 static GUID null_guid; 00121 00122 if (!null_inited) 00123 { 00124 int i; 00125 00126 for (i = 0; i < GUID_DATA_SIZE; i++) 00127 null_guid.data[i] = '\0'; 00128 00129 null_inited = 1; 00130 } 00131 00132 return &null_guid; 00133 }
| 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 618 of file guid.c.
00619 { 00620 #ifdef G_THREADS_ENABLED 00621 static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT; 00622 gchar *string; 00623 00624 string = g_static_private_get (&guid_buffer_key); 00625 if (string == NULL) 00626 { 00627 string = malloc(GUID_ENCODING_LENGTH + 1); 00628 g_static_private_set (&guid_buffer_key, string, g_free); 00629 } 00630 #else 00631 static char string[64]; 00632 #endif 00633 00634 encode_md5_data(guid->data, string); 00635 string[GUID_ENCODING_LENGTH] = '\0'; 00636 00637 return string; 00638 }
| 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.
1.5.7.1