• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/lib/util/
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 "includes.h"
25#include "system/locale.h"
26#undef strncasecmp
27#undef strcasemp
28
29/**
30 * @file
31 * @brief String utilities.
32 **/
33
34/**
35 Safe string copy into a known length string. maxlength does not
36 include the terminating zero.
37**/
38_PUBLIC_ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
39{
40	size_t len;
41
42	if (!dest) {
43		DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
44		return NULL;
45	}
46
47#ifdef DEVELOPER
48	/* We intentionally write out at the extremity of the destination
49	 * string.  If the destination is too short (e.g. pstrcpy into mallocd
50	 * or fstring) then this should cause an error under a memory
51	 * checker. */
52	dest[maxlength] = '\0';
53	if (PTR_DIFF(&len, dest) > 0) {  /* check if destination is on the stack, ok if so */
54		log_suspicious_usage("safe_strcpy", src);
55	}
56#endif
57
58	if (!src) {
59		*dest = 0;
60		return dest;
61	}
62
63	len = strlen(src);
64
65	if (len > maxlength) {
66		DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
67			 (uint_t)(len-maxlength), (unsigned)len, (unsigned)maxlength, src));
68		len = maxlength;
69	}
70
71	memmove(dest, src, len);
72	dest[len] = 0;
73	return dest;
74}
75
76/**
77 Safe string cat into a string. maxlength does not
78 include the terminating zero.
79**/
80_PUBLIC_ char *safe_strcat(char *dest, const char *src, size_t maxlength)
81{
82	size_t src_len, dest_len;
83
84	if (!dest) {
85		DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
86		return NULL;
87	}
88
89	if (!src)
90		return dest;
91
92#ifdef DEVELOPER
93	if (PTR_DIFF(&src_len, dest) > 0) {  /* check if destination is on the stack, ok if so */
94		log_suspicious_usage("safe_strcat", src);
95	}
96#endif
97	src_len = strlen(src);
98	dest_len = strlen(dest);
99
100	if (src_len + dest_len > maxlength) {
101		DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
102			 (int)(src_len + dest_len - maxlength), src));
103		if (maxlength > dest_len) {
104			memcpy(&dest[dest_len], src, maxlength - dest_len);
105		}
106		dest[maxlength] = 0;
107		return NULL;
108	}
109
110	memcpy(&dest[dest_len], src, src_len);
111	dest[dest_len + src_len] = 0;
112	return dest;
113}
114
115#ifdef VALGRIND
116size_t valgrind_strlen(const char *s)
117{
118	size_t count;
119	for(count = 0; *s++; count++)
120		;
121	return count;
122}
123#endif
124
125
126/**
127  format a string into length-prefixed dotted domain format, as used in NBT
128  and in some ADS structures
129**/
130_PUBLIC_ const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s)
131{
132	char *ret;
133	int i;
134	if (!s || !*s) {
135		return talloc_strdup(mem_ctx, "");
136	}
137	ret = talloc_array(mem_ctx, char, strlen(s)+2);
138	if (!ret) {
139		return ret;
140	}
141
142	memcpy(ret+1, s, strlen(s)+1);
143	ret[0] = '.';
144
145	for (i=0;ret[i];i++) {
146		if (ret[i] == '.') {
147			char *p = strchr(ret+i+1, '.');
148			if (p) {
149				ret[i] = p-(ret+i+1);
150			} else {
151				ret[i] = strlen(ret+i+1);
152			}
153		}
154	}
155
156	talloc_set_name_const(ret, ret);
157
158	return ret;
159}
160
161/**
162 * Add a string to an array of strings.
163 *
164 * num should be a pointer to an integer that holds the current
165 * number of elements in strings. It will be updated by this function.
166 */
167_PUBLIC_ bool add_string_to_array(TALLOC_CTX *mem_ctx,
168			 const char *str, const char ***strings, int *num)
169{
170	char *dup_str = talloc_strdup(mem_ctx, str);
171
172	*strings = talloc_realloc(mem_ctx,
173				    *strings,
174				    const char *, ((*num)+1));
175
176	if ((*strings == NULL) || (dup_str == NULL))
177		return false;
178
179	(*strings)[*num] = dup_str;
180	*num += 1;
181
182	return true;
183}
184
185/**
186 * Parse a string containing a boolean value.
187 *
188 * val will be set to the read value.
189 *
190 * @retval true if a boolean value was parsed, false otherwise.
191 */
192_PUBLIC_ bool conv_str_bool(const char * str, bool * val)
193{
194	char *	end = NULL;
195	long	lval;
196
197	if (str == NULL || *str == '\0') {
198		return false;
199	}
200
201	lval = strtol(str, &end, 10 /* base */);
202	if (end == NULL || *end != '\0' || end == str) {
203		return set_boolean(str, val);
204	}
205
206	*val = (lval) ? true : false;
207	return true;
208}
209
210/**
211 * Convert a size specification like 16K into an integral number of bytes.
212 **/
213_PUBLIC_ bool conv_str_size(const char * str, uint64_t * val)
214{
215	char *		    end = NULL;
216	unsigned long long  lval;
217
218	if (str == NULL || *str == '\0') {
219		return false;
220	}
221
222	lval = strtoull(str, &end, 10 /* base */);
223	if (end == NULL || end == str) {
224		return false;
225	}
226
227	if (*end) {
228		if (strwicmp(end, "K") == 0) {
229			lval *= 1024ULL;
230		} else if (strwicmp(end, "M") == 0) {
231			lval *= (1024ULL * 1024ULL);
232		} else if (strwicmp(end, "G") == 0) {
233			lval *= (1024ULL * 1024ULL * 1024ULL);
234		} else if (strwicmp(end, "T") == 0) {
235			lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
236		} else if (strwicmp(end, "P") == 0) {
237			lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
238		} else {
239			return false;
240		}
241	}
242
243	*val = (uint64_t)lval;
244	return true;
245}
246
247/**
248 * Parse a uint64_t value from a string
249 *
250 * val will be set to the value read.
251 *
252 * @retval true if parsing was successful, false otherwise
253 */
254_PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val)
255{
256	char *		    end = NULL;
257	unsigned long long  lval;
258
259	if (str == NULL || *str == '\0') {
260		return false;
261	}
262
263	lval = strtoull(str, &end, 10 /* base */);
264	if (end == NULL || *end != '\0' || end == str) {
265		return false;
266	}
267
268	*val = (uint64_t)lval;
269	return true;
270}
271
272/**
273Do a case-insensitive, whitespace-ignoring string compare.
274**/
275_PUBLIC_ int strwicmp(const char *psz1, const char *psz2)
276{
277	/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
278	/* appropriate value. */
279	if (psz1 == psz2)
280		return (0);
281	else if (psz1 == NULL)
282		return (-1);
283	else if (psz2 == NULL)
284		return (1);
285
286	/* sync the strings on first non-whitespace */
287	while (1) {
288		while (isspace((int)*psz1))
289			psz1++;
290		while (isspace((int)*psz2))
291			psz2++;
292		if (toupper((unsigned char)*psz1) != toupper((unsigned char)*psz2)
293		    || *psz1 == '\0'
294		    || *psz2 == '\0')
295			break;
296		psz1++;
297		psz2++;
298	}
299	return (*psz1 - *psz2);
300}
301
302/**
303 * Compare 2 strings.
304 *
305 * @note The comparison is case-insensitive.
306 **/
307_PUBLIC_ bool strequal(const char *s1, const char *s2)
308{
309	if (s1 == s2)
310		return true;
311	if (!s1 || !s2)
312		return false;
313
314	return strcasecmp(s1,s2) == 0;
315}
316
317_PUBLIC_ size_t ucs2_align(const void *base_ptr, const void *p, int flags)
318{
319	if (flags & (STR_NOALIGN|STR_ASCII))
320		return 0;
321	return PTR_DIFF(p, base_ptr) & 1;
322}
323
324/**
325 String replace.
326**/
327_PUBLIC_ void string_replace(char *s, char oldc, char newc)
328{
329	while (*s) {
330		if (*s == oldc) *s = newc;
331		s++;
332	}
333}
334
335
336