1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-08-02 04:22:02 +03:00

Move the core of the lib/config/config.c functionality into libdevmapper,

leaving behind the LVM-specific parts of the code (convenience wrappers that
handle `struct device` and `struct cmd_context`, basically). A number of
functions have been renamed (in addition to getting a dm_ prefix) -- namely,
all of the config interface now has a dm_config_ prefix.
This commit is contained in:
Petr Rockai
2011-08-30 14:55:15 +00:00
parent d35188058b
commit e59e2f7c3c
53 changed files with 1988 additions and 1858 deletions

View File

@ -161,3 +161,225 @@ int dm_asprintf(char **result, const char *format, ...)
dm_free(buf);
return n + 1;
}
/*
* Count occurences of 'c' in 'str' until we reach a null char.
*
* Returns:
* len - incremented for each char we encounter.
* count - number of occurrences of 'c' and 'c2'.
*/
static void _count_chars(const char *str, size_t *len, int *count,
const int c1, const int c2)
{
const char *ptr;
for (ptr = str; *ptr; ptr++, (*len)++)
if (*ptr == c1 || *ptr == c2)
(*count)++;
}
unsigned dm_count_chars(const char *str, size_t len, const int c)
{
size_t i;
unsigned count = 0;
for (i = 0; i < len; i++)
if (str[i] == c)
count++;
return count;
}
size_t dm_escaped_len(const char *str)
{
size_t len = 1;
int count = 0;
_count_chars(str, &len, &count, '\"', '\\');
return count + len;
}
/*
* Copies a string, quoting orig_char with quote_char.
* Optionally also quote quote_char.
*/
static void _quote_characters(char **out, const char *src,
const int orig_char, const int quote_char,
int quote_quote_char)
{
while (*src) {
if (*src == orig_char ||
(*src == quote_char && quote_quote_char))
*(*out)++ = quote_char;
*(*out)++ = *src++;
}
}
static void _unquote_one_character(char *src, const char orig_char,
const char quote_char)
{
char *out;
char s, n;
/* Optimise for the common case where no changes are needed. */
while ((s = *src++)) {
if (s == quote_char &&
((n = *src) == orig_char || n == quote_char)) {
out = src++;
*(out - 1) = n;
while ((s = *src++)) {
if (s == quote_char &&
((n = *src) == orig_char || n == quote_char)) {
s = n;
src++;
}
*out = s;
out++;
}
*out = '\0';
return;
}
}
}
/*
* Unquote each character given in orig_char array and unquote quote_char
* as well. Also save the first occurrence of each character from orig_char
* that was found unquoted in arr_substr_first_unquoted array. This way we can
* process several characters in one go.
*/
static void _unquote_characters(char *src, const char *orig_chars,
size_t num_orig_chars,
const char quote_char,
char *arr_substr_first_unquoted[])
{
char *out = src;
char c, s, n;
unsigned i;
while ((s = *src++)) {
for (i = 0; i < num_orig_chars; i++) {
c = orig_chars[i];
if (s == quote_char &&
((n = *src) == c || n == quote_char)) {
s = n;
src++;
break;
}
if (arr_substr_first_unquoted && (s == c) &&
!arr_substr_first_unquoted[i])
arr_substr_first_unquoted[i] = out;
};
*out++ = s;
}
*out = '\0';
}
/*
* Copies a string, quoting hyphens with hyphens.
*/
static void _quote_hyphens(char **out, const char *src)
{
_quote_characters(out, src, '-', '-', 0);
}
char *dm_build_dm_name(struct dm_pool *mem, const char *vgname,
const char *lvname, const char *layer)
{
size_t len = 1;
int hyphens = 1;
char *r, *out;
_count_chars(vgname, &len, &hyphens, '-', 0);
_count_chars(lvname, &len, &hyphens, '-', 0);
if (layer && *layer) {
_count_chars(layer, &len, &hyphens, '-', 0);
hyphens++;
}
len += hyphens;
if (!(r = dm_pool_alloc(mem, len))) {
log_error("build_dm_name: Allocation failed for %" PRIsize_t
" for %s %s %s.", len, vgname, lvname, layer);
return NULL;
}
out = r;
_quote_hyphens(&out, vgname);
*out++ = '-';
_quote_hyphens(&out, lvname);
if (layer && *layer) {
/* No hyphen if the layer begins with _ e.g. _mlog */
if (*layer != '_')
*out++ = '-';
_quote_hyphens(&out, layer);
}
*out = '\0';
return r;
}
char *dm_build_dm_uuid(struct dm_pool *mem, const char *prefix, const char *lvid, const char *layer)
{
char *dmuuid;
size_t len;
if (!layer)
layer = "";
len = strlen(prefix) + strlen(lvid) + strlen(layer) + 1;
if (!(dmuuid = dm_pool_alloc(mem, len))) {
log_error("build_dm_name: Allocation failed for %" PRIsize_t
" %s %s.", len, lvid, layer);
return NULL;
}
sprintf(dmuuid, "%s%s%s%s", prefix, lvid, (*layer) ? "-" : "", layer);
return dmuuid;
}
/*
* Copies a string, quoting double quotes with backslashes.
*/
char *dm_escape_double_quotes(char *out, const char *src)
{
char *buf = out;
_quote_characters(&buf, src, '\"', '\\', 1);
*buf = '\0';
return out;
}
void dm_unescape_double_quotes(char *src)
{
_unquote_one_character(src, '\"', '\\');
}
void dm_unescape_colons_and_at_signs(char *src,
char **substr_first_unquoted_colon,
char **substr_first_unquoted_at_sign)
{
const char *orig_chars = ":@";
char *arr_substr_first_unquoted[] = {NULL, NULL, NULL};
_unquote_characters(src, orig_chars, 2, '\\', arr_substr_first_unquoted);
if (substr_first_unquoted_colon)
*substr_first_unquoted_colon = arr_substr_first_unquoted[0];
if (substr_first_unquoted_at_sign)
*substr_first_unquoted_at_sign = arr_substr_first_unquoted[1];
}