execute_cmd.c revision d1154eb460efe588eaed3d439c1caaca149fa362
1/* 2 * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose is hereby granted, provided that 6 * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in 7 * advertising or publicity pertaining to distribution of the software 8 * without specific, written prior permission. M.I.T. and the 9 * M.I.T. S.I.P.B. make no representations about the suitability of 10 * this software for any purpose. It is provided "as is" without 11 * express or implied warranty. 12 */ 13 14#include "config.h" 15#ifdef HAS_STDLIB_H 16#include <stdlib.h> 17#endif 18#ifdef HAVE_ERRNO_H 19#include <errno.h> 20#else 21extern int errno; 22#endif 23#include "ss_internal.h" 24#include <stdio.h> 25 26static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc, 27 char *argv[], int sci_idx)); 28static int really_execute_command PROTOTYPE((int sci_idx, int argc, 29 char **argv[])); 30 31/* 32 * get_request(tbl, idx) 33 * 34 * Function: 35 * Gets the idx'th request from the request table pointed to 36 * by tbl. 37 * Arguments: 38 * tbl (ss_request_table *) 39 * pointer to request table 40 * idx (int) 41 * index into table 42 * Returns: 43 * (ss_request_entry *) 44 * pointer to request table entry 45 * Notes: 46 * Has been replaced by a macro. 47 */ 48 49#ifdef __SABER__ 50/* sigh. saber won't deal with pointer-to-const-struct */ 51static struct _ss_request_entry * get_request (tbl, idx) 52 ss_request_table * tbl; 53 int idx; 54{ 55 struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl; 56 struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests; 57 return e + idx; 58} 59#else 60#define get_request(tbl,idx) ((tbl) -> requests + (idx)) 61#endif 62 63/* 64 * check_request_table(rqtbl, argc, argv, sci_idx) 65 * 66 * Function: 67 * If the command string in argv[0] is in the request table, execute 68 * the commands and return error code 0. Otherwise, return error 69 * code ss_et_command_not_found. 70 * Arguments: 71 * rqtbl (ss_request_table *) 72 * pointer to request table 73 * argc (int) 74 * number of elements in argv[] 75 * argv (char *[]) 76 * argument string array 77 * sci_idx (int) 78 * ss-internal index for subsystem control info structure 79 * Returns: 80 * (int) 81 * zero if command found, ss_et_command_not_found otherwise 82 * Notes: 83 */ 84 85static int check_request_table (rqtbl, argc, argv, sci_idx) 86 register ss_request_table *rqtbl; 87 int argc; 88 char *argv[]; 89 int sci_idx; 90{ 91#ifdef __SABER__ 92 struct _ss_request_entry *request; 93#else 94 register ss_request_entry *request; 95#endif 96 register ss_data *info; 97 register char const * const * name; 98 char *string = argv[0]; 99 int i; 100 101 info = ss_info(sci_idx); 102 info->argc = argc; 103 info->argv = argv; 104 for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { 105 for (name = request->command_names; *name; name++) 106 if (!strcmp(*name, string)) { 107 info->current_request = request->command_names[0]; 108 (request->function)(argc, (const char *const *) argv, 109 sci_idx,info->info_ptr); 110 info->current_request = (char *)NULL; 111 return(0); 112 } 113 } 114 return(SS_ET_COMMAND_NOT_FOUND); 115} 116 117/* 118 * really_execute_command(sci_idx, argc, argv) 119 * 120 * Function: 121 * Fills in the argc, argv values in the subsystem entry and 122 * call the appropriate routine. 123 * Arguments: 124 * sci_idx (int) 125 * ss-internal index for subsystem control info structure 126 * argc (int) 127 * number of arguments in argument list 128 * argv (char **[]) 129 * pointer to parsed argument list (may be reallocated 130 * on abbrev expansion) 131 * 132 * Returns: 133 * (int) 134 * Zero if successful, ss_et_command_not_found otherwise. 135 * Notes: 136 */ 137 138static int really_execute_command (sci_idx, argc, argv) 139 int sci_idx; 140 int argc; 141 char **argv[]; 142{ 143 register ss_request_table **rqtbl; 144 register ss_data *info; 145 146 info = ss_info(sci_idx); 147 148 for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) { 149 if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0) 150 return(0); 151 } 152 return(SS_ET_COMMAND_NOT_FOUND); 153} 154 155/* 156 * ss_execute_command(sci_idx, argv) 157 * 158 * Function: 159 * Executes a parsed command list within the subsystem. 160 * Arguments: 161 * sci_idx (int) 162 * ss-internal index for subsystem control info structure 163 * argv (char *[]) 164 * parsed argument list 165 * Returns: 166 * (int) 167 * Zero if successful, ss_et_command_not_found otherwise. 168 * Notes: 169 */ 170 171int ss_execute_command(sci_idx, argv) 172 int sci_idx; 173 register char *argv[]; 174{ 175 register int i, argc; 176 char **argp; 177 178 argc = 0; 179 for (argp = argv; *argp; argp++) 180 argc++; 181 argp = (char **)malloc((argc+1)*sizeof(char *)); 182 for (i = 0; i <= argc; i++) 183 argp[i] = argv[i]; 184 i = really_execute_command(sci_idx, argc, &argp); 185 free(argp); 186 return(i); 187} 188 189/* 190 * ss_execute_line(sci_idx, line_ptr) 191 * 192 * Function: 193 * Parses and executes a command line within a subsystem. 194 * Arguments: 195 * sci_idx (int) 196 * ss-internal index for subsystem control info structure 197 * line_ptr (char *) 198 * Pointer to command line to be parsed. 199 * Returns: 200 * (int) 201 * Error code. 202 * Notes: 203 */ 204 205int ss_execute_line (sci_idx, line_ptr) 206 int sci_idx; 207 char *line_ptr; 208{ 209 char **argv; 210 int argc, ret; 211 212 /* flush leading whitespace */ 213 while (line_ptr[0] == ' ' || line_ptr[0] == '\t') 214 line_ptr++; 215 216 /* check if it should be sent to operating system for execution */ 217 if (*line_ptr == '!') { 218 if (ss_info(sci_idx)->flags.escape_disabled) 219 return SS_ET_ESCAPE_DISABLED; 220 else { 221 line_ptr++; 222 return (system(line_ptr) < 0) ? errno : 0; 223 } 224 } 225 226 /* parse it */ 227 argv = ss_parse(sci_idx, line_ptr, &argc); 228 if (argc == 0) { 229 free(argv); 230 return 0; 231 } 232 233 /* look it up in the request tables, execute if found */ 234 ret = really_execute_command (sci_idx, argc, &argv); 235 236 free(argv); 237 238 return(ret); 239} 240