Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Samba utility functions
4 :
5 : Copyright (C) Andrew Tridgell 1992-2001
6 : Copyright (C) Simo Sorce 2001-2002
7 : Copyright (C) Martin Pool 2003
8 : Copyright (C) James Peach 2005
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "replace.h"
25 : #include "lib/util/samba_util.h"
26 : #include "system/locale.h"
27 : #include "smb_strtox.h"
28 : #undef strncasecmp
29 : #undef strcasemp
30 :
31 : /**
32 : * @file
33 : * @brief String utilities.
34 : **/
35 :
36 : /**
37 : * Parse a string containing a boolean value.
38 : *
39 : * val will be set to the read value.
40 : *
41 : * @retval true if a boolean value was parsed, false otherwise.
42 : */
43 0 : _PUBLIC_ bool conv_str_bool(const char * str, bool * val)
44 : {
45 0 : char * end = NULL;
46 0 : long lval;
47 :
48 0 : if (str == NULL || *str == '\0') {
49 0 : return false;
50 : }
51 :
52 0 : lval = strtol(str, &end, 10 /* base */);
53 0 : if (end == NULL || *end != '\0' || end == str) {
54 0 : return set_boolean(str, val);
55 : }
56 :
57 0 : *val = (lval) ? true : false;
58 0 : return true;
59 : }
60 :
61 : /**
62 : * Convert a size specification like 16K into an integral number of bytes.
63 : **/
64 196805 : _PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val)
65 : {
66 196805 : char * end = NULL;
67 4421 : unsigned long long lval;
68 196805 : int error = 0;
69 :
70 196805 : if (str == NULL || *str == '\0') {
71 0 : return false;
72 : }
73 :
74 196805 : lval = smb_strtoull(str, &end, 10, &error, SMB_STR_STANDARD);
75 196805 : if (error != 0) {
76 0 : return false;
77 : }
78 :
79 196805 : if (*end) {
80 44221 : if (strwicmp(end, "K") == 0) {
81 44221 : lval *= 1024ULL;
82 0 : } else if (strwicmp(end, "M") == 0) {
83 0 : lval *= (1024ULL * 1024ULL);
84 0 : } else if (strwicmp(end, "G") == 0) {
85 0 : lval *= (1024ULL * 1024ULL * 1024ULL);
86 0 : } else if (strwicmp(end, "T") == 0) {
87 0 : lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
88 0 : } else if (strwicmp(end, "P") == 0) {
89 0 : lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
90 : } else {
91 0 : return false;
92 : }
93 : }
94 :
95 196805 : *val = (uint64_t)lval;
96 196805 : return true;
97 : }
98 :
99 : /**
100 : * Parse a uint64_t value from a string
101 : *
102 : * val will be set to the value read.
103 : *
104 : * @retval true if parsing was successful, false otherwise
105 : */
106 22 : _PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val)
107 : {
108 6 : unsigned long long lval;
109 22 : int error = 0;
110 :
111 22 : if (str == NULL || *str == '\0') {
112 0 : return false;
113 : }
114 :
115 22 : lval = smb_strtoull(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
116 22 : if (error != 0) {
117 0 : return false;
118 : }
119 :
120 20 : *val = (uint64_t)lval;
121 20 : return true;
122 : }
123 :
124 : /**
125 : * Compare 2 strings.
126 : *
127 : * @note The comparison is case-insensitive.
128 : **/
129 265883264 : _PUBLIC_ bool strequal(const char *s1, const char *s2)
130 : {
131 265883264 : if (s1 == s2)
132 622797 : return true;
133 265249593 : if (!s1 || !s2)
134 6119111 : return false;
135 :
136 259112833 : return strcasecmp_m(s1,s2) == 0;
137 : }
138 :
139 : /**
140 : * @file
141 : * @brief String utilities.
142 : **/
143 :
144 14313858 : static bool next_token_internal_talloc(TALLOC_CTX *ctx,
145 : const char **ptr,
146 : char **pp_buff,
147 : const char *sep,
148 : bool ltrim)
149 : {
150 84063 : const char *s;
151 84063 : const char *saved_s;
152 84063 : char *pbuf;
153 84063 : bool quoted;
154 14313858 : size_t len=1;
155 :
156 14313858 : *pp_buff = NULL;
157 14313858 : if (!ptr) {
158 0 : return(false);
159 : }
160 :
161 14313858 : s = *ptr;
162 :
163 : /* default to simple separators */
164 14313858 : if (!sep) {
165 60333 : sep = " \t\n\r";
166 : }
167 :
168 : /* find the first non sep char, if left-trimming is requested */
169 14313858 : if (ltrim) {
170 14375006 : while (*s && strchr_m(sep,*s)) {
171 64138 : s++;
172 : }
173 : }
174 :
175 : /* nothing left? */
176 14313858 : if (!*s) {
177 3792119 : return false;
178 : }
179 :
180 : /* When restarting we need to go from here. */
181 10437676 : saved_s = s;
182 :
183 : /* Work out the length needed. */
184 142064444 : for (quoted = false; *s &&
185 269280213 : (quoted || !strchr_m(sep,*s)); s++) {
186 131563588 : if (*s == '\"') {
187 79762 : quoted = !quoted;
188 : } else {
189 131483826 : len++;
190 : }
191 : }
192 :
193 : /* We started with len = 1 so we have space for the nul. */
194 10500856 : *pp_buff = talloc_array(ctx, char, len);
195 10500856 : if (!*pp_buff) {
196 0 : return false;
197 : }
198 :
199 : /* copy over the token */
200 10437676 : pbuf = *pp_buff;
201 10437676 : s = saved_s;
202 142064444 : for (quoted = false; *s &&
203 269280213 : (quoted || !strchr_m(sep,*s)); s++) {
204 131563588 : if ( *s == '\"' ) {
205 79762 : quoted = !quoted;
206 : } else {
207 131483826 : *pbuf++ = *s;
208 : }
209 : }
210 :
211 10500856 : *ptr = (*s) ? s+1 : s;
212 10500856 : *pbuf = 0;
213 :
214 10500856 : return true;
215 : }
216 :
217 14310868 : bool next_token_talloc(TALLOC_CTX *ctx,
218 : const char **ptr,
219 : char **pp_buff,
220 : const char *sep)
221 : {
222 14310868 : return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
223 : }
224 :
225 : /*
226 : * Get the next token from a string, return false if none found. Handles
227 : * double-quotes. This version does not trim leading separator characters
228 : * before looking for a token.
229 : */
230 :
231 2990 : bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
232 : const char **ptr,
233 : char **pp_buff,
234 : const char *sep)
235 : {
236 2990 : return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
237 : }
238 :
239 : /**
240 : * Get the next token from a string, return False if none found.
241 : * Handles double-quotes.
242 : *
243 : * Based on a routine by GJC@VILLAGE.COM.
244 : * Extensively modified by Andrew.Tridgell@anu.edu.au
245 : **/
246 2184 : _PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
247 : {
248 16 : const char *s;
249 16 : bool quoted;
250 2184 : size_t len=1;
251 :
252 2184 : if (!ptr)
253 0 : return false;
254 :
255 2183 : s = *ptr;
256 :
257 : /* default to simple separators */
258 2183 : if (!sep)
259 4 : sep = " \t\n\r";
260 :
261 : /* find the first non sep char */
262 2187 : while (*s && strchr_m(sep,*s))
263 4 : s++;
264 :
265 : /* nothing left? */
266 2183 : if (!*s)
267 104 : return false;
268 :
269 : /* copy over the token */
270 65505 : for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
271 63431 : if (*s == '\"') {
272 3 : quoted = !quoted;
273 : } else {
274 63428 : len++;
275 63428 : *buff++ = *s;
276 : }
277 : }
278 :
279 2074 : *ptr = (*s) ? s+1 : s;
280 2074 : *buff = 0;
281 :
282 2074 : return true;
283 : }
284 :
285 : /**
286 : Set a boolean variable from the text value stored in the passed string.
287 : Returns true in success, false if the passed string does not correctly
288 : represent a boolean.
289 : **/
290 :
291 5667454 : _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean)
292 : {
293 8130506 : if (strwicmp(boolean_string, "yes") == 0 ||
294 3971928 : strwicmp(boolean_string, "true") == 0 ||
295 3017752 : strwicmp(boolean_string, "on") == 0 ||
296 1508876 : strwicmp(boolean_string, "1") == 0) {
297 4158584 : *boolean = true;
298 4158584 : return true;
299 1686871 : } else if (strwicmp(boolean_string, "no") == 0 ||
300 178001 : strwicmp(boolean_string, "false") == 0 ||
301 0 : strwicmp(boolean_string, "off") == 0 ||
302 0 : strwicmp(boolean_string, "0") == 0) {
303 1508870 : *boolean = false;
304 1508870 : return true;
305 : }
306 0 : return false;
307 : }
|