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