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 */
get_request(tbl,idx)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
check_request_table(register ss_request_table * rqtbl,int argc,char * argv[],int sci_idx)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
really_execute_command(int sci_idx,int argc,char ** argv[])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
ss_execute_command(int sci_idx,register char * argv[])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
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