xref: /freebsd/crypto/krb5/src/util/ss/execute_cmd.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
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(ss_request_table * rqtbl,int argc,char * argv[],int sci_idx)56 check_request_table(ss_request_table *rqtbl, int argc, char *argv[],
57                     int sci_idx)
58 {
59     ss_request_entry *request;
60     ss_data *info;
61     char const *const *name;
62     char *string = argv[0];
63     int i;
64 
65     info = ss_info(sci_idx);
66     info->argc = argc;
67     info->argv = argv;
68     for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
69         for (name = request->command_names; *name; name++)
70             if (!strcmp(*name, string)) {
71                 info->current_request = request->command_names[0];
72                 (request->function)(argc, (const char *const *) argv,
73                                     sci_idx,info->info_ptr);
74                 info->current_request = (char *)NULL;
75                 return(0);
76             }
77     }
78     return(SS_ET_COMMAND_NOT_FOUND);
79 }
80 
81 /*
82  * really_execute_command(sci_idx, argc, argv)
83  *
84  * Function:
85  *      Fills in the argc, argv values in the subsystem entry and
86  *      call the appropriate routine.
87  * Arguments:
88  *      sci_idx (int)
89  *              ss-internal index for subsystem control info structure
90  *      argc (int)
91  *              number of arguments in argument list
92  *      argv (char **[])
93  *              pointer to parsed argument list (may be reallocated
94  *              on abbrev expansion)
95  *
96  * Returns:
97  *      (int)
98  *              Zero if successful, ss_et_command_not_found otherwise.
99  * Notes:
100  */
101 
102 static int
really_execute_command(int sci_idx,int argc,char ** argv[])103 really_execute_command(int sci_idx, int argc, char **argv[])
104 {
105     ss_request_table **rqtbl;
106     ss_data *info;
107 
108     info = ss_info(sci_idx);
109 
110     for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
111         if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
112             return(0);
113     }
114     return(SS_ET_COMMAND_NOT_FOUND);
115 }
116 
117 /*
118  * ss_execute_command(sci_idx, argv)
119  *
120  * Function:
121  *      Executes a parsed command list within the subsystem.
122  * Arguments:
123  *      sci_idx (int)
124  *              ss-internal index for subsystem control info structure
125  *      argv (char *[])
126  *              parsed argument list
127  * Returns:
128  *      (int)
129  *              Zero if successful, ss_et_command_not_found otherwise.
130  * Notes:
131  */
132 
133 int
ss_execute_command(int sci_idx,char * argv[])134 ss_execute_command(int sci_idx, char *argv[])
135 {
136     unsigned int i, argc;
137     char **argp;
138     int ret;
139 
140     argc = 0;
141     for (argp = argv; *argp; argp++)
142         argc++;
143     argp = (char **)malloc((argc+1)*sizeof(char *));
144     if (argp == NULL)
145         return(ENOMEM);
146     for (i = 0; i <= argc; i++)
147         argp[i] = argv[i];
148     ret = really_execute_command(sci_idx, argc, &argp);
149     free(argp);
150     return(ret);
151 }
152 
153 /*
154  * ss_execute_line(sci_idx, line_ptr)
155  *
156  * Function:
157  *      Parses and executes a command line within a subsystem.
158  * Arguments:
159  *      sci_idx (int)
160  *              ss-internal index for subsystem control info structure
161  *      line_ptr (char *)
162  *              Pointer to command line to be parsed.
163  * Returns:
164  *      (int)
165  *              Error code.
166  * Notes:
167  */
168 
169 int
ss_execute_line(int sci_idx,char * line_ptr)170 ss_execute_line(int sci_idx, char *line_ptr)
171 {
172     char **argv;
173     int argc, ret;
174 
175     /* flush leading whitespace */
176     while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
177         line_ptr++;
178 
179     /* check if it should be sent to operating system for execution */
180     if (*line_ptr == '!') {
181         if (ss_info(sci_idx)->flags.escape_disabled)
182             return SS_ET_ESCAPE_DISABLED;
183         else {
184             line_ptr++;
185             system(line_ptr);
186             return 0;
187         }
188     }
189 
190     /* parse it */
191     argv = ss_parse(sci_idx, line_ptr, &argc);
192     if (argc == 0)
193         return 0;
194 
195     /* look it up in the request tables, execute if found */
196     ret = really_execute_command (sci_idx, argc, &argv);
197 
198     free(argv);
199 
200     return(ret);
201 }
202