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 21 extern int errno; 22 #endif 23 #include "ss_internal.h" 24 #include <stdio.h> 25 26 static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc, 27 char *argv[], int sci_idx)); 28 static 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 */ 51 static 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 85 static int check_request_table(register ss_request_table *rqtbl, int argc, 86 char *argv[], int sci_idx) 87 { 88 #ifdef __SABER__ 89 struct _ss_request_entry *request; 90 #else 91 register ss_request_entry *request; 92 #endif 93 register ss_data *info; 94 register char const * const * name; 95 char *string = argv[0]; 96 int i; 97 98 info = ss_info(sci_idx); 99 info->argc = argc; 100 info->argv = argv; 101 for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { 102 for (name = request->command_names; *name; name++) 103 if (!strcmp(*name, string)) { 104 info->current_request = request->command_names[0]; 105 (request->function)(argc, (const char *const *) argv, 106 sci_idx,info->info_ptr); 107 info->current_request = (char *)NULL; 108 return(0); 109 } 110 } 111 return(SS_ET_COMMAND_NOT_FOUND); 112 } 113 114 /* 115 * really_execute_command(sci_idx, argc, argv) 116 * 117 * Function: 118 * Fills in the argc, argv values in the subsystem entry and 119 * call the appropriate routine. 120 * Arguments: 121 * sci_idx (int) 122 * ss-internal index for subsystem control info structure 123 * argc (int) 124 * number of arguments in argument list 125 * argv (char **[]) 126 * pointer to parsed argument list (may be reallocated 127 * on abbrev expansion) 128 * 129 * Returns: 130 * (int) 131 * Zero if successful, ss_et_command_not_found otherwise. 132 * Notes: 133 */ 134 135 static int really_execute_command(int sci_idx, int argc, 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(int sci_idx, register char *argv[]) 166 { 167 register int i, argc; 168 char **argp; 169 170 argc = 0; 171 for (argp = argv; *argp; argp++) 172 argc++; 173 argp = (char **)malloc((argc+1)*sizeof(char *)); 174 for (i = 0; i <= argc; i++) 175 argp[i] = argv[i]; 176 i = really_execute_command(sci_idx, argc, &argp); 177 free(argp); 178 return(i); 179 } 180 181 /* 182 * ss_execute_line(sci_idx, line_ptr) 183 * 184 * Function: 185 * Parses and executes a command line within a subsystem. 186 * Arguments: 187 * sci_idx (int) 188 * ss-internal index for subsystem control info structure 189 * line_ptr (char *) 190 * Pointer to command line to be parsed. 191 * Returns: 192 * (int) 193 * Error code. 194 * Notes: 195 */ 196 197 int ss_execute_line(int sci_idx, char *line_ptr) 198 { 199 char **argv; 200 int argc, ret; 201 202 /* flush leading whitespace */ 203 while (line_ptr[0] == ' ' || line_ptr[0] == '\t') 204 line_ptr++; 205 206 /* check if it should be sent to operating system for execution */ 207 if (*line_ptr == '!') { 208 if (ss_info(sci_idx)->flags.escape_disabled) 209 return SS_ET_ESCAPE_DISABLED; 210 else { 211 line_ptr++; 212 return (system(line_ptr) < 0) ? errno : 0; 213 } 214 } 215 216 /* parse it */ 217 argv = ss_parse(sci_idx, line_ptr, &argc); 218 if (argc == 0) { 219 free(argv); 220 return 0; 221 } 222 223 /* look it up in the request tables, execute if found */ 224 ret = really_execute_command (sci_idx, argc, &argv); 225 226 free(argv); 227 228 return(ret); 229 } 230