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