1 1.8 skrll /* $NetBSD: subr_optstr.c,v 1.8 2023/04/20 09:04:45 skrll Exp $ */ 2 1.1 jmmv 3 1.1 jmmv /*- 4 1.1 jmmv * Copyright (c) 2006 The NetBSD Foundation, Inc. 5 1.1 jmmv * All rights reserved. 6 1.1 jmmv * 7 1.1 jmmv * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jmmv * by Julio M. Merino Vidal. 9 1.1 jmmv * 10 1.1 jmmv * Redistribution and use in source and binary forms, with or without 11 1.1 jmmv * modification, are permitted provided that the following conditions 12 1.1 jmmv * are met: 13 1.1 jmmv * 1. Redistributions of source code must retain the above copyright 14 1.1 jmmv * notice, this list of conditions and the following disclaimer. 15 1.1 jmmv * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jmmv * notice, this list of conditions and the following disclaimer in the 17 1.1 jmmv * documentation and/or other materials provided with the distribution. 18 1.1 jmmv * 19 1.1 jmmv * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jmmv * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jmmv * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jmmv * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jmmv * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jmmv * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jmmv * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jmmv * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jmmv * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jmmv * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jmmv * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jmmv */ 31 1.1 jmmv 32 1.1 jmmv #include <sys/cdefs.h> 33 1.8 skrll __KERNEL_RCSID(0, "$NetBSD: subr_optstr.c,v 1.8 2023/04/20 09:04:45 skrll Exp $"); 34 1.1 jmmv 35 1.1 jmmv #include <sys/param.h> 36 1.1 jmmv #include <sys/optstr.h> 37 1.1 jmmv 38 1.1 jmmv /* --------------------------------------------------------------------- */ 39 1.1 jmmv 40 1.1 jmmv /* 41 1.1 jmmv * Given an options string of the form 'a=b c=d ... y=z' and a key, 42 1.1 jmmv * looks for the given key's value in the string and returns it in buf 43 1.4 thorpej * with a maximum of bufsize bytes. If the key is found, returns true; 44 1.1 jmmv * otherwise FALSE. 45 1.1 jmmv */ 46 1.8 skrll 47 1.8 skrll 48 1.8 skrll static bool 49 1.8 skrll optstr_get_pointer(const char *optstr, const char *key, const char **result) 50 1.1 jmmv { 51 1.7 skrll bool found = false; 52 1.1 jmmv 53 1.8 skrll /* Skip any initial spaces or tabs until we find a word. */ 54 1.8 skrll while (*optstr == ' ' || *optstr == '\t') 55 1.1 jmmv optstr++; 56 1.1 jmmv 57 1.1 jmmv /* Search for the given key within the option string. */ 58 1.1 jmmv while (!found && *optstr != '\0') { 59 1.2 jmmv const char *keyp; 60 1.2 jmmv 61 1.1 jmmv /* Check if the next word matches the key. */ 62 1.1 jmmv keyp = key; 63 1.1 jmmv while (*optstr == *keyp) { 64 1.1 jmmv optstr++; 65 1.1 jmmv keyp++; 66 1.1 jmmv } 67 1.1 jmmv 68 1.2 jmmv if (*optstr == '=' && *keyp == '\0') 69 1.4 thorpej found = true; 70 1.1 jmmv else { 71 1.1 jmmv /* Key not found; skip until next space. */ 72 1.1 jmmv while (*optstr != ' ' && *optstr != '\0') 73 1.1 jmmv optstr++; 74 1.1 jmmv 75 1.1 jmmv /* And now skip until next word. */ 76 1.6 martin while (*optstr == ' ') 77 1.1 jmmv optstr++; 78 1.1 jmmv } 79 1.1 jmmv } 80 1.1 jmmv 81 1.8 skrll if (found) { 82 1.8 skrll optstr++; /* Skip '='. */ 83 1.8 skrll *result = optstr; 84 1.8 skrll } 85 1.8 skrll 86 1.8 skrll return found; 87 1.8 skrll } 88 1.8 skrll 89 1.8 skrll bool 90 1.8 skrll optstr_get(const char *optstr, const char *key, char *buf, size_t bufsize) 91 1.8 skrll { 92 1.8 skrll const char *data; 93 1.8 skrll bool found = optstr_get_pointer(optstr, key, &data); 94 1.8 skrll 95 1.8 skrll /* If the key was found; copy its value to the target buffer. */ 96 1.8 skrll if (found) { 97 1.8 skrll const char *lastbuf = buf + (bufsize - 1); 98 1.8 skrll 99 1.8 skrll while (buf != lastbuf && *data != ' ' && *data != '\0') 100 1.8 skrll *buf++ = *data++; 101 1.8 skrll *buf = '\0'; 102 1.8 skrll } 103 1.8 skrll return found; 104 1.8 skrll } 105 1.8 skrll 106 1.8 skrll 107 1.8 skrll bool 108 1.8 skrll optstr_get_string(const char *optstr, const char *key, const char **result) 109 1.8 skrll { 110 1.8 skrll const char *data; 111 1.8 skrll const bool found = optstr_get_pointer(optstr, key, &data); 112 1.8 skrll 113 1.8 skrll /* If the key was found; copy its value to the target buffer. */ 114 1.8 skrll if (found) { 115 1.8 skrll *result = data; 116 1.8 skrll } 117 1.8 skrll return found; 118 1.8 skrll } 119 1.8 skrll 120 1.8 skrll bool 121 1.8 skrll optstr_get_number(const char *optstr, const char *key, unsigned long *result) 122 1.8 skrll { 123 1.8 skrll const char *data; 124 1.8 skrll const bool found = optstr_get_pointer(optstr, key, &data); 125 1.8 skrll 126 1.1 jmmv /* If the key was found; copy its value to the target buffer. */ 127 1.1 jmmv if (found) { 128 1.8 skrll char *ep; 129 1.8 skrll const unsigned long ulval = strtoul(data, &ep, 10); 130 1.8 skrll if (ep == data) 131 1.8 skrll return false; 132 1.8 skrll *result = ulval; 133 1.8 skrll return true; 134 1.8 skrll } 135 1.8 skrll return false; 136 1.8 skrll } 137 1.8 skrll 138 1.8 skrll bool 139 1.8 skrll optstr_get_number_hex(const char *optstr, const char *key, 140 1.8 skrll unsigned long *result) 141 1.8 skrll { 142 1.8 skrll const char *data; 143 1.8 skrll const bool found = optstr_get_pointer(optstr, key, &data); 144 1.8 skrll 145 1.8 skrll /* If the key was found; copy its value to the target buffer. */ 146 1.8 skrll if (found) { 147 1.8 skrll char *ep; 148 1.8 skrll const unsigned long ulval = strtoul(data, &ep, 16); 149 1.8 skrll if (ep == data) 150 1.8 skrll return false; 151 1.8 skrll *result = ulval; 152 1.8 skrll return true; 153 1.8 skrll } 154 1.8 skrll return false; 155 1.8 skrll } 156 1.1 jmmv 157 1.8 skrll bool 158 1.8 skrll optstr_get_number_binary(const char *optstr, const char *key, 159 1.8 skrll unsigned long *result) 160 1.8 skrll { 161 1.8 skrll const char *data; 162 1.8 skrll const bool found = optstr_get_pointer(optstr, key, &data); 163 1.1 jmmv 164 1.8 skrll /* If the key was found; copy its value to the target buffer. */ 165 1.8 skrll if (found) { 166 1.8 skrll char *ep; 167 1.8 skrll const unsigned long ulval = strtoul(data, &ep, 2); 168 1.8 skrll if (ep == data) 169 1.8 skrll return false; 170 1.8 skrll *result = ulval; 171 1.8 skrll return true; 172 1.1 jmmv } 173 1.8 skrll return false; 174 1.8 skrll } 175 1.1 jmmv 176 1.8 skrll 177 1.8 skrll #if NETHER > 0 178 1.8 skrll bool 179 1.8 skrll optstr_get_macaddr(const char *optstr, const char *key, 180 1.8 skrll uint8_t result[ETHER_ADDR_LEN]) 181 1.8 skrll { 182 1.8 skrll const char *data; 183 1.8 skrll const bool found = optstr_get_pointer(optstr, key, &data); 184 1.8 skrll 185 1.8 skrll /* If the key was found; copy its value to the target buffer. */ 186 1.8 skrll if (found) { 187 1.8 skrll uint8_t temp[ETHER_ADDR_LEN]; 188 1.8 skrll int error = ether_aton_r(temp, sizeof(temp), data); 189 1.8 skrll if (error) 190 1.8 skrll return false; 191 1.8 skrll memcpy(result, temp, sizeof(temp)); 192 1.8 skrll } 193 1.1 jmmv return found; 194 1.1 jmmv } 195 1.8 skrll #endif 196