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