Understand environment variables in commands

Submitted by: Mark Knight <markk@knigma.org>
This commit is contained in:
Brian Somers 2000-03-14 01:47:31 +00:00
parent d568d6c405
commit 2a30e2ac0b
5 changed files with 101 additions and 61 deletions

View File

@ -100,3 +100,4 @@ o Unbalanced quotes in commands are now warned about and the entire command
is ignored.
o It is now only necessary to escape the `-' character in chat scripts twice.
See the example files for details.
o Environment variables and ~ are expanded on in commands

View File

@ -934,6 +934,18 @@ FindExec(struct bundle *bundle, struct cmdtab const *cmds, int argc, int argn,
return val;
}
int
command_Expand_Interpret(char *buff, int nb, char *argv[MAXARGS], int offset)
{
char buff2[LINE_LEN-offset];
InterpretArg(buff, buff2);
strncpy(buff, buff2, LINE_LEN - offset - 1);
buff[LINE_LEN - offset - 1] = '\0';
return command_Interpret(buff, nb, argv);
}
int
command_Interpret(char *buff, int nb, char *argv[MAXARGS])
{
@ -1013,7 +1025,7 @@ command_Decode(struct bundle *bundle, char *buff, int nb, struct prompt *prompt,
int argc;
char *argv[MAXARGS];
if ((argc = command_Interpret(buff, nb, argv)) < 0)
if ((argc = command_Expand_Interpret(buff, nb, argv, 0)) < 0)
return 0;
command_Run(bundle, argc, (char const *const *)argv, prompt, label, NULL);

View File

@ -55,6 +55,7 @@ extern const char Version[];
extern void command_Expand(char **, int, char const *const *, struct bundle *,
int, pid_t);
extern int command_Expand_Interpret(char *, int, char *vector[MAXARGS], int);
extern int command_Interpret(char *, int, char *vector[MAXARGS]);
extern void command_Run(struct bundle *, int, char const *const *,
struct prompt *, const char *, struct datalink *);
@ -62,3 +63,4 @@ extern int command_Decode(struct bundle *, char *, int, struct prompt *,
const char *);
extern struct link *command_ChooseLink(struct cmdargs const *);
extern const char *command_ShowNegval(unsigned);

View File

@ -59,79 +59,106 @@ CloseSecret(FILE *fp)
}
/* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */
static const char *
const char *
InterpretArg(const char *from, char *to)
{
const char *env;
char *ptr, *startto, *endto;
int len;
struct passwd *pwd;
int len, instring;
const char *env;
instring = 0;
startto = to;
endto = to + LINE_LEN - 1;
while(issep(*from))
from++;
if (*from == '~') {
struct passwd *pwd;
while (*from != '\0') {
switch (*from) {
case '"':
instring = !instring;
*to++ = *from++;
break;
case '\\':
switch (*++from) {
case '$':
case '~':
break; /* Swallow the escapes */
ptr = strchr(++from, '/');
len = ptr ? ptr - from : strlen(from);
if (len == 0) {
pwd = getpwuid(ID0realuid());
} else {
strncpy(to, from, len);
to[len] = '\0';
pwd = getpwnam(to);
}
strncpy(to, pwd ? pwd->pw_dir : _PATH_PPP, endto - to);
endpwent();
*endto = '\0';
to += strlen(to);
from += len;
}
while (to < endto && !issep(*from) && *from != '#' && *from != '\0') {
if (*from == '$') {
if (from[1] == '$') {
*to = '\0'; /* For an empty var name below */
from += 2;
} else if (from[1] == '{') {
ptr = strchr(from+2, '}');
if (ptr) {
len = ptr - from - 2;
if (endto - to < len )
len = endto - to;
if (len) {
strncpy(to, from+2, len);
to[len] = '\0';
from = ptr+1;
default:
*to++ = '\\'; /* Pass the escapes on, maybe skipping \# */
break;
}
*to++ = *from++;
break;
case '$':
if (from[1] == '$') {
*to = '\0'; /* For an empty var name below */
from += 2;
} else if (from[1] == '{') {
ptr = strchr(from+2, '}');
if (ptr) {
len = ptr - from - 2;
if (endto - to < len )
len = endto - to;
if (len) {
strncpy(to, from+2, len);
to[len] = '\0';
from = ptr+1;
} else {
*to++ = *from++;
continue;
}
} else {
*to++ = *from++;
continue;
}
} else {
*to++ = *from++;
continue;
ptr = to;
for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++)
*ptr++ = *from;
*ptr = '\0';
}
} else {
ptr = to;
for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++)
*ptr++ = *from;
*ptr = '\0';
}
if (*to == '\0')
*to++ = '$';
else if ((env = getenv(to)) != NULL) {
strncpy(to, env, endto - to);
*endto = '\0';
to += strlen(to);
}
} else {
if (*from == '\\')
from++;
*to++ = *from++;
if (*to == '\0')
*to++ = '$';
else if ((env = getenv(to)) != NULL) {
strncpy(to, env, endto - to);
*endto = '\0';
to += strlen(to);
}
break;
case '~':
ptr = strchr(++from, '/');
len = ptr ? ptr - from : strlen(from);
if (len == 0)
pwd = getpwuid(ID0realuid());
else {
strncpy(to, from, len);
to[len] = '\0';
pwd = getpwnam(to);
}
if (pwd == NULL)
*to++ = '~';
else {
strncpy(to, pwd->pw_dir, endto - to);
*endto = '\0';
to += strlen(to);
from += len;
}
endpwent();
break;
case '#':
if (!instring)
while (*from != '\0')
*to++ = *from++;
break;
default:
*to++ = *from++;
break;
}
}
@ -144,9 +171,6 @@ InterpretArg(const char *from, char *to)
}
*to = '\0';
while (issep(*from))
from++;
return from;
}
@ -363,7 +387,7 @@ ReadSystem(struct bundle *bundle, const char *name, const char *file,
}
len = strlen(cp);
if ((argc = command_Interpret(cp, len, argv)) < 0)
if ((argc = command_Expand_Interpret(cp, len, argv, cp - line)) < 0)
log_Printf(LogWARN, "%s: %d: Syntax error\n", filename, linenum);
else {
allowcmd = argc > 0 && !strcasecmp(argv[0], "allow");

View File

@ -35,3 +35,4 @@ extern int AllowUsers(struct cmdargs const *);
extern int AllowModes(struct cmdargs const *);
extern int LoadCommand(struct cmdargs const *);
extern int SaveCommand(struct cmdargs const *);
extern const char *InterpretArg(const char *, char *);