execute_cmd.c revision d1154eb460efe588eaed3d439c1caaca149fa362
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
21extern int errno;
22#endif
23#include "ss_internal.h"
24#include <stdio.h>
25
26static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc,
27					  char *argv[], int sci_idx));
28static 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 */
51static 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
85static 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
138static 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
171int ss_execute_command(sci_idx, argv)
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
205int ss_execute_line (sci_idx, line_ptr)
206    int sci_idx;
207    char *line_ptr;
208{
209    char **argv;
210    int argc, ret;
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++;
222            return (system(line_ptr) < 0) ? errno : 0;
223        }
224    }
225
226    /* parse it */
227    argv = ss_parse(sci_idx, line_ptr, &argc);
228    if (argc == 0) {
229	free(argv);
230        return 0;
231    }
232
233    /* look it up in the request tables, execute if found */
234    ret = really_execute_command (sci_idx, argc, &argv);
235
236    free(argv);
237
238    return(ret);
239}
240