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