2 Unix SMB/CIFS implementation.
3 Samba utility functions
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 2006
9 Copyright (C) Jeremy Allison 1992-2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * @brief String utilities.
33 * Internal function to get the next token from a string, return false if none
34 * found. Handles double-quotes. This is the work horse function called by
35 * next_token() and next_token_no_ltrim().
37 * Based on a routine by GJC@VILLAGE.COM.
38 * Extensively modified by Andrew.Tridgell@anu.edu.au
40 static bool next_token_internal(const char **ptr,
56 /* default to simple separators */
60 /* find the first non sep char, if left-trimming is requested */
62 while (*s && strchr_m(sep,*s))
70 /* copy over the token */
72 for (quoted = false; len < bufsize && *s &&
73 (quoted || !strchr_m(sep,*s)); s++) {
82 *ptr = (*s) ? s+1 : s;
88 static bool next_token_internal_talloc(TALLOC_CTX *ctx,
107 /* default to simple separators */
112 /* find the first non sep char, if left-trimming is requested */
114 while (*s && strchr_m(sep,*s))
123 /* When restarting we need to go from here. */
126 /* Work out the length needed. */
127 for (quoted = false; *s &&
128 (quoted || !strchr_m(sep,*s)); s++) {
136 /* We started with len = 1 so we have space for the nul. */
137 *pp_buff = TALLOC_ARRAY(ctx, char, len);
142 /* copy over the token */
145 for (quoted = false; *s &&
146 (quoted || !strchr_m(sep,*s)); s++) {
154 *ptr = (*s) ? s+1 : s;
161 * Get the next token from a string, return false if none found. Handles
162 * double-quotes. This version trims leading separator characters before
163 * looking for a token.
165 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
167 return next_token_internal(ptr, buff, sep, bufsize, true);
170 bool next_token_talloc(TALLOC_CTX *ctx,
175 return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
179 * Get the next token from a string, return false if none found. Handles
180 * double-quotes. This version does not trim leading separator characters
181 * before looking for a token.
183 bool next_token_no_ltrim(const char **ptr,
188 return next_token_internal(ptr, buff, sep, bufsize, false);
191 bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
196 return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
200 This is like next_token but is not re-entrant and "remembers" the first
201 parameter so you can pass NULL. This is useful for user interface code
202 but beware the fact that it is not re-entrant!
205 static const char *last_ptr=NULL;
207 bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
214 ret = next_token(ptr, buff, sep, bufsize);
219 bool next_token_nr_talloc(TALLOC_CTX *ctx,
229 ret = next_token_talloc(ctx, ptr, pp_buff, sep);
234 void set_first_token(char *ptr)
240 Convert list of tokens to array; dependent on above routine.
241 Uses last_ptr from above - bit of a hack.
244 char **toktocliplist(int *ctok, const char *sep)
246 char *s=(char *)last_ptr;
253 while(*s && strchr_m(sep,*s))
262 while(*s && (!strchr_m(sep,*s)))
264 while(*s && strchr_m(sep,*s))
271 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
289 * Case insensitive string compararison.
291 * iconv does not directly give us a way to compare strings in
292 * arbitrary unix character sets -- all we can is convert and then
293 * compare. This is expensive.
295 * As an optimization, we do a first pass that considers only the
296 * prefix of the strings that is entirely 7-bit. Within this, we
297 * check whether they have the same value.
299 * Hopefully this will often give the answer without needing to copy.
300 * In particular it should speed comparisons to literal ascii strings
301 * or comparisons of strings that are "obviously" different.
303 * If we find a non-ascii character we fall back to converting via
306 * This should never be slower than convering the whole thing, and
309 * A different optimization would be to compare for bitwise equality
310 * in the binary encoding. (It would be possible thought hairy to do
311 * both simultaneously.) But in that case if they turn out to be
312 * different, we'd need to restart the whole thing.
314 * Even better is to implement strcasecmp for each encoding and use a
317 int StrCaseCmp(const char *s, const char *t)
322 smb_ucs2_t *buffer_s, *buffer_t;
325 for (ps = s, pt = t; ; ps++, pt++) {
329 return 0; /* both ended */
331 return -1; /* s is a prefix */
333 return +1; /* t is a prefix */
334 else if ((*ps & 0x80) || (*pt & 0x80))
335 /* not ascii anymore, do it the hard way
339 us = toupper_ascii(*ps);
340 ut = toupper_ascii(*pt);
349 size = push_ucs2_allocate(&buffer_s, ps);
350 if (size == (size_t)-1) {
351 return strcmp(ps, pt);
352 /* Not quite the right answer, but finding the right one
353 under this failure case is expensive, and it's pretty
357 size = push_ucs2_allocate(&buffer_t, pt);
358 if (size == (size_t)-1) {
360 return strcmp(ps, pt);
361 /* Not quite the right answer, but finding the right one
362 under this failure case is expensive, and it's pretty
366 ret = strcasecmp_w(buffer_s, buffer_t);
374 Case insensitive string compararison, length limited.
376 int StrnCaseCmp(const char *s, const char *t, size_t len)
381 smb_ucs2_t *buffer_s, *buffer_t;
384 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
388 return 0; /* both ended */
390 return -1; /* s is a prefix */
392 return +1; /* t is a prefix */
393 else if ((*ps & 0x80) || (*pt & 0x80))
394 /* not ascii anymore, do it the
395 * hard way from here on in */
398 us = toupper_ascii(*ps);
399 ut = toupper_ascii(*pt);
412 size = push_ucs2_allocate(&buffer_s, ps);
413 if (size == (size_t)-1) {
414 return strncmp(ps, pt, len-n);
415 /* Not quite the right answer, but finding the right one
416 under this failure case is expensive,
417 and it's pretty close */
420 size = push_ucs2_allocate(&buffer_t, pt);
421 if (size == (size_t)-1) {
423 return strncmp(ps, pt, len-n);
424 /* Not quite the right answer, but finding the right one
425 under this failure case is expensive,
426 and it's pretty close */
429 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
438 * @note The comparison is case-insensitive.
440 bool strequal(const char *s1, const char *s2)
447 return(StrCaseCmp(s1,s2)==0);
451 * Compare 2 strings up to and including the nth char.
453 * @note The comparison is case-insensitive.
455 bool strnequal(const char *s1,const char *s2,size_t n)
459 if (!s1 || !s2 || !n)
462 return(StrnCaseCmp(s1,s2,n)==0);
466 Compare 2 strings (case sensitive).
469 bool strcsequal(const char *s1,const char *s2)
476 return(strcmp(s1,s2)==0);
480 Do a case-insensitive, whitespace-ignoring string compare.
483 int strwicmp(const char *psz1, const char *psz2)
485 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
486 /* appropriate value. */
489 else if (psz1 == NULL)
491 else if (psz2 == NULL)
494 /* sync the strings on first non-whitespace */
496 while (isspace((int)*psz1))
498 while (isspace((int)*psz2))
500 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
501 *psz1 == '\0' || *psz2 == '\0')
506 return (*psz1 - *psz2);
511 Convert a string to upper case, but don't modify it.
514 char *strupper_static(const char *s)
516 static char *str = NULL;
525 Convert a string to "normal" form.
528 void strnorm(char *s, int case_default)
530 if (case_default == CASE_UPPER)
537 Check if a string is in "normal" case.
540 bool strisnormal(const char *s, int case_default)
542 if (case_default == CASE_UPPER)
543 return(!strhaslower(s));
545 return(!strhasupper(s));
551 NOTE: oldc and newc must be 7 bit characters
553 void string_replace( char *s, char oldc, char newc )
557 /* this is quite a common operation, so we want it to be
558 fast. We optimise for the ascii case, knowing that all our
559 supported multi-byte character sets are ascii-compatible
560 (ie. they match for the first 128 chars) */
562 for (p = s; *p; p++) {
563 if (*p & 0x80) /* mb string - slow path. */
573 /* Slow (mb) path. */
574 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
575 /* With compose characters we must restart from the beginning. JRA. */
581 next_codepoint(p, &c_size);
593 * Skip past some strings in a buffer - old version - no checks.
596 char *push_skip_string(char *buf)
598 buf += strlen(buf) + 1;
603 Skip past a string in a buffer. Buffer may not be
604 null terminated. end_ptr points to the first byte after
605 then end of the buffer.
608 char *skip_string(const char *base, size_t len, char *buf)
610 const char *end_ptr = base + len;
612 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
616 /* Skip the string */
619 if (buf >= end_ptr) {
629 Count the number of characters in a string. Normally this will
630 be the same as the number of bytes in a string for single byte strings,
631 but will be different for multibyte.
634 size_t str_charnum(const char *s)
637 smb_ucs2_t *tmpbuf2 = NULL;
638 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
641 ret = strlen_w(tmpbuf2);
647 Count the number of characters in a string. Normally this will
648 be the same as the number of bytes in a string for single byte strings,
649 but will be different for multibyte.
652 size_t str_ascii_charnum(const char *s)
655 char *tmpbuf2 = NULL;
656 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
659 ret = strlen(tmpbuf2);
664 bool trim_char(char *s,char cfront,char cback)
670 /* Ignore null or empty strings. */
671 if (!s || (s[0] == '\0'))
675 while (*fp && *fp == cfront)
678 /* We ate the string. */
686 ep = fp + strlen(fp) - 1;
688 /* Attempt ascii only. Bail for mb strings. */
689 while ((ep >= fp) && (*ep == cback)) {
691 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
692 /* Could be mb... bail back to tim_string. */
700 return trim_string(s, cfront ? fs : NULL, bs);
706 /* We ate the string. */
713 memmove(s, fp, ep-fp+2);
718 Trim the specified elements off the front and back of a string.
721 bool trim_string(char *s,const char *front,const char *back)
728 /* Ignore null or empty strings. */
729 if (!s || (s[0] == '\0'))
732 front_len = front? strlen(front) : 0;
733 back_len = back? strlen(back) : 0;
738 while (len && strncmp(s, front, front_len)==0) {
739 /* Must use memmove here as src & dest can
740 * easily overlap. Found by valgrind. JRA. */
741 memmove(s, s+front_len, (len-front_len)+1);
748 while ((len >= back_len) &&
749 strncmp(s+len-back_len,back,back_len)==0) {
750 s[len-back_len]='\0';
759 Does a string have any uppercase chars in it?
762 bool strhasupper(const char *s)
767 if (push_ucs2_allocate(&tmp, s) == -1) {
771 for(p = tmp; *p != 0; p++) {
783 Does a string have any lowercase chars in it?
786 bool strhaslower(const char *s)
791 if (push_ucs2_allocate(&tmp, s) == -1) {
795 for(p = tmp; *p != 0; p++) {
807 Find the number of 'c' chars in a string
810 size_t count_chars(const char *s,char c)
814 smb_ucs2_t *alloc_tmpbuf = NULL;
816 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
820 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
821 if(*ptr==UCS2_CHAR(c))
824 SAFE_FREE(alloc_tmpbuf);
829 Safe string copy into a known length string. maxlength does not
830 include the terminating zero.
833 char *safe_strcpy_fn(const char *fn,
842 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
843 "called from [%s][%d]\n", fn, line));
848 clobber_region(fn,line,dest, maxlength+1);
856 len = strnlen(src, maxlength+1);
858 if (len > maxlength) {
859 DEBUG(0,("ERROR: string overflow by "
860 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
861 (unsigned long)(len-maxlength), (unsigned long)len,
862 (unsigned long)maxlength, src));
866 memmove(dest, src, len);
872 Safe string cat into a string. maxlength does not
873 include the terminating zero.
875 char *safe_strcat_fn(const char *fn,
881 size_t src_len, dest_len;
884 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
885 "called from [%s][%d]\n", fn, line));
892 src_len = strnlen(src, maxlength + 1);
893 dest_len = strnlen(dest, maxlength + 1);
896 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
899 if (src_len + dest_len > maxlength) {
900 DEBUG(0,("ERROR: string overflow by %d "
901 "in safe_strcat [%.50s]\n",
902 (int)(src_len + dest_len - maxlength), src));
903 if (maxlength > dest_len) {
904 memcpy(&dest[dest_len], src, maxlength - dest_len);
910 memcpy(&dest[dest_len], src, src_len);
911 dest[dest_len + src_len] = 0;
916 Paranoid strcpy into a buffer of given length (includes terminating
917 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
918 and replaces with '_'. Deliberately does *NOT* check for multibyte
919 characters. Don't change it !
922 char *alpha_strcpy_fn(const char *fn,
926 const char *other_safe_chars,
932 clobber_region(fn, line, dest, maxlength);
936 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
937 "called from [%s][%d]\n", fn, line));
947 if (len >= maxlength)
950 if (!other_safe_chars)
951 other_safe_chars = "";
953 for(i = 0; i < len; i++) {
954 int val = (src[i] & 0xff);
955 if (isupper_ascii(val) || islower_ascii(val) ||
956 isdigit(val) || strchr_m(other_safe_chars, val))
968 Like strncpy but always null terminates. Make sure there is room!
969 The variable n should always be one less than the available size.
971 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
976 clobber_region(fn, line, dest, n+1);
980 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
981 "called from [%s][%d]\n", fn, line));
990 while (n-- && (*d = *src)) {
1001 Like strncpy but copies up to the character marker. always null terminates.
1002 returns a pointer to the character marker in the source string (src).
1005 static char *strncpyn(char *dest, const char *src, size_t n, char c)
1011 clobber_region(dest, n+1);
1013 p = strchr_m(src, c);
1015 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
1019 str_len = PTR_DIFF(p, src);
1020 strncpy(dest, src, MIN(n, str_len));
1021 dest[str_len] = '\0';
1028 Routine to get hex characters and turn them into a 16 byte array.
1029 the array can be variable length, and any non-hex-numeric
1030 characters are skipped. "0xnn" or "0Xnn" is specially catered
1033 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
1037 size_t strhex_to_str(char *buf, size_t buf_len, const char *strhex, size_t strhex_len)
1040 size_t num_chars = 0;
1041 unsigned char lonybble, hinybble;
1042 const char *hexchars = "0123456789ABCDEF";
1043 char *p1 = NULL, *p2 = NULL;
1045 for (i = 0; i < strhex_len && strhex[i] != 0; i++) {
1046 if (strnequal(hexchars, "0x", 2)) {
1047 i++; /* skip two chars */
1051 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
1054 i++; /* next hex digit */
1056 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
1059 /* get the two nybbles */
1060 hinybble = PTR_DIFF(p1, hexchars);
1061 lonybble = PTR_DIFF(p2, hexchars);
1063 if (num_chars >= buf_len) {
1066 buf[num_chars] = (hinybble << 4) | lonybble;
1075 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
1079 if (mem_ctx != NULL)
1080 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
1082 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
1084 ret_blob.length = strhex_to_str((char*)ret_blob.data,
1093 * Routine to print a buffer as HEX digits, into an allocated string.
1096 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
1101 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
1103 for (i = 0; i < len; i++)
1104 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
1110 Check if a string is part of a list.
1113 bool in_list(const char *s, const char *list, bool casesensitive)
1117 size_t bufsize = strlen(list);
1123 /* We know a token can't be larger
1124 * than the entire list. */
1126 tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1131 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1132 if (casesensitive) {
1133 if (strcmp(tok,s) == 0) {
1138 if (StrCaseCmp(tok,s) == 0) {
1149 /* this is used to prevent lots of mallocs of size 1 */
1150 static const char *null_string = "";
1153 Set a string value, allocing the space for the string
1156 static bool string_init(char **dest,const char *src)
1166 *dest = CONST_DISCARD(char*, null_string);
1168 (*dest) = SMB_STRDUP(src);
1169 if ((*dest) == NULL) {
1170 DEBUG(0,("Out of memory in string_init\n"));
1178 Free a string value.
1181 void string_free(char **s)
1185 if (*s == null_string)
1191 Set a string value, deallocating any existing space, and allocing the space
1195 bool string_set(char **dest,const char *src)
1198 return(string_init(dest,src));
1202 Substitute a string for a pattern in another string. Make sure there is
1205 This routine looks for pattern in s and replaces it with
1206 insert. It may do multiple replacements or just one.
1208 Any of " ; ' $ or ` in the insert string are replaced with _
1209 if len==0 then the string cannot be extended. This is different from the old
1210 use of len==0 which was for no length checks to be done.
1213 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1214 bool remove_unsafe_characters, bool replace_once,
1215 bool allow_trailing_dollar)
1218 ssize_t ls,lp,li, i;
1220 if (!insert || !pattern || !*pattern || !s)
1223 ls = (ssize_t)strlen(s);
1224 lp = (ssize_t)strlen(pattern);
1225 li = (ssize_t)strlen(insert);
1228 len = ls + 1; /* len is number of *bytes* */
1230 while (lp <= ls && (p = strstr_m(s,pattern))) {
1231 if (ls + (li-lp) >= len) {
1232 DEBUG(0,("ERROR: string overflow by "
1233 "%d in string_sub(%.50s, %d)\n",
1234 (int)(ls + (li-lp) - len),
1235 pattern, (int)len));
1239 memmove(p+li,p+lp,strlen(p+lp)+1);
1241 for (i=0;i<li;i++) {
1242 switch (insert[i]) {
1248 /* allow a trailing $
1249 * (as in machine accounts) */
1250 if (allow_trailing_dollar && (i == li - 1 )) {
1257 if ( remove_unsafe_characters ) {
1259 /* yes this break should be here
1260 * since we want to fall throw if
1261 * not replacing unsafe chars */
1276 void string_sub_once(char *s, const char *pattern,
1277 const char *insert, size_t len)
1279 string_sub2( s, pattern, insert, len, true, true, false );
1282 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1284 string_sub2( s, pattern, insert, len, true, false, false );
1287 void fstring_sub(char *s,const char *pattern,const char *insert)
1289 string_sub(s, pattern, insert, sizeof(fstring));
1292 void pstring_sub(char *s,const char *pattern,const char *insert)
1294 string_sub(s, pattern, insert, sizeof(pstring));
1298 Similar to string_sub2, but it will accept only allocated strings
1299 and may realloc them so pay attention at what you pass on no
1300 pointers inside strings, no pstrings or const may be passed
1304 char *realloc_string_sub2(char *string,
1305 const char *pattern,
1307 bool remove_unsafe_characters,
1308 bool allow_trailing_dollar)
1312 ssize_t ls,lp,li,ld, i;
1314 if (!insert || !pattern || !*pattern || !string || !*string)
1319 in = SMB_STRDUP(insert);
1321 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1324 ls = (ssize_t)strlen(s);
1325 lp = (ssize_t)strlen(pattern);
1326 li = (ssize_t)strlen(insert);
1328 for (i=0;i<li;i++) {
1335 /* allow a trailing $
1336 * (as in machine accounts) */
1337 if (allow_trailing_dollar && (i == li - 1 )) {
1343 if ( remove_unsafe_characters ) {
1353 while ((p = strstr_m(s,pattern))) {
1355 int offset = PTR_DIFF(s,string);
1356 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1358 DEBUG(0, ("realloc_string_sub: "
1359 "out of memory!\n"));
1363 p = string + offset + (p - s);
1366 memmove(p+li,p+lp,strlen(p+lp)+1);
1376 char *realloc_string_sub(char *string,
1377 const char *pattern,
1380 return realloc_string_sub2(string, pattern, insert, true, false);
1384 * Internal guts of talloc_string_sub and talloc_all_string_sub.
1385 * talloc version of string_sub2.
1388 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
1389 const char *pattern,
1391 bool remove_unsafe_characters,
1393 bool allow_trailing_dollar)
1398 ssize_t ls,lp,li,ld, i;
1400 if (!insert || !pattern || !*pattern || !src || !*src) {
1404 string = talloc_strdup(mem_ctx, src);
1405 if (string == NULL) {
1406 DEBUG(0, ("talloc_string_sub2: "
1407 "talloc_strdup failed\n"));
1413 in = SMB_STRDUP(insert);
1415 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
1418 ls = (ssize_t)strlen(s);
1419 lp = (ssize_t)strlen(pattern);
1420 li = (ssize_t)strlen(insert);
1423 for (i=0;i<li;i++) {
1430 /* allow a trailing $
1431 * (as in machine accounts) */
1432 if (allow_trailing_dollar && (i == li - 1 )) {
1438 if (remove_unsafe_characters) {
1448 while ((p = strstr_m(s,pattern))) {
1450 int offset = PTR_DIFF(s,string);
1451 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1454 DEBUG(0, ("talloc_string_sub: out of "
1459 p = string + offset + (p - s);
1462 memmove(p+li,p+lp,strlen(p+lp)+1);
1476 /* Same as string_sub, but returns a talloc'ed string */
1478 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1480 const char *pattern,
1483 return talloc_string_sub2(mem_ctx, src, pattern, insert,
1484 true, false, false);
1488 Similar to string_sub() but allows for any character to be substituted.
1490 if len==0 then the string cannot be extended. This is different from the old
1491 use of len==0 which was for no length checks to be done.
1494 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1499 if (!insert || !pattern || !s)
1502 ls = (ssize_t)strlen(s);
1503 lp = (ssize_t)strlen(pattern);
1504 li = (ssize_t)strlen(insert);
1510 len = ls + 1; /* len is number of *bytes* */
1512 while (lp <= ls && (p = strstr_m(s,pattern))) {
1513 if (ls + (li-lp) >= len) {
1514 DEBUG(0,("ERROR: string overflow by "
1515 "%d in all_string_sub(%.50s, %d)\n",
1516 (int)(ls + (li-lp) - len),
1517 pattern, (int)len));
1521 memmove(p+li,p+lp,strlen(p+lp)+1);
1523 memcpy(p, insert, li);
1529 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1531 const char *pattern,
1534 return talloc_string_sub2(ctx, src, pattern, insert,
1535 false, false, false);
1540 Splits out the front and back at a separator.
1543 static void split_at_last_component(char *path, char *front, char sep,
1546 char *p = strrchr_m(path, sep);
1552 pstrcpy(front, path);
1566 Write an octal as a string.
1569 const char *octal_string(int i)
1571 static char ret[64];
1574 slprintf(ret, sizeof(ret)-1, "0%o", i);
1580 Truncate a string at a specified length.
1583 char *string_truncate(char *s, unsigned int length)
1585 if (s && strlen(s) > length)
1591 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1592 We convert via ucs2 for now.
1595 char *strchr_m(const char *src, char c)
1597 smb_ucs2_t *ws = NULL;
1603 /* characters below 0x3F are guaranteed to not appear in
1604 non-initial position in multi-byte charsets */
1605 if ((c & 0xC0) == 0) {
1606 return strchr(src, c);
1609 /* this is quite a common operation, so we want it to be
1610 fast. We optimise for the ascii case, knowing that all our
1611 supported multi-byte character sets are ascii-compatible
1612 (ie. they match for the first 128 chars) */
1614 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1622 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1623 /* With compose characters we must restart from the beginning. JRA. */
1627 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1628 /* Wrong answer, but what can we do... */
1629 return strchr(src, c);
1631 p = strchr_w(ws, UCS2_CHAR(c));
1637 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1639 /* Wrong answer, but what can we do... */
1640 return strchr(src, c);
1642 ret = (char *)(s+strlen(s2));
1648 char *strrchr_m(const char *s, char c)
1650 /* characters below 0x3F are guaranteed to not appear in
1651 non-initial position in multi-byte charsets */
1652 if ((c & 0xC0) == 0) {
1653 return strrchr(s, c);
1656 /* this is quite a common operation, so we want it to be
1657 fast. We optimise for the ascii case, knowing that all our
1658 supported multi-byte character sets are ascii-compatible
1659 (ie. they match for the first 128 chars). Also, in Samba
1660 we only search for ascii characters in 'c' and that
1661 in all mb character sets with a compound character
1662 containing c, if 'c' is not a match at position
1663 p, then p[-1] > 0x7f. JRA. */
1666 size_t len = strlen(s);
1668 bool got_mb = false;
1675 /* Could be a match. Part of a multibyte ? */
1677 (((unsigned char)cp[-1]) & 0x80)) {
1678 /* Yep - go slow :-( */
1682 /* No - we have a match ! */
1685 } while (cp-- != s);
1690 /* String contained a non-ascii char. Slow path. */
1692 smb_ucs2_t *ws = NULL;
1697 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1698 /* Wrong answer, but what can we do. */
1699 return strrchr(s, c);
1701 p = strrchr_w(ws, UCS2_CHAR(c));
1707 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1709 /* Wrong answer, but what can we do. */
1710 return strrchr(s, c);
1712 ret = (char *)(s+strlen(s2));
1719 /***********************************************************************
1720 Return the equivalent of doing strrchr 'n' times - always going
1722 ***********************************************************************/
1724 char *strnrchr_m(const char *s, char c, unsigned int n)
1726 smb_ucs2_t *ws = NULL;
1731 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1732 /* Too hard to try and get right. */
1735 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1741 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1743 /* Too hard to try and get right. */
1746 ret = (char *)(s+strlen(s2));
1752 /***********************************************************************
1753 strstr_m - We convert via ucs2 for now.
1754 ***********************************************************************/
1756 char *strstr_m(const char *src, const char *findstr)
1759 smb_ucs2_t *src_w, *find_w;
1764 size_t findstr_len = 0;
1766 /* for correctness */
1771 /* Samba does single character findstr calls a *lot*. */
1772 if (findstr[1] == '\0')
1773 return strchr_m(src, *findstr);
1775 /* We optimise for the ascii case, knowing that all our
1776 supported multi-byte character sets are ascii-compatible
1777 (ie. they match for the first 128 chars) */
1779 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1780 if (*s == *findstr) {
1782 findstr_len = strlen(findstr);
1784 if (strncmp(s, findstr, findstr_len) == 0) {
1793 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1794 /* 'make check' fails unless we do this */
1796 /* With compose characters we must restart from the beginning. JRA. */
1800 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1801 DEBUG(0,("strstr_m: src malloc fail\n"));
1805 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1807 DEBUG(0,("strstr_m: find malloc fail\n"));
1811 p = strstr_w(src_w, find_w);
1820 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1823 DEBUG(0,("strstr_m: dest malloc fail\n"));
1826 retp = (char *)(s+strlen(s2));
1834 Convert a string to lower case.
1837 void strlower_m(char *s)
1842 /* this is quite a common operation, so we want it to be
1843 fast. We optimise for the ascii case, knowing that all our
1844 supported multi-byte character sets are ascii-compatible
1845 (ie. they match for the first 128 chars) */
1847 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1848 *s = tolower_ascii((unsigned char)*s);
1855 /* I assume that lowercased string takes the same number of bytes
1856 * as source string even in UTF-8 encoding. (VIV) */
1857 len = strlen(s) + 1;
1860 unix_strlower(s,len,s,len);
1861 /* Catch mb conversion errors that may not terminate. */
1868 Convert a string to upper case.
1871 void strupper_m(char *s)
1876 /* this is quite a common operation, so we want it to be
1877 fast. We optimise for the ascii case, knowing that all our
1878 supported multi-byte character sets are ascii-compatible
1879 (ie. they match for the first 128 chars) */
1881 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1882 *s = toupper_ascii((unsigned char)*s);
1889 /* I assume that lowercased string takes the same number of bytes
1890 * as source string even in multibyte encoding. (VIV) */
1891 len = strlen(s) + 1;
1894 unix_strupper(s,len,s,len);
1895 /* Catch mb conversion errors that may not terminate. */
1902 Count the number of UCS2 characters in a string. Normally this will
1903 be the same as the number of bytes in a string for single byte strings,
1904 but will be different for multibyte.
1907 size_t strlen_m(const char *s)
1915 while (*s && !(((uint8_t)*s) & 0x80)) {
1926 codepoint_t c = next_codepoint(s, &c_size);
1928 /* Unicode char fits into 16 bits. */
1931 /* Double-width unicode char - 32 bits. */
1941 Count the number of UCS2 characters in a string including the null
1945 size_t strlen_m_term(const char *s)
1950 return strlen_m(s) + 1;
1954 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1955 * if a string is there, include the terminator.
1958 size_t strlen_m_term_null(const char *s)
1972 Return a RFC2254 binary string representation of a buffer.
1973 Used in LDAP filters.
1977 char *binary_string_rfc2254(char *buf, int len)
1981 const char *hex = "0123456789ABCDEF";
1982 s = (char *)SMB_MALLOC(len * 3 + 1);
1985 for (j=i=0;i<len;i++) {
1987 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1988 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1995 char *binary_string(char *buf, int len)
1999 const char *hex = "0123456789ABCDEF";
2000 s = (char *)SMB_MALLOC(len * 2 + 1);
2003 for (j=i=0;i<len;i++) {
2004 s[j] = hex[((unsigned char)buf[i]) >> 4];
2005 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
2012 Just a typesafety wrapper for snprintf into a pstring.
2015 int pstr_sprintf(pstring s, const char *fmt, ...)
2021 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
2028 Just a typesafety wrapper for snprintf into a fstring.
2031 int fstr_sprintf(fstring s, const char *fmt, ...)
2037 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
2043 List of Strings manipulation functions
2046 #define S_LIST_ABS 16 /* List Allocation Block Size */
2048 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
2052 char **list, **rlist;
2057 TALLOC_CTX *frame = NULL;
2059 if (!string || !*string)
2062 s = talloc_strdup(mem_ctx, string);
2064 s = SMB_STRDUP(string);
2067 DEBUG(0,("str_list_make: Unable to allocate memory"));
2070 if (!sep) sep = LIST_SEP;
2076 frame = talloc_stackframe();
2077 while (next_token_talloc(frame, &str, &tok, sep)) {
2079 lsize += S_LIST_ABS;
2081 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
2084 /* We need to keep the old list on
2085 * error so we can free the elements
2086 if the realloc fails. */
2087 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2091 DEBUG(0,("str_list_make: "
2092 "Unable to allocate memory"));
2093 str_list_free(&list);
2104 memset (&list[num], 0,
2105 ((sizeof(char**)) * (S_LIST_ABS +1)));
2109 list[num] = talloc_strdup(mem_ctx, tok);
2111 list[num] = SMB_STRDUP(tok);
2115 DEBUG(0,("str_list_make: Unable to allocate memory"));
2116 str_list_free(&list);
2140 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
2144 return str_list_make_internal(mem_ctx, string, sep);
2147 char **str_list_make(const char *string, const char *sep)
2149 return str_list_make_internal(NULL, string, sep);
2152 bool str_list_copy(char ***dest, const char **src)
2154 char **list, **rlist;
2166 lsize += S_LIST_ABS;
2167 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2170 DEBUG(0,("str_list_copy: "
2171 "Unable to re-allocate memory"));
2172 str_list_free(&list);
2177 memset (&list[num], 0,
2178 ((sizeof(char **)) * (S_LIST_ABS +1)));
2181 list[num] = SMB_STRDUP(src[num]);
2183 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2184 str_list_free(&list);
2196 * Return true if all the elements of the list match exactly.
2198 bool str_list_compare(char **list1, char **list2)
2202 if (!list1 || !list2)
2203 return (list1 == list2);
2205 for (num = 0; list1[num]; num++) {
2208 if (!strcsequal(list1[num], list2[num]))
2212 return false; /* if list2 has more elements than list1 fail */
2217 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2221 if (!list || !*list)
2224 for(; *tlist; tlist++) {
2226 TALLOC_FREE(*tlist);
2232 TALLOC_FREE(*tlist);
2238 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2240 str_list_free_internal(mem_ctx, list);
2243 void str_list_free(char ***list)
2245 str_list_free_internal(NULL, list);
2248 /******************************************************************************
2249 *****************************************************************************/
2251 int str_list_count( const char **list )
2258 /* count the number of list members */
2260 for ( i=0; *list; i++, list++ );
2265 /******************************************************************************
2266 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2268 *****************************************************************************/
2270 bool str_list_sub_basic( char **list, const char *smb_name,
2271 const char *domain_name )
2277 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2279 DEBUG(0,("str_list_sub_basic: "
2280 "alloc_sub_basic() return NULL!\n"));
2293 /******************************************************************************
2294 substritute a specific pattern in a string list
2295 *****************************************************************************/
2297 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2300 ssize_t ls, lp, li, ld, i, d;
2309 lp = (ssize_t)strlen(pattern);
2310 li = (ssize_t)strlen(insert);
2315 ls = (ssize_t)strlen(s);
2317 while ((p = strstr_m(s, pattern))) {
2321 t = (char *) SMB_MALLOC(ls +ld +1);
2323 DEBUG(0,("str_list_substitute: "
2324 "Unable to allocate memory"));
2327 memcpy(t, *list, d);
2328 memcpy(t +d +li, p +lp, ls -d -lp +1);
2335 for (i = 0; i < li; i++) {
2336 switch (insert[i]) {
2348 t[d +i] = insert[i];
2360 #define IPSTR_LIST_SEP ","
2361 #define IPSTR_LIST_CHAR ','
2364 * Add ip string representation to ipstr list. Used also
2365 * as part of @function ipstr_list_make
2367 * @param ipstr_list pointer to string containing ip list;
2368 * MUST BE already allocated and IS reallocated if necessary
2369 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2370 * as a result of reallocation)
2371 * @param ip IP address which is to be added to list
2372 * @return pointer to string appended with new ip and possibly
2373 * reallocated to new length
2376 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2378 char *new_ipstr = NULL;
2379 char addr_buf[INET6_ADDRSTRLEN];
2381 /* arguments checking */
2382 if (!ipstr_list || !service) {
2386 print_sockaddr(addr_buf,
2390 /* attempt to convert ip to a string and append colon separator to it */
2392 if (service->ss.ss_family == AF_INET) {
2394 asprintf(&new_ipstr, "%s%s%s:%d",
2401 asprintf(&new_ipstr, "%s%s[%s]:%d",
2407 SAFE_FREE(*ipstr_list);
2409 if (service->ss.ss_family == AF_INET) {
2411 asprintf(&new_ipstr, "%s:%d",
2416 asprintf(&new_ipstr, "[%s]:%d",
2421 *ipstr_list = new_ipstr;
2426 * Allocate and initialise an ipstr list using ip adresses
2427 * passed as arguments.
2429 * @param ipstr_list pointer to string meant to be allocated and set
2430 * @param ip_list array of ip addresses to place in the list
2431 * @param ip_count number of addresses stored in ip_list
2432 * @return pointer to allocated ip string
2435 char *ipstr_list_make(char **ipstr_list,
2436 const struct ip_service *ip_list,
2441 /* arguments checking */
2442 if (!ip_list || !ipstr_list) {
2448 /* process ip addresses given as arguments */
2449 for (i = 0; i < ip_count; i++) {
2450 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2453 return (*ipstr_list);
2458 * Parse given ip string list into array of ip addresses
2459 * (as ip_service structures)
2460 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2462 * @param ipstr ip string list to be parsed
2463 * @param ip_list pointer to array of ip addresses which is
2464 * allocated by this function and must be freed by caller
2465 * @return number of succesfully parsed addresses
2468 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2474 if (!ipstr_list || !ip_list)
2477 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2478 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2479 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2480 (unsigned long)count));
2484 for ( i=0; next_token(&ipstr_list, token_str,
2485 IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
2486 char *s = token_str;
2487 char *p = strrchr(token_str, ':');
2491 (*ip_list)[i].port = atoi(p+1);
2494 /* convert single token to ip address */
2495 if (token_str[0] == '[') {
2498 p = strchr(token_str, ']');
2504 if (!interpret_string_addr(&(*ip_list)[i].ss,
2515 * Safely free ip string list
2517 * @param ipstr_list ip string list to be freed
2520 void ipstr_list_free(char* ipstr_list)
2522 SAFE_FREE(ipstr_list);
2526 Unescape a URL encoded string, in place.
2529 void rfc1738_unescape(char *buf)
2533 while (p && *p && (p=strchr_m(p,'%'))) {
2537 if (c1 >= '0' && c1 <= '9')
2539 else if (c1 >= 'A' && c1 <= 'F')
2541 else if (c1 >= 'a' && c1 <= 'f')
2543 else {p++; continue;}
2545 if (c2 >= '0' && c2 <= '9')
2547 else if (c2 >= 'A' && c2 <= 'F')
2549 else if (c2 >= 'a' && c2 <= 'f')
2551 else {p++; continue;}
2555 memmove(p+1, p+3, strlen(p+3)+1);
2560 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2563 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2565 DATA_BLOB base64_decode_data_blob(const char *s)
2567 int bit_offset, byte_offset, idx, i, n;
2568 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2569 unsigned char *d = decoded.data;
2574 while (*s && (p=strchr_m(b64,*s))) {
2575 idx = (int)(p - b64);
2576 byte_offset = (i*6)/8;
2577 bit_offset = (i*6)%8;
2578 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2579 if (bit_offset < 3) {
2580 d[byte_offset] |= (idx << (2-bit_offset));
2583 d[byte_offset] |= (idx >> (bit_offset-2));
2584 d[byte_offset+1] = 0;
2585 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2591 if ((n > 0) && (*s == '=')) {
2601 * Decode a base64 string in-place - wrapper for the above
2603 void base64_decode_inplace(char *s)
2605 DATA_BLOB decoded = base64_decode_data_blob(s);
2607 if ( decoded.length != 0 ) {
2608 memcpy(s, decoded.data, decoded.length);
2610 /* null terminate */
2611 s[decoded.length] = '\0';
2616 data_blob_free(&decoded);
2620 * Encode a base64 string into a malloc()ed string caller to free.
2622 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2626 char *base64_encode_data_blob(DATA_BLOB data)
2630 size_t out_cnt, len, output_len;
2633 if (!data.length || !data.data)
2638 output_len = data.length * 2;
2639 result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */
2640 SMB_ASSERT(result != NULL);
2642 while (len-- && out_cnt < (data.length * 2) - 5) {
2643 int c = (unsigned char) *(data.data++);
2646 if (char_count == 3) {
2647 result[out_cnt++] = b64[bits >> 18];
2648 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2649 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2650 result[out_cnt++] = b64[bits & 0x3f];
2657 if (char_count != 0) {
2658 bits <<= 16 - (8 * char_count);
2659 result[out_cnt++] = b64[bits >> 18];
2660 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2661 if (char_count == 1) {
2662 result[out_cnt++] = '=';
2663 result[out_cnt++] = '=';
2665 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2666 result[out_cnt++] = '=';
2669 result[out_cnt] = '\0'; /* terminate */
2673 /* read a SMB_BIG_UINT from a string */
2674 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2677 SMB_BIG_UINT val = -1;
2678 const char *p = nptr;
2687 while (*p && isspace(*p))
2690 #ifdef LARGE_SMB_OFF_T
2691 sscanf(p,"%llu",&val);
2692 #else /* LARGE_SMB_OFF_T */
2693 sscanf(p,"%lu",&val);
2694 #endif /* LARGE_SMB_OFF_T */
2696 while (*p && isdigit(*p))
2704 /* Convert a size specification to a count of bytes. We accept the following
2706 * bytes if there is no suffix
2711 * pP whatever the ISO name for petabytes is
2713 * Returns 0 if the string can't be converted.
2715 SMB_OFF_T conv_str_size(const char * str)
2720 if (str == NULL || *str == '\0') {
2724 #ifdef HAVE_STRTOULL
2725 if (sizeof(SMB_OFF_T) == 8) {
2726 lval = strtoull(str, &end, 10 /* base */);
2728 lval = strtoul(str, &end, 10 /* base */);
2731 lval = strtoul(str, &end, 10 /* base */);
2734 if (end == NULL || end == str) {
2739 SMB_OFF_T lval_orig = lval;
2741 if (strwicmp(end, "K") == 0) {
2742 lval *= (SMB_OFF_T)1024;
2743 } else if (strwicmp(end, "M") == 0) {
2744 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2745 } else if (strwicmp(end, "G") == 0) {
2746 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2748 } else if (strwicmp(end, "T") == 0) {
2749 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2750 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2751 } else if (strwicmp(end, "P") == 0) {
2752 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2753 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2759 /* Primitive attempt to detect wrapping on platforms with
2760 * 4-byte SMB_OFF_T. It's better to let the caller handle
2761 * a failure than some random number.
2763 if (lval_orig <= lval) {
2771 void string_append(char **left, const char *right)
2773 int new_len = strlen(right) + 1;
2775 if (*left == NULL) {
2776 *left = (char *)SMB_MALLOC(new_len);
2779 new_len += strlen(*left);
2780 *left = (char *)SMB_REALLOC(*left, new_len);
2783 if (*left == NULL) {
2787 safe_strcat(*left, right, new_len-1);
2790 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2791 const char *str, const char ***strings,
2794 char *dup_str = talloc_strdup(mem_ctx, str);
2796 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2797 const char *, (*num)+1);
2799 if ((*strings == NULL) || (dup_str == NULL)) {
2804 (*strings)[*num] = dup_str;
2809 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2810 * error checking in between. The indiation that something weird happened is
2813 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2814 size_t *bufsize, const char *fmt, ...)
2821 /* len<0 is an internal marker that something failed */
2825 if (*string == NULL) {
2829 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2830 if (*string == NULL)
2835 ret = vasprintf(&newstr, fmt, ap);
2843 while ((*len)+ret >= *bufsize) {
2846 if (*bufsize >= (1024*1024*256))
2851 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2853 if (*string == NULL) {
2858 StrnCpy((*string)+(*len), newstr, ret);
2869 Returns the substring from src between the first occurrence of
2870 the char "front" and the first occurence of the char "back".
2871 Mallocs the return string which must be freed. Not for use
2872 with wide character strings.
2874 char *sstring_sub(const char *src, char front, char back)
2876 char *temp1, *temp2, *temp3;
2879 temp1 = strchr(src, front);
2880 if (temp1 == NULL) return NULL;
2881 temp2 = strchr(src, back);
2882 if (temp2 == NULL) return NULL;
2883 len = temp2 - temp1;
2884 if (len <= 0) return NULL;
2885 temp3 = (char*)SMB_MALLOC(len);
2886 if (temp3 == NULL) {
2887 DEBUG(1,("Malloc failure in sstring_sub\n"));
2890 memcpy(temp3, temp1+1, len-1);
2891 temp3[len-1] = '\0';
2895 /********************************************************************
2896 Check a string for any occurrences of a specified list of invalid
2898 ********************************************************************/
2900 bool validate_net_name( const char *name,
2901 const char *invalid_chars,
2906 for ( i=0; i<max_len && name[i]; i++ ) {
2907 /* fail if strchr_m() finds one of the invalid characters */
2908 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2918 return the number of bytes occupied by a buffer in ASCII format
2919 the result includes the null termination
2920 limited by 'n' bytes
2922 size_t ascii_len_n(const char *src, size_t n)
2926 len = strnlen(src, n);
2935 return the number of bytes occupied by a buffer in CH_UTF16 format
2936 the result includes the null termination
2938 size_t utf16_len(const void *buf)
2942 for (len = 0; SVAL(buf,len); len += 2) ;
2948 return the number of bytes occupied by a buffer in CH_UTF16 format
2949 the result includes the null termination
2950 limited by 'n' bytes
2952 size_t utf16_len_n(const void *src, size_t n)
2956 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2965 /*******************************************************************
2966 Add a shell escape character '\' to any character not in a known list
2967 of characters. UNIX charset format.
2968 *******************************************************************/
2970 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2971 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2973 char *escape_shell_string(const char *src)
2975 size_t srclen = strlen(src);
2976 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2978 bool in_s_quote = false;
2979 bool in_d_quote = false;
2980 bool next_escaped = false;
2988 codepoint_t c = next_codepoint(src, &c_size);
2990 if (c == INVALID_CODEPOINT) {
2996 memcpy(dest, src, c_size);
2999 next_escaped = false;
3004 * Deal with backslash escaped state.
3005 * This only lasts for one character.
3010 next_escaped = false;
3015 * Deal with single quote state. The
3016 * only thing we care about is exiting
3029 * Deal with double quote state. The most
3030 * complex state. We must cope with \, meaning
3031 * possibly escape next char (depending what it
3032 * is), ", meaning exit this state, and possibly
3033 * add an \ escape to any unprotected character
3034 * (listed in INSIDE_DQUOTE_LIST).
3040 * Next character might be escaped.
3041 * We have to peek. Inside double
3042 * quotes only INSIDE_DQUOTE_LIST
3043 * characters are escaped by a \.
3048 c = next_codepoint(&src[1], &c_size);
3049 if (c == INVALID_CODEPOINT) {
3055 * Don't escape the next char.
3064 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
3066 next_escaped = true;
3073 /* Exit double quote state. */
3080 * We know the character isn't \ or ",
3081 * so escape it if it's any of the other
3082 * possible unprotected characters.
3085 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
3093 * From here to the end of the loop we're
3094 * not in the single or double quote state.
3098 /* Next character must be escaped. */
3099 next_escaped = true;
3105 /* Go into single quote state. */
3112 /* Go into double quote state. */
3118 /* Check if we need to escape the character. */
3120 if (!strchr(INCLUDE_LIST, (int)*src)) {