1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker * Common hostapd/wpa_supplicant command line interface functions
3*03f9172cSAndroid Build Coastguard Worker * Copyright (c) 2004-2016, Jouni Malinen <[email protected]>
4*03f9172cSAndroid Build Coastguard Worker *
5*03f9172cSAndroid Build Coastguard Worker * This software may be distributed under the terms of the BSD license.
6*03f9172cSAndroid Build Coastguard Worker * See README for more details.
7*03f9172cSAndroid Build Coastguard Worker */
8*03f9172cSAndroid Build Coastguard Worker
9*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
10*03f9172cSAndroid Build Coastguard Worker
11*03f9172cSAndroid Build Coastguard Worker #include "utils/common.h"
12*03f9172cSAndroid Build Coastguard Worker #include "common/cli.h"
13*03f9172cSAndroid Build Coastguard Worker
14*03f9172cSAndroid Build Coastguard Worker
15*03f9172cSAndroid Build Coastguard Worker const char *const cli_license =
16*03f9172cSAndroid Build Coastguard Worker "This software may be distributed under the terms of the BSD license.\n"
17*03f9172cSAndroid Build Coastguard Worker "See README for more details.\n";
18*03f9172cSAndroid Build Coastguard Worker
19*03f9172cSAndroid Build Coastguard Worker const char *const cli_full_license =
20*03f9172cSAndroid Build Coastguard Worker "This software may be distributed under the terms of the BSD license.\n"
21*03f9172cSAndroid Build Coastguard Worker "\n"
22*03f9172cSAndroid Build Coastguard Worker "Redistribution and use in source and binary forms, with or without\n"
23*03f9172cSAndroid Build Coastguard Worker "modification, are permitted provided that the following conditions are\n"
24*03f9172cSAndroid Build Coastguard Worker "met:\n"
25*03f9172cSAndroid Build Coastguard Worker "\n"
26*03f9172cSAndroid Build Coastguard Worker "1. Redistributions of source code must retain the above copyright\n"
27*03f9172cSAndroid Build Coastguard Worker " notice, this list of conditions and the following disclaimer.\n"
28*03f9172cSAndroid Build Coastguard Worker "\n"
29*03f9172cSAndroid Build Coastguard Worker "2. Redistributions in binary form must reproduce the above copyright\n"
30*03f9172cSAndroid Build Coastguard Worker " notice, this list of conditions and the following disclaimer in the\n"
31*03f9172cSAndroid Build Coastguard Worker " documentation and/or other materials provided with the distribution.\n"
32*03f9172cSAndroid Build Coastguard Worker "\n"
33*03f9172cSAndroid Build Coastguard Worker "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
34*03f9172cSAndroid Build Coastguard Worker " names of its contributors may be used to endorse or promote products\n"
35*03f9172cSAndroid Build Coastguard Worker " derived from this software without specific prior written permission.\n"
36*03f9172cSAndroid Build Coastguard Worker "\n"
37*03f9172cSAndroid Build Coastguard Worker "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
38*03f9172cSAndroid Build Coastguard Worker "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
39*03f9172cSAndroid Build Coastguard Worker "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
40*03f9172cSAndroid Build Coastguard Worker "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
41*03f9172cSAndroid Build Coastguard Worker "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
42*03f9172cSAndroid Build Coastguard Worker "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
43*03f9172cSAndroid Build Coastguard Worker "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
44*03f9172cSAndroid Build Coastguard Worker "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
45*03f9172cSAndroid Build Coastguard Worker "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
46*03f9172cSAndroid Build Coastguard Worker "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
47*03f9172cSAndroid Build Coastguard Worker "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
48*03f9172cSAndroid Build Coastguard Worker "\n";
49*03f9172cSAndroid Build Coastguard Worker
50*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_free(struct cli_txt_entry * e)51*03f9172cSAndroid Build Coastguard Worker void cli_txt_list_free(struct cli_txt_entry *e)
52*03f9172cSAndroid Build Coastguard Worker {
53*03f9172cSAndroid Build Coastguard Worker dl_list_del(&e->list);
54*03f9172cSAndroid Build Coastguard Worker os_free(e->txt);
55*03f9172cSAndroid Build Coastguard Worker os_free(e);
56*03f9172cSAndroid Build Coastguard Worker }
57*03f9172cSAndroid Build Coastguard Worker
58*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_flush(struct dl_list * list)59*03f9172cSAndroid Build Coastguard Worker void cli_txt_list_flush(struct dl_list *list)
60*03f9172cSAndroid Build Coastguard Worker {
61*03f9172cSAndroid Build Coastguard Worker struct cli_txt_entry *e;
62*03f9172cSAndroid Build Coastguard Worker
63*03f9172cSAndroid Build Coastguard Worker while ((e = dl_list_first(list, struct cli_txt_entry, list)))
64*03f9172cSAndroid Build Coastguard Worker cli_txt_list_free(e);
65*03f9172cSAndroid Build Coastguard Worker }
66*03f9172cSAndroid Build Coastguard Worker
67*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_get(struct dl_list * txt_list,const char * txt)68*03f9172cSAndroid Build Coastguard Worker struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
69*03f9172cSAndroid Build Coastguard Worker const char *txt)
70*03f9172cSAndroid Build Coastguard Worker {
71*03f9172cSAndroid Build Coastguard Worker struct cli_txt_entry *e;
72*03f9172cSAndroid Build Coastguard Worker
73*03f9172cSAndroid Build Coastguard Worker dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
74*03f9172cSAndroid Build Coastguard Worker if (os_strcmp(e->txt, txt) == 0)
75*03f9172cSAndroid Build Coastguard Worker return e;
76*03f9172cSAndroid Build Coastguard Worker }
77*03f9172cSAndroid Build Coastguard Worker return NULL;
78*03f9172cSAndroid Build Coastguard Worker }
79*03f9172cSAndroid Build Coastguard Worker
80*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_del(struct dl_list * txt_list,const char * txt)81*03f9172cSAndroid Build Coastguard Worker void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
82*03f9172cSAndroid Build Coastguard Worker {
83*03f9172cSAndroid Build Coastguard Worker struct cli_txt_entry *e;
84*03f9172cSAndroid Build Coastguard Worker
85*03f9172cSAndroid Build Coastguard Worker e = cli_txt_list_get(txt_list, txt);
86*03f9172cSAndroid Build Coastguard Worker if (e)
87*03f9172cSAndroid Build Coastguard Worker cli_txt_list_free(e);
88*03f9172cSAndroid Build Coastguard Worker }
89*03f9172cSAndroid Build Coastguard Worker
90*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_del_addr(struct dl_list * txt_list,const char * txt)91*03f9172cSAndroid Build Coastguard Worker void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
92*03f9172cSAndroid Build Coastguard Worker {
93*03f9172cSAndroid Build Coastguard Worker u8 addr[ETH_ALEN];
94*03f9172cSAndroid Build Coastguard Worker char buf[18];
95*03f9172cSAndroid Build Coastguard Worker
96*03f9172cSAndroid Build Coastguard Worker if (hwaddr_aton(txt, addr) < 0)
97*03f9172cSAndroid Build Coastguard Worker return;
98*03f9172cSAndroid Build Coastguard Worker os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
99*03f9172cSAndroid Build Coastguard Worker cli_txt_list_del(txt_list, buf);
100*03f9172cSAndroid Build Coastguard Worker }
101*03f9172cSAndroid Build Coastguard Worker
102*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_del_word(struct dl_list * txt_list,const char * txt,int separator)103*03f9172cSAndroid Build Coastguard Worker void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt,
104*03f9172cSAndroid Build Coastguard Worker int separator)
105*03f9172cSAndroid Build Coastguard Worker {
106*03f9172cSAndroid Build Coastguard Worker const char *end;
107*03f9172cSAndroid Build Coastguard Worker char *buf;
108*03f9172cSAndroid Build Coastguard Worker
109*03f9172cSAndroid Build Coastguard Worker end = os_strchr(txt, separator);
110*03f9172cSAndroid Build Coastguard Worker if (end == NULL)
111*03f9172cSAndroid Build Coastguard Worker end = txt + os_strlen(txt);
112*03f9172cSAndroid Build Coastguard Worker buf = dup_binstr(txt, end - txt);
113*03f9172cSAndroid Build Coastguard Worker if (buf == NULL)
114*03f9172cSAndroid Build Coastguard Worker return;
115*03f9172cSAndroid Build Coastguard Worker cli_txt_list_del(txt_list, buf);
116*03f9172cSAndroid Build Coastguard Worker os_free(buf);
117*03f9172cSAndroid Build Coastguard Worker }
118*03f9172cSAndroid Build Coastguard Worker
119*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_add(struct dl_list * txt_list,const char * txt)120*03f9172cSAndroid Build Coastguard Worker int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
121*03f9172cSAndroid Build Coastguard Worker {
122*03f9172cSAndroid Build Coastguard Worker struct cli_txt_entry *e;
123*03f9172cSAndroid Build Coastguard Worker
124*03f9172cSAndroid Build Coastguard Worker e = cli_txt_list_get(txt_list, txt);
125*03f9172cSAndroid Build Coastguard Worker if (e)
126*03f9172cSAndroid Build Coastguard Worker return 0;
127*03f9172cSAndroid Build Coastguard Worker e = os_zalloc(sizeof(*e));
128*03f9172cSAndroid Build Coastguard Worker if (e == NULL)
129*03f9172cSAndroid Build Coastguard Worker return -1;
130*03f9172cSAndroid Build Coastguard Worker e->txt = os_strdup(txt);
131*03f9172cSAndroid Build Coastguard Worker if (e->txt == NULL) {
132*03f9172cSAndroid Build Coastguard Worker os_free(e);
133*03f9172cSAndroid Build Coastguard Worker return -1;
134*03f9172cSAndroid Build Coastguard Worker }
135*03f9172cSAndroid Build Coastguard Worker dl_list_add(txt_list, &e->list);
136*03f9172cSAndroid Build Coastguard Worker return 0;
137*03f9172cSAndroid Build Coastguard Worker }
138*03f9172cSAndroid Build Coastguard Worker
139*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_add_addr(struct dl_list * txt_list,const char * txt)140*03f9172cSAndroid Build Coastguard Worker int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
141*03f9172cSAndroid Build Coastguard Worker {
142*03f9172cSAndroid Build Coastguard Worker u8 addr[ETH_ALEN];
143*03f9172cSAndroid Build Coastguard Worker char buf[18];
144*03f9172cSAndroid Build Coastguard Worker
145*03f9172cSAndroid Build Coastguard Worker if (hwaddr_aton(txt, addr) < 0)
146*03f9172cSAndroid Build Coastguard Worker return -1;
147*03f9172cSAndroid Build Coastguard Worker os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
148*03f9172cSAndroid Build Coastguard Worker return cli_txt_list_add(txt_list, buf);
149*03f9172cSAndroid Build Coastguard Worker }
150*03f9172cSAndroid Build Coastguard Worker
151*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_add_word(struct dl_list * txt_list,const char * txt,int separator)152*03f9172cSAndroid Build Coastguard Worker int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt,
153*03f9172cSAndroid Build Coastguard Worker int separator)
154*03f9172cSAndroid Build Coastguard Worker {
155*03f9172cSAndroid Build Coastguard Worker const char *end;
156*03f9172cSAndroid Build Coastguard Worker char *buf;
157*03f9172cSAndroid Build Coastguard Worker int ret;
158*03f9172cSAndroid Build Coastguard Worker
159*03f9172cSAndroid Build Coastguard Worker end = os_strchr(txt, separator);
160*03f9172cSAndroid Build Coastguard Worker if (end == NULL)
161*03f9172cSAndroid Build Coastguard Worker end = txt + os_strlen(txt);
162*03f9172cSAndroid Build Coastguard Worker buf = dup_binstr(txt, end - txt);
163*03f9172cSAndroid Build Coastguard Worker if (buf == NULL)
164*03f9172cSAndroid Build Coastguard Worker return -1;
165*03f9172cSAndroid Build Coastguard Worker ret = cli_txt_list_add(txt_list, buf);
166*03f9172cSAndroid Build Coastguard Worker os_free(buf);
167*03f9172cSAndroid Build Coastguard Worker return ret;
168*03f9172cSAndroid Build Coastguard Worker }
169*03f9172cSAndroid Build Coastguard Worker
170*03f9172cSAndroid Build Coastguard Worker
cli_txt_list_array(struct dl_list * txt_list)171*03f9172cSAndroid Build Coastguard Worker char ** cli_txt_list_array(struct dl_list *txt_list)
172*03f9172cSAndroid Build Coastguard Worker {
173*03f9172cSAndroid Build Coastguard Worker unsigned int i, count = dl_list_len(txt_list);
174*03f9172cSAndroid Build Coastguard Worker char **res;
175*03f9172cSAndroid Build Coastguard Worker struct cli_txt_entry *e;
176*03f9172cSAndroid Build Coastguard Worker
177*03f9172cSAndroid Build Coastguard Worker res = os_calloc(count + 1, sizeof(char *));
178*03f9172cSAndroid Build Coastguard Worker if (res == NULL)
179*03f9172cSAndroid Build Coastguard Worker return NULL;
180*03f9172cSAndroid Build Coastguard Worker
181*03f9172cSAndroid Build Coastguard Worker i = 0;
182*03f9172cSAndroid Build Coastguard Worker dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
183*03f9172cSAndroid Build Coastguard Worker res[i] = os_strdup(e->txt);
184*03f9172cSAndroid Build Coastguard Worker if (res[i] == NULL)
185*03f9172cSAndroid Build Coastguard Worker break;
186*03f9172cSAndroid Build Coastguard Worker i++;
187*03f9172cSAndroid Build Coastguard Worker }
188*03f9172cSAndroid Build Coastguard Worker
189*03f9172cSAndroid Build Coastguard Worker return res;
190*03f9172cSAndroid Build Coastguard Worker }
191*03f9172cSAndroid Build Coastguard Worker
192*03f9172cSAndroid Build Coastguard Worker
get_cmd_arg_num(const char * str,int pos)193*03f9172cSAndroid Build Coastguard Worker int get_cmd_arg_num(const char *str, int pos)
194*03f9172cSAndroid Build Coastguard Worker {
195*03f9172cSAndroid Build Coastguard Worker int arg = 0, i;
196*03f9172cSAndroid Build Coastguard Worker
197*03f9172cSAndroid Build Coastguard Worker for (i = 0; i <= pos; i++) {
198*03f9172cSAndroid Build Coastguard Worker if (str[i] != ' ') {
199*03f9172cSAndroid Build Coastguard Worker arg++;
200*03f9172cSAndroid Build Coastguard Worker while (i <= pos && str[i] != ' ')
201*03f9172cSAndroid Build Coastguard Worker i++;
202*03f9172cSAndroid Build Coastguard Worker }
203*03f9172cSAndroid Build Coastguard Worker }
204*03f9172cSAndroid Build Coastguard Worker
205*03f9172cSAndroid Build Coastguard Worker if (arg > 0)
206*03f9172cSAndroid Build Coastguard Worker arg--;
207*03f9172cSAndroid Build Coastguard Worker return arg;
208*03f9172cSAndroid Build Coastguard Worker }
209*03f9172cSAndroid Build Coastguard Worker
210*03f9172cSAndroid Build Coastguard Worker
write_cmd(char * buf,size_t buflen,const char * cmd,int argc,char * argv[])211*03f9172cSAndroid Build Coastguard Worker int write_cmd(char *buf, size_t buflen, const char *cmd, int argc, char *argv[])
212*03f9172cSAndroid Build Coastguard Worker {
213*03f9172cSAndroid Build Coastguard Worker int i, res;
214*03f9172cSAndroid Build Coastguard Worker char *pos, *end;
215*03f9172cSAndroid Build Coastguard Worker
216*03f9172cSAndroid Build Coastguard Worker pos = buf;
217*03f9172cSAndroid Build Coastguard Worker end = buf + buflen;
218*03f9172cSAndroid Build Coastguard Worker
219*03f9172cSAndroid Build Coastguard Worker res = os_snprintf(pos, end - pos, "%s", cmd);
220*03f9172cSAndroid Build Coastguard Worker if (os_snprintf_error(end - pos, res))
221*03f9172cSAndroid Build Coastguard Worker goto fail;
222*03f9172cSAndroid Build Coastguard Worker pos += res;
223*03f9172cSAndroid Build Coastguard Worker
224*03f9172cSAndroid Build Coastguard Worker for (i = 0; i < argc; i++) {
225*03f9172cSAndroid Build Coastguard Worker res = os_snprintf(pos, end - pos, " %s", argv[i]);
226*03f9172cSAndroid Build Coastguard Worker if (os_snprintf_error(end - pos, res))
227*03f9172cSAndroid Build Coastguard Worker goto fail;
228*03f9172cSAndroid Build Coastguard Worker pos += res;
229*03f9172cSAndroid Build Coastguard Worker }
230*03f9172cSAndroid Build Coastguard Worker
231*03f9172cSAndroid Build Coastguard Worker buf[buflen - 1] = '\0';
232*03f9172cSAndroid Build Coastguard Worker return 0;
233*03f9172cSAndroid Build Coastguard Worker
234*03f9172cSAndroid Build Coastguard Worker fail:
235*03f9172cSAndroid Build Coastguard Worker printf("Too long command\n");
236*03f9172cSAndroid Build Coastguard Worker return -1;
237*03f9172cSAndroid Build Coastguard Worker }
238*03f9172cSAndroid Build Coastguard Worker
239*03f9172cSAndroid Build Coastguard Worker
tokenize_cmd(char * cmd,char * argv[])240*03f9172cSAndroid Build Coastguard Worker int tokenize_cmd(char *cmd, char *argv[])
241*03f9172cSAndroid Build Coastguard Worker {
242*03f9172cSAndroid Build Coastguard Worker char *pos;
243*03f9172cSAndroid Build Coastguard Worker int argc = 0;
244*03f9172cSAndroid Build Coastguard Worker
245*03f9172cSAndroid Build Coastguard Worker pos = cmd;
246*03f9172cSAndroid Build Coastguard Worker for (;;) {
247*03f9172cSAndroid Build Coastguard Worker while (*pos == ' ')
248*03f9172cSAndroid Build Coastguard Worker pos++;
249*03f9172cSAndroid Build Coastguard Worker if (*pos == '\0')
250*03f9172cSAndroid Build Coastguard Worker break;
251*03f9172cSAndroid Build Coastguard Worker argv[argc] = pos;
252*03f9172cSAndroid Build Coastguard Worker argc++;
253*03f9172cSAndroid Build Coastguard Worker if (argc == max_args)
254*03f9172cSAndroid Build Coastguard Worker break;
255*03f9172cSAndroid Build Coastguard Worker if (*pos == '"') {
256*03f9172cSAndroid Build Coastguard Worker char *pos2 = os_strrchr(pos, '"');
257*03f9172cSAndroid Build Coastguard Worker if (pos2)
258*03f9172cSAndroid Build Coastguard Worker pos = pos2 + 1;
259*03f9172cSAndroid Build Coastguard Worker }
260*03f9172cSAndroid Build Coastguard Worker while (*pos != '\0' && *pos != ' ')
261*03f9172cSAndroid Build Coastguard Worker pos++;
262*03f9172cSAndroid Build Coastguard Worker if (*pos == ' ')
263*03f9172cSAndroid Build Coastguard Worker *pos++ = '\0';
264*03f9172cSAndroid Build Coastguard Worker }
265*03f9172cSAndroid Build Coastguard Worker
266*03f9172cSAndroid Build Coastguard Worker return argc;
267*03f9172cSAndroid Build Coastguard Worker }
268