(root)/
util-linux-2.39/
libuuid/
src/
gen_uuid.c
       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  #ifdef _WIN32
      36  #define _WIN32_WINNT 0x0500
      37  #include <windows.h>
      38  #define UUID MYUUID
      39  #endif
      40  #include <stdio.h>
      41  #ifdef HAVE_UNISTD_H
      42  #include <unistd.h>
      43  #endif
      44  #ifdef HAVE_STDLIB_H
      45  #include <stdlib.h>
      46  #endif
      47  #include <string.h>
      48  #include <fcntl.h>
      49  #include <errno.h>
      50  #include <limits.h>
      51  #include <sys/types.h>
      52  #ifdef HAVE_SYS_TIME_H
      53  #include <sys/time.h>
      54  #endif
      55  #include <sys/stat.h>
      56  #ifdef HAVE_SYS_FILE_H
      57  #include <sys/file.h>
      58  #endif
      59  #ifdef HAVE_SYS_IOCTL_H
      60  #include <sys/ioctl.h>
      61  #endif
      62  #ifdef HAVE_SYS_SOCKET_H
      63  #include <sys/socket.h>
      64  #endif
      65  #ifdef HAVE_SYS_UN_H
      66  #include <sys/un.h>
      67  #endif
      68  #ifdef HAVE_SYS_SOCKIO_H
      69  #include <sys/sockio.h>
      70  #endif
      71  #ifdef HAVE_NET_IF_H
      72  #include <net/if.h>
      73  #endif
      74  #ifdef HAVE_NETINET_IN_H
      75  #include <netinet/in.h>
      76  #endif
      77  #ifdef HAVE_NET_IF_DL_H
      78  #include <net/if_dl.h>
      79  #endif
      80  #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
      81  #include <sys/syscall.h>
      82  #endif
      83  
      84  #include "all-io.h"
      85  #include "uuidP.h"
      86  #include "uuidd.h"
      87  #include "randutils.h"
      88  #include "strutils.h"
      89  #include "c.h"
      90  #include "md5.h"
      91  #include "sha1.h"
      92  
      93  #ifdef HAVE_TLS
      94  #define THREAD_LOCAL static __thread
      95  #else
      96  #define THREAD_LOCAL static
      97  #endif
      98  
      99  #ifdef _WIN32
     100  static void gettimeofday (struct timeval *tv, void *dummy)
     101  {
     102  	FILETIME	ftime;
     103  	uint64_t	n;
     104  
     105  	GetSystemTimeAsFileTime (&ftime);
     106  	n = (((uint64_t) ftime.dwHighDateTime << 32)
     107  	     + (uint64_t) ftime.dwLowDateTime);
     108  	if (n) {
     109  		n /= 10;
     110  		n -= ((369 * 365 + 89) * (uint64_t) 86400) * 1000000;
     111  	}
     112  
     113  	tv->tv_sec = n / 1000000;
     114  	tv->tv_usec = n % 1000000;
     115  }
     116  
     117  static int getuid (void)
     118  {
     119  	return 1;
     120  }
     121  #endif
     122  
     123  /*
     124   * Get the ethernet hardware address, if we can find it...
     125   *
     126   * XXX for a windows version, probably should use GetAdaptersInfo:
     127   * http://www.codeguru.com/cpp/i-n/network/networkinformation/article.php/c5451
     128   * commenting out get_node_id just to get gen_uuid to compile under windows
     129   * is not the right way to go!
     130   */
     131  static int get_node_id(unsigned char *node_id)
     132  {
     133  #ifdef HAVE_NET_IF_H
     134  	int		sd;
     135  	struct ifreq	ifr, *ifrp;
     136  	struct ifconf	ifc;
     137  	char buf[1024];
     138  	int		n, i;
     139  	unsigned char	*a = NULL;
     140  #ifdef HAVE_NET_IF_DL_H
     141  	struct sockaddr_dl *sdlp;
     142  #endif
     143  
     144  /*
     145   * BSD 4.4 defines the size of an ifreq to be
     146   * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
     147   * However, under earlier systems, sa_len isn't present, so the size is
     148   * just sizeof(struct ifreq)
     149   */
     150  #ifdef HAVE_SA_LEN
     151  #define ifreq_size(i) max(sizeof(struct ifreq),\
     152       sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
     153  #else
     154  #define ifreq_size(i) sizeof(struct ifreq)
     155  #endif /* HAVE_SA_LEN */
     156  
     157  	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
     158  	if (sd < 0) {
     159  		return -1;
     160  	}
     161  	memset(buf, 0, sizeof(buf));
     162  	ifc.ifc_len = sizeof(buf);
     163  	ifc.ifc_buf = buf;
     164  	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
     165  		close(sd);
     166  		return -1;
     167  	}
     168  	n = ifc.ifc_len;
     169  	for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {
     170  		ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
     171  		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
     172  #ifdef SIOCGIFHWADDR
     173  		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
     174  			continue;
     175  		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
     176  #else
     177  #ifdef SIOCGENADDR
     178  		if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
     179  			continue;
     180  		a = (unsigned char *) ifr.ifr_enaddr;
     181  #else
     182  #ifdef HAVE_NET_IF_DL_H
     183  		sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
     184  		if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
     185  			continue;
     186  		a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
     187  #else
     188  		/*
     189  		 * XXX we don't have a way of getting the hardware
     190  		 * address
     191  		 */
     192  		close(sd);
     193  		return 0;
     194  #endif /* HAVE_NET_IF_DL_H */
     195  #endif /* SIOCGENADDR */
     196  #endif /* SIOCGIFHWADDR */
     197  		if (a == NULL || (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]))
     198  			continue;
     199  		if (node_id) {
     200  			memcpy(node_id, a, 6);
     201  			close(sd);
     202  			return 1;
     203  		}
     204  	}
     205  	close(sd);
     206  #endif
     207  	return 0;
     208  }
     209  
     210  /* Assume that the gettimeofday() has microsecond granularity */
     211  #define MAX_ADJUSTMENT 10
     212  /* Reserve a clock_seq value for the 'continuous clock' implementation */
     213  #define CLOCK_SEQ_CONT 0
     214  
     215  /*
     216   * Get clock from global sequence clock counter.
     217   *
     218   * Return -1 if the clock counter could not be opened/locked (in this case
     219   * pseudorandom value is returned in @ret_clock_seq), otherwise return 0.
     220   */
     221  static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
     222  		     uint16_t *ret_clock_seq, int *num)
     223  {
     224  	THREAD_LOCAL int		adjustment = 0;
     225  	THREAD_LOCAL struct timeval	last = {0, 0};
     226  	THREAD_LOCAL int		state_fd = -2;
     227  	THREAD_LOCAL FILE		*state_f;
     228  	THREAD_LOCAL uint16_t		clock_seq;
     229  	struct timeval			tv;
     230  	uint64_t			clock_reg;
     231  	mode_t				save_umask;
     232  	int				len;
     233  	int				ret = 0;
     234  
     235  	if (state_fd == -1)
     236  		ret = -1;
     237  
     238  	if (state_fd == -2) {
     239  		save_umask = umask(0);
     240  		state_fd = open(LIBUUID_CLOCK_FILE, O_RDWR|O_CREAT|O_CLOEXEC, 0660);
     241  		(void) umask(save_umask);
     242  		if (state_fd != -1) {
     243  			state_f = fdopen(state_fd, "r+" UL_CLOEXECSTR);
     244  			if (!state_f) {
     245  				close(state_fd);
     246  				state_fd = -1;
     247  				ret = -1;
     248  			}
     249  		}
     250  		else
     251  			ret = -1;
     252  	}
     253  	if (state_fd >= 0) {
     254  		rewind(state_f);
     255  		while (flock(state_fd, LOCK_EX) < 0) {
     256  			if ((errno == EAGAIN) || (errno == EINTR))
     257  				continue;
     258  			fclose(state_f);
     259  			close(state_fd);
     260  			state_fd = -1;
     261  			ret = -1;
     262  			break;
     263  		}
     264  	}
     265  	if (state_fd >= 0) {
     266  		unsigned int cl;
     267  		unsigned long tv1, tv2;
     268  		int a;
     269  
     270  		if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n",
     271  			   &cl, &tv1, &tv2, &a) == 4) {
     272  			clock_seq = cl & 0x3FFF;
     273  			last.tv_sec = tv1;
     274  			last.tv_usec = tv2;
     275  			adjustment = a;
     276  		}
     277  		// reset in case of reserved CLOCK_SEQ_CONT
     278  		if (clock_seq == CLOCK_SEQ_CONT) {
     279  			last.tv_sec = 0;
     280  			last.tv_usec = 0;
     281  		}
     282  	}
     283  
     284  	if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
     285  		do {
     286  			ul_random_get_bytes(&clock_seq, sizeof(clock_seq));
     287  			clock_seq &= 0x3FFF;
     288  		} while (clock_seq == CLOCK_SEQ_CONT);
     289  		gettimeofday(&last, NULL);
     290  		last.tv_sec--;
     291  	}
     292  
     293  try_again:
     294  	gettimeofday(&tv, NULL);
     295  	if ((tv.tv_sec < last.tv_sec) ||
     296  	    ((tv.tv_sec == last.tv_sec) &&
     297  	     (tv.tv_usec < last.tv_usec))) {
     298  		do {
     299  			clock_seq = (clock_seq+1) & 0x3FFF;
     300  		} while (clock_seq == CLOCK_SEQ_CONT);
     301  		adjustment = 0;
     302  		last = tv;
     303  	} else if ((tv.tv_sec == last.tv_sec) &&
     304  	    (tv.tv_usec == last.tv_usec)) {
     305  		if (adjustment >= MAX_ADJUSTMENT)
     306  			goto try_again;
     307  		adjustment++;
     308  	} else {
     309  		adjustment = 0;
     310  		last = tv;
     311  	}
     312  
     313  	clock_reg = tv.tv_usec*10 + adjustment;
     314  	clock_reg += ((uint64_t) tv.tv_sec)*10000000;
     315  	clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
     316  
     317  	if (num && (*num > 1)) {
     318  		adjustment += *num - 1;
     319  		last.tv_usec += adjustment / 10;
     320  		adjustment = adjustment % 10;
     321  		last.tv_sec += last.tv_usec / 1000000;
     322  		last.tv_usec = last.tv_usec % 1000000;
     323  	}
     324  
     325  	if (state_fd >= 0) {
     326  		rewind(state_f);
     327  		len = fprintf(state_f,
     328  			      "clock: %04x tv: %016ld %08ld adj: %08d\n",
     329  			      clock_seq, (long)last.tv_sec, (long)last.tv_usec, adjustment);
     330  		fflush(state_f);
     331  		if (ftruncate(state_fd, len) < 0) {
     332  			fprintf(state_f, "                   \n");
     333  			fflush(state_f);
     334  		}
     335  		rewind(state_f);
     336  		flock(state_fd, LOCK_UN);
     337  	}
     338  
     339  	*clock_high = clock_reg >> 32;
     340  	*clock_low = clock_reg;
     341  	*ret_clock_seq = clock_seq;
     342  	return ret;
     343  }
     344  
     345  /*
     346   * Get current time in 100ns ticks.
     347   */
     348  static uint64_t get_clock_counter(void)
     349  {
     350  	struct timeval tv;
     351  	uint64_t clock_reg;
     352  
     353  	gettimeofday(&tv, NULL);
     354  	clock_reg = tv.tv_usec*10;
     355  	clock_reg += ((uint64_t) tv.tv_sec) * 10000000ULL;
     356  
     357  	return clock_reg;
     358  }
     359  
     360  /*
     361   * Get continuous clock value.
     362   *
     363   * Return -1 if there is no further clock counter available,
     364   * otherwise return 0.
     365   *
     366   * This implementation doesn't deliver clock counters based on
     367   * the current time because last_clock_reg is only incremented
     368   * by the number of requested UUIDs.
     369   * max_clock_offset is used to limit the offset of last_clock_reg.
     370   */
     371  static int get_clock_cont(uint32_t *clock_high,
     372  			  uint32_t *clock_low,
     373  			  int num,
     374  			  uint32_t max_clock_offset)
     375  {
     376  	/* 100ns based time offset according to RFC 4122. 4.1.4. */
     377  	const uint64_t reg_offset = (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
     378  	static uint64_t last_clock_reg = 0;
     379  	uint64_t clock_reg;
     380  
     381  	if (last_clock_reg == 0)
     382  		last_clock_reg = get_clock_counter();
     383  
     384  	clock_reg = get_clock_counter();
     385  	if (max_clock_offset) {
     386  		uint64_t clock_offset = max_clock_offset * 10000000ULL;
     387  		if (last_clock_reg < (clock_reg - clock_offset))
     388  			last_clock_reg = clock_reg - clock_offset;
     389  	}
     390  
     391  	clock_reg += MAX_ADJUSTMENT;
     392  
     393  	if ((last_clock_reg + num) >= clock_reg)
     394  		return -1;
     395  
     396  	*clock_high = (last_clock_reg + reg_offset) >> 32;
     397  	*clock_low = last_clock_reg + reg_offset;
     398  	last_clock_reg += num;
     399  
     400  	return 0;
     401  }
     402  
     403  #if defined(HAVE_UUIDD) && defined(HAVE_SYS_UN_H)
     404  
     405  /*
     406   * Try using the uuidd daemon to generate the UUID
     407   *
     408   * Returns 0 on success, non-zero on failure.
     409   */
     410  static int get_uuid_via_daemon(int op, uuid_t out, int *num)
     411  {
     412  	char op_buf[64];
     413  	int op_len;
     414  	int s;
     415  	ssize_t ret;
     416  	int32_t reply_len = 0, expected = 16;
     417  	struct sockaddr_un srv_addr;
     418  
     419  	if (sizeof(UUIDD_SOCKET_PATH) > sizeof(srv_addr.sun_path))
     420  		return -1;
     421  
     422  	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
     423  		return -1;
     424  
     425  	srv_addr.sun_family = AF_UNIX;
     426  	xstrncpy(srv_addr.sun_path, UUIDD_SOCKET_PATH, sizeof(srv_addr.sun_path));
     427  
     428  	if (connect(s, (const struct sockaddr *) &srv_addr,
     429  		    sizeof(struct sockaddr_un)) < 0)
     430  		goto fail;
     431  
     432  	op_buf[0] = op;
     433  	op_len = 1;
     434  	if (op == UUIDD_OP_BULK_TIME_UUID) {
     435  		memcpy(op_buf+1, num, sizeof(*num));
     436  		op_len += sizeof(*num);
     437  		expected += sizeof(*num);
     438  	}
     439  
     440  	ret = write(s, op_buf, op_len);
     441  	if (ret < 1)
     442  		goto fail;
     443  
     444  	ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
     445  	if (ret < 0)
     446  		goto fail;
     447  
     448  	if (reply_len != expected)
     449  		goto fail;
     450  
     451  	ret = read_all(s, op_buf, reply_len);
     452  
     453  	if (op == UUIDD_OP_BULK_TIME_UUID)
     454  		memcpy(op_buf+16, num, sizeof(int));
     455  
     456  	memcpy(out, op_buf, 16);
     457  
     458  	close(s);
     459  	return ((ret == expected) ? 0 : -1);
     460  
     461  fail:
     462  	close(s);
     463  	return -1;
     464  }
     465  
     466  #else /* !defined(HAVE_UUIDD) && defined(HAVE_SYS_UN_H) */
     467  static int get_uuid_via_daemon(int op __attribute__((__unused__)),
     468  				uuid_t out __attribute__((__unused__)),
     469  				int *num __attribute__((__unused__)))
     470  {
     471  	return -1;
     472  }
     473  #endif
     474  
     475  static int __uuid_generate_time_internal(uuid_t out, int *num, uint32_t cont_offset)
     476  {
     477  	static unsigned char node_id[6];
     478  	static int has_init = 0;
     479  	struct uuid uu;
     480  	uint32_t	clock_mid;
     481  	int ret;
     482  
     483  	if (!has_init) {
     484  		if (get_node_id(node_id) <= 0) {
     485  			ul_random_get_bytes(node_id, 6);
     486  			/*
     487  			 * Set multicast bit, to prevent conflicts
     488  			 * with IEEE 802 addresses obtained from
     489  			 * network cards
     490  			 */
     491  			node_id[0] |= 0x01;
     492  		}
     493  		has_init = 1;
     494  	}
     495  	if (cont_offset) {
     496  		ret = get_clock_cont(&clock_mid, &uu.time_low, *num, cont_offset);
     497  		uu.clock_seq = CLOCK_SEQ_CONT;
     498  		if (ret != 0)	/* fallback to previous implpementation */
     499  			ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
     500  	} else {
     501  		ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
     502  	}
     503  	uu.clock_seq |= 0x8000;
     504  	uu.time_mid = (uint16_t) clock_mid;
     505  	uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
     506  	memcpy(uu.node, node_id, 6);
     507  	uuid_pack(&uu, out);
     508  	return ret;
     509  }
     510  
     511  int __uuid_generate_time(uuid_t out, int *num)
     512  {
     513  	return __uuid_generate_time_internal(out, num, 0);
     514  }
     515  
     516  int __uuid_generate_time_cont(uuid_t out, int *num, uint32_t cont_offset)
     517  {
     518  	return __uuid_generate_time_internal(out, num, cont_offset);
     519  }
     520  
     521  /*
     522   * Generate time-based UUID and store it to @out
     523   *
     524   * Tries to guarantee uniqueness of the generated UUIDs by obtaining them from the uuidd daemon,
     525   * or, if uuidd is not usable, by using the global clock state counter (see get_clock()).
     526   * If neither of these is possible (e.g. because of insufficient permissions), it generates
     527   * the UUID anyway, but returns -1. Otherwise, returns 0.
     528   */
     529  static int uuid_generate_time_generic(uuid_t out) {
     530  #ifdef HAVE_TLS
     531  	/* thread local cache for uuidd based requests */
     532  	const int			cs_min = (1<<6);
     533  	const int			cs_max = (1<<18);
     534  	const int			cs_factor = 2;
     535  	THREAD_LOCAL int		num = 0;
     536  	THREAD_LOCAL int		cache_size = cs_min;
     537  	THREAD_LOCAL int		last_used = 0;
     538  	THREAD_LOCAL struct uuid	uu;
     539  	THREAD_LOCAL time_t		last_time = 0;
     540  	time_t				now;
     541  
     542  	if (num > 0) { /* expire cache */
     543  		now = time(NULL);
     544  		if (now > last_time+1) {
     545  			last_used = cache_size - num;
     546  			num = 0;
     547  		}
     548  	}
     549  	if (num <= 0) { /* fill cache */
     550  		/*
     551  		 * num + OP_BULK provides a local cache in each application.
     552  		 * Start with a small cache size to cover short running applications
     553  		 * and adjust the cache size over the runntime.
     554  		 */
     555  		if ((last_used == cache_size) && (cache_size < cs_max))
     556  			cache_size *= cs_factor;
     557  		else if ((last_used < (cache_size / cs_factor)) && (cache_size > cs_min))
     558  			cache_size /= cs_factor;
     559  
     560  		num = cache_size;
     561  
     562  		if (get_uuid_via_daemon(UUIDD_OP_BULK_TIME_UUID,
     563  					out, &num) == 0) {
     564  			last_time = time(NULL);
     565  			uuid_unpack(out, &uu);
     566  			num--;
     567  			return 0;
     568  		}
     569  		/* request to daemon failed, reset cache */
     570  		num = 0;
     571  		cache_size = cs_min;
     572  	}
     573  	if (num > 0) { /* serve uuid from cache */
     574  		uu.time_low++;
     575  		if (uu.time_low == 0) {
     576  			uu.time_mid++;
     577  			if (uu.time_mid == 0)
     578  				uu.time_hi_and_version++;
     579  		}
     580  		num--;
     581  		uuid_pack(&uu, out);
     582  		if (num == 0)
     583  			last_used = cache_size;
     584  		return 0;
     585  	}
     586  #else
     587  	if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)
     588  		return 0;
     589  #endif
     590  
     591  	return __uuid_generate_time(out, NULL);
     592  }
     593  
     594  /*
     595   * Generate time-based UUID and store it to @out.
     596   *
     597   * Discards return value from uuid_generate_time_generic()
     598   */
     599  void uuid_generate_time(uuid_t out)
     600  {
     601  	(void)uuid_generate_time_generic(out);
     602  }
     603  
     604  
     605  int uuid_generate_time_safe(uuid_t out)
     606  {
     607  	return uuid_generate_time_generic(out);
     608  }
     609  
     610  
     611  int __uuid_generate_random(uuid_t out, int *num)
     612  {
     613  	uuid_t	buf;
     614  	struct uuid uu;
     615  	int i, n, r = 0;
     616  
     617  	if (!num || !*num)
     618  		n = 1;
     619  	else
     620  		n = *num;
     621  
     622  	for (i = 0; i < n; i++) {
     623  		if (ul_random_get_bytes(buf, sizeof(buf)))
     624  			r = -1;
     625  		uuid_unpack(buf, &uu);
     626  
     627  		uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
     628  		uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF)
     629  			| 0x4000;
     630  		uuid_pack(&uu, out);
     631  		out += sizeof(uuid_t);
     632  	}
     633  
     634  	return r;
     635  }
     636  
     637  void uuid_generate_random(uuid_t out)
     638  {
     639  	int	num = 1;
     640  	/* No real reason to use the daemon for random uuid's -- yet */
     641  
     642  	__uuid_generate_random(out, &num);
     643  }
     644  
     645  /*
     646   * This is the generic front-end to __uuid_generate_random and
     647   * uuid_generate_time.  It uses __uuid_generate_random output
     648   * only if high-quality randomness is available.
     649   */
     650  void uuid_generate(uuid_t out)
     651  {
     652  	int num = 1;
     653  
     654  	if (__uuid_generate_random(out, &num))
     655  		uuid_generate_time(out);
     656  }
     657  
     658  /*
     659   * Generate an MD5 hashed (predictable) UUID based on a well-known UUID
     660   * providing the namespace and an arbitrary binary string.
     661   */
     662  void uuid_generate_md5(uuid_t out, const uuid_t ns, const char *name, size_t len)
     663  {
     664  	UL_MD5_CTX ctx;
     665  	char hash[UL_MD5LENGTH];
     666  	uuid_t buf;
     667  	struct uuid uu;
     668  
     669  	ul_MD5Init(&ctx);
     670  	ul_MD5Update(&ctx, ns, sizeof(uuid_t));
     671  	ul_MD5Update(&ctx, (const unsigned char *)name, len);
     672  	ul_MD5Final((unsigned char *)hash, &ctx);
     673  
     674  	assert(sizeof(buf) <= sizeof(hash));
     675  
     676  	memcpy(buf, hash, sizeof(buf));
     677  	uuid_unpack(buf, &uu);
     678  
     679  	uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
     680  	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x3000;
     681  	uuid_pack(&uu, out);
     682  }
     683  
     684  /*
     685   * Generate a SHA1 hashed (predictable) UUID based on a well-known UUID
     686   * providing the namespace and an arbitrary binary string.
     687   */
     688  void uuid_generate_sha1(uuid_t out, const uuid_t ns, const char *name, size_t len)
     689  {
     690  	UL_SHA1_CTX ctx;
     691  	char hash[UL_SHA1LENGTH];
     692  	uuid_t buf;
     693  	struct uuid uu;
     694  
     695  	ul_SHA1Init(&ctx);
     696  	ul_SHA1Update(&ctx, ns, sizeof(uuid_t));
     697  	ul_SHA1Update(&ctx, (const unsigned char *)name, len);
     698  	ul_SHA1Final((unsigned char *)hash, &ctx);
     699  
     700  	assert(sizeof(buf) <= sizeof(hash));
     701  
     702  	memcpy(buf, hash, sizeof(buf));
     703  	uuid_unpack(buf, &uu);
     704  
     705  	uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
     706  	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x5000;
     707  	uuid_pack(&uu, out);
     708  }