mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
common: New function substitute_envvars.
* common/stringhelp.c (substitute_envvars): New. Based on code in gpg-connect-agent. * common/t-stringhelp.c: Include sysutils.h. (test_substitute_envvars): New. -- GnuPG-bug-id: 5599
This commit is contained in:
parent
7f8ccb67e3
commit
9c272dc245
@ -1692,3 +1692,107 @@ format_text (const char *text_in, int target_cols, int max_cols)
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
/* Substitute environment variables in STRING and return a new string.
|
||||
* On error the function returns NULL. */
|
||||
char *
|
||||
substitute_envvars (const char *string)
|
||||
{
|
||||
char *line, *p, *pend;
|
||||
const char *value;
|
||||
size_t valuelen, n;
|
||||
char *result = NULL;
|
||||
|
||||
result = line = xtrystrdup (string);
|
||||
if (!result)
|
||||
return NULL; /* Ooops */
|
||||
|
||||
while (*line)
|
||||
{
|
||||
p = strchr (line, '$');
|
||||
if (!p)
|
||||
goto leave; /* No or no more variables. */
|
||||
|
||||
if (p[1] == '$') /* Escaped dollar sign. */
|
||||
{
|
||||
memmove (p, p+1, strlen (p+1)+1);
|
||||
line = p + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p[1] == '{')
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (pend=p+2; *pend; pend++)
|
||||
{
|
||||
if (*pend == '{')
|
||||
count++;
|
||||
else if (*pend == '}')
|
||||
{
|
||||
if (--count < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!*pend)
|
||||
goto leave; /* Unclosed - don't substitute. */
|
||||
}
|
||||
else
|
||||
{
|
||||
for (pend = p+1; *pend && (alnump (pend) || *pend == '_'); pend++)
|
||||
;
|
||||
}
|
||||
|
||||
if (p[1] == '{' && *pend == '}')
|
||||
{
|
||||
int save = *pend;
|
||||
*pend = 0;
|
||||
value = getenv (p+2);
|
||||
*pend++ = save;
|
||||
}
|
||||
else
|
||||
{
|
||||
int save = *pend;
|
||||
*pend = 0;
|
||||
value = getenv (p+1);
|
||||
*pend = save;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
value = "";
|
||||
valuelen = strlen (value);
|
||||
if (valuelen <= pend - p)
|
||||
{
|
||||
memcpy (p, value, valuelen);
|
||||
p += valuelen;
|
||||
n = pend - p;
|
||||
if (n)
|
||||
memmove (p, p+n, strlen (p+n)+1);
|
||||
line = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *src = result;
|
||||
char *dst;
|
||||
|
||||
dst = xtrymalloc (strlen (src) + valuelen + 1);
|
||||
if (!dst)
|
||||
{
|
||||
xfree (result);
|
||||
return NULL;
|
||||
}
|
||||
n = p - src;
|
||||
memcpy (dst, src, n);
|
||||
memcpy (dst + n, value, valuelen);
|
||||
n += valuelen;
|
||||
strcpy (dst + n, pend);
|
||||
line = dst + n;
|
||||
xfree (result);
|
||||
result = dst;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
return result;
|
||||
}
|
||||
|
@ -166,6 +166,9 @@ int compare_version_strings (const char *my_version, const char *req_version);
|
||||
/* Format a string so that it fits within about TARGET_COLS columns. */
|
||||
char *format_text (const char *text, int target_cols, int max_cols);
|
||||
|
||||
/* Substitute environmen variabales in STRING. */
|
||||
char *substitute_envvars (const char *string);
|
||||
|
||||
|
||||
/*-- mapstrings.c --*/
|
||||
const char *map_static_macro_string (const char *string);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <limits.h>
|
||||
|
||||
#include "t-support.h"
|
||||
#include "sysutils.h"
|
||||
#include "stringhelp.h"
|
||||
|
||||
|
||||
@ -1194,6 +1195,103 @@ test_compare_version_strings (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_substitute_envvars (void)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
const char *value;
|
||||
} envvars[] = {
|
||||
{ "HOME", "/home/joe" },
|
||||
{ "AVAR", "avar" },
|
||||
{ "AVAR1", "avarx" },
|
||||
{ "AVAR2", "avarxy" },
|
||||
{ "AVAR3", "avarxyz" },
|
||||
{ "AVAR0", "ava" },
|
||||
{ "MY_VAR", "my_vars_value" },
|
||||
{ "STRANGE{X}VAR", "strange{x}vars-value" },
|
||||
{ "ZERO", "" }
|
||||
};
|
||||
struct {
|
||||
const char *string;
|
||||
const char *result;
|
||||
} tests[] = {
|
||||
{ "foo bar",
|
||||
"foo bar"
|
||||
},
|
||||
{ "foo $HOME",
|
||||
"foo /home/joe"
|
||||
},
|
||||
{ "foo $HOME ",
|
||||
"foo /home/joe "
|
||||
},
|
||||
{ "foo $HOME$$",
|
||||
"foo /home/joe$"
|
||||
},
|
||||
{ "foo ${HOME}/.ssh",
|
||||
"foo /home/joe/.ssh"
|
||||
},
|
||||
{ "foo $HOME/.ssh",
|
||||
"foo /home/joe/.ssh"
|
||||
},
|
||||
{ "foo $HOME_/.ssh",
|
||||
"foo /.ssh"
|
||||
},
|
||||
{ "foo $HOME/.ssh/$MY_VAR:1",
|
||||
"foo /home/joe/.ssh/my_vars_value:1"
|
||||
},
|
||||
{ "foo $HOME${MY_VAR}:1",
|
||||
"foo /home/joemy_vars_value:1"
|
||||
},
|
||||
{ "${STRANGE{X}VAR}-bla",
|
||||
"strange{x}vars-value-bla"
|
||||
},
|
||||
{ "${STRANGE{X}{VAR}-bla", /* missing "}" */
|
||||
"${STRANGE{X}{VAR}-bla"
|
||||
},
|
||||
{ "zero->$ZERO<-",
|
||||
"zero-><-"
|
||||
},
|
||||
{ "->$AVAR.$AVAR1.$AVAR2.$AVAR3.$AVAR0<-",
|
||||
"->avar.avarx.avarxy.avarxyz.ava<-"
|
||||
},
|
||||
{ "",
|
||||
""
|
||||
}
|
||||
};
|
||||
int idx;
|
||||
char *res;
|
||||
|
||||
for (idx=0; idx < DIM(envvars); idx++)
|
||||
if (gnupg_setenv (envvars[idx].name, envvars[idx].value, 1))
|
||||
{
|
||||
fprintf (stderr,"error setting envvar '%s' to '%s': %s\n",
|
||||
envvars[idx].name, envvars[idx].value,
|
||||
strerror (errno));
|
||||
exit (2);
|
||||
}
|
||||
|
||||
for (idx=0; idx < DIM(tests); idx++)
|
||||
{
|
||||
res = substitute_envvars (tests[idx].string);
|
||||
if (!res)
|
||||
{
|
||||
fprintf (stderr,"error substituting '%s' (test %d): %s\n",
|
||||
tests[idx].string, idx, strerror (errno));
|
||||
exit (2);
|
||||
}
|
||||
if (strcmp (res, tests[idx].result))
|
||||
{
|
||||
fprintf (stderr, "substituted '%s'\n", tests[idx].string);
|
||||
fprintf (stderr, " wanted '%s'\n", tests[idx].result);
|
||||
fprintf (stderr, " got '%s'\n", res);
|
||||
fail (idx);
|
||||
}
|
||||
xfree (res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -1213,6 +1311,7 @@ main (int argc, char **argv)
|
||||
test_split_fields_colon ();
|
||||
test_compare_version_strings ();
|
||||
test_format_text ();
|
||||
test_substitute_envvars ();
|
||||
|
||||
xfree (home_buffer);
|
||||
return !!errcount;
|
||||
|
Loading…
x
Reference in New Issue
Block a user