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