1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology
4 *
5 * For copyright info, see copyright.h.
6 */
7
8 #include "ss_internal.h"
9 #include "copyright.h"
10 #include <stdio.h>
11
12
13 /*
14 * get_request(tbl, idx)
15 *
16 * Function:
17 * Gets the idx'th request from the request table pointed to
18 * by tbl.
19 * Arguments:
20 * tbl (ss_request_table *)
21 * pointer to request table
22 * idx (int)
23 * index into table
24 * Returns:
25 * (ss_request_entry *)
26 * pointer to request table entry
27 * Notes:
28 * Has been replaced by a macro.
29 */
30
31 #define get_request(tbl,idx) ((tbl) -> requests + (idx))
32
33 /*
34 * check_request_table(rqtbl, argc, argv, sci_idx)
35 *
36 * Function:
37 * If the command string in argv[0] is in the request table, execute
38 * the commands and return error code 0. Otherwise, return error
39 * code ss_et_command_not_found.
40 * Arguments:
41 * rqtbl (ss_request_table *)
42 * pointer to request table
43 * argc (int)
44 * number of elements in argv[]
45 * argv (char *[])
46 * argument string array
47 * sci_idx (int)
48 * ss-internal index for subsystem control info structure
49 * Returns:
50 * (int)
51 * zero if command found, ss_et_command_not_found otherwise
52 * Notes:
53 */
54
55 static int
check_request_table(ss_request_table * rqtbl,int argc,char * argv[],int sci_idx)56 check_request_table(ss_request_table *rqtbl, int argc, char *argv[],
57 int sci_idx)
58 {
59 ss_request_entry *request;
60 ss_data *info;
61 char const *const *name;
62 char *string = argv[0];
63 int i;
64
65 info = ss_info(sci_idx);
66 info->argc = argc;
67 info->argv = argv;
68 for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
69 for (name = request->command_names; *name; name++)
70 if (!strcmp(*name, string)) {
71 info->current_request = request->command_names[0];
72 (request->function)(argc, (const char *const *) argv,
73 sci_idx,info->info_ptr);
74 info->current_request = (char *)NULL;
75 return(0);
76 }
77 }
78 return(SS_ET_COMMAND_NOT_FOUND);
79 }
80
81 /*
82 * really_execute_command(sci_idx, argc, argv)
83 *
84 * Function:
85 * Fills in the argc, argv values in the subsystem entry and
86 * call the appropriate routine.
87 * Arguments:
88 * sci_idx (int)
89 * ss-internal index for subsystem control info structure
90 * argc (int)
91 * number of arguments in argument list
92 * argv (char **[])
93 * pointer to parsed argument list (may be reallocated
94 * on abbrev expansion)
95 *
96 * Returns:
97 * (int)
98 * Zero if successful, ss_et_command_not_found otherwise.
99 * Notes:
100 */
101
102 static int
really_execute_command(int sci_idx,int argc,char ** argv[])103 really_execute_command(int sci_idx, int argc, char **argv[])
104 {
105 ss_request_table **rqtbl;
106 ss_data *info;
107
108 info = ss_info(sci_idx);
109
110 for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
111 if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
112 return(0);
113 }
114 return(SS_ET_COMMAND_NOT_FOUND);
115 }
116
117 /*
118 * ss_execute_command(sci_idx, argv)
119 *
120 * Function:
121 * Executes a parsed command list within the subsystem.
122 * Arguments:
123 * sci_idx (int)
124 * ss-internal index for subsystem control info structure
125 * argv (char *[])
126 * parsed argument list
127 * Returns:
128 * (int)
129 * Zero if successful, ss_et_command_not_found otherwise.
130 * Notes:
131 */
132
133 int
ss_execute_command(int sci_idx,char * argv[])134 ss_execute_command(int sci_idx, char *argv[])
135 {
136 unsigned int i, argc;
137 char **argp;
138 int ret;
139
140 argc = 0;
141 for (argp = argv; *argp; argp++)
142 argc++;
143 argp = (char **)malloc((argc+1)*sizeof(char *));
144 if (argp == NULL)
145 return(ENOMEM);
146 for (i = 0; i <= argc; i++)
147 argp[i] = argv[i];
148 ret = really_execute_command(sci_idx, argc, &argp);
149 free(argp);
150 return(ret);
151 }
152
153 /*
154 * ss_execute_line(sci_idx, line_ptr)
155 *
156 * Function:
157 * Parses and executes a command line within a subsystem.
158 * Arguments:
159 * sci_idx (int)
160 * ss-internal index for subsystem control info structure
161 * line_ptr (char *)
162 * Pointer to command line to be parsed.
163 * Returns:
164 * (int)
165 * Error code.
166 * Notes:
167 */
168
169 int
ss_execute_line(int sci_idx,char * line_ptr)170 ss_execute_line(int sci_idx, char *line_ptr)
171 {
172 char **argv;
173 int argc, ret;
174
175 /* flush leading whitespace */
176 while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
177 line_ptr++;
178
179 /* check if it should be sent to operating system for execution */
180 if (*line_ptr == '!') {
181 if (ss_info(sci_idx)->flags.escape_disabled)
182 return SS_ET_ESCAPE_DISABLED;
183 else {
184 line_ptr++;
185 system(line_ptr);
186 return 0;
187 }
188 }
189
190 /* parse it */
191 argv = ss_parse(sci_idx, line_ptr, &argc);
192 if (argc == 0)
193 return 0;
194
195 /* look it up in the request tables, execute if found */
196 ret = really_execute_command (sci_idx, argc, &argv);
197
198 free(argv);
199
200 return(ret);
201 }
202