• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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