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