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 #endif
21 #include "ss_internal.h"
22 #include <stdio.h>
23
24 static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc,
25 char *argv[], int sci_idx));
26 static int really_execute_command PROTOTYPE((int sci_idx, int argc,
27 char **argv[]));
28
29 /*
30 * get_request(tbl, idx)
31 *
32 * Function:
33 * Gets the idx'th request from the request table pointed to
34 * by tbl.
35 * Arguments:
36 * tbl (ss_request_table *)
37 * pointer to request table
38 * idx (int)
39 * index into table
40 * Returns:
41 * (ss_request_entry *)
42 * pointer to request table entry
43 * Notes:
44 * Has been replaced by a macro.
45 */
46
47 #ifdef __SABER__
48 /* sigh. saber won't deal with pointer-to-const-struct */
get_request(tbl,idx)49 static struct _ss_request_entry * get_request (tbl, idx)
50 ss_request_table * tbl;
51 int idx;
52 {
53 struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
54 struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
55 return e + idx;
56 }
57 #else
58 #define get_request(tbl,idx) ((tbl) -> requests + (idx))
59 #endif
60
61 /*
62 * check_request_table(rqtbl, argc, argv, sci_idx)
63 *
64 * Function:
65 * If the command string in argv[0] is in the request table, execute
66 * the commands and return error code 0. Otherwise, return error
67 * code ss_et_command_not_found.
68 * Arguments:
69 * rqtbl (ss_request_table *)
70 * pointer to request table
71 * argc (int)
72 * number of elements in argv[]
73 * argv (char *[])
74 * argument string array
75 * sci_idx (int)
76 * ss-internal index for subsystem control info structure
77 * Returns:
78 * (int)
79 * zero if command found, ss_et_command_not_found otherwise
80 * Notes:
81 */
82
check_request_table(register ss_request_table * rqtbl,int argc,char * argv[],int sci_idx)83 static int check_request_table(register ss_request_table *rqtbl, int argc,
84 char *argv[], int sci_idx)
85 {
86 #ifdef __SABER__
87 struct _ss_request_entry *request;
88 #else
89 register ss_request_entry *request;
90 #endif
91 register ss_data *info;
92 register char const * const * name;
93 char *string = argv[0];
94 int i;
95
96 info = ss_info(sci_idx);
97 info->argc = argc;
98 info->argv = argv;
99 for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
100 for (name = request->command_names; *name; name++)
101 if (!strcmp(*name, string)) {
102 info->current_request = request->command_names[0];
103 (request->function)(argc, (const char *const *) argv,
104 sci_idx,info->info_ptr);
105 info->current_request = (char *)NULL;
106 return(0);
107 }
108 }
109 return(SS_ET_COMMAND_NOT_FOUND);
110 }
111
112 /*
113 * really_execute_command(sci_idx, argc, argv)
114 *
115 * Function:
116 * Fills in the argc, argv values in the subsystem entry and
117 * call the appropriate routine.
118 * Arguments:
119 * sci_idx (int)
120 * ss-internal index for subsystem control info structure
121 * argc (int)
122 * number of arguments in argument list
123 * argv (char **[])
124 * pointer to parsed argument list (may be reallocated
125 * on abbrev expansion)
126 *
127 * Returns:
128 * (int)
129 * Zero if successful, ss_et_command_not_found otherwise.
130 * Notes:
131 */
132
really_execute_command(int sci_idx,int argc,char ** argv[])133 static int really_execute_command(int sci_idx, int argc, char **argv[])
134 {
135 register ss_request_table **rqtbl;
136 register ss_data *info;
137
138 info = ss_info(sci_idx);
139
140 for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
141 if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
142 return(0);
143 }
144 return(SS_ET_COMMAND_NOT_FOUND);
145 }
146
147 /*
148 * ss_execute_command(sci_idx, argv)
149 *
150 * Function:
151 * Executes a parsed command list within the subsystem.
152 * Arguments:
153 * sci_idx (int)
154 * ss-internal index for subsystem control info structure
155 * argv (char *[])
156 * parsed argument list
157 * Returns:
158 * (int)
159 * Zero if successful, ss_et_command_not_found otherwise.
160 * Notes:
161 */
162
ss_execute_command(int sci_idx,register char * argv[])163 int ss_execute_command(int sci_idx, register char *argv[])
164 {
165 register int i, argc;
166 char **argp;
167
168 argc = 0;
169 for (argp = argv; *argp; argp++)
170 argc++;
171 argp = (char **)malloc((argc+1)*sizeof(char *));
172 if (!argp)
173 return(ENOMEM);
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
ss_execute_line(int sci_idx,char * line_ptr)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