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