]>
Commit | Line | Data |
---|---|---|
3839e657 TT |
1 | /* |
2 | * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology | |
3 | * | |
06cefee5 TT |
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. | |
3839e657 TT |
12 | */ |
13 | ||
d1154eb4 | 14 | #include "config.h" |
f3db3566 TT |
15 | #ifdef HAS_STDLIB_H |
16 | #include <stdlib.h> | |
17 | #endif | |
9ea68828 TT |
18 | #ifdef HAVE_ERRNO_H |
19 | #include <errno.h> | |
20 | #else | |
21 | extern int errno; | |
22 | #endif | |
3839e657 | 23 | #include "ss_internal.h" |
3839e657 TT |
24 | #include <stdio.h> |
25 | ||
546a1ff1 TT |
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 | ||
3839e657 TT |
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 (rqtbl, argc, argv, sci_idx) | |
86 | register ss_request_table *rqtbl; | |
87 | int argc; | |
88 | char *argv[]; | |
89 | int sci_idx; | |
90 | { | |
91 | #ifdef __SABER__ | |
92 | struct _ss_request_entry *request; | |
93 | #else | |
94 | register ss_request_entry *request; | |
95 | #endif | |
96 | register ss_data *info; | |
97 | register char const * const * name; | |
98 | char *string = argv[0]; | |
99 | int i; | |
100 | ||
101 | info = ss_info(sci_idx); | |
102 | info->argc = argc; | |
103 | info->argv = argv; | |
104 | for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { | |
105 | for (name = request->command_names; *name; name++) | |
106 | if (!strcmp(*name, string)) { | |
107 | info->current_request = request->command_names[0]; | |
108 | (request->function)(argc, (const char *const *) argv, | |
109 | sci_idx,info->info_ptr); | |
110 | info->current_request = (char *)NULL; | |
111 | return(0); | |
112 | } | |
113 | } | |
114 | return(SS_ET_COMMAND_NOT_FOUND); | |
115 | } | |
116 | ||
117 | /* | |
118 | * really_execute_command(sci_idx, argc, argv) | |
119 | * | |
120 | * Function: | |
121 | * Fills in the argc, argv values in the subsystem entry and | |
122 | * call the appropriate routine. | |
123 | * Arguments: | |
124 | * sci_idx (int) | |
125 | * ss-internal index for subsystem control info structure | |
126 | * argc (int) | |
127 | * number of arguments in argument list | |
128 | * argv (char **[]) | |
129 | * pointer to parsed argument list (may be reallocated | |
130 | * on abbrev expansion) | |
131 | * | |
132 | * Returns: | |
133 | * (int) | |
134 | * Zero if successful, ss_et_command_not_found otherwise. | |
135 | * Notes: | |
136 | */ | |
137 | ||
138 | static int really_execute_command (sci_idx, argc, argv) | |
139 | int sci_idx; | |
140 | int argc; | |
141 | char **argv[]; | |
142 | { | |
143 | register ss_request_table **rqtbl; | |
144 | register ss_data *info; | |
145 | ||
146 | info = ss_info(sci_idx); | |
147 | ||
148 | for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) { | |
149 | if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0) | |
150 | return(0); | |
151 | } | |
152 | return(SS_ET_COMMAND_NOT_FOUND); | |
153 | } | |
154 | ||
155 | /* | |
156 | * ss_execute_command(sci_idx, argv) | |
157 | * | |
158 | * Function: | |
159 | * Executes a parsed command list within the subsystem. | |
160 | * Arguments: | |
161 | * sci_idx (int) | |
162 | * ss-internal index for subsystem control info structure | |
163 | * argv (char *[]) | |
164 | * parsed argument list | |
165 | * Returns: | |
166 | * (int) | |
167 | * Zero if successful, ss_et_command_not_found otherwise. | |
168 | * Notes: | |
169 | */ | |
170 | ||
1e3472c5 | 171 | int ss_execute_command(sci_idx, argv) |
3839e657 TT |
172 | int sci_idx; |
173 | register char *argv[]; | |
174 | { | |
175 | register int i, argc; | |
176 | char **argp; | |
177 | ||
178 | argc = 0; | |
179 | for (argp = argv; *argp; argp++) | |
180 | argc++; | |
181 | argp = (char **)malloc((argc+1)*sizeof(char *)); | |
182 | for (i = 0; i <= argc; i++) | |
183 | argp[i] = argv[i]; | |
184 | i = really_execute_command(sci_idx, argc, &argp); | |
185 | free(argp); | |
186 | return(i); | |
187 | } | |
188 | ||
189 | /* | |
190 | * ss_execute_line(sci_idx, line_ptr) | |
191 | * | |
192 | * Function: | |
193 | * Parses and executes a command line within a subsystem. | |
194 | * Arguments: | |
195 | * sci_idx (int) | |
196 | * ss-internal index for subsystem control info structure | |
197 | * line_ptr (char *) | |
198 | * Pointer to command line to be parsed. | |
199 | * Returns: | |
200 | * (int) | |
201 | * Error code. | |
202 | * Notes: | |
203 | */ | |
204 | ||
205 | int ss_execute_line (sci_idx, line_ptr) | |
206 | int sci_idx; | |
207 | char *line_ptr; | |
208 | { | |
209 | char **argv; | |
7b352e35 | 210 | int argc, ret; |
3839e657 TT |
211 | |
212 | /* flush leading whitespace */ | |
213 | while (line_ptr[0] == ' ' || line_ptr[0] == '\t') | |
214 | line_ptr++; | |
215 | ||
216 | /* check if it should be sent to operating system for execution */ | |
217 | if (*line_ptr == '!') { | |
218 | if (ss_info(sci_idx)->flags.escape_disabled) | |
219 | return SS_ET_ESCAPE_DISABLED; | |
220 | else { | |
221 | line_ptr++; | |
9ea68828 | 222 | return (system(line_ptr) < 0) ? errno : 0; |
3839e657 TT |
223 | } |
224 | } | |
225 | ||
226 | /* parse it */ | |
227 | argv = ss_parse(sci_idx, line_ptr, &argc); | |
f19c46df | 228 | if (argc == 0) { |
45e338f5 | 229 | free(argv); |
3839e657 | 230 | return 0; |
f19c46df | 231 | } |
3839e657 TT |
232 | |
233 | /* look it up in the request tables, execute if found */ | |
7b352e35 TT |
234 | ret = really_execute_command (sci_idx, argc, &argv); |
235 | ||
236 | free(argv); | |
237 | ||
238 | return(ret); | |
3839e657 | 239 | } |