Sync ax_have_epoll.m4 with autoconf-archive
[lttng-tools.git] / src / common / uuid.c
CommitLineData
c70636a7
MJ
1/*
2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 * Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
4 *
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License, version 2.1 only,
7 * as published by the Free Software Foundation.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
a1298db6 19#include <common/compat/string.h>
c70636a7
MJ
20#include <stddef.h>
21#include <stdint.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <time.h>
26
27#include "uuid.h"
28
29static const lttng_uuid nil_uuid;
30static bool lttng_uuid_is_init;
31
32void lttng_uuid_to_str(const lttng_uuid uuid, char *uuid_str)
33{
34 sprintf(uuid_str, LTTNG_UUID_FMT, LTTNG_UUID_FMT_VALUES(uuid));
35}
36
37int lttng_uuid_from_str(const char *str_in, lttng_uuid uuid_out)
38{
39 int ret = 0;
40 lttng_uuid uuid_scan;
41
42 if ((str_in == NULL) || (uuid_out == NULL)) {
43 ret = -1;
44 goto end;
45 }
46
a1298db6 47 if (lttng_strnlen(str_in, LTTNG_UUID_STR_LEN) != LTTNG_UUID_STR_LEN - 1) {
c70636a7
MJ
48 ret = -1;
49 goto end;
50 }
51
52 /* Scan to a temporary location in case of a partial match. */
53 if (sscanf(str_in, LTTNG_UUID_FMT, LTTNG_UUID_SCAN_VALUES(uuid_scan)) !=
54 LTTNG_UUID_LEN) {
55 ret = -1;
56 }
57
58 lttng_uuid_copy(uuid_out, uuid_scan);
59end:
60 return ret;
61}
62
63bool lttng_uuid_is_equal(const lttng_uuid a, const lttng_uuid b)
64{
65 return memcmp(a, b, LTTNG_UUID_LEN) == 0;
66}
67
68bool lttng_uuid_is_nil(const lttng_uuid uuid)
69{
70 return memcmp(nil_uuid, uuid, sizeof(lttng_uuid)) == 0;
71}
72
73void lttng_uuid_copy(lttng_uuid dst, const lttng_uuid src)
74{
75 memcpy(dst, src, LTTNG_UUID_LEN);
76}
77
78/*
79 * Generate a random UUID according to RFC4122, section 4.4.
80 */
81int lttng_uuid_generate(lttng_uuid uuid_out)
82{
83 int i, ret = 0;
84
85 if (uuid_out == NULL) {
86 ret = -1;
87 goto end;
88 }
89
90 if (!lttng_uuid_is_init) {
91 /*
92 * We don't need cryptographic quality randomness to
93 * generate UUIDs, seed rand with the epoch.
94 */
95 const time_t epoch = time(NULL);
96
97 if (epoch == (time_t) -1) {
98 ret = -1;
99 goto end;
100 }
101 srand(epoch);
102
103 lttng_uuid_is_init = true;
104 }
105
106 /*
107 * Generate 16 bytes of random bits.
108 */
109 for (i = 0; i < LTTNG_UUID_LEN; i++) {
110 uuid_out[i] = (uint8_t) rand();
111 }
112
113 /*
114 * Set the two most significant bits (bits 6 and 7) of the
115 * clock_seq_hi_and_reserved to zero and one, respectively.
116 */
117 uuid_out[8] &= ~(1 << 6);
118 uuid_out[8] |= (1 << 7);
119
120 /*
121 * Set the four most significant bits (bits 12 through 15) of the
122 * time_hi_and_version field to the 4-bit version number from
123 * Section 4.1.3.
124 */
125 uuid_out[6] &= 0x0f;
126 uuid_out[6] |= (LTTNG_UUID_VER << 4);
127
128end:
129 return ret;
130}
This page took 0.027588 seconds and 4 git commands to generate.