]> sourceware.org Git - lvm2.git/blame - lib/uuid/uuid.c
thin: fix recent commits
[lvm2.git] / lib / uuid / uuid.c
CommitLineData
72a5e12b 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
be684599 3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
72a5e12b 4 *
6606c3ae
AK
5 * This file is part of LVM2.
6 *
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
be684599 9 * of the GNU Lesser General Public License v.2.1.
6606c3ae 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae
AK
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
72a5e12b
JT
14 */
15
d1d9800e 16#include "lib.h"
72a5e12b 17#include "uuid.h"
b721056e 18#include "lvm-wrappers.h"
72a5e12b 19
56d88440 20#include <assert.h>
72a5e12b
JT
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <unistd.h>
18c8a64d 24#include <ctype.h>
72a5e12b 25
1e35409b 26static const char _c[] =
4c22730b 27 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#";
72a5e12b 28
db73838c 29static int _built_inverse;
72b2cb61 30static char _inverse_c[256];
db73838c 31
25b73380
AK
32int lvid_create(union lvid *lvid, struct id *vgid)
33{
34 memcpy(lvid->id, vgid, sizeof(*lvid->id));
52f9afec 35 return id_create(&lvid->id[1]);
25b73380
AK
36}
37
cc8f6e3d
AK
38void uuid_from_num(char *uuid, uint32_t num)
39{
40 unsigned i;
41
42 for (i = ID_LEN; i; i--) {
43 uuid[i - 1] = _c[num % (sizeof(_c) - 1)];
44 num /= sizeof(_c) - 1;
45 }
cc8f6e3d
AK
46}
47
8ef2b021 48int lvid_from_lvnum(union lvid *lvid, struct id *vgid, uint32_t lv_num)
b5ed5327
AK
49{
50 int i;
51
15c325f0
AK
52 memcpy(lvid->id, vgid, sizeof(*lvid->id));
53
b5ed5327 54 for (i = ID_LEN; i; i--) {
15c325f0 55 lvid->id[1].uuid[i - 1] = _c[lv_num % (sizeof(_c) - 1)];
b5ed5327
AK
56 lv_num /= sizeof(_c) - 1;
57 }
58
15c325f0
AK
59 lvid->s[sizeof(lvid->s) - 1] = '\0';
60
b5ed5327
AK
61 return 1;
62}
63
15c325f0 64int lvnum_from_lvid(union lvid *lvid)
b5ed5327
AK
65{
66 int i, lv_num = 0;
72b2cb61 67 char *c;
b5ed5327
AK
68
69 for (i = 0; i < ID_LEN; i++) {
70 lv_num *= sizeof(_c) - 1;
15c325f0 71 if ((c = strchr(_c, lvid->id[1].uuid[i])))
b5ed5327 72 lv_num += (int) (c - _c);
9c520b11
MB
73 if (lv_num < 0)
74 lv_num = 0;
b5ed5327
AK
75 }
76
77 return lv_num;
78}
79
9c520b11
MB
80int lvid_in_restricted_range(union lvid *lvid)
81{
82 int i;
83
84 for (i = 0; i < ID_LEN - 3; i++)
85 if (lvid->id[1].uuid[i] != '0')
86 return 0;
87
88 for (i = ID_LEN - 3; i < ID_LEN; i++)
89 if (!isdigit(lvid->id[1].uuid[i]))
90 return 0;
91
92 return 1;
93}
94
95
72a5e12b
JT
96int id_create(struct id *id)
97{
72b2cb61 98 unsigned i;
8ef2b021 99 size_t len = sizeof(id->uuid);
72a5e12b
JT
100
101 memset(id->uuid, 0, len);
b721056e 102 if (!read_urandom(&id->uuid, len)) {
72a5e12b
JT
103 return 0;
104 }
105
67cdbd7e
AK
106 /*
107 * Skip out the last 2 chars in randomized creation for LVM1
108 * backwards compatibility.
109 */
72a5e12b 110 for (i = 0; i < len; i++)
6a5b8035 111 id->uuid[i] = _c[id->uuid[i] % (sizeof(_c) - 3)];
72a5e12b
JT
112
113 return 1;
114}
115
db73838c
JT
116/*
117 * The only validity check we have is that
118 * the uuid just contains characters from
119 * '_c'. A checksum would have been nice :(
120 */
8ef2b021 121static void _build_inverse(void)
db73838c 122{
1e35409b 123 const char *ptr;
db73838c
JT
124
125 if (_built_inverse)
126 return;
127
65fc4dae 128 _built_inverse = 1;
db73838c
JT
129 memset(_inverse_c, 0, sizeof(_inverse_c));
130
131 for (ptr = _c; *ptr; ptr++)
132 _inverse_c[(int) *ptr] = (char) 0x1;
133}
134
72a5e12b
JT
135int id_valid(struct id *id)
136{
db73838c 137 int i;
db73838c
JT
138
139 _build_inverse();
140
141 for (i = 0; i < ID_LEN; i++)
142 if (!_inverse_c[id->uuid[i]]) {
b8f47d5f 143 log_error("UUID contains invalid character");
db73838c
JT
144 return 0;
145 }
146
72a5e12b
JT
147 return 1;
148}
149
8ef2b021 150int id_equal(const struct id *lhs, const struct id *rhs)
72a5e12b 151{
6036e5e0 152 return !memcmp(lhs->uuid, rhs->uuid, sizeof(lhs->uuid));
72a5e12b 153}
db73838c
JT
154
155#define GROUPS (ID_LEN / 4)
2041d905 156
8ef2b021 157int id_write_format(const struct id *id, char *buffer, size_t size)
db73838c 158{
9640f93d
JT
159 int i, tot;
160
aec21154 161 static const unsigned group_size[] = { 6, 4, 4, 4, 4, 4, 6 };
db73838c 162
9640f93d
JT
163 assert(ID_LEN == 32);
164
685d88b2 165 /* split into groups separated by dashes */
9640f93d 166 if (size < (32 + 6 + 1)) {
b8f47d5f 167 log_error("Couldn't write uuid, buffer too small.");
db73838c 168 return 0;
9640f93d 169 }
db73838c 170
9640f93d
JT
171 for (i = 0, tot = 0; i < 7; i++) {
172 memcpy(buffer, id->uuid + tot, group_size[i]);
173 buffer += group_size[i];
174 tot += group_size[i];
175 *buffer++ = '-';
db73838c
JT
176 }
177
9640f93d 178 *--buffer = '\0';
db73838c
JT
179 return 1;
180}
181
8ef2b021 182int id_read_format(struct id *id, const char *buffer)
db73838c 183{
9640f93d 184 int out = 0;
0803634c 185
9640f93d
JT
186 /* just strip out any dashes */
187 while (*buffer) {
188
189 if (*buffer == '-') {
190 buffer++;
191 continue;
192 }
193
194 if (out >= ID_LEN) {
b8f47d5f 195 log_error("Too many characters to be uuid.");
9640f93d
JT
196 return 0;
197 }
198
199 id->uuid[out++] = *buffer++;
db73838c
JT
200 }
201
9640f93d 202 if (out != ID_LEN) {
b8f47d5f
AK
203 log_error("Couldn't read uuid: incorrect number of "
204 "characters.");
9640f93d
JT
205 return 0;
206 }
db73838c
JT
207
208 return id_valid(id);
209}
f4fd4155
DW
210
211char *id_format_and_copy(struct dm_pool *mem, const struct id *id)
212{
213 char *repstr = NULL;
214
215 if (!(repstr = dm_pool_alloc(mem, 40))) {
216 log_error("dm_pool_alloc failed");
217 return NULL;
218 }
219
220 if (!id_write_format(id, repstr, 40))
221 return_NULL;
222
223 return repstr;
224}
This page took 0.100084 seconds and 5 git commands to generate.