~ubuntu-branches/ubuntu/wily/mediatomb/wily

« back to all changes in this revision

Viewing changes to .pc/0005_use_system_libuuid.patch/src/uuid/gen_uuid.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek
  • Date: 2015-08-12 15:51:30 UTC
  • mfrom: (4.1.15 sid)
  • Revision ID: package-import@ubuntu.com-20150812155130-54v3y5zta9oyuejg
Tags: 0.12.1-47-g7ab7616-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - debian/control:
    + Don't build-depend on libmozjs-dev.
  - debian/{mediatomb-daemon.mediatomb.upstart,rules}: Introduce upstart
    support to fix start-on-boot failure.
  - debian/rules: Disable JS support.
* Dropped changes:
  - drop OR depends on abrowser, which last existed in precise.
  - debian/mediatomb-daemon.postinst: no reason this needs an executable
    bit in the source package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * gen_uuid.c --- generate a DCE-compatible uuid
 
3
 *
 
4
 * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
 
5
 *
 
6
 * %Begin-Header%
 
7
 * This file may be redistributed under the terms of the GNU 
 
8
 * Library General Public License.
 
9
 * %End-Header%
 
10
 */
 
11
 
 
12
/*
 
13
 * Force inclusion of SVID stuff since we need it if we're compiling in
 
14
 * gcc-wall wall mode
 
15
 */
 
16
#define _SVID_SOURCE
 
17
 
 
18
#include "autoconfig.h"
 
19
 
 
20
#ifdef HAVE_UNISTD_H
 
21
#include <unistd.h>
 
22
#endif
 
23
#ifdef HAVE_STDLIB_H
 
24
#include <stdlib.h>
 
25
#endif
 
26
#include <string.h>
 
27
#include <fcntl.h>
 
28
#include <errno.h>
 
29
#include <sys/types.h>
 
30
#include <sys/time.h>
 
31
#include <sys/stat.h>
 
32
#include <sys/file.h>
 
33
#ifdef HAVE_SYS_IOCTL_H
 
34
#include <sys/ioctl.h>
 
35
#endif
 
36
#ifdef HAVE_SYS_SOCKET_H
 
37
#include <sys/socket.h>
 
38
#endif
 
39
#ifdef HAVE_SYS_SOCKIO_H
 
40
#include <sys/sockio.h>
 
41
#endif
 
42
#ifdef HAVE_NET_IF_H
 
43
#include <net/if.h>
 
44
#endif
 
45
#ifdef HAVE_NETINET_IN_H
 
46
#include <netinet/in.h>
 
47
#endif
 
48
 
 
49
#include "uuidP.h"
 
50
 
 
51
#ifdef HAVE_SRANDOM
 
52
#define srand(x)        srandom(x)
 
53
#define rand()          random()
 
54
#endif
 
55
 
 
56
static int get_random_fd(void)
 
57
{
 
58
        struct timeval  tv;
 
59
        static int      fd = -2;
 
60
        int             i;
 
61
 
 
62
        if (fd == -2) {
 
63
                gettimeofday(&tv, 0);
 
64
                fd = open("/dev/urandom", O_RDONLY);
 
65
                if (fd == -1)
 
66
                        fd = open("/dev/random", O_RDONLY);
 
67
                        //fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
 
68
                srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
 
69
        }
 
70
        /* Crank the random number generator a few times */
 
71
        gettimeofday(&tv, 0);
 
72
        for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
 
73
                rand();
 
74
        return fd;
 
75
}
 
76
 
 
77
 
 
78
/*
 
79
 * Generate a series of random bytes.  Use /dev/urandom if possible,
 
80
 * and if not, use srandom/random.
 
81
 */
 
82
static void get_random_bytes(void *buf, int nbytes)
 
83
{
 
84
        int i, n = nbytes, fd = get_random_fd();
 
85
        int lose_counter = 0;
 
86
        unsigned char *cp = (unsigned char *) buf;
 
87
 
 
88
        if (fd >= 0) {
 
89
                while (n > 0) {
 
90
                        i = read(fd, cp, n);
 
91
                        if (i <= 0) {
 
92
                                if (lose_counter++ > 16)
 
93
                                        break;
 
94
                                continue;
 
95
                        }
 
96
                        n -= i;
 
97
                        cp += i;
 
98
                        lose_counter = 0;
 
99
                }
 
100
        }
 
101
        
 
102
        /*
 
103
         * We do this all the time, but this is the only source of
 
104
         * randomness if /dev/random/urandom is out to lunch.
 
105
         */
 
106
        for (cp = buf, i = 0; i < nbytes; i++)
 
107
                *cp++ ^= (rand() >> 7) & 0xFF;
 
108
        return;
 
109
}
 
110
 
 
111
/*
 
112
 * Get the ethernet hardware address, if we can find it...
 
113
 */
 
114
static int get_node_id(unsigned char *node_id)
 
