diff options
Diffstat (limited to 'lib/ss/execute_cmd.c')
-rw-r--r-- | lib/ss/execute_cmd.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/lib/ss/execute_cmd.c b/lib/ss/execute_cmd.c new file mode 100644 index 0000000..d092134 --- /dev/null +++ b/lib/ss/execute_cmd.c @@ -0,0 +1,229 @@ +/* + * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose is hereby granted, provided that + * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. M.I.T. and the + * M.I.T. S.I.P.B. make no representations about the suitability of + * this software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include "config.h" +#ifdef HAS_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +#include "ss_internal.h" +#include <stdio.h> + +static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc, + char *argv[], int sci_idx)); +static int really_execute_command PROTOTYPE((int sci_idx, int argc, + char **argv[])); + +/* + * get_request(tbl, idx) + * + * Function: + * Gets the idx'th request from the request table pointed to + * by tbl. + * Arguments: + * tbl (ss_request_table *) + * pointer to request table + * idx (int) + * index into table + * Returns: + * (ss_request_entry *) + * pointer to request table entry + * Notes: + * Has been replaced by a macro. + */ + +#ifdef __SABER__ +/* sigh. saber won't deal with pointer-to-const-struct */ +static struct _ss_request_entry * get_request (tbl, idx) + ss_request_table * tbl; + int idx; +{ + struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl; + struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests; + return e + idx; +} +#else +#define get_request(tbl,idx) ((tbl) -> requests + (idx)) +#endif + +/* + * check_request_table(rqtbl, argc, argv, sci_idx) + * + * Function: + * If the command string in argv[0] is in the request table, execute + * the commands and return error code 0. Otherwise, return error + * code ss_et_command_not_found. + * Arguments: + * rqtbl (ss_request_table *) + * pointer to request table + * argc (int) + * number of elements in argv[] + * argv (char *[]) + * argument string array + * sci_idx (int) + * ss-internal index for subsystem control info structure + * Returns: + * (int) + * zero if command found, ss_et_command_not_found otherwise + * Notes: + */ + +static int check_request_table(register ss_request_table *rqtbl, int argc, + char *argv[], int sci_idx) +{ +#ifdef __SABER__ + struct _ss_request_entry *request; +#else + register ss_request_entry *request; +#endif + register ss_data *info; + register char const * const * name; + char *string = argv[0]; + int i; + + info = ss_info(sci_idx); + info->argc = argc; + info->argv = argv; + for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { + for (name = request->command_names; *name; name++) + if (!strcmp(*name, string)) { + info->current_request = request->command_names[0]; + (request->function)(argc, (const char *const *) argv, + sci_idx,info->info_ptr); + info->current_request = (char *)NULL; + return(0); + } + } + return(SS_ET_COMMAND_NOT_FOUND); +} + +/* + * really_execute_command(sci_idx, argc, argv) + * + * Function: + * Fills in the argc, argv values in the subsystem entry and + * call the appropriate routine. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * argc (int) + * number of arguments in argument list + * argv (char **[]) + * pointer to parsed argument list (may be reallocated + * on abbrev expansion) + * + * Returns: + * (int) + * Zero if successful, ss_et_command_not_found otherwise. + * Notes: + */ + +static int really_execute_command(int sci_idx, int argc, char **argv[]) +{ + register ss_request_table **rqtbl; + register ss_data *info; + + info = ss_info(sci_idx); + + for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) { + if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0) + return(0); + } + return(SS_ET_COMMAND_NOT_FOUND); +} + +/* + * ss_execute_command(sci_idx, argv) + * + * Function: + * Executes a parsed command list within the subsystem. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * argv (char *[]) + * parsed argument list + * Returns: + * (int) + * Zero if successful, ss_et_command_not_found otherwise. + * Notes: + */ + +int ss_execute_command(int sci_idx, register char *argv[]) +{ + register int i, argc; + char **argp; + + argc = 0; + for (argp = argv; *argp; argp++) + argc++; + argp = (char **)malloc((argc+1)*sizeof(char *)); + if (!argp) + return(ENOMEM); + for (i = 0; i <= argc; i++) + argp[i] = argv[i]; + i = really_execute_command(sci_idx, argc, &argp); + free(argp); + return(i); +} + +/* + * ss_execute_line(sci_idx, line_ptr) + * + * Function: + * Parses and executes a command line within a subsystem. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * line_ptr (char *) + * Pointer to command line to be parsed. + * Returns: + * (int) + * Error code. + * Notes: + */ + +int ss_execute_line(int sci_idx, char *line_ptr) +{ + char **argv; + int argc, ret; + + /* flush leading whitespace */ + while (line_ptr[0] == ' ' || line_ptr[0] == '\t') + line_ptr++; + + /* check if it should be sent to operating system for execution */ + if (*line_ptr == '!') { + if (ss_info(sci_idx)->flags.escape_disabled) + return SS_ET_ESCAPE_DISABLED; + else { + line_ptr++; + return (system(line_ptr) < 0) ? errno : 0; + } + } + + /* parse it */ + argv = ss_parse(sci_idx, line_ptr, &argc); + if (argc == 0) { + free(argv); + return 0; + } + + /* look it up in the request tables, execute if found */ + ret = really_execute_command (sci_idx, argc, &argv); + + free(argv); + + return(ret); +} |