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