115
{
 
116
#ifdef HAVE_NET_IF_H
 
117
        int             sd;
 
118
        struct ifreq    ifr, *ifrp;
 
119
        struct ifconf   ifc;
 
120
        char buf[1024];
 
121
        int             n, i;
 
122
        unsigned char   *a;
 
123
        
 
124
/*
 
125
 * BSD 4.4 defines the size of an ifreq to be
 
126
 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
 
127
 * However, under earlier systems, sa_len isn't present, so the size is 
 
128
 * just sizeof(struct ifreq)
 
129
 */
 
130
#ifdef HAVE_SA_LEN
 
131
#ifndef max
 
132
#define max(a,b) ((a) > (b) ? (a) : (b))
 
133
#endif
 
134
#define ifreq_size(i) max(sizeof(struct ifreq),\
 
135
     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
 
136
#else
 
137
#define ifreq_size(i) sizeof(struct ifreq)
 
138
#endif /* HAVE_SA_LEN*/
 
139
 
 
140
        sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
 
141
        if (sd < 0) {
 
142
                return -1;
 
143
        }
 
144
        memset(buf, 0, sizeof(buf));
 
145
        ifc.ifc_len = sizeof(buf);
 
146
        ifc.ifc_buf = buf;
 
147
        if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
 
148
                close(sd);
 
149
                return -1;
 
150
        }
 
151
        n = ifc.ifc_len;
 
152
        for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
 
153
                ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
 
154
                strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
 
155
#ifdef SIOCGIFHWADDR
 
156
                if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
 
157
                        continue;
 
158
                a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
 
159
#else
 
160
#ifdef SIOCGENADDR
 
161
                if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
 
162
                        continue;
 
163
                a = (unsigned char *) ifr.ifr_enaddr;
 
164
#else
 
165
                /*
 
166
                 * XXX we don't have a way of getting the hardware
 
167
                 * address
 
168
                 */
 
169
                close(sd);
 
170
                return 0;
 
171
#endif /* SIOCGENADDR */
 
172
#endif /* SIOCGIFHWADDR */
 
173
                if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
 
174
                        continue;
 
175
                if (node_id) {
 
176
                        memcpy(node_id, a, 6);
 
177
                        close(sd);
 
178
                        return 1;
 
179
                }
 
180
        }
 
181
        close(sd);
 
182
#endif
 
183
        return 0;
 
184
}
 
185
 
 
186
/* Assume that the gettimeofday() has microsecond granularity */
 
187
#define MAX_ADJUSTMENT 10
 
188
 
 
189
static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
 
190
{
 
191
        static int                      adjustment = 0;
 
192
        static struct timeval           last = {0, 0};
 
193
        static __u16                    clock_seq;
 
194
        struct timeval                  tv;
 
195
        unsigned long long              clock_reg;
 
196
        
 
197
try_again:
 
198
        gettimeofday(&tv, 0);
 
199
        if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
 
200
                get_random_bytes(&clock_seq, sizeof(clock_seq));
 
201
                clock_seq &= 0x1FFF;
 
202
                last = tv;
 
203
                last.tv_sec--;
 
204
        }
 
205
        if ((tv.tv_sec < last.tv_sec) ||
 
206
            ((tv.tv_sec == last.tv_sec) &&
 
207
             (tv.tv_usec < last.tv_usec))) {
 
208
                clock_seq = (clock_seq+1) & 0x1FFF;
 
209
                adjustment = 0;
 
210
                last = tv;
 
211
        } else if ((tv.tv_sec == last.tv_sec) &&
 
212
            (tv.tv_usec == last.tv_usec)) {
 
213
                if (adjustment >= MAX_ADJUSTMENT)
 
214
                        goto try_again;
 
215
                adjustment++;
 
216
        } else {
 
217
                adjustment = 0;
 
218
                last = tv;
 
219
        }
 
220
                
 
221
        clock_reg = tv.tv_usec*10 + adjustment;
 
222
        clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
 
223
        clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
 
224
 
 
225
        *clock_high = clock_reg >> 32;
 
226
        *clock_low = clock_reg;
 
227
        *ret_clock_seq = clock_seq;
 
228
        return 0;
 
229
}
 
230
 
 
231
void uuid_generate_time(uuid_t out)
 
232
{
 
233
        static unsigned char node_id[6];
 
234
        static int has_init = 0;
 
235
        struct uuid uu;
 
236
        __u32   clock_mid;
 
237
 
 
238
        if (!has_init) {
 
239
                if (get_node_id(node_id) <= 0) {
 
240
                        get_random_bytes(node_id, 6);
 
241
                        /*
 
242
                         * Set multicast bit, to prevent conflicts
 
243
                         * with IEEE 802 addresses obtained from
 
244
                         * network cards
 
245
                         */
 
246
                        node_id[0] |= 0x01;
 
247
                }
 
248
                has_init = 1;
 
249
        }
 
250
        get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
 
251
        uu.clock_seq |= 0x8000;
 
252
        uu.time_mid = (__u16) clock_mid;
 
253
        uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
 
254
        memcpy(uu.node, node_id, 6);
 
255
        uuid_pack2(&uu, out);
 
256
}
 
257
 
 
258
void uuid_generate_random(uuid_t out)
 
259
{
 
260
        uuid_t  buf;
 
261
        struct uuid uu;
 
262
 
 
263
        get_random_bytes(buf, sizeof(buf));
 
264
        uuid_unpack2(buf, &uu);
 
265
 
 
266
        uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
 
267
        uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
 
268
        uuid_pack2(&uu, out);
 
269
}
 
270
 
 
271
/*
 
272
 * This is the generic front-end to uuid_generate_random and
 
273
 * uuid_generate_time.  It uses uuid_generate_random only if
 
274
 * /dev/urandom is available, since otherwise we won't have
 
275
 * high-quality randomness.
 
276
 */
 
277
void uuid_generate(uuid_t out)
 
278
{
 
279
        if (get_random_fd() >= 0)
 
280
                uuid_generate_random(out);
 
281
        else
 
282
                uuid_generate_time(out);
 
283
}