execute_cmd.c revision a6ce1349539f866334ef3d5758bc2ee44a454acd
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#ifdef HAVE_ERRNO_H
18#include <errno.h>
19#else
20extern int errno;
21#endif
22#include "ss_internal.h"
23#include <stdio.h>
24
25static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc,
26					  char *argv[], int sci_idx));
27static int really_execute_command PROTOTYPE((int sci_idx, int argc,
28					     char **argv[]));
29
30/*
31 * get_request(tbl, idx)
32 *
33 * Function:
34 *      Gets the idx'th request from the request table pointed to
35 *      by tbl.
36 * Arguments:
37 *      tbl (ss_request_table *)
38 *              pointer to request table
39 *      idx (int)
40 *              index into table
41 * Returns:
42 *      (ss_request_entry *)
43 *              pointer to request table entry
44 * Notes:
45 *      Has been replaced by a macro.
46 */
47
48#ifdef __SABER__
49/* sigh.  saber won't deal with pointer-to-const-struct */
50static struct _ss_request_entry * get_request (tbl, idx)
51    ss_request_table * tbl;
52    int idx;
53{
54    struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
55    struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
56    return e + idx;
57}
58#else
59#define get_request(tbl,idx)    ((tbl) -> requests + (idx))
60#endif
61
62/*
63 * check_request_table(rqtbl, argc, argv, sci_idx)
64 *
65 * Function:
66 *      If the command string in argv[0] is in the request table, execute
67 *      the commands and return error code 0.  Otherwise, return error
68 *      code ss_et_command_not_found.
69 * Arguments:
70 *      rqtbl (ss_request_table *)
71 *              pointer to request table
72 *      argc (int)
73 *              number of elements in argv[]
74 *      argv (char *[])
75 *              argument string array
76 *      sci_idx (int)
77 *              ss-internal index for subsystem control info structure
78 * Returns:
79 *      (int)
80 *              zero if command found, ss_et_command_not_found otherwise
81 * Notes:
82 */
83
84static int check_request_table (rqtbl, argc, argv, sci_idx)
85    register ss_request_table *rqtbl;
86    int argc;
87    char *argv[];
88    int sci_idx;
89{
90#ifdef __SABER__
91    struct _ss_request_entry *request;
92#else
93    register ss_request_entry *request;
94#endif
95    register ss_data *info;
96    register char const * const * name;
97    char *string = argv[0];
98    int i;
99
100    info = ss_info(sci_idx);
101    info->argc = argc;
102    info->argv = argv;
103    for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
104	for (name = request->command_names; *name; name++)
105	    if (!strcmp(*name, string)) {
106		info->current_request = request->command_names[0];
107		(request->function)(argc, (const char *const *) argv,
108				    sci_idx,info->info_ptr);
109		info->current_request = (char *)NULL;
110		return(0);
111	    }
112    }
113    return(SS_ET_COMMAND_NOT_FOUND);
114}
115
116/*
117 * really_execute_command(sci_idx, argc, argv)
118 *
119 * Function:
120 *      Fills in the argc, argv values in the subsystem entry and
121 *      call the appropriate routine.
122 * Arguments:
123 *      sci_idx (int)
124 *              ss-internal index for subsystem control info structure
125 *      argc (int)
126 *              number of arguments in argument list
127 *      argv (char **[])
128 *              pointer to parsed argument list (may be reallocated
129 *              on abbrev expansion)
130 *
131 * Returns:
132 *      (int)
133 *              Zero if successful, ss_et_command_not_found otherwise.
134 * Notes:
135 */
136
137static int really_execute_command (sci_idx, argc, argv)
138    int sci_idx;
139    int argc;
140    char **argv[];
141{
142    register ss_request_table **rqtbl;
143    register ss_data *info;
144
145    info = ss_info(sci_idx);
146
147    for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
148        if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
149            return(0);
150    }
151    return(SS_ET_COMMAND_NOT_FOUND);
152}
153
154/*
155 * ss_execute_command(sci_idx, argv)
156 *
157 * Function:
158 *	Executes a parsed command list within the subsystem.
159 * Arguments:
160 *	sci_idx (int)
161 *		ss-internal index for subsystem control info structure
162 *	argv (char *[])
163 *		parsed argument list
164 * Returns:
165 *	(int)
166 *		Zero if successful, ss_et_command_not_found otherwise.
167 * Notes:
168 */
169
170int ss_execute_command(sci_idx, argv)
171	int sci_idx;
172	register char *argv[];
173{
174	register int i, argc;
175	char **argp;
176
177	argc = 0;
178	for (argp = argv; *argp; argp++)
179		argc++;
180	argp = (char **)malloc((argc+1)*sizeof(char *));
181	for (i = 0; i <= argc; i++)
182		argp[i] = argv[i];
183	i = really_execute_command(sci_idx, argc, &argp);
184	free(argp);
185	return(i);
186}
187
188/*
189 * ss_execute_line(sci_idx, line_ptr)
190 *
191 * Function:
192 *      Parses and executes a command line within a subsystem.
193 * Arguments:
194 *      sci_idx (int)
195 *              ss-internal index for subsystem control info structure
196 *      line_ptr (char *)
197 *              Pointer to command line to be parsed.
198 * Returns:
199 *      (int)
200 *      	Error code.
201 * Notes:
202 */
203
204int ss_execute_line (sci_idx, line_ptr)
205    int sci_idx;
206    char *line_ptr;
207{
208    char **argv;
209    int argc, ret;
210
211    /* flush leading whitespace */
212    while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
213        line_ptr++;
214
215    /* check if it should be sent to operating system for execution */
216    if (*line_ptr == '!') {
217        if (ss_info(sci_idx)->flags.escape_disabled)
218            return SS_ET_ESCAPE_DISABLED;
219        else {
220            line_ptr++;
221            return (system(line_ptr) < 0) ? errno : 0;
222        }
223    }
224
225    /* parse it */
226    argv = ss_parse(sci_idx, line_ptr, &argc);
227    if (argc == 0) {
228	free(argv);
229        return 0;
230    }
231
232    /* look it up in the request tables, execute if found */
233    ret = really_execute_command (sci_idx, argc, &argv);
234
235    free(argv);
236
237    return(ret);
238}
239