version 1.27, 2017/01/16 14:52:25 |
version 1.28, 2017/01/24 19:53:37 |
|
|
(*p)--; |
(*p)--; |
} |
} |
|
|
struct cmd_list * |
int |
cmd_string_parse(const char *s, const char *file, u_int line, char **cause) |
cmd_string_split(const char *s, int *rargc, char ***rargv) |
{ |
{ |
size_t p = 0; |
size_t p = 0; |
int ch, i, argc = 0; |
int ch, argc = 0, append = 0; |
char **argv = NULL, *buf = NULL, *t; |
char **argv = NULL, *buf = NULL, *t; |
const char *whitespace, *equals; |
const char *whitespace, *equals; |
size_t len = 0; |
size_t len = 0; |
struct cmd_list *cmdlist = NULL; |
|
|
|
*cause = NULL; |
|
for (;;) { |
for (;;) { |
ch = cmd_string_getc(s, &p); |
ch = cmd_string_getc(s, &p); |
switch (ch) { |
switch (ch) { |
|
|
argc--; |
argc--; |
memmove(argv, argv + 1, argc * (sizeof *argv)); |
memmove(argv, argv + 1, argc * (sizeof *argv)); |
} |
} |
if (argc == 0) |
goto done; |
goto out; |
|
|
|
cmdlist = cmd_list_parse(argc, argv, file, line, cause); |
|
goto out; |
|
case '~': |
case '~': |
if (buf == NULL) { |
if (buf != NULL) { |
t = cmd_string_expand_tilde(s, &p); |
append = 1; |
if (t == NULL) |
|
goto error; |
|
cmd_string_copy(&buf, t, &len); |
|
break; |
break; |
} |
} |
/* FALLTHROUGH */ |
t = cmd_string_expand_tilde(s, &p); |
|
if (t == NULL) |
|
goto error; |
|
cmd_string_copy(&buf, t, &len); |
|
break; |
default: |
default: |
|
append = 1; |
|
break; |
|
} |
|
if (append) { |
if (len >= SIZE_MAX - 2) |
if (len >= SIZE_MAX - 2) |
goto error; |
goto error; |
|
|
buf = xrealloc(buf, len + 1); |
buf = xrealloc(buf, len + 1); |
buf[len++] = ch; |
buf[len++] = ch; |
break; |
|
} |
} |
|
append = 0; |
} |
} |
|
|
error: |
done: |
xasprintf(cause, "invalid or unknown command: %s", s); |
*rargc = argc; |
|
*rargv = argv; |
|
|
out: |
|
free(buf); |
free(buf); |
|
return (0); |
|
|
if (argv != NULL) { |
error: |
for (i = 0; i < argc; i++) |
if (argv != NULL) |
free(argv[i]); |
cmd_free_argv(argc, argv); |
free(argv); |
free(buf); |
} |
return (-1); |
|
} |
|
|
|
struct cmd_list * |
|
cmd_string_parse(const char *s, const char *file, u_int line, char **cause) |
|
{ |
|
struct cmd_list *cmdlist = NULL; |
|
int argc; |
|
char **argv; |
|
|
|
*cause = NULL; |
|
if (cmd_string_split(s, &argc, &argv) != 0) |
|
goto error; |
|
if (argc != 0) { |
|
cmdlist = cmd_list_parse(argc, argv, file, line, cause); |
|
if (cmdlist == NULL) { |
|
cmd_free_argv(argc, argv); |
|
goto error; |
|
} |
|
} |
|
cmd_free_argv(argc, argv); |
return (cmdlist); |
return (cmdlist); |
|
|
|
error: |
|
xasprintf(cause, "invalid or unknown command: %s", s); |
|
return (NULL); |
} |
} |
|
|
static void |
static void |