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 */
get_request(tbl,idx)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
check_request_table(rqtbl,argc,argv,sci_idx)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
really_execute_command(sci_idx,argc,argv)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
ss_execute_command(sci_idx,argv)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
ss_execute_line(sci_idx,line_ptr)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