47
* Count occurences of 'c' in 'str' until we reach a null char.
50
* len - incremented for each char we encounter.
51
* count - number of occurrences of 'c' and 'c2'.
53
static void _count_chars(const char *str, size_t *len, int *count,
54
const int c1, const int c2)
58
for (ptr = str; *ptr; ptr++, (*len)++)
59
if (*ptr == c1 || *ptr == c2)
64
* Count occurences of 'c' in 'str' of length 'size'.
67
* Number of occurrences of 'c'
69
unsigned count_chars(const char *str, size_t len, const int c)
74
for (i = 0; i < len; i++)
82
* Length of string after escaping double quotes and backslashes.
84
size_t escaped_len(const char *str)
89
_count_chars(str, &len, &count, '\"', '\\');
95
* Copies a string, quoting orig_char with quote_char.
96
* Optionally also quote quote_char.
98
static void _quote_characters(char **out, const char *src,
99
const int orig_char, const int quote_char,
100
int quote_quote_char)
103
if (*src == orig_char ||
104
(*src == quote_char && quote_quote_char))
105
*(*out)++ = quote_char;
111
static void _unquote_one_character(char *src, const char orig_char,
112
const char quote_char)
117
/* Optimise for the common case where no changes are needed. */
118
while ((s = *src++)) {
119
if (s == quote_char &&
120
((n = *src) == orig_char || n == quote_char)) {
124
while ((s = *src++)) {
125
if (s == quote_char &&
126
((n = *src) == orig_char || n == quote_char)) {
141
* Unquote each character given in orig_char array and unquote quote_char
142
* as well. Also save the first occurrence of each character from orig_char
143
* that was found unquoted in arr_substr_first_unquoted array. This way we can
144
* process several characters in one go.
146
static void _unquote_characters(char *src, const char *orig_chars,
147
size_t num_orig_chars,
148
const char quote_char,
149
char *arr_substr_first_unquoted[])
155
while ((s = *src++)) {
156
for (i = 0; i < num_orig_chars; i++) {
158
if (s == quote_char &&
159
((n = *src) == c || n == quote_char)) {
164
if (arr_substr_first_unquoted && (s == c) &&
165
!arr_substr_first_unquoted[i])
166
arr_substr_first_unquoted[i] = out;
175
* Copies a string, quoting hyphens with hyphens.
177
static void _quote_hyphens(char **out, const char *src)
179
_quote_characters(out, src, '-', '-', 0);
183
* <vg>-<lv>-<layer> or if !layer just <vg>-<lv>.
185
char *build_dm_name(struct dm_pool *mem, const char *vgname,
186
const char *lvname, const char *layer)
192
_count_chars(vgname, &len, &hyphens, '-', 0);
193
_count_chars(lvname, &len, &hyphens, '-', 0);
195
if (layer && *layer) {
196
_count_chars(layer, &len, &hyphens, '-', 0);
202
if (!(r = dm_pool_alloc(mem, len))) {
203
log_error("build_dm_name: Allocation failed for %" PRIsize_t
204
" for %s %s %s.", len, vgname, lvname, layer);
209
_quote_hyphens(&out, vgname);
211
_quote_hyphens(&out, lvname);
213
if (layer && *layer) {
214
/* No hyphen if the layer begins with _ e.g. _mlog */
217
_quote_hyphens(&out, layer);
224
char *build_dm_uuid(struct dm_pool *mem, const char *lvid, const char *layer)
232
len = sizeof(UUID_PREFIX) + strlen(lvid) + strlen(layer) + 1;
234
if (!(dmuuid = dm_pool_alloc(mem, len))) {
235
log_error("build_dm_name: Allocation failed for %" PRIsize_t
236
" %s %s.", len, lvid, layer);
240
sprintf(dmuuid, UUID_PREFIX "%s%s%s", lvid, (*layer) ? "-" : "", layer);
246
* Copies a string, quoting double quotes with backslashes.
248
char *escape_double_quotes(char *out, const char *src)
252
_quote_characters(&buf, src, '\"', '\\', 1);
259
* Undo quoting in situ.
261
void unescape_double_quotes(char *src)
263
_unquote_one_character(src, '\"', '\\');
267
* Unescape colons and "at" signs in situ and save the substrings
268
* starting at the position of the first unescaped colon and the
269
* first unescaped "at" sign. This is normally used to unescape
270
* device names used as PVs.
272
void unescape_colons_and_at_signs(char *src,
273
char **substr_first_unquoted_colon,
274
char **substr_first_unquoted_at_sign)
276
const char *orig_chars = ":@";
277
char *arr_substr_first_unquoted[] = {NULL, NULL, NULL};
279
_unquote_characters(src, orig_chars, 2, '\\', arr_substr_first_unquoted);
281
if (substr_first_unquoted_colon)
282
*substr_first_unquoted_colon = arr_substr_first_unquoted[0];
284
if (substr_first_unquoted_at_sign)
285
*substr_first_unquoted_at_sign = arr_substr_first_unquoted[1];
289
47
* A-Za-z0-9._-+/=!:&#
291
49
int validate_tag(const char *n)
294
register int len = 0;
299
while ((len++, c = *n++))
57
/* FIXME: Is unlimited tag size support needed ? */
58
while ((/* len++, */ c = *n++))
300
59
if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+' && c != '/'
301
60
&& c != '=' && c != '!' && c != ':' && c != '&' && c != '#')
338
97
int apply_lvname_restrictions(const char *name)
340
if (!strncmp(name, "snapshot", 8)) {
341
log_error("Names starting \"snapshot\" are reserved. "
342
"Please choose a different LV name.");
346
if (!strncmp(name, "pvmove", 6)) {
347
log_error("Names starting \"pvmove\" are reserved. "
348
"Please choose a different LV name.");
352
if (strstr(name, "_mlog")) {
353
log_error("Names including \"_mlog\" are reserved. "
354
"Please choose a different LV name.");
358
if (strstr(name, "_mimage")) {
359
log_error("Names including \"_mimage\" are reserved. "
360
"Please choose a different LV name.");
364
if (strstr(name, "_rimage")) {
365
log_error("Names including \"_rimage\" are reserved. "
366
"Please choose a different LV name.");
370
if (strstr(name, "_rmeta")) {
371
log_error("Names including \"_rmeta\" are reserved. "
372
"Please choose a different LV name.");
376
if (strstr(name, "_vorigin")) {
377
log_error("Names including \"_vorigin\" are reserved. "
378
"Please choose a different LV name.");
99
const char *reserved_prefixes[] = {
105
const char *reserved_strings[] = {
119
for (i = 0; (s = reserved_prefixes[i]); i++) {
120
if (!strncmp(name, s, strlen(s))) {
121
log_error("Names starting \"%s\" are reserved. "
122
"Please choose a different LV name.", s);
127
for (i = 0; (s = reserved_strings[i]); i++) {
128
if (strstr(name, s)) {
129
log_error("Names including \"%s\" are reserved. "
130
"Please choose a different LV name.", s);