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