26 #ifdef HAVE_SYS_TYPES_H 27 # include <sys/types.h> 36 #ifdef HAVE_SYS_TIMES_H 37 # include <sys/times.h> 45 # define P_tmpdir "/tmp" 50 #define BLOCKSIZE 4096 51 #define THRESHOLD (2 * BLOCKSIZE) 55 static gboolean guid_initialized = FALSE;
56 static struct md5_ctx guid_context;
66 return g_slice_new (
GUID);
70 guid_free (
GUID * guid)
75 g_slice_free (
GUID, guid);
81 static int null_inited = 0;
82 static GUID null_guid;
87 char *tmp =
"NULLGUID.EMPTY.";
91 null_guid.data[i] = tmp[i];
103 init_from_stream (FILE * stream,
size_t max_size)
105 char buffer[BLOCKSIZE + 72];
106 size_t sum, block_size, total;
122 if (max_size < BLOCKSIZE)
123 block_size = max_size;
125 block_size = BLOCKSIZE;
130 n = fread (buffer + sum, 1, block_size - sum, stream);
134 while (sum < block_size && n != 0);
138 if (n == 0 && ferror (stream))
142 if ((n == 0) || (max_size == 0))
147 md5_process_block (buffer, BLOCKSIZE, &guid_context);
155 md5_process_bytes (buffer, sum, &guid_context);
163 init_from_file (
const char *filename,
size_t max_size)
170 memset (&stats, 0,
sizeof (stats));
171 if (stat (filename, &stats) != 0)
174 md5_process_bytes (&stats,
sizeof (stats), &guid_context);
175 total +=
sizeof (stats);
180 fp = fopen (filename,
"r");
184 file_bytes = init_from_stream (fp, max_size);
186 PINFO (
"guid_init got %llu bytes from %s",
187 (
unsigned long long int) file_bytes, filename);
197 init_from_dir (
const char *dirname,
unsigned int max_files)
209 dir = opendir (dirname);
221 md5_process_bytes (de->d_name, strlen (de->d_name), &guid_context);
222 total += strlen (de->d_name);
224 result = snprintf (filename,
sizeof (filename),
225 "%s/%s", dirname, de->d_name);
226 if ((result < 0) || (result >= (
int)
sizeof (filename)))
229 memset (&stats, 0,
sizeof (stats));
230 if (stat (filename, &stats) != 0)
232 md5_process_bytes (&stats,
sizeof (stats), &guid_context);
233 total +=
sizeof (stats);
237 while (max_files > 0);
245 init_from_time (
void)
249 #ifdef HAVE_SYS_TIMES_H 256 t_time = time (NULL);
257 md5_process_bytes (&t_time,
sizeof (t_time), &guid_context);
258 total +=
sizeof (t_time);
260 #ifdef HAVE_SYS_TIMES_H 261 clocks = times (&tms_buf);
262 md5_process_bytes (&clocks,
sizeof (clocks), &guid_context);
263 md5_process_bytes (&tms_buf,
sizeof (tms_buf), &guid_context);
264 total +=
sizeof (clocks) +
sizeof (tms_buf);
271 init_from_int (
int val)
273 md5_process_bytes (&val,
sizeof (val), &guid_context);
278 init_from_buff (
unsigned char *buf,
size_t buflen)
280 md5_process_bytes (buf, buflen, &guid_context);
292 md5_init_ctx (&guid_context);
295 bytes += init_from_file (
"/dev/urandom", 512);
299 const char *files[] = {
"/etc/passwd",
304 "/proc/self/environ",
312 for (i = 0; files[i] != NULL; i++)
313 bytes += init_from_file (files[i], BLOCKSIZE);
319 const char *dirs[] = {
331 for (i = 0; dirs[i] != NULL; i++)
332 bytes += init_from_dir (dirs[i], 32);
334 dirname = g_get_home_dir ();
336 bytes += init_from_dir (dirname, 32);
344 md5_process_bytes (&pid,
sizeof (pid), &guid_context);
345 bytes +=
sizeof (pid);
349 md5_process_bytes (&pid,
sizeof (pid), &guid_context);
350 bytes +=
sizeof (pid);
364 md5_process_bytes (s, strlen (s), &guid_context);
369 md5_process_bytes (&uid,
sizeof (uid), &guid_context);
370 bytes +=
sizeof (uid);
373 md5_process_bytes (&gid,
sizeof (gid), &guid_context);
374 bytes +=
sizeof (gid);
380 #ifdef HAVE_GETHOSTNAME 383 memset (
string, 0,
sizeof (
string));
384 gethostname (
string,
sizeof (
string));
385 md5_process_bytes (
string,
sizeof (
string), &guid_context);
386 bytes +=
sizeof (string);
394 srand ((
unsigned int) time (NULL));
396 for (i = 0; i < 32; i++)
400 md5_process_bytes (&n,
sizeof (n), &guid_context);
406 bytes += init_from_time ();
408 PINFO (
"got %llu bytes", (
unsigned long long int) bytes);
410 if (bytes < THRESHOLD)
411 PWARN (
"only got %llu bytes.\n" 412 "The identifiers might not be very random.\n",
413 (
unsigned long long int) bytes);
415 guid_initialized = TRUE;
423 md5_process_bytes (salt, salt_len, &guid_context);
429 md5_init_ctx (&guid_context);
431 md5_process_bytes (salt, salt_len, &guid_context);
433 guid_initialized = TRUE;
441 #define GUID_PERIOD 5000 446 static int counter = 0;
452 if (!guid_initialized)
457 md5_finish_ctx (&ctx, guid->data);
473 init_from_int (433781 * counter);
480 fp = fopen (
"/dev/urandom",
"r");
484 init_from_stream (fp, 32);
488 counter = GUID_PERIOD;
506 encode_md5_data (
const unsigned char *data,
char *buffer)
511 sprintf (buffer,
"%02x", data[count]);
518 decode_md5_string (
const unsigned char *
string,
unsigned char *data)
520 unsigned char n1, n2;
522 unsigned char c1, c2;
532 if ((0 ==
string[2 * count]) || (0 ==
string[2 * count + 1]))
535 c1 = tolower (
string[2 * count]);
539 c2 = tolower (
string[2 * count + 1]);
553 data[count] = (n1 << 4) | n2;
570 #ifdef G_THREADS_ENABLED 571 #ifdef GLIB_DEPRECATED_IN_2_32 572 static GPrivate guid_buffer_key = G_PRIVATE_INIT (g_free);
574 static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT;
577 #ifdef GLIB_DEPRECATED_IN_2_32 578 string = g_private_get (&guid_buffer_key);
580 string = g_static_private_get (&guid_buffer_key);
585 #ifdef GLIB_DEPRECATED_IN_2_32 586 g_private_set (&guid_buffer_key,
string);
588 g_static_private_set (&guid_buffer_key,
string, g_free);
592 static char string[64];
595 encode_md5_data (guid->data,
string);
604 if (!
string || !guid)
607 encode_md5_data (guid->data,
string);
616 return decode_md5_string ((
const guchar *)
string, (guid != NULL) ? guid->data : NULL);
622 if (guid_1 && guid_2)
629 guid_compare (
const GUID * guid_1,
const GUID * guid_2)
631 if (guid_1 == guid_2)
635 if (!guid_1 && guid_2)
638 if (guid_1 && !guid_2)
647 const GUID *guid = ptr;
653 PERR (
"received NULL guid pointer.");
657 for (i = 0, j = 0; i <
sizeof (guint); i++, j++)
663 hash |= guid->data[j];
670 guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b)
676 guid_hash_table_new (
void)
gboolean guid_equal(const GUID *guid_1, const GUID *guid_2)
#define PERR(format, args...)
GUID guid_new_return(void)
const GUID * guid_null(void)
#define PINFO(format, args...)
void guid_init_with_salt(const void *salt, size_t salt_len)
gboolean string_to_guid(const gchar *string, GUID *guid)
#define GUID_ENCODING_LENGTH
const char * guid_to_string(const GUID *guid)
gchar * guid_to_string_buff(const GUID *guid, gchar *buff)
guint guid_hash_to_guint(gconstpointer ptr)
void guid_new(GUID *guid)
void guid_init_only_salt(const void *salt, size_t salt_len)
#define PWARN(format, args...)
const gchar * QofLogModule