Replace libuuid with internal implementation
[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
19#include <stddef.h>
20#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <time.h>
25
26#include "uuid.h"
27
28static const lttng_uuid nil_uuid;
29static bool lttng_uuid_is_init;
30
31void lttng_uuid_to_str(const lttng_uuid uuid, char *uuid_str)
32{
33 sprintf(uuid_str, LTTNG_UUID_FMT, LTTNG_UUID_FMT_VALUES(uuid));
34}
35
36int lttng_uuid_from_str(const char *str_in, lttng_uuid uuid_out)
37{
38 int ret = 0;
39 lttng_uuid uuid_scan;
40
41 if ((str_in == NULL) || (uuid_out == NULL)) {
42 ret = -1;
43 goto end;
44 }
45
46 if (strnlen(str_in, LTTNG_UUID_STR_LEN) != LTTNG_UUID_STR_LEN - 1) {
47 ret = -1;
48 goto end;
49 }
50
51 /* Scan to a temporary location in case of a partial match. */
52 if (sscanf(str_in, LTTNG_UUID_FMT, LTTNG_UUID_SCAN_VALUES(uuid_scan)) !=
53 LTTNG_UUID_LEN) {
54 ret = -1;
55 }
56
57 lttng_uuid_copy(uuid_out, uuid_scan);
58end:
59 return ret;
60}
61
62bool lttng_uuid_is_equal(const lttng_uuid a, const lttng_uuid b)
63{
64 return memcmp(a, b, LTTNG_UUID_LEN) == 0;
65}
66
67bool lttng_uuid_is_nil(const lttng_uuid uuid)
68{
69 return memcmp(nil_uuid, uuid, sizeof(lttng_uuid)) == 0;
70}
71
72void lttng_uuid_copy(lttng_uuid dst, const lttng_uuid src)
73{
74 memcpy(dst, src, LTTNG_UUID_LEN);
75}
76
77/*
78 * Generate a random UUID according to RFC4122, section 4.4.
79 */
80int lttng_uuid_generate(lttng_uuid uuid_out)
81{
82 int i, ret = 0;
83
84 if (uuid_out == NULL) {
85 ret = -1;
86 goto end;
87 }
88
89 if (!lttng_uuid_is_init) {
90 /*
91 * We don't need cryptographic quality randomness to
92 * generate UUIDs, seed rand with the epoch.
93 */
94 const time_t epoch = time(NULL);
95
96 if (epoch == (time_t) -1) {
97 ret = -1;
98 goto end;
99 }
100 srand(epoch);
101
102 lttng_uuid_is_init = true;
103 }
104
105 /*
106 * Generate 16 bytes of random bits.
107 */
108 for (i = 0; i < LTTNG_UUID_LEN; i++) {
109 uuid_out[i] = (uint8_t) rand();
110 }
111
112 /*
113 * Set the two most significant bits (bits 6 and 7) of the
114 * clock_seq_hi_and_reserved to zero and one, respectively.
115 */
116 uuid_out[8] &= ~(1 << 6);
117 uuid_out[8] |= (1 << 7);
118
119 /*
120 * Set the four most significant bits (bits 12 through 15) of the
121 * time_hi_and_version field to the 4-bit version number from
122 * Section 4.1.3.
123 */
124 uuid_out[6] &= 0x0f;
125 uuid_out[6] |= (LTTNG_UUID_VER << 4);
126
127end:
128 return ret;
129}
This page took 0.026825 seconds and 4 git commands to generate.