11e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o/*
21e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * gen_uuid.c --- generate a DCE-compatible uuid
319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o *
43030daa8aba89830fb0623be01e507bffd636399Theodore Ts'o * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o *
619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header%
71bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * Redistribution and use in source and binary forms, with or without
81bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * modification, are permitted provided that the following conditions
91bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * are met:
101bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * 1. Redistributions of source code must retain the above copyright
111bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o *    notice, and the entire permission notice in its entirety,
121bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o *    including the disclaimer of warranties.
131bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * 2. Redistributions in binary form must reproduce the above copyright
141bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o *    notice, this list of conditions and the following disclaimer in the
151bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o *    documentation and/or other materials provided with the distribution.
161bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * 3. The name of the author may not be used to endorse or promote
171bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o *    products derived from this software without specific prior
181bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o *    written permission.
19efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
201bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
211bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
221bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
231bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
241bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
251bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
261bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
271bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
281bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
291bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
301bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
311bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o * DAMAGE.
3219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header%
331e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o */
341e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
35b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'o/*
36b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'o * Force inclusion of SVID stuff since we need it if we're compiling in
37b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'o * gcc-wall wall mode
38b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'o */
39b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'o#define _SVID_SOURCE
40b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'o
41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
426ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#ifdef _WIN32
436ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#define _WIN32_WINNT 0x0500
446ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#include <windows.h>
456ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#define UUID MYUUID
466ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#endif
47740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#include <stdio.h>
481e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_UNISTD_H
491e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <unistd.h>
501e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
511e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_STDLIB_H
521e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <stdlib.h>
531e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
541e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <string.h>
551e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <fcntl.h>
56b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o#include <errno.h>
571e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/types.h>
586ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#ifdef HAVE_SYS_TIME_H
591e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/time.h>
606ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#endif
619d8c203a462ee18c1fd09a68cfe0e2ec7d8288daTheodore Ts'o#include <sys/wait.h>
621e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/stat.h>
636ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#ifdef HAVE_SYS_FILE_H
641e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/file.h>
656ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#endif
66fff45483ede7fe38a31b3364a9c07e2418776deeTheodore Ts'o#ifdef HAVE_SYS_IOCTL_H
671e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/ioctl.h>
68fff45483ede7fe38a31b3364a9c07e2418776deeTheodore Ts'o#endif
69fff45483ede7fe38a31b3364a9c07e2418776deeTheodore Ts'o#ifdef HAVE_SYS_SOCKET_H
701e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/socket.h>
71fff45483ede7fe38a31b3364a9c07e2418776deeTheodore Ts'o#endif
72e7cc6f7d0b86d76963058ef099ca553da29d2c3fChristophe GRENIER#ifdef HAVE_SYS_UN_H
73740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#include <sys/un.h>
74e7cc6f7d0b86d76963058ef099ca553da29d2c3fChristophe GRENIER#endif
751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_SYS_SOCKIO_H
761e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <sys/sockio.h>
771e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
781e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_NET_IF_H
791e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <net/if.h>
801e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
811e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_NETINET_IN_H
821e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include <netinet/in.h>
831e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
8484ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o#ifdef HAVE_NET_IF_DL_H
8584ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o#include <net/if_dl.h>
8684ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o#endif
8729dd9d1e90c8ccefa2f8bdc6463694edc3a909d7Theodore Ts'o#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
88ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#include <sys/syscall.h>
89ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#endif
901207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#ifdef HAVE_SYS_RESOURCE_H
911207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#include <sys/resource.h>
921207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#endif
931e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
941e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include "uuidP.h"
95740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#include "uuidd.h"
961e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
971e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_SRANDOM
981e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#define srand(x) 	srandom(x)
991e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#define rand() 		random()
1001e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
1011e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
102740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#ifdef TLS
103740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#define THREAD_LOCAL static TLS
104740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#else
105740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#define THREAD_LOCAL static
106740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#endif
107740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
108ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48)
109ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#define DO_JRAND_MIX
110740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'oTHREAD_LOCAL unsigned short jrand_seed[3];
111ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#endif
112ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o
1136ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#ifdef _WIN32
1146ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'ostatic void gettimeofday (struct timeval *tv, void *dummy)
1156ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o{
1166ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	FILETIME	ftime;
1176ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	uint64_t	n;
1186ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o
1196ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	GetSystemTimeAsFileTime (&ftime);
1206ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	n = (((uint64_t) ftime.dwHighDateTime << 32)
1216ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	     + (uint64_t) ftime.dwLowDateTime);
1226ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	if (n) {
1236ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o		n /= 10;
1246ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o		n -= ((369 * 365 + 89) * (uint64_t) 86400) * 1000000;
1256ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	}
1266ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o
1276ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	tv->tv_sec = n / 1000000;
1286ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	tv->tv_usec = n % 1000000;
1296ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o}
1306ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o
1316ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'ostatic int getuid (void)
1326ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o{
1336ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	return 1;
1346ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o}
1356ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#endif
1366ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o
137b1416db3227b4b7192ee0d2d3ff6e00e92e9d3e2Theodore Ts'ostatic int get_random_fd(void)
1385dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o{
13996394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o	struct timeval	tv;
14096394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o	static int	fd = -2;
14196394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o	int		i;
1425dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o
1435dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o	if (fd == -2) {
14496394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o		gettimeofday(&tv, 0);
1456ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#ifndef _WIN32
1465dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o		fd = open("/dev/urandom", O_RDONLY);
1475dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o		if (fd == -1)
1485dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o			fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
1492adc320f01906cce0b55fa7bc9fccb24b5640ceeTheodore Ts'o		if (fd >= 0) {
1502adc320f01906cce0b55fa7bc9fccb24b5640ceeTheodore Ts'o			i = fcntl(fd, F_GETFD);
151efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			if (i >= 0)
1522adc320f01906cce0b55fa7bc9fccb24b5640ceeTheodore Ts'o				fcntl(fd, F_SETFD, i | FD_CLOEXEC);
1532adc320f01906cce0b55fa7bc9fccb24b5640ceeTheodore Ts'o		}
1546ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o#endif
15596394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o		srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
156ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#ifdef DO_JRAND_MIX
157ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o		jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
158ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o		jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
159ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o		jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;
160ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#endif
1615dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o	}
1625dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o	/* Crank the random number generator a few times */
16396394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o	gettimeofday(&tv, 0);
16496394d11b01b5613b635e4c5963a19e222e57afbTheodore Ts'o	for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
1655dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o		rand();
1665dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o	return fd;
1675dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o}
1685dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o
1695dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o
1701e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o/*
1711e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * Generate a series of random bytes.  Use /dev/urandom if possible,
1721e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * and if not, use srandom/random.
1731e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o */
1741e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'ostatic void get_random_bytes(void *buf, int nbytes)
1751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o{
176edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o	int i, n = nbytes, fd = get_random_fd();
177e589f678e1ed5efa8dd4450f37bee0486caa3504Theodore Ts'o	int lose_counter = 0;
178e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	unsigned char *cp = buf;
1791e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
180b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o	if (fd >= 0) {
181edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o		while (n > 0) {
182edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o			i = read(fd, cp, n);
183e589f678e1ed5efa8dd4450f37bee0486caa3504Theodore Ts'o			if (i <= 0) {
18461bee88d456c39bdfa4799577a4bd183d766b596Theodore Ts'o				if (lose_counter++ > 16)
185e589f678e1ed5efa8dd4450f37bee0486caa3504Theodore Ts'o					break;
186e589f678e1ed5efa8dd4450f37bee0486caa3504Theodore Ts'o				continue;
187b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o			}
188edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o			n -= i;
1891e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			cp += i;
190e589f678e1ed5efa8dd4450f37bee0486caa3504Theodore Ts'o			lose_counter = 0;
1911e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		}
1921e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
193efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
194edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o	/*
195edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o	 * We do this all the time, but this is the only source of
196edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o	 * randomness if /dev/random/urandom is out to lunch.
197edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o	 */
198edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o	for (cp = buf, i = 0; i < nbytes; i++)
199edab294f1cc70f296dad0e5ac30e805cfccf3146Theodore Ts'o		*cp++ ^= (rand() >> 7) & 0xFF;
200ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#ifdef DO_JRAND_MIX
201e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	{
202e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		unsigned short tmp_seed[3];
203e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
204e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		memcpy(tmp_seed, jrand_seed, sizeof(tmp_seed));
205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		jrand_seed[2] = jrand_seed[2] ^ syscall(__NR_gettid);
206e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		for (cp = buf, i = 0; i < nbytes; i++)
207e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF;
208e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		memcpy(jrand_seed, tmp_seed,
209e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		       sizeof(jrand_seed) - sizeof(unsigned short));
210e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
211ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o#endif
212ae2868acf0acb6dd5e4426e6c109c02cd16dfec0Theodore Ts'o
213b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o	return;
2141e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o}
2151e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
2161e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o/*
2171e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * Get the ethernet hardware address, if we can find it...
2186ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o *
2196ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o * XXX for a windows version, probably should use GetAdaptersInfo:
2206ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o * http://www.codeguru.com/cpp/i-n/network/networkinformation/article.php/c5451
2216ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o * commenting out get_node_id just to get gen_uuid to compile under windows
2226ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o * is not the right way to go!
2231e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o */
2241e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'ostatic int get_node_id(unsigned char *node_id)
2251e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o{
2261e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_NET_IF_H
2271e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	int 		sd;
2281e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	struct ifreq 	ifr, *ifrp;
2291e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	struct ifconf 	ifc;
2301e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	char buf[1024];
2311e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	int		n, i;
2321e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	unsigned char 	*a;
2339ee42c9509d01bb8e888c8cc1aa944312d7e88e7Theodore Ts'o#ifdef HAVE_NET_IF_DL_H
23484ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o	struct sockaddr_dl *sdlp;
23584ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o#endif
23684ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o
2371e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o/*
2381e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * BSD 4.4 defines the size of an ifreq to be
2391e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
240efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * However, under earlier systems, sa_len isn't present, so the size is
2411e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o * just sizeof(struct ifreq)
2421e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o */
2431e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef HAVE_SA_LEN
2441e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifndef max
2451e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#define max(a,b) ((a) > (b) ? (a) : (b))
2461e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
2471e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#define ifreq_size(i) max(sizeof(struct ifreq),\
2481e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
2491e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#else
2501e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#define ifreq_size(i) sizeof(struct ifreq)
2511e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif /* HAVE_SA_LEN*/
2521e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
2531e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
2541e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (sd < 0) {
2551e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		return -1;
2561e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
2571e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	memset(buf, 0, sizeof(buf));
2581e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	ifc.ifc_len = sizeof(buf);
2591e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	ifc.ifc_buf = buf;
2601e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
2611e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		close(sd);
2621e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		return -1;
2631e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
2641e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	n = ifc.ifc_len;
26584ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o	for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {
266dc3710e5ea6bd83addec20f6956bda707438fa92Theodore Ts'o		ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
2671e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
2681e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef SIOCGIFHWADDR
2691e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
2701e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			continue;
2711e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
2721e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#else
2731e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#ifdef SIOCGENADDR
2741e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
2751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			continue;
2761e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		a = (unsigned char *) ifr.ifr_enaddr;
2771e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#else
2789ee42c9509d01bb8e888c8cc1aa944312d7e88e7Theodore Ts'o#ifdef HAVE_NET_IF_DL_H
27984ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o		sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
28013be1fff0009465741845a785fa4aff153ec20d9Theodore Ts'o		if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
28184ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o			continue;
28284ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o		a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
28384ea6e70b77090c8a35702b265039d58c2efd6adTheodore Ts'o#else
2841e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		/*
2851e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		 * XXX we don't have a way of getting the hardware
2861e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		 * address
2871e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		 */
2881e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		close(sd);
2891e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		return 0;
2909ee42c9509d01bb8e888c8cc1aa944312d7e88e7Theodore Ts'o#endif /* HAVE_NET_IF_DL_H */
2911e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif /* SIOCGENADDR */
2921e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif /* SIOCGIFHWADDR */
2931e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
2941e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			continue;
2951e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		if (node_id) {
2961e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			memcpy(node_id, a, 6);
2971e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			close(sd);
2981e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			return 1;
2991e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		}
3001e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
3011e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	close(sd);
3021e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#endif
3031e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	return 0;
3041e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o}
3051e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
3061e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o/* Assume that the gettimeofday() has microsecond granularity */
3071e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#define MAX_ADJUSTMENT 10
3081e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
309740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ostatic int get_clock(uint32_t *clock_high, uint32_t *clock_low,
310740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		     uint16_t *ret_clock_seq, int *num)
3111e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o{
312740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL int		adjustment = 0;
313740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL struct timeval	last = {0, 0};
314740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL int		state_fd = -2;
315740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL FILE		*state_f;
316740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL uint16_t		clock_seq;
3171e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	struct timeval 			tv;
318e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o	struct flock			fl;
3196ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	uint64_t			clock_reg;
320740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	mode_t				save_umask;
3211207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	int				len;
322740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
323740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (state_fd == -2) {
324740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		save_umask = umask(0);
325740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		state_fd = open("/var/lib/libuuid/clock.txt",
326740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				O_RDWR|O_CREAT, 0660);
327740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		(void) umask(save_umask);
328740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		state_f = fdopen(state_fd, "r+");
329740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		if (!state_f) {
330740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			close(state_fd);
331740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			state_fd = -1;
332740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		}
333740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
334e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o	fl.l_type = F_WRLCK;
335e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o	fl.l_whence = SEEK_SET;
336e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o	fl.l_start = 0;
337e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o	fl.l_len = 0;
338e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o	fl.l_pid = 0;
339740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (state_fd >= 0) {
340740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		rewind(state_f);
341e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o		while (fcntl(state_fd, F_SETLKW, &fl) < 0) {
342740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			if ((errno == EAGAIN) || (errno == EINTR))
343740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				continue;
344740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			fclose(state_f);
345740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			close(state_fd);
346740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			state_fd = -1;
347e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o			break;
348740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		}
349740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
350740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (state_fd >= 0) {
351740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		unsigned int cl;
352740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		unsigned long tv1, tv2;
353740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		int a;
354740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
355740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n",
356740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			   &cl, &tv1, &tv2, &a) == 4) {
357740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			clock_seq = cl & 0x3FFF;
358740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			last.tv_sec = tv1;
359740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			last.tv_usec = tv2;
360740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			adjustment = a;
361740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		}
362740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
363740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
3641e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
3651e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		get_random_bytes(&clock_seq, sizeof(clock_seq));
3661bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o		clock_seq &= 0x3FFF;
367cc435cb11aaa5da9bba5272aeca8eb8d23039decMatthias Koenig		gettimeofday(&last, 0);
3681e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		last.tv_sec--;
3691e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
370740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
371740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'otry_again:
372740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	gettimeofday(&tv, 0);
3731e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if ((tv.tv_sec < last.tv_sec) ||
3741e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	    ((tv.tv_sec == last.tv_sec) &&
3751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	     (tv.tv_usec < last.tv_usec))) {
3761bbfec624c4bbe767060a13762aa9a656536a4fdTheodore Ts'o		clock_seq = (clock_seq+1) & 0x3FFF;
3771e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		adjustment = 0;
378fa7cc280044533fd20468673bba9623787925f8eTheodore Ts'o		last = tv;
3791e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	} else if ((tv.tv_sec == last.tv_sec) &&
3801e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	    (tv.tv_usec == last.tv_usec)) {
3811e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		if (adjustment >= MAX_ADJUSTMENT)
3821e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			goto try_again;
3831e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		adjustment++;
384fa7cc280044533fd20468673bba9623787925f8eTheodore Ts'o	} else {
3851e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		adjustment = 0;
386fa7cc280044533fd20468673bba9623787925f8eTheodore Ts'o		last = tv;
387fa7cc280044533fd20468673bba9623787925f8eTheodore Ts'o	}
388efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
389d546447fda86e33383e69cefa8d7737cdef14427Theodore Ts'o	clock_reg = tv.tv_usec*10 + adjustment;
3906ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	clock_reg += ((uint64_t) tv.tv_sec)*10000000;
3916ec9ef1881e636540cfe28e6f32c93e1781ad173Theodore Ts'o	clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
3921e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
393740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (num && (*num > 1)) {
394740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		adjustment += *num - 1;
395740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		last.tv_usec += adjustment / 10;
396740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		adjustment = adjustment % 10;
397740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		last.tv_sec += last.tv_usec / 1000000;
398740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		last.tv_usec = last.tv_usec % 1000000;
399740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
400740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
401740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (state_fd > 0) {
402740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		rewind(state_f);
403e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		len = fprintf(state_f,
4041207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o			      "clock: %04x tv: %016lu %08lu adj: %08d\n",
405e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			      clock_seq, last.tv_sec, (long)last.tv_usec,
406e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			      adjustment);
407740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		fflush(state_f);
4081207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o		if (ftruncate(state_fd, len) < 0) {
4091207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o			fprintf(state_f, "                   \n");
4101207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o			fflush(state_f);
4111207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o		}
412740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		rewind(state_f);
413e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o		fl.l_type = F_UNLCK;
414e70f32b79d29e287f8347c5d41c6716f094cc654Theodore Ts'o		fcntl(state_fd, F_SETLK, &fl);
415740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
416740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
417d546447fda86e33383e69cefa8d7737cdef14427Theodore Ts'o	*clock_high = clock_reg >> 32;
418d546447fda86e33383e69cefa8d7737cdef14427Theodore Ts'o	*clock_low = clock_reg;
4191e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	*ret_clock_seq = clock_seq;
4201e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	return 0;
4211e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o}
4221e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
423740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ostatic ssize_t read_all(int fd, char *buf, size_t count)
424740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o{
425740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	ssize_t ret;
426740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	ssize_t c = 0;
427caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o	int tries = 0;
428740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
429740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	memset(buf, 0, count);
430740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	while (count > 0) {
431740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		ret = read(fd, buf, count);
432caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o		if (ret <= 0) {
433caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o			if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
434caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o			    (tries++ < 5))
435740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				continue;
436caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o			return c ? c : -1;
437740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		}
438caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o		if (ret > 0)
439caa6003b6419d001593478a46fb4cbf8e502e818Theodore Ts'o			tries = 0;
440740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		count -= ret;
441740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		buf += ret;
442740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		c += ret;
443740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
444740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	return c;
445740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o}
446740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
4471207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o/*
4481207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o * Close all file descriptors
4491207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o */
4501207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'ostatic void close_all_fds(void)
4511207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o{
4521207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	int i, max;
4531207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o
4541207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
4551207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	max = sysconf(_SC_OPEN_MAX);
4561207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#elif defined(HAVE_GETDTABLESIZE)
4571207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	max = getdtablesize();
4581207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
4591207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	struct rlimit rl;
4601207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o
4611207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	getrlimit(RLIMIT_NOFILE, &rl);
4621207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	max = rl.rlim_cur;
4631207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#else
4641207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o	max = OPEN_MAX;
4651207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o#endif
4661207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o
467e8b9466fc9d4aec66476f1bc7a48436da02ab557Theodore Ts'o	for (i=0; i < max; i++) {
4681207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o		close(i);
469e8b9466fc9d4aec66476f1bc7a48436da02ab557Theodore Ts'o		if (i <= 2)
470e8b9466fc9d4aec66476f1bc7a48436da02ab557Theodore Ts'o			open("/dev/null", O_RDWR);
471e8b9466fc9d4aec66476f1bc7a48436da02ab557Theodore Ts'o	}
4721207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o}
4731207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o
474740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
475740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o/*
476740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o * Try using the uuidd daemon to generate the UUID
477740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o *
478740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o * Returns 0 on success, non-zero on failure.
479740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o */
480740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ostatic int get_uuid_via_daemon(int op, uuid_t out, int *num)
481740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o{
482e7cc6f7d0b86d76963058ef099ca553da29d2c3fChristophe GRENIER#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
483740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	char op_buf[64];
484740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	int op_len;
485740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	int s;
486740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	ssize_t ret;
487740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	int32_t reply_len = 0, expected = 16;
488740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	struct sockaddr_un srv_addr;
4893381a63c54f2221e3742211df39c5e2ee13d16ccTheodore Ts'o	struct stat st;
4909d8c203a462ee18c1fd09a68cfe0e2ec7d8288daTheodore Ts'o	pid_t pid;
491740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	static const char *uuidd_path = UUIDD_PATH;
492740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	static int access_ret = -2;
493d37a4fa78806d9dd02586ef6696332ba944ae906Theodore Ts'o	static int start_attempts = 0;
494740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
495740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
496740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		return -1;
497740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
498740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	srv_addr.sun_family = AF_UNIX;
499740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	strcpy(srv_addr.sun_path, UUIDD_SOCKET_PATH);
500740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
501740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (connect(s, (const struct sockaddr *) &srv_addr,
502740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		    sizeof(struct sockaddr_un)) < 0) {
503740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		if (access_ret == -2)
504740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			access_ret = access(uuidd_path, X_OK);
5053381a63c54f2221e3742211df39c5e2ee13d16ccTheodore Ts'o		if (access_ret == 0)
5063381a63c54f2221e3742211df39c5e2ee13d16ccTheodore Ts'o			access_ret = stat(uuidd_path, &st);
5073381a63c54f2221e3742211df39c5e2ee13d16ccTheodore Ts'o		if (access_ret == 0 && (st.st_mode & (S_ISUID | S_ISGID)) == 0)
5083381a63c54f2221e3742211df39c5e2ee13d16ccTheodore Ts'o			access_ret = access(UUIDD_DIR, W_OK);
509d37a4fa78806d9dd02586ef6696332ba944ae906Theodore Ts'o		if (access_ret == 0 && start_attempts++ < 5) {
5109d8c203a462ee18c1fd09a68cfe0e2ec7d8288daTheodore Ts'o			if ((pid = fork()) == 0) {
5111207e36d0a8674d6c627bb9b2759faf1e290e13eTheodore Ts'o				close_all_fds();
512efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o				execl(uuidd_path, "uuidd", "-qT", "300",
513edeee8f36f25b8d4bd6a9f6694f00a4060dd03f3Theodore Ts'o				      (char *) NULL);
514740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				exit(1);
515740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			}
5169d8c203a462ee18c1fd09a68cfe0e2ec7d8288daTheodore Ts'o			(void) waitpid(pid, 0, 0);
517740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			if (connect(s, (const struct sockaddr *) &srv_addr,
518740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				    sizeof(struct sockaddr_un)) < 0)
519740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				goto fail;
520740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		} else
521740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			goto fail;
522740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
523740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	op_buf[0] = op;
524740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	op_len = 1;
525740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (op == UUIDD_OP_BULK_TIME_UUID) {
526f79fb4976cd1e4775a4959be3ddda557204939e0Theodore Ts'o		memcpy(op_buf+1, num, sizeof(*num));
527f79fb4976cd1e4775a4959be3ddda557204939e0Theodore Ts'o		op_len += sizeof(*num);
528f79fb4976cd1e4775a4959be3ddda557204939e0Theodore Ts'o		expected += sizeof(*num);
529740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
530740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
531740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	ret = write(s, op_buf, op_len);
532740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (ret < 1)
533740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		goto fail;
534740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
535740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
536740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (ret < 0)
537740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		goto fail;
538740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
539740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (reply_len != expected)
540740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		goto fail;
541740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
542740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	ret = read_all(s, op_buf, reply_len);
543740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
544740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (op == UUIDD_OP_BULK_TIME_UUID)
545740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		memcpy(op_buf+16, num, sizeof(int));
546740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
547740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	memcpy(out, op_buf, 16);
548740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
549740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	close(s);
550740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	return ((ret == expected) ? 0 : -1);
551740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
552740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ofail:
553740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	close(s);
5545610f9924bfe506852701f1f11f6ca9f421e8a57Theodore Ts'o#endif
555740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	return -1;
556740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o}
557740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
558740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ovoid uuid__generate_time(uuid_t out, int *num)
5591e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o{
5601e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	static unsigned char node_id[6];
5611e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	static int has_init = 0;
5621e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	struct uuid uu;
5632625803ecff90ba8ab60d3c6b83a1ea0c91d2294Theodore Ts'o	uint32_t	clock_mid;
5641e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
5651e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (!has_init) {
56619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o		if (get_node_id(node_id) <= 0) {
5671e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			get_random_bytes(node_id, 6);
56819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o			/*
56919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o			 * Set multicast bit, to prevent conflicts
57019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o			 * with IEEE 802 addresses obtained from
57119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o			 * network cards
57219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o			 */
5739c5534d48470471ec3480458b661e80d8bcfad66Theodore Ts'o			node_id[0] |= 0x01;
57419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o		}
5751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		has_init = 1;
5761e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
577740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
5781e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	uu.clock_seq |= 0x8000;
5792625803ecff90ba8ab60d3c6b83a1ea0c91d2294Theodore Ts'o	uu.time_mid = (uint16_t) clock_mid;
580d1492994a51719dc59932151b55a9b24e1879bceTheodore Ts'o	uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
5811e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	memcpy(uu.node, node_id, 6);
5821e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	uuid_pack(&uu, out);
5831e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o}
584b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o
585740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ovoid uuid_generate_time(uuid_t out)
586740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o{
587740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#ifdef TLS
588740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL int		num = 0;
589740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL struct uuid	uu;
590740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	THREAD_LOCAL time_t		last_time = 0;
591740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	time_t				now;
592740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
593740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (num > 0) {
594740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		now = time(0);
595740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		if (now > last_time+1)
596740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			num = 0;
597740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
598740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (num <= 0) {
599740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		num = 1000;
600740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		if (get_uuid_via_daemon(UUIDD_OP_BULK_TIME_UUID,
601740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o					out, &num) == 0) {
602740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			last_time = time(0);
603740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			uuid_unpack(out, &uu);
604740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			num--;
605740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			return;
606740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		}
607740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		num = 0;
608740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
609740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (num > 0) {
610740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		uu.time_low++;
611740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		if (uu.time_low == 0) {
612740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			uu.time_mid++;
613740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			if (uu.time_mid == 0)
614740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o				uu.time_hi_and_version++;
615740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		}
616740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		num--;
617740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		uuid_pack(&uu, out);
618740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		return;
619740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
620740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#else
621740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)
622740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		return;
623740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o#endif
624740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
625740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	uuid__generate_time(out, 0);
626740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o}
627740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
628740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
629740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ovoid uuid__generate_random(uuid_t out, int *num)
630b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o{
631b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o	uuid_t	buf;
632b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o	struct uuid uu;
633740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	int i, n;
634b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o
635740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	if (!num || !*num)
636740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		n = 1;
637740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	else
638740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		n = *num;
639b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o
640740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	for (i = 0; i < n; i++) {
641740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		get_random_bytes(buf, sizeof(buf));
642740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		uuid_unpack(buf, &uu);
643740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
644740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
645740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF)
646740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o			| 0x4000;
647740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		uuid_pack(&uu, out);
648740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o		out += sizeof(uuid_t);
649740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	}
650b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o}
651b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o
652740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'ovoid uuid_generate_random(uuid_t out)
653740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o{
654740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	int	num = 1;
655740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	/* No real reason to use the daemon for random uuid's -- yet */
656740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
657740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o	uuid__generate_random(out, &num);
658740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o}
659740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
660740837def7fc55ba6b0368f46a4b4abcaba0becdTheodore Ts'o
661b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o/*
662b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o * This is the generic front-end to uuid_generate_random and
663b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o * uuid_generate_time.  It uses uuid_generate_random only if
664b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o * /dev/urandom is available, since otherwise we won't have
665b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o * high-quality randomness.
666b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o */
667b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'ovoid uuid_generate(uuid_t out)
668b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o{
6695dd7ff07d032df32b018c0dfd1cbdf30bd7bf29fTheodore Ts'o	if (get_random_fd() >= 0)
670b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o		uuid_generate_random(out);
671b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o	else
672b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o		uuid_generate_time(out);
673b19d1a959eeea17d6b899a5b994bf3f3691de947Theodore Ts'o}
674