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