/src/samba/lib/util/util_str.c
Line | Count | Source |
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 | | _PUBLIC_ bool conv_str_bool(const char * str, bool * val) |
44 | 0 | { |
45 | 0 | char * end = NULL; |
46 | 0 | long lval; |
47 | |
|
48 | 0 | if (str == NULL || *str == '\0') { |
49 | 0 | return false; |
50 | 0 | } |
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 | 0 | } |
56 | | |
57 | 0 | *val = (lval) ? true : false; |
58 | 0 | return true; |
59 | 0 | } |
60 | | |
61 | | /** |
62 | | * Convert a size specification like 16K into an integral number of bytes. |
63 | | **/ |
64 | | _PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val) |
65 | 0 | { |
66 | 0 | char * end = NULL; |
67 | 0 | unsigned long long lval; |
68 | 0 | int error = 0; |
69 | |
|
70 | 0 | if (str == NULL || *str == '\0') { |
71 | 0 | return false; |
72 | 0 | } |
73 | | |
74 | 0 | lval = smb_strtoull(str, &end, 10, &error, SMB_STR_STANDARD); |
75 | 0 | if (error != 0) { |
76 | 0 | return false; |
77 | 0 | } |
78 | | |
79 | 0 | if (*end) { |
80 | 0 | if (strwicmp(end, "K") == 0) { |
81 | 0 | 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 | 0 | } else { |
91 | 0 | return false; |
92 | 0 | } |
93 | 0 | } |
94 | | |
95 | 0 | *val = (uint64_t)lval; |
96 | 0 | return true; |
97 | 0 | } |
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 | | _PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val) |
107 | 0 | { |
108 | 0 | unsigned long long lval; |
109 | 0 | int error = 0; |
110 | |
|
111 | 0 | if (str == NULL || *str == '\0') { |
112 | 0 | return false; |
113 | 0 | } |
114 | | |
115 | 0 | lval = smb_strtoull(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV); |
116 | 0 | if (error != 0) { |
117 | 0 | return false; |
118 | 0 | } |
119 | | |
120 | 0 | *val = (uint64_t)lval; |
121 | 0 | return true; |
122 | 0 | } |
123 | | |
124 | | /** |
125 | | * Compare 2 strings. |
126 | | * |
127 | | * @note The comparison is case-insensitive. |
128 | | **/ |
129 | | _PUBLIC_ bool strequal(const char *s1, const char *s2) |
130 | 605 | { |
131 | 605 | if (s1 == s2) |
132 | 0 | return true; |
133 | 605 | if (!s1 || !s2) |
134 | 0 | return false; |
135 | | |
136 | 605 | return strcasecmp_m(s1,s2) == 0; |
137 | 605 | } |
138 | | |
139 | | /** |
140 | | * @file |
141 | | * @brief String utilities. |
142 | | **/ |
143 | | |
144 | | /** |
145 | | * Get the next token from a string, return False if none found. |
146 | | * Handles double-quotes. |
147 | | * |
148 | | * Based on a routine by GJC@VILLAGE.COM. |
149 | | * Extensively modified by Andrew.Tridgell@anu.edu.au |
150 | | **/ |
151 | | |
152 | | static bool next_token_internal_talloc(TALLOC_CTX *ctx, |
153 | | const char **ptr, |
154 | | char **pp_buff, |
155 | | const char *sep, |
156 | | bool ltrim) |
157 | 10.1k | { |
158 | 10.1k | const char *s; |
159 | 10.1k | const char *saved_s; |
160 | 10.1k | char *pbuf; |
161 | 10.1k | bool quoted; |
162 | 10.1k | size_t len=1; |
163 | | |
164 | 10.1k | *pp_buff = NULL; |
165 | 10.1k | if (!ptr) { |
166 | 0 | return(false); |
167 | 0 | } |
168 | | |
169 | 10.1k | s = *ptr; |
170 | | |
171 | | /* default to simple separators */ |
172 | 10.1k | if (!sep) { |
173 | 7.31k | sep = " \t\n\r"; |
174 | 7.31k | } |
175 | | |
176 | | /* find the first non sep char, if left-trimming is requested */ |
177 | 10.1k | if (ltrim) { |
178 | 12.1k | while (*s && strchr_m(sep,*s)) { |
179 | 1.99k | s++; |
180 | 1.99k | } |
181 | 10.1k | } |
182 | | |
183 | | /* nothing left? */ |
184 | 10.1k | if (!*s) { |
185 | 1.16k | return false; |
186 | 1.16k | } |
187 | | |
188 | | /* When restarting we need to go from here. */ |
189 | 9.00k | saved_s = s; |
190 | | |
191 | | /* Work out the length needed. */ |
192 | 21.3M | for (quoted = false; *s && |
193 | 21.3M | (quoted || !strchr_m(sep,*s)); s++) { |
194 | 21.3M | if (*s == '\"') { |
195 | 3.31k | quoted = !quoted; |
196 | 21.3M | } else { |
197 | 21.3M | len++; |
198 | 21.3M | } |
199 | 21.3M | } |
200 | | |
201 | | /* We started with len = 1 so we have space for the nul. */ |
202 | 9.00k | *pp_buff = talloc_array(ctx, char, len); |
203 | 9.00k | if (!*pp_buff) { |
204 | 0 | return false; |
205 | 0 | } |
206 | | |
207 | | /* copy over the token */ |
208 | 9.00k | pbuf = *pp_buff; |
209 | 9.00k | s = saved_s; |
210 | 21.3M | for (quoted = false; *s && |
211 | 21.3M | (quoted || !strchr_m(sep,*s)); s++) { |
212 | 21.3M | if ( *s == '\"' ) { |
213 | 3.31k | quoted = !quoted; |
214 | 21.3M | } else { |
215 | 21.3M | *pbuf++ = *s; |
216 | 21.3M | } |
217 | 21.3M | } |
218 | | |
219 | 9.00k | *ptr = (*s) ? s+1 : s; |
220 | 9.00k | *pbuf = 0; |
221 | | |
222 | 9.00k | return true; |
223 | 9.00k | } |
224 | | |
225 | | bool next_token_talloc(TALLOC_CTX *ctx, |
226 | | const char **ptr, |
227 | | char **pp_buff, |
228 | | const char *sep) |
229 | 10.1k | { |
230 | 10.1k | return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); |
231 | 10.1k | } |
232 | | |
233 | | /* |
234 | | * Get the next token from a string, return false if none found. Handles |
235 | | * double-quotes. This version does not trim leading separator characters |
236 | | * before looking for a token. |
237 | | */ |
238 | | |
239 | | bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, |
240 | | const char **ptr, |
241 | | char **pp_buff, |
242 | | const char *sep) |
243 | 0 | { |
244 | 0 | return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); |
245 | 0 | } |
246 | | |
247 | | /** |
248 | | Set a boolean variable from the text value stored in the passed string. |
249 | | Returns true in success, false if the passed string does not correctly |
250 | | represent a boolean. |
251 | | **/ |
252 | | |
253 | | _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean) |
254 | 0 | { |
255 | 0 | if (strwicmp(boolean_string, "yes") == 0 || |
256 | 0 | strwicmp(boolean_string, "true") == 0 || |
257 | 0 | strwicmp(boolean_string, "on") == 0 || |
258 | 0 | strwicmp(boolean_string, "1") == 0) { |
259 | 0 | *boolean = true; |
260 | 0 | return true; |
261 | 0 | } else if (strwicmp(boolean_string, "no") == 0 || |
262 | 0 | strwicmp(boolean_string, "false") == 0 || |
263 | 0 | strwicmp(boolean_string, "off") == 0 || |
264 | 0 | strwicmp(boolean_string, "0") == 0) { |
265 | 0 | *boolean = false; |
266 | 0 | return true; |
267 | 0 | } |
268 | 0 | return false; |
269 | 0 | } |