diff options
-rw-r--r-- | bashline.c | 12 | ||||
-rw-r--r-- | eval.c | 95 | ||||
-rw-r--r-- | general.c | 22 | ||||
-rw-r--r-- | general.h | 3 | ||||
-rw-r--r-- | pcomplete.c | 23 |
5 files changed, 144 insertions, 11 deletions
@@ -1067,7 +1067,8 @@ attempt_shell_completion (text, start, end) #if defined (PROGRAMMABLE_COMPLETION) /* Attempt programmable completion. */ - if (!matches && in_command_position == 0 && prog_completion_enabled && + if (!matches && prog_completion_enabled && + (in_vyatta_restricted_mode(OUTPUT) || in_command_position == 0) && (progcomp_size () > 0) && current_prompt_string == ps1_prompt) { int s, e, foundcs; @@ -1081,7 +1082,9 @@ attempt_shell_completion (text, start, end) s = find_cmd_start (start); e = find_cmd_end (end); n = find_cmd_name (s); - if (e > s && assignment (n, 0) == 0) + if ((e > s || (in_vyatta_restricted_mode(OUTPUT) && + strcmp(n, text) == 0)) && + assignment (n, 0) == 0) prog_complete_matches = programmable_completions (n, text, s, e, &foundcs); else foundcs = 0; @@ -1126,6 +1129,11 @@ bash_default_completion (text, start, end, qc, in_command_position) matches = (char **)NULL; + if (in_vyatta_restricted_mode(OUTPUT)) { + rl_ignore_some_completions_function = bash_ignore_everything; + return matches; + } + /* New posix-style command substitution or variable name? */ if (!matches && *text == '$') { @@ -29,6 +29,7 @@ #include "bashansi.h" #include <stdio.h> +#include <dirent.h> #include "bashintl.h" @@ -57,6 +58,11 @@ extern int expand_aliases; static void send_pwd_to_eterm __P((void)); static sighandler alrm_catcher __P((int)); +#if defined (READLINE) +extern char *current_readline_line; +extern int current_readline_line_index; +#endif + /* Read and execute commands until EOF is reached. This assumes that the input source has already been initialized. */ int @@ -192,6 +198,83 @@ send_pwd_to_eterm () fprintf (stderr, "\032/%s\n", pwd); } +static int +is_in_command_list(const char *cmd, const char *cmds[]) +{ + int idx = 0; + for (idx = 0; cmds[idx]; idx++) { + if (strcmp(cmd, cmds[idx]) == 0) { + return 1; + } + } + return 0; +} + +static int +is_vyatta_cfg_command(const char *cmd) +{ + char *valid_commands[] = { "set", "delete", "commit", "save", "load", + "show", "exit", "edit", "run", NULL }; + return is_in_command_list(cmd, valid_commands); +} + +static int +is_vyatta_op_command(const char *cmd) +{ + char *dir = getenv("vyatta_op_templates"); + DIR *dp = NULL; + struct dirent *dent = NULL; + char *other_commands[] = { "exit", NULL }; + int ret = 0; + + if (dir == NULL || (dp = opendir(dir)) == NULL) { + return 0; + } + while (dent = readdir(dp)) { + if (strncmp(dent->d_name, ".", 1) == 0) { + continue; + } + if (strcmp(dent->d_name, cmd) == 0) { + ret = 1; + break; + } + } + closedir(dp); + return (ret) ? 1 : is_in_command_list(cmd, other_commands); +} + +static int +is_vyatta_command(char *cmdline) +{ + char *cfg = getenv("_OFR_CONFIGURE"); + int in_cfg = (cfg) ? (strcmp(cfg, "ok") == 0) : 0; + char *start = cmdline; + char *end = NULL; + char save = 0; + int ret = 0; + while (*start && (whitespace(*start) || *start == '\n')) { + start++; + } + if (*start == 0) { + /* empty command line */ + return 1; + } + end = start; + while (*end && (!whitespace(*end) && *end != '\n')) { + end++; + } + save = *end; + *end = 0; + + if (in_cfg) { + ret = is_vyatta_cfg_command(start); + } else { + ret = is_vyatta_op_command(start); + } + *end = save; + return ret; +} + /* Call the YACC-generated parser and return the status of the parse. Input is read from the current input stream (bash_input). yyparse leaves the parsed command in the global variable GLOBAL_COMMAND. @@ -221,6 +304,18 @@ parse_command () current_command_line_count = 0; r = yyparse (); +#if defined (READLINE) + if (in_vyatta_restricted_mode(FULL) && current_readline_line) { + if (!is_vyatta_command(current_readline_line)) { + printf("Invalid command\n"); + current_readline_line_index = 0; + current_readline_line[0] = '\n'; + current_readline_line[1] = '\0'; + return 1; + } + } +#endif + if (need_here_doc) gather_here_documents (); @@ -1023,3 +1023,25 @@ get_group_array (ngp) *ngp = ngroups; return group_iarray; } + +int +in_vyatta_restricted_mode(enum vyatta_restricted_type type) +{ + char *rval = getenv("VYATTA_RESTRICTED_MODE"); + int output = 0, full = 0; + if (rval == NULL) { + return 0; + } + output = (strcmp(rval, "output") == 0); + full = (strcmp(rval, "full") == 0); + + if (type == OUTPUT && (output || full)) { + return 1; + } + if (type == FULL && full) { + return 1; + } + + return 0; +} + @@ -317,4 +317,7 @@ extern int group_member __P((gid_t)); extern char **get_group_list __P((int *)); extern int *get_group_array __P((int *)); +enum vyatta_restricted_type { OUTPUT, FULL }; +extern int in_vyatta_restricted_mode __P((enum vyatta_restricted_type)); + #endif /* _GENERAL_H_ */ diff --git a/pcomplete.c b/pcomplete.c index ee462dc..74dad05 100644 --- a/pcomplete.c +++ b/pcomplete.c @@ -1353,15 +1353,20 @@ programmable_completions (cmd, word, start, end, foundp) STRINGLIST *ret; char **rmatches, *t; - /* We look at the basename of CMD if the full command does not have - an associated COMPSPEC. */ - cs = progcomp_search (cmd); - if (cs == 0) - { - t = strrchr (cmd, '/'); - if (t) - cs = progcomp_search (++t); - } + if (in_vyatta_restricted_mode(OUTPUT) && strcmp(cmd, word) == 0) { + /* command completion */ + cs = progcomp_search(""); + } else { + /* We look at the basename of CMD if the full command does not have + an associated COMPSPEC. */ + cs = progcomp_search (cmd); + if (cs == 0) + { + t = strrchr (cmd, '/'); + if (t) + cs = progcomp_search (++t); + } + } if (cs == 0) { if (foundp) |