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