xref: /aosp_15_r20/external/wpa_supplicant_8/src/common/cli.c (revision 03f9172ca588f91df233974f4258bab95191f931)
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