1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 _public_
char *sd_id128_to_string(sd_id128_t id
, char s
[33]) {
37 for (n
= 0; n
< 16; n
++) {
38 s
[n
*2] = hexchar(id
.bytes
[n
] >> 4);
39 s
[n
*2+1] = hexchar(id
.bytes
[n
] & 0xF);
47 _public_
int sd_id128_from_string(const char s
[33], sd_id128_t
*ret
) {
56 for (n
= 0; n
< 16; n
++) {
59 a
= unhexchar(s
[n
*2]);
63 b
= unhexchar(s
[n
*2+1]);
67 t
.bytes
[n
] = (a
<< 4) | b
;
77 static sd_id128_t
make_v4_uuid(sd_id128_t id
) {
78 /* Stolen from generate_random_uuid() of drivers/char/random.c
79 * in the kernel sources */
81 /* Set UUID version to 4 --- truly random generation */
82 id
.bytes
[6] = (id
.bytes
[6] & 0x0F) | 0x40;
84 /* Set the UUID variant to DCE */
85 id
.bytes
[8] = (id
.bytes
[8] & 0x3F) | 0x80;
90 _public_
int sd_id128_get_machine(sd_id128_t
*ret
) {
91 static __thread sd_id128_t saved_machine_id
;
92 static __thread
bool saved_machine_id_valid
= false;
102 if (saved_machine_id_valid
) {
103 *ret
= saved_machine_id
;
107 fd
= open("/etc/machine-id", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
111 k
= loop_read(fd
, buf
, 32, false);
112 close_nointr_nofail(fd
);
120 for (j
= 0; j
< 16; j
++) {
123 a
= unhexchar(buf
[j
*2]);
124 b
= unhexchar(buf
[j
*2+1]);
129 t
.bytes
[j
] = a
<< 4 | b
;
132 saved_machine_id
= t
;
133 saved_machine_id_valid
= true;
139 _public_
int sd_id128_get_boot(sd_id128_t
*ret
) {
140 static __thread sd_id128_t saved_boot_id
;
141 static __thread
bool saved_boot_id_valid
= false;
152 if (saved_boot_id_valid
) {
153 *ret
= saved_boot_id
;
157 fd
= open("/proc/sys/kernel/random/boot_id", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
161 k
= loop_read(fd
, buf
, 36, false);
162 close_nointr_nofail(fd
);
170 for (j
= 0, p
= buf
; j
< 16; j
++) {
182 t
.bytes
[j
] = a
<< 4 | b
;
188 saved_boot_id_valid
= true;
194 _public_
int sd_id128_randomize(sd_id128_t
*ret
) {
202 fd
= open("/dev/urandom", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
206 k
= loop_read(fd
, &t
, 16, false);
207 close_nointr_nofail(fd
);
215 /* Turn this into a valid v4 UUID, to be nice. Note that we
216 * only guarantee this for newly generated UUIDs, not for
217 * pre-existing ones.*/
219 *ret
= make_v4_uuid(t
);