dynamic-array: fix documentation of lttng_dynamic_pointer_array_get_pointer
[lttng-tools.git] / src / common / uuid.c
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
28 static const lttng_uuid nil_uuid;
29 static bool lttng_uuid_is_init;
30
31 void 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
36 int 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);
58 end:
59 return ret;
60 }
61
62 bool lttng_uuid_is_equal(const lttng_uuid a, const lttng_uuid b)
63 {
64 return memcmp(a, b, LTTNG_UUID_LEN) == 0;
65 }
66
67 bool lttng_uuid_is_nil(const lttng_uuid uuid)
68 {
69 return memcmp(nil_uuid, uuid, sizeof(lttng_uuid)) == 0;
70 }
71
72 void 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 */
80 int 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
127 end:
128 return ret;
129 }
This page took 0.03275 seconds and 5 git commands to generate.