1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02: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:
Werner Koch 2021-09-17 17:33:21 +02:00
parent 7f8ccb67e3
commit 9c272dc245
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
3 changed files with 206 additions and 0 deletions

View file

@ -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;
}