4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "lvm-string.h"
23 int emit_to_buffer(char **buffer
, size_t *size
, const char *fmt
, ...)
29 n
= vsnprintf(*buffer
, *size
, fmt
, ap
);
32 if (n
< 0 || ((size_t)n
== *size
))
41 * Count occurences of 'c' in 'str' until we reach a null char.
44 * len - incremented for each char we encounter.
45 * count - number of occurrences of 'c' and 'c2'.
47 static void _count_chars(const char *str
, size_t *len
, int *count
,
48 const int c1
, const int c2
)
52 for (ptr
= str
; *ptr
; ptr
++, (*len
)++)
53 if (*ptr
== c1
|| *ptr
== c2
)
58 * Count occurences of 'c' in 'str' of length 'size'.
61 * Number of occurrences of 'c'
63 unsigned count_chars(const char *str
, size_t len
, const int c
)
68 for (i
= 0; i
< len
; i
++)
76 * Length of string after escaping double quotes and backslashes.
78 size_t escaped_len(const char *str
)
83 _count_chars(str
, &len
, &count
, '\"', '\\');
89 * Copies a string, quoting orig_char with quote_char.
90 * Optionally also quote quote_char.
92 static void _quote_characters(char **out
, const char *src
,
93 const int orig_char
, const int quote_char
,
97 if (*src
== orig_char
||
98 (*src
== quote_char
&& quote_quote_char
))
99 *(*out
)++ = quote_char
;
106 * Unquote orig_char in string.
107 * Also unquote quote_char.
109 static void _unquote_characters(char *src
, const int orig_char
,
110 const int quote_char
)
115 if (*src
== quote_char
&&
116 (*(src
+ 1) == orig_char
|| *(src
+ 1) == quote_char
))
126 * Copies a string, quoting hyphens with hyphens.
128 static void _quote_hyphens(char **out
, const char *src
)
130 return _quote_characters(out
, src
, '-', '-', 0);
134 * <vg>-<lv>-<layer> or if !layer just <vg>-<lv>.
136 char *build_dm_name(struct dm_pool
*mem
, const char *vgname
,
137 const char *lvname
, const char *layer
)
143 _count_chars(vgname
, &len
, &hyphens
, '-', 0);
144 _count_chars(lvname
, &len
, &hyphens
, '-', 0);
146 if (layer
&& *layer
) {
147 _count_chars(layer
, &len
, &hyphens
, '-', 0);
153 if (!(r
= dm_pool_alloc(mem
, len
))) {
154 log_error("build_dm_name: Allocation failed for %" PRIsize_t
155 " for %s %s %s.", len
, vgname
, lvname
, layer
);
160 _quote_hyphens(&out
, vgname
);
162 _quote_hyphens(&out
, lvname
);
164 if (layer
&& *layer
) {
165 /* No hyphen if the layer begins with _ e.g. _mlog */
168 _quote_hyphens(&out
, layer
);
176 * Copies a string, quoting double quotes with backslashes.
178 char *escape_double_quotes(char *out
, const char *src
)
182 _quote_characters(&buf
, src
, '\"', '\\', 1);
189 * Undo quoting in situ.
191 void unescape_double_quotes(char *src
)
193 _unquote_characters(src
, '\"', '\\');
197 * Device layer names are all of the form <vg>-<lv>-<layer>, any
198 * other hyphens that appear in these names are quoted with yet
199 * another hyphen. The top layer of any device has no layer
200 * name. eg, vg0-lvol0.
202 int validate_name(const char *n
)
205 register int len
= 0;
210 /* Hyphen used as VG-LV separator - ambiguity if LV starts with it */
214 if (!strcmp(n
, ".") || !strcmp(n
, ".."))
217 while ((len
++, c
= *n
++))
218 if (!isalnum(c
) && c
!= '.' && c
!= '_' && c
!= '-' && c
!= '+')