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