Understand environment variables in commands
Submitted by: Mark Knight <markk@knigma.org>
This commit is contained in:
parent
d568d6c405
commit
2a30e2ac0b
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user