L4Re/departure

libext2fs/lib/libuuid/gen_uuid.c

618:7123a7307a82
8 months ago Paul Boddie Introduced some debugging output control.
     1 /*     2  * gen_uuid.c --- generate a DCE-compatible uuid     3  *     4  * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.     5  *     6  * %Begin-Header%     7  * Redistribution and use in source and binary forms, with or without     8  * modification, are permitted provided that the following conditions     9  * are met:    10  * 1. Redistributions of source code must retain the above copyright    11  *    notice, and the entire permission notice in its entirety,    12  *    including the disclaimer of warranties.    13  * 2. Redistributions in binary form must reproduce the above copyright    14  *    notice, this list of conditions and the following disclaimer in the    15  *    documentation and/or other materials provided with the distribution.    16  * 3. The name of the author may not be used to endorse or promote    17  *    products derived from this software without specific prior    18  *    written permission.    19  *    20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED    21  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES    22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF    23  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE    24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR    25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT    26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR    27  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT    29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE    30  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH    31  * DAMAGE.    32  * %End-Header%    33  */    34     35 /*    36  * Force inclusion of SVID stuff since we need it if we're compiling in    37  * gcc-wall wall mode    38  */    39 #define _SVID_SOURCE    40 #define _DEFAULT_SOURCE	  /* since glibc 2.20 _SVID_SOURCE is deprecated */    41     42 #include "config.h"    43     44 #ifdef _WIN32    45 #define _WIN32_WINNT 0x0500    46 #include <windows.h>    47 #define UUID MYUUID    48 #endif    49 #include <stdio.h>    50 #ifdef HAVE_UNISTD_H    51 #include <unistd.h>    52 #endif    53 #ifdef HAVE_STDLIB_H    54 #include <stdlib.h>    55 #endif    56 #include <string.h>    57 #include <fcntl.h>    58 #include <errno.h>    59 #include <sys/types.h>    60 #ifdef HAVE_SYS_TIME_H    61 #include <sys/time.h>    62 #endif    63 #ifdef HAVE_SYS_WAIT_H    64 #include <sys/wait.h>    65 #endif    66 #include <sys/stat.h>    67 #ifdef HAVE_SYS_FILE_H    68 #include <sys/file.h>    69 #endif    70 #ifdef HAVE_SYS_IOCTL_H    71 #include <sys/ioctl.h>    72 #endif    73 #ifdef HAVE_SYS_SOCKET_H    74 #include <sys/socket.h>    75 #endif    76 #ifdef HAVE_SYS_UN_H    77 #include <sys/un.h>    78 #endif    79 #ifdef HAVE_SYS_SOCKIO_H    80 #include <sys/sockio.h>    81 #endif    82 #ifdef HAVE_NET_IF_H    83 #include <net/if.h>    84 #endif    85 #ifdef HAVE_NETINET_IN_H    86 #include <netinet/in.h>    87 #endif    88 #ifdef HAVE_NET_IF_DL_H    89 #include <net/if_dl.h>    90 #endif    91 #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)    92 #include <sys/syscall.h>    93 #endif    94 #ifdef HAVE_SYS_RESOURCE_H    95 #include <sys/resource.h>    96 #endif    97     98 #include "uuidP.h"    99 #include "uuidd.h"   100    101 #ifdef HAVE_SRANDOM   102 #define srand(x) 	srandom(x)   103 #define rand() 		random()   104 #endif   105    106 #ifdef TLS   107 #define THREAD_LOCAL static TLS   108 #else   109 #define THREAD_LOCAL static   110 #endif   111    112 #if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48)   113 #define DO_JRAND_MIX   114 THREAD_LOCAL unsigned short jrand_seed[3];   115 #endif   116    117 #ifdef _WIN32   118 #ifndef USE_MINGW   119 static void gettimeofday (struct timeval *tv, void *dummy)   120 {   121 	FILETIME	ftime;   122 	uint64_t	n;   123    124 	GetSystemTimeAsFileTime (&ftime);   125 	n = (((uint64_t) ftime.dwHighDateTime << 32)   126 	     + (uint64_t) ftime.dwLowDateTime);   127 	if (n) {   128 		n /= 10;   129 		n -= ((369 * 365 + 89) * (uint64_t) 86400) * 1000000;   130 	}   131    132 	tv->tv_sec = n / 1000000;   133 	tv->tv_usec = n % 1000000;   134 }   135 #endif   136 #endif   137    138 static int get_random_fd(void)   139 {   140 	struct timeval	tv;   141 	static int	fd = -2;   142 	int		i;   143    144 	if (fd == -2) {   145 		gettimeofday(&tv, 0);   146 #ifndef _WIN32   147 		fd = open("/dev/urandom", O_RDONLY);   148 		if (fd == -1)   149 			fd = open("/dev/random", O_RDONLY | O_NONBLOCK);   150 		if (fd >= 0) {   151 			i = fcntl(fd, F_GETFD);   152 			if (i >= 0)   153 				fcntl(fd, F_SETFD, i | FD_CLOEXEC);   154 		}   155 #endif   156 		srand(((unsigned)getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);   157 #ifdef DO_JRAND_MIX   158 		jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);   159 		jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);   160 		jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;   161 #endif   162 	}   163 	/* Crank the random number generator a few times */   164 	gettimeofday(&tv, 0);   165 	for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)   166 		rand();   167 	return fd;   168 }   169    170    171 /*   172  * Generate a series of random bytes.  Use /dev/urandom if possible,   173  * and if not, use srandom/random.   174  */   175 static void get_random_bytes(void *buf, int nbytes)   176 {   177 	int i, n = nbytes, fd = get_random_fd();   178 	int lose_counter = 0;   179 	unsigned char *cp = buf;   180    181 	if (fd >= 0) {   182 		while (n > 0) {   183 			i = read(fd, cp, n);   184 			if (i <= 0) {   185 				if (lose_counter++ > 16)   186 					break;   187 				continue;   188 			}   189 			n -= i;   190 			cp += i;   191 			lose_counter = 0;   192 		}   193 	}   194    195 	/*   196 	 * We do this all the time, but this is the only source of   197 	 * randomness if /dev/random/urandom is out to lunch.   198 	 */   199 	for (cp = buf, i = 0; i < nbytes; i++)   200 		*cp++ ^= (rand() >> 7) & 0xFF;   201 #ifdef DO_JRAND_MIX   202 	{   203 		unsigned short tmp_seed[3];   204    205 		memcpy(tmp_seed, jrand_seed, sizeof(tmp_seed));   206 		jrand_seed[2] = jrand_seed[2] ^ syscall(__NR_gettid);   207 		for (cp = buf, i = 0; i < nbytes; i++)   208 			*cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF;   209 		memcpy(jrand_seed, tmp_seed,   210 		       sizeof(jrand_seed) - sizeof(unsigned short));   211 	}   212 #endif   213    214 	return;   215 }   216    217 /*   218  * Get the ethernet hardware address, if we can find it...   219  *   220  * XXX for a windows version, probably should use GetAdaptersInfo:   221  * http://www.codeguru.com/cpp/i-n/network/networkinformation/article.php/c5451   222  * commenting out get_node_id just to get gen_uuid to compile under windows   223  * is not the right way to go!   224  */   225 static int get_node_id(unsigned char *node_id)   226 {   227 #ifdef HAVE_NET_IF_H   228 	int 		sd;   229 	struct ifreq 	ifr, *ifrp;   230 	struct ifconf 	ifc;   231 	char buf[1024];   232 	int		n, i;   233 	unsigned char 	*a;   234 #ifdef HAVE_NET_IF_DL_H   235 	struct sockaddr_dl *sdlp;   236 #endif   237    238 /*   239  * BSD 4.4 defines the size of an ifreq to be   240  * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len   241  * However, under earlier systems, sa_len isn't present, so the size is   242  * just sizeof(struct ifreq)   243  */   244 #ifdef HAVE_SA_LEN   245 #ifndef max   246 #define max(a,b) ((a) > (b) ? (a) : (b))   247 #endif   248 #define ifreq_size(i) max(sizeof(struct ifreq),\   249      sizeof((i).ifr_name)+(i).ifr_addr.sa_len)   250 #else   251 #define ifreq_size(i) sizeof(struct ifreq)   252 #endif /* HAVE_SA_LEN*/   253    254 	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);   255 	if (sd < 0) {   256 		return -1;   257 	}   258 	memset(buf, 0, sizeof(buf));   259 	ifc.ifc_len = sizeof(buf);   260 	ifc.ifc_buf = buf;   261 	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {   262 		close(sd);   263 		return -1;   264 	}   265 	n = ifc.ifc_len;   266 	for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {   267 		ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);   268 		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);   269 #ifdef SIOCGIFHWADDR   270 		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)   271 			continue;   272 		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;   273 #else   274 #ifdef SIOCGENADDR   275 		if (ioctl(sd, SIOCGENADDR, &ifr) < 0)   276 			continue;   277 		a = (unsigned char *) ifr.ifr_enaddr;   278 #else   279 #ifdef HAVE_NET_IF_DL_H   280 		sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;   281 		if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))   282 			continue;   283 		a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];   284 #else   285 		/*   286 		 * XXX we don't have a way of getting the hardware   287 		 * address   288 		 */   289 		close(sd);   290 		return 0;   291 #endif /* HAVE_NET_IF_DL_H */   292 #endif /* SIOCGENADDR */   293 #endif /* SIOCGIFHWADDR */   294 		if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])   295 			continue;   296 		if (node_id) {   297 			memcpy(node_id, a, 6);   298 			close(sd);   299 			return 1;   300 		}   301 	}   302 	close(sd);   303 #endif   304 	return 0;   305 }   306    307 /* Assume that the gettimeofday() has microsecond granularity */   308 #define MAX_ADJUSTMENT 10   309    310 static int get_clock(uint32_t *clock_high, uint32_t *clock_low,   311 		     uint16_t *ret_clock_seq, int *num)   312 {   313 	THREAD_LOCAL int		adjustment = 0;   314 	THREAD_LOCAL struct timeval	last = {0, 0};   315 	THREAD_LOCAL int		state_fd = -2;   316 	THREAD_LOCAL FILE		*state_f;   317 	THREAD_LOCAL uint16_t		clock_seq;   318 	struct timeval 			tv;   319 #ifndef _WIN32   320 	struct flock			fl;   321 #endif   322 	uint64_t			clock_reg;   323 	mode_t				save_umask;   324 	int				len;   325    326 	if (state_fd == -2) {   327 		save_umask = umask(0);   328 		state_fd = open("/var/lib/libuuid/clock.txt",   329 				O_RDWR|O_CREAT, 0660);   330 		(void) umask(save_umask);   331 		if (state_fd >= 0) {   332 			state_f = fdopen(state_fd, "r+");   333 			if (!state_f) {   334 				close(state_fd);   335 				state_fd = -1;   336 			}   337 		}   338 	}   339 #ifndef _WIN32   340 	fl.l_type = F_WRLCK;   341 	fl.l_whence = SEEK_SET;   342 	fl.l_start = 0;   343 	fl.l_len = 0;   344 	fl.l_pid = 0;   345 	if (state_fd >= 0) {   346 		rewind(state_f);   347 		while (fcntl(state_fd, F_SETLKW, &fl) < 0) {   348 			if ((errno == EAGAIN) || (errno == EINTR))   349 				continue;   350 			fclose(state_f);   351 			state_fd = -1;   352 			break;   353 		}   354 	}   355 #endif   356 	if (state_fd >= 0) {   357 		unsigned int cl;   358 		unsigned long tv1, tv2;   359 		int a;   360    361 		if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n",   362 			   &cl, &tv1, &tv2, &a) == 4) {   363 			clock_seq = cl & 0x3FFF;   364 			last.tv_sec = tv1;   365 			last.tv_usec = tv2;   366 			adjustment = a;   367 		}   368 	}   369    370 	if ((last.tv_sec == 0) && (last.tv_usec == 0)) {   371 		get_random_bytes(&clock_seq, sizeof(clock_seq));   372 		clock_seq &= 0x3FFF;   373 		gettimeofday(&last, 0);   374 		last.tv_sec--;   375 	}   376    377 try_again:   378 	gettimeofday(&tv, 0);   379 	if ((tv.tv_sec < last.tv_sec) ||   380 	    ((tv.tv_sec == last.tv_sec) &&   381 	     (tv.tv_usec < last.tv_usec))) {   382 		clock_seq = (clock_seq+1) & 0x3FFF;   383 		adjustment = 0;   384 		last = tv;   385 	} else if ((tv.tv_sec == last.tv_sec) &&   386 	    (tv.tv_usec == last.tv_usec)) {   387 		if (adjustment >= MAX_ADJUSTMENT)   388 			goto try_again;   389 		adjustment++;   390 	} else {   391 		adjustment = 0;   392 		last = tv;   393 	}   394    395 	clock_reg = tv.tv_usec*10 + adjustment;   396 	clock_reg += ((uint64_t) tv.tv_sec)*10000000;   397 	clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;   398    399 	if (num && (*num > 1)) {   400 		adjustment += *num - 1;   401 		last.tv_usec += adjustment / 10;   402 		adjustment = adjustment % 10;   403 		last.tv_sec += last.tv_usec / 1000000;   404 		last.tv_usec = last.tv_usec % 1000000;   405 	}   406    407 	if (state_fd > 0) {   408 		rewind(state_f);   409 		len = fprintf(state_f,   410 			      "clock: %04x tv: %016lu %08lu adj: %08d\n",   411 			      clock_seq, last.tv_sec, (long)last.tv_usec,   412 			      adjustment);   413 		fflush(state_f);   414 		if (ftruncate(state_fd, len) < 0) {   415 			fprintf(state_f, "                   \n");   416 			fflush(state_f);   417 		}   418 		rewind(state_f);   419 #ifndef _WIN32   420 		fl.l_type = F_UNLCK;   421 		if (fcntl(state_fd, F_SETLK, &fl) < 0) {   422 			fclose(state_f);   423 			state_fd = -1;   424 		}   425 #endif   426 	}   427    428 	*clock_high = clock_reg >> 32;   429 	*clock_low = clock_reg;   430 	*ret_clock_seq = clock_seq;   431 	return 0;   432 }   433    434 #if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)   435 static ssize_t read_all(int fd, char *buf, size_t count)   436 {   437 	ssize_t ret;   438 	ssize_t c = 0;   439 	int tries = 0;   440    441 	memset(buf, 0, count);   442 	while (count > 0) {   443 		ret = read(fd, buf, count);   444 		if (ret <= 0) {   445 			if ((errno == EAGAIN || errno == EINTR || ret == 0) &&   446 			    (tries++ < 5))   447 				continue;   448 			return c ? c : -1;   449 		}   450 		if (ret > 0)   451 			tries = 0;   452 		count -= ret;   453 		buf += ret;   454 		c += ret;   455 	}   456 	return c;   457 }   458    459 /*   460  * Close all file descriptors   461  */   462 static void close_all_fds(void)   463 {   464 	int i, max;   465    466 #if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)   467 	max = sysconf(_SC_OPEN_MAX);   468 #elif defined(HAVE_GETDTABLESIZE)   469 	max = getdtablesize();   470 #elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)   471 	struct rlimit rl;   472    473 	getrlimit(RLIMIT_NOFILE, &rl);   474 	max = rl.rlim_cur;   475 #else   476 	max = OPEN_MAX;   477 #endif   478    479 	for (i=0; i < max; i++) {   480 		close(i);   481 		if (i <= 2)   482 			open("/dev/null", O_RDWR);   483 	}   484 }   485 #endif /* defined(USE_UUIDD) && defined(HAVE_SYS_UN_H) */   486    487 #if __GNUC_PREREQ (4, 6)   488 #pragma GCC diagnostic push   489 #if !defined(USE_UUIDD) || !defined(HAVE_SYS_UN_H)   490 #pragma GCC diagnostic ignored "-Wunused-parameter"   491 #endif   492 #endif   493 /*   494  * Try using the uuidd daemon to generate the UUID   495  *   496  * Returns 0 on success, non-zero on failure.   497  */   498 static int get_uuid_via_daemon(int op, uuid_t out, int *num)   499 {   500 #if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)   501 	char op_buf[64];   502 	int op_len;   503 	int s;   504 	ssize_t ret;   505 	int32_t reply_len = 0, expected = 16;   506 	struct sockaddr_un srv_addr;   507 	struct stat st;   508 	pid_t pid;   509 	static const char *uuidd_path = UUIDD_PATH;   510 	static int access_ret = -2;   511 	static int start_attempts = 0;   512    513 	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)   514 		return -1;   515    516 	srv_addr.sun_family = AF_UNIX;   517 	strcpy(srv_addr.sun_path, UUIDD_SOCKET_PATH);   518    519 	if (connect(s, (const struct sockaddr *) &srv_addr,   520 		    sizeof(struct sockaddr_un)) < 0) {   521 		if (access_ret == -2)   522 			access_ret = access(uuidd_path, X_OK);   523 		if (access_ret == 0)   524 			access_ret = stat(uuidd_path, &st);   525 		if (access_ret == 0 && (st.st_mode & (S_ISUID | S_ISGID)) == 0)   526 			access_ret = access(UUIDD_DIR, W_OK);   527 		if (access_ret == 0 && start_attempts++ < 5) {   528 			if ((pid = fork()) == 0) {   529 				close_all_fds();   530 				execl(uuidd_path, "uuidd", "-qT", "300",   531 				      (char *) NULL);   532 				exit(1);   533 			}   534 			(void) waitpid(pid, 0, 0);   535 			if (connect(s, (const struct sockaddr *) &srv_addr,   536 				    sizeof(struct sockaddr_un)) < 0)   537 				goto fail;   538 		} else   539 			goto fail;   540 	}   541 	op_buf[0] = op;   542 	op_len = 1;   543 	if (op == UUIDD_OP_BULK_TIME_UUID) {   544 		memcpy(op_buf+1, num, sizeof(*num));   545 		op_len += sizeof(*num);   546 		expected += sizeof(*num);   547 	}   548    549 	ret = write(s, op_buf, op_len);   550 	if (ret < 1)   551 		goto fail;   552    553 	ret = read_all(s, (char *) &reply_len, sizeof(reply_len));   554 	if (ret < 0)   555 		goto fail;   556    557 	if (reply_len != expected)   558 		goto fail;   559    560 	ret = read_all(s, op_buf, reply_len);   561    562 	if (op == UUIDD_OP_BULK_TIME_UUID)   563 		memcpy(op_buf+16, num, sizeof(int));   564    565 	memcpy(out, op_buf, 16);   566    567 	close(s);   568 	return ((ret == expected) ? 0 : -1);   569    570 fail:   571 	close(s);   572 #endif   573 	return -1;   574 }   575 #if __GNUC_PREREQ (4, 6)   576 #pragma GCC diagnostic pop   577 #endif   578    579 void uuid__generate_time(uuid_t out, int *num)   580 {   581 	static unsigned char node_id[6];   582 	static int has_init = 0;   583 	struct uuid uu;   584 	uint32_t	clock_mid;   585    586 	if (!has_init) {   587 		if (get_node_id(node_id) <= 0) {   588 			get_random_bytes(node_id, 6);   589 			/*   590 			 * Set multicast bit, to prevent conflicts   591 			 * with IEEE 802 addresses obtained from   592 			 * network cards   593 			 */   594 			node_id[0] |= 0x01;   595 		}   596 		has_init = 1;   597 	}   598 	get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);   599 	uu.clock_seq |= 0x8000;   600 	uu.time_mid = (uint16_t) clock_mid;   601 	uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;   602 	memcpy(uu.node, node_id, 6);   603 	uuid_pack(&uu, out);   604 }   605    606 void uuid_generate_time(uuid_t out)   607 {   608 #ifdef TLS   609 	THREAD_LOCAL int		num = 0;   610 	THREAD_LOCAL struct uuid	uu;   611 	THREAD_LOCAL time_t		last_time = 0;   612 	time_t				now;   613    614 	if (num > 0) {   615 		now = time(0);   616 		if (now > last_time+1)   617 			num = 0;   618 	}   619 	if (num <= 0) {   620 		num = 1000;   621 		if (get_uuid_via_daemon(UUIDD_OP_BULK_TIME_UUID,   622 					out, &num) == 0) {   623 			last_time = time(0);   624 			uuid_unpack(out, &uu);   625 			num--;   626 			return;   627 		}   628 		num = 0;   629 	}   630 	if (num > 0) {   631 		uu.time_low++;   632 		if (uu.time_low == 0) {   633 			uu.time_mid++;   634 			if (uu.time_mid == 0)   635 				uu.time_hi_and_version++;   636 		}   637 		num--;   638 		uuid_pack(&uu, out);   639 		return;   640 	}   641 #else   642 	if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)   643 		return;   644 #endif   645    646 	uuid__generate_time(out, 0);   647 }   648    649    650 void uuid__generate_random(uuid_t out, int *num)   651 {   652 	uuid_t	buf;   653 	struct uuid uu;   654 	int i, n;   655    656 	if (!num || !*num)   657 		n = 1;   658 	else   659 		n = *num;   660    661 	for (i = 0; i < n; i++) {   662 		get_random_bytes(buf, sizeof(buf));   663 		uuid_unpack(buf, &uu);   664    665 		uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;   666 		uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF)   667 			| 0x4000;   668 		uuid_pack(&uu, out);   669 		out += sizeof(uuid_t);   670 	}   671 }   672    673 void uuid_generate_random(uuid_t out)   674 {   675 	int	num = 1;   676 	/* No real reason to use the daemon for random uuid's -- yet */   677    678 	uuid__generate_random(out, &num);   679 }   680    681    682 /*   683  * This is the generic front-end to uuid_generate_random and   684  * uuid_generate_time.  It uses uuid_generate_random only if   685  * /dev/urandom is available, since otherwise we won't have   686  * high-quality randomness.   687  */   688 void uuid_generate(uuid_t out)   689 {   690 	if (get_random_fd() >= 0)   691 		uuid_generate_random(out);   692 	else   693 		uuid_generate_time(out);   694 }