QOF 0.8.4
|
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) |
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 GUID_ENCODING_LENGTH 32 |
Given two GUIDs, return TRUE if they are non-NULL and equal. Return FALSE, otherwise.
Definition at line 609 of file guid.c.
{ if (guid_1 && guid_2) return (memcmp (guid_1, guid_2, GUID_DATA_SIZE) == 0); else return FALSE; }
guint guid_hash_to_guint | ( | gconstpointer | ptr | ) |
Given a GUID *, hash it to a guint
Definition at line 634 of file guid.c.
{ const GUID *guid = ptr; guint hash = 0; unsigned int i, j; if (!guid) { PERR ("received NULL guid pointer."); return 0; } for (i = 0, j = 0; i < sizeof (guint); i++, j++) { if (j == GUID_DATA_SIZE) j = 0; hash <<= 4; hash |= guid->data[j]; } return hash; }
void guid_init | ( | void | ) |
Initialize the id generator with a variety of random sources.
Definition at line 285 of file guid.c.
{ size_t bytes = 0; /* Not needed; taken care of on first malloc. * guid_memchunk_init(); */ md5_init_ctx (&guid_context); /* entropy pool */ bytes += init_from_file ("/dev/urandom", 512); /* files */ { const char *files[] = { "/etc/passwd", "/proc/loadavg", "/proc/meminfo", "/proc/net/dev", "/proc/rtc", "/proc/self/environ", "/proc/self/stat", "/proc/stat", "/proc/uptime", NULL }; int i; for (i = 0; files[i] != NULL; i++) bytes += init_from_file (files[i], BLOCKSIZE); } /* directories */ { const char *dirname; const char *dirs[] = { "/proc", P_tmpdir, "/var/lock", "/var/log", "/var/mail", "/var/spool/mail", "/var/run", NULL }; int i; for (i = 0; dirs[i] != NULL; i++) bytes += init_from_dir (dirs[i], 32); dirname = g_get_home_dir (); if (dirname != NULL) bytes += init_from_dir (dirname, 32); } /* process and parent ids */ { pid_t pid; pid = getpid (); md5_process_bytes (&pid, sizeof (pid), &guid_context); bytes += sizeof (pid); #ifdef HAVE_GETPPID pid = getppid (); md5_process_bytes (&pid, sizeof (pid), &guid_context); bytes += sizeof (pid); #endif } /* user info */ { #ifdef HAVE_GETUID uid_t uid; gid_t gid; char *s; s = getlogin (); if (s != NULL) { md5_process_bytes (s, strlen (s), &guid_context); bytes += strlen (s); } uid = getuid (); md5_process_bytes (&uid, sizeof (uid), &guid_context); bytes += sizeof (uid); gid = getgid (); md5_process_bytes (&gid, sizeof (gid), &guid_context); bytes += sizeof (gid); #endif } /* host info */ { #ifdef HAVE_GETHOSTNAME char string[1024]; memset (string, 0, sizeof (string)); gethostname (string, sizeof (string)); md5_process_bytes (string, sizeof (string), &guid_context); bytes += sizeof (string); #endif } /* plain old random */ { int n, i; srand ((unsigned int) time (NULL)); for (i = 0; i < 32; i++) { n = rand (); md5_process_bytes (&n, sizeof (n), &guid_context); bytes += sizeof (n); } } /* time in secs and clock ticks */ bytes += init_from_time (); PINFO ("got %llu bytes", (unsigned long long int) bytes); if (bytes < THRESHOLD) PWARN ("only got %llu bytes.\n" "The identifiers might not be very random.\n", (unsigned long long int) bytes); guid_initialized = TRUE; }
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.
{ md5_init_ctx (&guid_context); md5_process_bytes (salt, salt_len, &guid_context); guid_initialized = TRUE; }
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.
{ guid_init (); md5_process_bytes (salt, salt_len, &guid_context); }
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. |
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.
{ static int counter = 0; struct md5_ctx ctx; if (guid == NULL) return; if (!guid_initialized) guid_init (); /* make the id */ ctx = guid_context; md5_finish_ctx (&ctx, guid->data); /* update the global context */ init_from_time (); /* Make it a little extra salty. I think init_from_time was buggy, * or something, since duplicate id's actually happened. Or something * like that. I think this is because init_from_time kept returning * the same values too many times in a row. So we'll do some 'block * chaining', and feed in the old guid as new random data. * * Anyway, I think the whole fact that I saw a bunch of duplicate * id's at one point, but can't reproduce the bug is rather alarming. * Something must be broken somewhere, and merely adding more salt * is just hiding the problem, not fixing it. */ init_from_int (433781 * counter); init_from_buff (guid->data, GUID_DATA_SIZE); if (counter == 0) { FILE *fp; fp = fopen ("/dev/urandom", "r"); if (fp == NULL) return; init_from_stream (fp, 32); fclose (fp); counter = GUID_PERIOD; } counter--; }
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.
const GUID* guid_null | ( | void | ) |
Returns a GUID which is guaranteed to never reference any entity.
Definition at line 79 of file guid.c.
{ static int null_inited = 0; static GUID null_guid; if (!null_inited) { int i; char *tmp = "NULLGUID.EMPTY."; /* 16th space for '\O' */ for (i = 0; i < GUID_DATA_SIZE; i++) null_guid.data[i] = tmp[i]; null_inited = 1; } return &null_guid; }
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.
{ #ifdef G_THREADS_ENABLED static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT; gchar *string; string = g_static_private_get (&guid_buffer_key); if (string == NULL) { string = malloc (GUID_ENCODING_LENGTH + 1); g_static_private_set (&guid_buffer_key, string, g_free); } #else static char string[64]; #endif encode_md5_data (guid->data, string); string[GUID_ENCODING_LENGTH] = '\0'; return string; }
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.