Line data Source code
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 :
51 0 : void cli_txt_list_free(struct cli_txt_entry *e)
52 : {
53 0 : dl_list_del(&e->list);
54 0 : os_free(e->txt);
55 0 : os_free(e);
56 0 : }
57 :
58 :
59 0 : void cli_txt_list_flush(struct dl_list *list)
60 : {
61 : struct cli_txt_entry *e;
62 :
63 0 : while ((e = dl_list_first(list, struct cli_txt_entry, list)))
64 0 : cli_txt_list_free(e);
65 0 : }
66 :
67 :
68 0 : 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 0 : dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
74 0 : if (os_strcmp(e->txt, txt) == 0)
75 0 : return e;
76 : }
77 0 : return NULL;
78 : }
79 :
80 :
81 0 : void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
82 : {
83 : struct cli_txt_entry *e;
84 :
85 0 : e = cli_txt_list_get(txt_list, txt);
86 0 : if (e)
87 0 : cli_txt_list_free(e);
88 0 : }
89 :
90 :
91 0 : 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 0 : if (hwaddr_aton(txt, addr) < 0)
97 0 : return;
98 0 : os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
99 0 : cli_txt_list_del(txt_list, buf);
100 : }
101 :
102 :
103 0 : 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 0 : end = os_strchr(txt, separator);
110 0 : if (end == NULL)
111 0 : end = txt + os_strlen(txt);
112 0 : buf = dup_binstr(txt, end - txt);
113 0 : if (buf == NULL)
114 0 : return;
115 0 : cli_txt_list_del(txt_list, buf);
116 0 : os_free(buf);
117 : }
118 :
119 :
120 0 : int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
121 : {
122 : struct cli_txt_entry *e;
123 :
124 0 : e = cli_txt_list_get(txt_list, txt);
125 0 : if (e)
126 0 : return 0;
127 0 : e = os_zalloc(sizeof(*e));
128 0 : if (e == NULL)
129 0 : return -1;
130 0 : e->txt = os_strdup(txt);
131 0 : if (e->txt == NULL) {
132 0 : os_free(e);
133 0 : return -1;
134 : }
135 0 : dl_list_add(txt_list, &e->list);
136 0 : return 0;
137 : }
138 :
139 :
140 0 : 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 0 : if (hwaddr_aton(txt, addr) < 0)
146 0 : return -1;
147 0 : os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
148 0 : return cli_txt_list_add(txt_list, buf);
149 : }
150 :
151 :
152 0 : 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 0 : end = os_strchr(txt, separator);
160 0 : if (end == NULL)
161 0 : end = txt + os_strlen(txt);
162 0 : buf = dup_binstr(txt, end - txt);
163 0 : if (buf == NULL)
164 0 : return -1;
165 0 : ret = cli_txt_list_add(txt_list, buf);
166 0 : os_free(buf);
167 0 : return ret;
168 : }
169 :
170 :
171 0 : char ** cli_txt_list_array(struct dl_list *txt_list)
172 : {
173 0 : unsigned int i, count = dl_list_len(txt_list);
174 : char **res;
175 : struct cli_txt_entry *e;
176 :
177 0 : res = os_calloc(count + 1, sizeof(char *));
178 0 : if (res == NULL)
179 0 : return NULL;
180 :
181 0 : i = 0;
182 0 : dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
183 0 : res[i] = os_strdup(e->txt);
184 0 : if (res[i] == NULL)
185 0 : break;
186 0 : i++;
187 : }
188 :
189 0 : return res;
190 : }
191 :
192 :
193 0 : int get_cmd_arg_num(const char *str, int pos)
194 : {
195 0 : int arg = 0, i;
196 :
197 0 : for (i = 0; i <= pos; i++) {
198 0 : if (str[i] != ' ') {
199 0 : arg++;
200 0 : while (i <= pos && str[i] != ' ')
201 0 : i++;
202 : }
203 : }
204 :
205 0 : if (arg > 0)
206 0 : arg--;
207 0 : return arg;
208 : }
209 :
210 :
211 0 : 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 0 : pos = buf;
217 0 : end = buf + buflen;
218 :
219 0 : res = os_snprintf(pos, end - pos, "%s", cmd);
220 0 : if (os_snprintf_error(end - pos, res))
221 0 : goto fail;
222 0 : pos += res;
223 :
224 0 : for (i = 0; i < argc; i++) {
225 0 : res = os_snprintf(pos, end - pos, " %s", argv[i]);
226 0 : if (os_snprintf_error(end - pos, res))
227 0 : goto fail;
228 0 : pos += res;
229 : }
230 :
231 0 : buf[buflen - 1] = '\0';
232 0 : return 0;
233 :
234 : fail:
235 0 : printf("Too long command\n");
236 0 : return -1;
237 : }
238 :
239 :
240 0 : int tokenize_cmd(char *cmd, char *argv[])
241 : {
242 : char *pos;
243 0 : int argc = 0;
244 :
245 0 : pos = cmd;
246 : for (;;) {
247 0 : while (*pos == ' ')
248 0 : pos++;
249 0 : if (*pos == '\0')
250 0 : break;
251 0 : argv[argc] = pos;
252 0 : argc++;
253 0 : if (argc == max_args)
254 0 : break;
255 0 : if (*pos == '"') {
256 0 : char *pos2 = os_strrchr(pos, '"');
257 0 : if (pos2)
258 0 : pos = pos2 + 1;
259 : }
260 0 : while (*pos != '\0' && *pos != ' ')
261 0 : pos++;
262 0 : if (*pos == ' ')
263 0 : *pos++ = '\0';
264 0 : }
265 :
266 0 : return argc;
267 : }
|