summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2007-11-14 16:25:50 -0800
committerAn-Cheng Huang <ancheng@vyatta.com>2007-11-14 16:25:50 -0800
commit18d767fb17ec197d3ed24ec27a5364ee84b612ca (patch)
tree73f664a55c8a42afd3b72bb33ff5b389ad63905f /eval.c
parentbff0c156047ae6ca0bb9a5e04587ebe1d1ef5249 (diff)
downloadvyatta-bash-18d767fb17ec197d3ed24ec27a5364ee84b612ca.tar.gz
vyatta-bash-18d767fb17ec197d3ed24ec27a5364ee84b612ca.zip
* add restricted modes ("output" and "full").
* support "root-level" programmable completion in restricted modes.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 34a088c..72e5a45 100644
--- a/eval.c
+++ b/eval.c
@@ -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 ();