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