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/>.
27 char toupper_ascii_fast_table[128] = {
28 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
40 * @brief String utilities.
43 static bool next_token_internal_talloc(TALLOC_CTX *ctx,
62 /* default to simple separators */
67 /* find the first non sep char, if left-trimming is requested */
69 while (*s && strchr_m(sep,*s)) {
79 /* When restarting we need to go from here. */
82 /* Work out the length needed. */
83 for (quoted = false; *s &&
84 (quoted || !strchr_m(sep,*s)); s++) {
92 /* We started with len = 1 so we have space for the nul. */
93 *pp_buff = TALLOC_ARRAY(ctx, char, len);
98 /* copy over the token */
101 for (quoted = false; *s &&
102 (quoted || !strchr_m(sep,*s)); s++) {
110 *ptr = (*s) ? s+1 : s;
118 * Get the next token from a string, return false if none found. Handles
119 * double-quotes. This version trims leading separator characters before
120 * looking for a token.
122 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
124 return next_token_internal(ptr, buff, sep, bufsize, true);
128 bool next_token_talloc(TALLOC_CTX *ctx,
133 return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
137 * Get the next token from a string, return false if none found. Handles
138 * double-quotes. This version does not trim leading separator characters
139 * before looking for a token.
142 bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
147 return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
151 * Case insensitive string compararison.
153 * iconv does not directly give us a way to compare strings in
154 * arbitrary unix character sets -- all we can is convert and then
155 * compare. This is expensive.
157 * As an optimization, we do a first pass that considers only the
158 * prefix of the strings that is entirely 7-bit. Within this, we
159 * check whether they have the same value.
161 * Hopefully this will often give the answer without needing to copy.
162 * In particular it should speed comparisons to literal ascii strings
163 * or comparisons of strings that are "obviously" different.
165 * If we find a non-ascii character we fall back to converting via
168 * This should never be slower than convering the whole thing, and
171 * A different optimization would be to compare for bitwise equality
172 * in the binary encoding. (It would be possible thought hairy to do
173 * both simultaneously.) But in that case if they turn out to be
174 * different, we'd need to restart the whole thing.
176 * Even better is to implement strcasecmp for each encoding and use a
179 int StrCaseCmp(const char *s, const char *t)
184 smb_ucs2_t *buffer_s, *buffer_t;
187 for (ps = s, pt = t; ; ps++, pt++) {
191 return 0; /* both ended */
193 return -1; /* s is a prefix */
195 return +1; /* t is a prefix */
196 else if ((*ps & 0x80) || (*pt & 0x80))
197 /* not ascii anymore, do it the hard way
201 us = toupper_ascii_fast(*ps);
202 ut = toupper_ascii_fast(*pt);
211 size = push_ucs2_allocate(&buffer_s, ps);
212 if (size == (size_t)-1) {
213 return strcmp(ps, pt);
214 /* Not quite the right answer, but finding the right one
215 under this failure case is expensive, and it's pretty
219 size = push_ucs2_allocate(&buffer_t, pt);
220 if (size == (size_t)-1) {
222 return strcmp(ps, pt);
223 /* Not quite the right answer, but finding the right one
224 under this failure case is expensive, and it's pretty
228 ret = strcasecmp_w(buffer_s, buffer_t);
236 Case insensitive string compararison, length limited.
238 int StrnCaseCmp(const char *s, const char *t, size_t len)
243 smb_ucs2_t *buffer_s, *buffer_t;
246 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
250 return 0; /* both ended */
252 return -1; /* s is a prefix */
254 return +1; /* t is a prefix */
255 else if ((*ps & 0x80) || (*pt & 0x80))
256 /* not ascii anymore, do it the
257 * hard way from here on in */
260 us = toupper_ascii_fast(*ps);
261 ut = toupper_ascii_fast(*pt);
274 size = push_ucs2_allocate(&buffer_s, ps);
275 if (size == (size_t)-1) {
276 return strncmp(ps, pt, len-n);
277 /* Not quite the right answer, but finding the right one
278 under this failure case is expensive,
279 and it's pretty close */
282 size = push_ucs2_allocate(&buffer_t, pt);
283 if (size == (size_t)-1) {
285 return strncmp(ps, pt, len-n);
286 /* Not quite the right answer, but finding the right one
287 under this failure case is expensive,
288 and it's pretty close */
291 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
300 * @note The comparison is case-insensitive.
302 bool strequal(const char *s1, const char *s2)
309 return(StrCaseCmp(s1,s2)==0);
313 * Compare 2 strings up to and including the nth char.
315 * @note The comparison is case-insensitive.
317 bool strnequal(const char *s1,const char *s2,size_t n)
321 if (!s1 || !s2 || !n)
324 return(StrnCaseCmp(s1,s2,n)==0);
328 Compare 2 strings (case sensitive).
331 bool strcsequal(const char *s1,const char *s2)
338 return(strcmp(s1,s2)==0);
342 Do a case-insensitive, whitespace-ignoring string compare.
345 int strwicmp(const char *psz1, const char *psz2)
347 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
348 /* appropriate value. */
351 else if (psz1 == NULL)
353 else if (psz2 == NULL)
356 /* sync the strings on first non-whitespace */
358 while (isspace((int)*psz1))
360 while (isspace((int)*psz2))
362 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
363 *psz1 == '\0' || *psz2 == '\0')
368 return (*psz1 - *psz2);
372 Convert a string to "normal" form.
375 void strnorm(char *s, int case_default)
377 if (case_default == CASE_UPPER)
384 Check if a string is in "normal" case.
387 bool strisnormal(const char *s, int case_default)
389 if (case_default == CASE_UPPER)
390 return(!strhaslower(s));
392 return(!strhasupper(s));
398 NOTE: oldc and newc must be 7 bit characters
400 void string_replace( char *s, char oldc, char newc )
404 /* this is quite a common operation, so we want it to be
405 fast. We optimise for the ascii case, knowing that all our
406 supported multi-byte character sets are ascii-compatible
407 (ie. they match for the first 128 chars) */
409 for (p = s; *p; p++) {
410 if (*p & 0x80) /* mb string - slow path. */
420 /* Slow (mb) path. */
421 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
422 /* With compose characters we must restart from the beginning. JRA. */
428 next_codepoint(p, &c_size);
440 * Skip past some strings in a buffer - old version - no checks.
443 char *push_skip_string(char *buf)
445 buf += strlen(buf) + 1;
450 Skip past a string in a buffer. Buffer may not be
451 null terminated. end_ptr points to the first byte after
452 then end of the buffer.
455 char *skip_string(const char *base, size_t len, char *buf)
457 const char *end_ptr = base + len;
459 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
463 /* Skip the string */
466 if (buf >= end_ptr) {
476 Count the number of characters in a string. Normally this will
477 be the same as the number of bytes in a string for single byte strings,
478 but will be different for multibyte.
481 size_t str_charnum(const char *s)
484 smb_ucs2_t *tmpbuf2 = NULL;
485 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
488 ret = strlen_w(tmpbuf2);
494 Count the number of characters in a string. Normally this will
495 be the same as the number of bytes in a string for single byte strings,
496 but will be different for multibyte.
499 size_t str_ascii_charnum(const char *s)
502 char *tmpbuf2 = NULL;
503 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
506 ret = strlen(tmpbuf2);
511 bool trim_char(char *s,char cfront,char cback)
517 /* Ignore null or empty strings. */
518 if (!s || (s[0] == '\0'))
522 while (*fp && *fp == cfront)
525 /* We ate the string. */
533 ep = fp + strlen(fp) - 1;
535 /* Attempt ascii only. Bail for mb strings. */
536 while ((ep >= fp) && (*ep == cback)) {
538 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
539 /* Could be mb... bail back to tim_string. */
547 return trim_string(s, cfront ? fs : NULL, bs);
553 /* We ate the string. */
560 memmove(s, fp, ep-fp+2);
565 Trim the specified elements off the front and back of a string.
568 bool trim_string(char *s,const char *front,const char *back)
575 /* Ignore null or empty strings. */
576 if (!s || (s[0] == '\0'))
579 front_len = front? strlen(front) : 0;
580 back_len = back? strlen(back) : 0;
585 while (len && strncmp(s, front, front_len)==0) {
586 /* Must use memmove here as src & dest can
587 * easily overlap. Found by valgrind. JRA. */
588 memmove(s, s+front_len, (len-front_len)+1);
595 while ((len >= back_len) &&
596 strncmp(s+len-back_len,back,back_len)==0) {
597 s[len-back_len]='\0';
606 Does a string have any uppercase chars in it?
609 bool strhasupper(const char *s)
614 if (push_ucs2_allocate(&tmp, s) == -1) {
618 for(p = tmp; *p != 0; p++) {
630 Does a string have any lowercase chars in it?
633 bool strhaslower(const char *s)
638 if (push_ucs2_allocate(&tmp, s) == -1) {
642 for(p = tmp; *p != 0; p++) {
654 Find the number of 'c' chars in a string
657 size_t count_chars(const char *s,char c)
661 smb_ucs2_t *alloc_tmpbuf = NULL;
663 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
667 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
668 if(*ptr==UCS2_CHAR(c))
671 SAFE_FREE(alloc_tmpbuf);
676 Safe string copy into a known length string. maxlength does not
677 include the terminating zero.
680 char *safe_strcpy_fn(const char *fn,
689 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
690 "called from [%s][%d]\n", fn, line));
695 clobber_region(fn,line,dest, maxlength+1);
703 len = strnlen(src, maxlength+1);
705 if (len > maxlength) {
706 DEBUG(0,("ERROR: string overflow by "
707 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
708 (unsigned long)(len-maxlength), (unsigned long)len,
709 (unsigned long)maxlength, src));
713 memmove(dest, src, len);
719 Safe string cat into a string. maxlength does not
720 include the terminating zero.
722 char *safe_strcat_fn(const char *fn,
728 size_t src_len, dest_len;
731 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
732 "called from [%s][%d]\n", fn, line));
739 src_len = strnlen(src, maxlength + 1);
740 dest_len = strnlen(dest, maxlength + 1);
743 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
746 if (src_len + dest_len > maxlength) {
747 DEBUG(0,("ERROR: string overflow by %d "
748 "in safe_strcat [%.50s]\n",
749 (int)(src_len + dest_len - maxlength), src));
750 if (maxlength > dest_len) {
751 memcpy(&dest[dest_len], src, maxlength - dest_len);
757 memcpy(&dest[dest_len], src, src_len);
758 dest[dest_len + src_len] = 0;
763 Paranoid strcpy into a buffer of given length (includes terminating
764 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
765 and replaces with '_'. Deliberately does *NOT* check for multibyte
766 characters. Don't change it !
769 char *alpha_strcpy_fn(const char *fn,
773 const char *other_safe_chars,
779 clobber_region(fn, line, dest, maxlength);
783 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
784 "called from [%s][%d]\n", fn, line));
794 if (len >= maxlength)
797 if (!other_safe_chars)
798 other_safe_chars = "";
800 for(i = 0; i < len; i++) {
801 int val = (src[i] & 0xff);
802 if (isupper_ascii(val) || islower_ascii(val) ||
803 isdigit(val) || strchr_m(other_safe_chars, val))
815 Like strncpy but always null terminates. Make sure there is room!
816 The variable n should always be one less than the available size.
818 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
823 clobber_region(fn, line, dest, n+1);
827 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
828 "called from [%s][%d]\n", fn, line));
837 while (n-- && (*d = *src)) {
848 Like strncpy but copies up to the character marker. always null terminates.
849 returns a pointer to the character marker in the source string (src).
852 static char *strncpyn(char *dest, const char *src, size_t n, char c)
858 clobber_region(dest, n+1);
860 p = strchr_m(src, c);
862 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
866 str_len = PTR_DIFF(p, src);
867 strncpy(dest, src, MIN(n, str_len));
868 dest[str_len] = '\0';
875 Routine to get hex characters and turn them into a 16 byte array.
876 the array can be variable length, and any non-hex-numeric
877 characters are skipped. "0xnn" or "0Xnn" is specially catered
880 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
884 size_t strhex_to_str(char *buf, size_t buf_len, const char *strhex, size_t strhex_len)
887 size_t num_chars = 0;
888 unsigned char lonybble, hinybble;
889 const char *hexchars = "0123456789ABCDEF";
890 char *p1 = NULL, *p2 = NULL;
892 for (i = 0; i < strhex_len && strhex[i] != 0; i++) {
893 if (strnequal(hexchars, "0x", 2)) {
894 i++; /* skip two chars */
898 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
901 i++; /* next hex digit */
903 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
906 /* get the two nybbles */
907 hinybble = PTR_DIFF(p1, hexchars);
908 lonybble = PTR_DIFF(p2, hexchars);
910 if (num_chars >= buf_len) {
913 buf[num_chars] = (hinybble << 4) | lonybble;
922 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
927 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
929 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
931 ret_blob.length = strhex_to_str((char*)ret_blob.data,
940 * Routine to print a buffer as HEX digits, into an allocated string.
943 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
948 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
950 for (i = 0; i < len; i++)
951 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
957 Check if a string is part of a list.
960 bool in_list(const char *s, const char *list, bool casesensitive)
970 frame = talloc_stackframe();
971 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
973 if (strcmp(tok,s) == 0) {
978 if (StrCaseCmp(tok,s) == 0) {
988 /* this is used to prevent lots of mallocs of size 1 */
989 static const char null_string[] = "";
992 Set a string value, allocing the space for the string
995 static bool string_init(char **dest,const char *src)
1005 *dest = CONST_DISCARD(char*, null_string);
1007 (*dest) = SMB_STRDUP(src);
1008 if ((*dest) == NULL) {
1009 DEBUG(0,("Out of memory in string_init\n"));
1017 Free a string value.
1020 void string_free(char **s)
1024 if (*s == null_string)
1030 Set a string value, deallocating any existing space, and allocing the space
1034 bool string_set(char **dest,const char *src)
1037 return(string_init(dest,src));
1041 Substitute a string for a pattern in another string. Make sure there is
1044 This routine looks for pattern in s and replaces it with
1045 insert. It may do multiple replacements or just one.
1047 Any of " ; ' $ or ` in the insert string are replaced with _
1048 if len==0 then the string cannot be extended. This is different from the old
1049 use of len==0 which was for no length checks to be done.
1052 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1053 bool remove_unsafe_characters, bool replace_once,
1054 bool allow_trailing_dollar)
1057 ssize_t ls,lp,li, i;
1059 if (!insert || !pattern || !*pattern || !s)
1062 ls = (ssize_t)strlen(s);
1063 lp = (ssize_t)strlen(pattern);
1064 li = (ssize_t)strlen(insert);
1067 len = ls + 1; /* len is number of *bytes* */
1069 while (lp <= ls && (p = strstr_m(s,pattern))) {
1070 if (ls + (li-lp) >= len) {
1071 DEBUG(0,("ERROR: string overflow by "
1072 "%d in string_sub(%.50s, %d)\n",
1073 (int)(ls + (li-lp) - len),
1074 pattern, (int)len));
1078 memmove(p+li,p+lp,strlen(p+lp)+1);
1080 for (i=0;i<li;i++) {
1081 switch (insert[i]) {
1087 /* allow a trailing $
1088 * (as in machine accounts) */
1089 if (allow_trailing_dollar && (i == li - 1 )) {
1096 if ( remove_unsafe_characters ) {
1098 /* yes this break should be here
1099 * since we want to fall throw if
1100 * not replacing unsafe chars */
1115 void string_sub_once(char *s, const char *pattern,
1116 const char *insert, size_t len)
1118 string_sub2( s, pattern, insert, len, true, true, false );
1121 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1123 string_sub2( s, pattern, insert, len, true, false, false );
1126 void fstring_sub(char *s,const char *pattern,const char *insert)
1128 string_sub(s, pattern, insert, sizeof(fstring));
1132 Similar to string_sub2, but it will accept only allocated strings
1133 and may realloc them so pay attention at what you pass on no
1134 pointers inside strings, no const may be passed
1138 char *realloc_string_sub2(char *string,
1139 const char *pattern,
1141 bool remove_unsafe_characters,
1142 bool allow_trailing_dollar)
1146 ssize_t ls,lp,li,ld, i;
1148 if (!insert || !pattern || !*pattern || !string || !*string)
1153 in = SMB_STRDUP(insert);
1155 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1158 ls = (ssize_t)strlen(s);
1159 lp = (ssize_t)strlen(pattern);
1160 li = (ssize_t)strlen(insert);
1162 for (i=0;i<li;i++) {
1169 /* allow a trailing $
1170 * (as in machine accounts) */
1171 if (allow_trailing_dollar && (i == li - 1 )) {
1177 if ( remove_unsafe_characters ) {
1187 while ((p = strstr_m(s,pattern))) {
1189 int offset = PTR_DIFF(s,string);
1190 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1192 DEBUG(0, ("realloc_string_sub: "
1193 "out of memory!\n"));
1197 p = string + offset + (p - s);
1200 memmove(p+li,p+lp,strlen(p+lp)+1);
1210 char *realloc_string_sub(char *string,
1211 const char *pattern,
1214 return realloc_string_sub2(string, pattern, insert, true, false);
1218 * Internal guts of talloc_string_sub and talloc_all_string_sub.
1219 * talloc version of string_sub2.
1222 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
1223 const char *pattern,
1225 bool remove_unsafe_characters,
1227 bool allow_trailing_dollar)
1232 ssize_t ls,lp,li,ld, i;
1234 if (!insert || !pattern || !*pattern || !src || !*src) {
1238 string = talloc_strdup(mem_ctx, src);
1239 if (string == NULL) {
1240 DEBUG(0, ("talloc_string_sub2: "
1241 "talloc_strdup failed\n"));
1247 in = SMB_STRDUP(insert);
1249 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
1252 ls = (ssize_t)strlen(s);
1253 lp = (ssize_t)strlen(pattern);
1254 li = (ssize_t)strlen(insert);
1257 for (i=0;i<li;i++) {
1264 /* allow a trailing $
1265 * (as in machine accounts) */
1266 if (allow_trailing_dollar && (i == li - 1 )) {
1272 if (remove_unsafe_characters) {
1282 while ((p = strstr_m(s,pattern))) {
1284 int offset = PTR_DIFF(s,string);
1285 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1288 DEBUG(0, ("talloc_string_sub: out of "
1293 p = string + offset + (p - s);
1296 memmove(p+li,p+lp,strlen(p+lp)+1);
1310 /* Same as string_sub, but returns a talloc'ed string */
1312 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1314 const char *pattern,
1317 return talloc_string_sub2(mem_ctx, src, pattern, insert,
1318 true, false, false);
1322 Similar to string_sub() but allows for any character to be substituted.
1324 if len==0 then the string cannot be extended. This is different from the old
1325 use of len==0 which was for no length checks to be done.
1328 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1333 if (!insert || !pattern || !s)
1336 ls = (ssize_t)strlen(s);
1337 lp = (ssize_t)strlen(pattern);
1338 li = (ssize_t)strlen(insert);
1344 len = ls + 1; /* len is number of *bytes* */
1346 while (lp <= ls && (p = strstr_m(s,pattern))) {
1347 if (ls + (li-lp) >= len) {
1348 DEBUG(0,("ERROR: string overflow by "
1349 "%d in all_string_sub(%.50s, %d)\n",
1350 (int)(ls + (li-lp) - len),
1351 pattern, (int)len));
1355 memmove(p+li,p+lp,strlen(p+lp)+1);
1357 memcpy(p, insert, li);
1363 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1365 const char *pattern,
1368 return talloc_string_sub2(ctx, src, pattern, insert,
1369 false, false, false);
1373 Write an octal as a string.
1376 char *octal_string(int i)
1380 result = talloc_strdup(talloc_tos(), "-1");
1383 result = talloc_asprintf(talloc_tos(), "0%o", i);
1385 SMB_ASSERT(result != NULL);
1391 Truncate a string at a specified length.
1394 char *string_truncate(char *s, unsigned int length)
1396 if (s && strlen(s) > length)
1402 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1403 We convert via ucs2 for now.
1406 char *strchr_m(const char *src, char c)
1408 smb_ucs2_t *ws = NULL;
1414 /* characters below 0x3F are guaranteed to not appear in
1415 non-initial position in multi-byte charsets */
1416 if ((c & 0xC0) == 0) {
1417 return strchr(src, c);
1420 /* this is quite a common operation, so we want it to be
1421 fast. We optimise for the ascii case, knowing that all our
1422 supported multi-byte character sets are ascii-compatible
1423 (ie. they match for the first 128 chars) */
1425 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1433 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1434 /* With compose characters we must restart from the beginning. JRA. */
1438 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1439 /* Wrong answer, but what can we do... */
1440 return strchr(src, c);
1442 p = strchr_w(ws, UCS2_CHAR(c));
1448 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1450 /* Wrong answer, but what can we do... */
1451 return strchr(src, c);
1453 ret = (char *)(s+strlen(s2));
1459 char *strrchr_m(const char *s, char c)
1461 /* characters below 0x3F are guaranteed to not appear in
1462 non-initial position in multi-byte charsets */
1463 if ((c & 0xC0) == 0) {
1464 return strrchr(s, c);
1467 /* this is quite a common operation, so we want it to be
1468 fast. We optimise for the ascii case, knowing that all our
1469 supported multi-byte character sets are ascii-compatible
1470 (ie. they match for the first 128 chars). Also, in Samba
1471 we only search for ascii characters in 'c' and that
1472 in all mb character sets with a compound character
1473 containing c, if 'c' is not a match at position
1474 p, then p[-1] > 0x7f. JRA. */
1477 size_t len = strlen(s);
1479 bool got_mb = false;
1486 /* Could be a match. Part of a multibyte ? */
1488 (((unsigned char)cp[-1]) & 0x80)) {
1489 /* Yep - go slow :-( */
1493 /* No - we have a match ! */
1496 } while (cp-- != s);
1501 /* String contained a non-ascii char. Slow path. */
1503 smb_ucs2_t *ws = NULL;
1508 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1509 /* Wrong answer, but what can we do. */
1510 return strrchr(s, c);
1512 p = strrchr_w(ws, UCS2_CHAR(c));
1518 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1520 /* Wrong answer, but what can we do. */
1521 return strrchr(s, c);
1523 ret = (char *)(s+strlen(s2));
1530 /***********************************************************************
1531 Return the equivalent of doing strrchr 'n' times - always going
1533 ***********************************************************************/
1535 char *strnrchr_m(const char *s, char c, unsigned int n)
1537 smb_ucs2_t *ws = NULL;
1542 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1543 /* Too hard to try and get right. */
1546 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1552 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1554 /* Too hard to try and get right. */
1557 ret = (char *)(s+strlen(s2));
1563 /***********************************************************************
1564 strstr_m - We convert via ucs2 for now.
1565 ***********************************************************************/
1567 char *strstr_m(const char *src, const char *findstr)
1570 smb_ucs2_t *src_w, *find_w;
1575 size_t findstr_len = 0;
1577 /* for correctness */
1582 /* Samba does single character findstr calls a *lot*. */
1583 if (findstr[1] == '\0')
1584 return strchr_m(src, *findstr);
1586 /* We optimise for the ascii case, knowing that all our
1587 supported multi-byte character sets are ascii-compatible
1588 (ie. they match for the first 128 chars) */
1590 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1591 if (*s == *findstr) {
1593 findstr_len = strlen(findstr);
1595 if (strncmp(s, findstr, findstr_len) == 0) {
1604 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1605 /* 'make check' fails unless we do this */
1607 /* With compose characters we must restart from the beginning. JRA. */
1611 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1612 DEBUG(0,("strstr_m: src malloc fail\n"));
1616 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1618 DEBUG(0,("strstr_m: find malloc fail\n"));
1622 p = strstr_w(src_w, find_w);
1631 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1634 DEBUG(0,("strstr_m: dest malloc fail\n"));
1637 retp = (char *)(s+strlen(s2));
1645 Convert a string to lower case.
1648 void strlower_m(char *s)
1653 /* this is quite a common operation, so we want it to be
1654 fast. We optimise for the ascii case, knowing that all our
1655 supported multi-byte character sets are ascii-compatible
1656 (ie. they match for the first 128 chars) */
1658 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1659 *s = tolower_ascii((unsigned char)*s);
1666 /* I assume that lowercased string takes the same number of bytes
1667 * as source string even in UTF-8 encoding. (VIV) */
1668 len = strlen(s) + 1;
1671 unix_strlower(s,len,s,len);
1672 /* Catch mb conversion errors that may not terminate. */
1679 Convert a string to upper case.
1682 void strupper_m(char *s)
1687 /* this is quite a common operation, so we want it to be
1688 fast. We optimise for the ascii case, knowing that all our
1689 supported multi-byte character sets are ascii-compatible
1690 (ie. they match for the first 128 chars) */
1692 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1693 *s = toupper_ascii_fast((unsigned char)*s);
1700 /* I assume that lowercased string takes the same number of bytes
1701 * as source string even in multibyte encoding. (VIV) */
1702 len = strlen(s) + 1;
1705 unix_strupper(s,len,s,len);
1706 /* Catch mb conversion errors that may not terminate. */
1713 Count the number of UCS2 characters in a string. Normally this will
1714 be the same as the number of bytes in a string for single byte strings,
1715 but will be different for multibyte.
1718 size_t strlen_m(const char *s)
1726 while (*s && !(((uint8_t)*s) & 0x80)) {
1737 codepoint_t c = next_codepoint(s, &c_size);
1739 /* Unicode char fits into 16 bits. */
1742 /* Double-width unicode char - 32 bits. */
1752 Count the number of UCS2 characters in a string including the null
1756 size_t strlen_m_term(const char *s)
1761 return strlen_m(s) + 1;
1765 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1766 * if a string is there, include the terminator.
1769 size_t strlen_m_term_null(const char *s)
1783 Return a RFC2254 binary string representation of a buffer.
1784 Used in LDAP filters.
1788 char *binary_string_rfc2254(char *buf, int len)
1792 const char *hex = "0123456789ABCDEF";
1793 s = (char *)SMB_MALLOC(len * 3 + 1);
1796 for (j=i=0;i<len;i++) {
1798 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1799 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1806 char *binary_string(char *buf, int len)
1810 const char *hex = "0123456789ABCDEF";
1811 s = (char *)SMB_MALLOC(len * 2 + 1);
1814 for (j=i=0;i<len;i++) {
1815 s[j] = hex[((unsigned char)buf[i]) >> 4];
1816 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1824 Just a typesafety wrapper for snprintf into a fstring.
1827 int fstr_sprintf(fstring s, const char *fmt, ...)
1833 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1839 List of Strings manipulation functions
1842 #define S_LIST_ABS 16 /* List Allocation Block Size */
1844 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
1848 char **list, **rlist;
1853 TALLOC_CTX *frame = NULL;
1855 if (!string || !*string)
1858 s = talloc_strdup(mem_ctx, string);
1860 s = SMB_STRDUP(string);
1863 DEBUG(0,("str_list_make: Unable to allocate memory"));
1866 if (!sep) sep = LIST_SEP;
1872 frame = talloc_stackframe();
1873 while (next_token_talloc(frame, &str, &tok, sep)) {
1875 lsize += S_LIST_ABS;
1877 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
1880 /* We need to keep the old list on
1881 * error so we can free the elements
1882 if the realloc fails. */
1883 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
1887 DEBUG(0,("str_list_make: "
1888 "Unable to allocate memory"));
1889 str_list_free(&list);
1900 memset (&list[num], 0,
1901 ((sizeof(char**)) * (S_LIST_ABS +1)));
1905 list[num] = talloc_strdup(mem_ctx, tok);
1907 list[num] = SMB_STRDUP(tok);
1911 DEBUG(0,("str_list_make: Unable to allocate memory"));
1912 str_list_free(&list);
1936 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
1940 return str_list_make_internal(mem_ctx, string, sep);
1943 char **str_list_make(const char *string, const char *sep)
1945 return str_list_make_internal(NULL, string, sep);
1948 bool str_list_copy(char ***dest, const char **src)
1950 char **list, **rlist;
1962 lsize += S_LIST_ABS;
1963 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
1966 DEBUG(0,("str_list_copy: "
1967 "Unable to re-allocate memory"));
1968 str_list_free(&list);
1973 memset (&list[num], 0,
1974 ((sizeof(char **)) * (S_LIST_ABS +1)));
1977 list[num] = SMB_STRDUP(src[num]);
1979 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1980 str_list_free(&list);
1992 * Return true if all the elements of the list match exactly.
1994 bool str_list_compare(char **list1, char **list2)
1998 if (!list1 || !list2)
1999 return (list1 == list2);
2001 for (num = 0; list1[num]; num++) {
2004 if (!strcsequal(list1[num], list2[num]))
2008 return false; /* if list2 has more elements than list1 fail */
2013 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2017 if (!list || !*list)
2020 for(; *tlist; tlist++) {
2022 TALLOC_FREE(*tlist);
2028 TALLOC_FREE(*tlist);
2034 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2036 str_list_free_internal(mem_ctx, list);
2039 void str_list_free(char ***list)
2041 str_list_free_internal(NULL, list);
2044 /******************************************************************************
2045 *****************************************************************************/
2047 int str_list_count( const char **list )
2054 /* count the number of list members */
2056 for ( i=0; *list; i++, list++ );
2061 /******************************************************************************
2062 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2064 *****************************************************************************/
2066 bool str_list_sub_basic( char **list, const char *smb_name,
2067 const char *domain_name )
2073 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2075 DEBUG(0,("str_list_sub_basic: "
2076 "alloc_sub_basic() return NULL!\n"));
2089 /******************************************************************************
2090 substritute a specific pattern in a string list
2091 *****************************************************************************/
2093 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2096 ssize_t ls, lp, li, ld, i, d;
2105 lp = (ssize_t)strlen(pattern);
2106 li = (ssize_t)strlen(insert);
2111 ls = (ssize_t)strlen(s);
2113 while ((p = strstr_m(s, pattern))) {
2117 t = (char *) SMB_MALLOC(ls +ld +1);
2119 DEBUG(0,("str_list_substitute: "
2120 "Unable to allocate memory"));
2123 memcpy(t, *list, d);
2124 memcpy(t +d +li, p +lp, ls -d -lp +1);
2131 for (i = 0; i < li; i++) {
2132 switch (insert[i]) {
2144 t[d +i] = insert[i];
2156 #define IPSTR_LIST_SEP ","
2157 #define IPSTR_LIST_CHAR ','
2160 * Add ip string representation to ipstr list. Used also
2161 * as part of @function ipstr_list_make
2163 * @param ipstr_list pointer to string containing ip list;
2164 * MUST BE already allocated and IS reallocated if necessary
2165 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2166 * as a result of reallocation)
2167 * @param ip IP address which is to be added to list
2168 * @return pointer to string appended with new ip and possibly
2169 * reallocated to new length
2172 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2174 char *new_ipstr = NULL;
2175 char addr_buf[INET6_ADDRSTRLEN];
2177 /* arguments checking */
2178 if (!ipstr_list || !service) {
2182 print_sockaddr(addr_buf,
2186 /* attempt to convert ip to a string and append colon separator to it */
2188 if (service->ss.ss_family == AF_INET) {
2190 asprintf(&new_ipstr, "%s%s%s:%d",
2197 asprintf(&new_ipstr, "%s%s[%s]:%d",
2203 SAFE_FREE(*ipstr_list);
2205 if (service->ss.ss_family == AF_INET) {
2207 asprintf(&new_ipstr, "%s:%d",
2212 asprintf(&new_ipstr, "[%s]:%d",
2217 *ipstr_list = new_ipstr;
2222 * Allocate and initialise an ipstr list using ip adresses
2223 * passed as arguments.
2225 * @param ipstr_list pointer to string meant to be allocated and set
2226 * @param ip_list array of ip addresses to place in the list
2227 * @param ip_count number of addresses stored in ip_list
2228 * @return pointer to allocated ip string
2231 char *ipstr_list_make(char **ipstr_list,
2232 const struct ip_service *ip_list,
2237 /* arguments checking */
2238 if (!ip_list || !ipstr_list) {
2244 /* process ip addresses given as arguments */
2245 for (i = 0; i < ip_count; i++) {
2246 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2249 return (*ipstr_list);
2254 * Parse given ip string list into array of ip addresses
2255 * (as ip_service structures)
2256 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2258 * @param ipstr ip string list to be parsed
2259 * @param ip_list pointer to array of ip addresses which is
2260 * allocated by this function and must be freed by caller
2261 * @return number of succesfully parsed addresses
2264 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2267 char *token_str = NULL;
2271 if (!ipstr_list || !ip_list)
2274 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2275 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2276 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2277 (unsigned long)count));
2281 frame = talloc_stackframe();
2282 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
2283 IPSTR_LIST_SEP) && i<count; i++ ) {
2284 char *s = token_str;
2285 char *p = strrchr(token_str, ':');
2289 (*ip_list)[i].port = atoi(p+1);
2292 /* convert single token to ip address */
2293 if (token_str[0] == '[') {
2296 p = strchr(token_str, ']');
2302 if (!interpret_string_addr(&(*ip_list)[i].ss,
2313 * Safely free ip string list
2315 * @param ipstr_list ip string list to be freed
2318 void ipstr_list_free(char* ipstr_list)
2320 SAFE_FREE(ipstr_list);
2324 Unescape a URL encoded string, in place.
2327 void rfc1738_unescape(char *buf)
2331 while (p && *p && (p=strchr_m(p,'%'))) {
2335 if (c1 >= '0' && c1 <= '9')
2337 else if (c1 >= 'A' && c1 <= 'F')
2339 else if (c1 >= 'a' && c1 <= 'f')
2341 else {p++; continue;}
2343 if (c2 >= '0' && c2 <= '9')
2345 else if (c2 >= 'A' && c2 <= 'F')
2347 else if (c2 >= 'a' && c2 <= 'f')
2349 else {p++; continue;}
2353 memmove(p+1, p+3, strlen(p+3)+1);
2358 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2361 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2363 DATA_BLOB base64_decode_data_blob(const char *s)
2365 int bit_offset, byte_offset, idx, i, n;
2366 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2367 unsigned char *d = decoded.data;
2372 while (*s && (p=strchr_m(b64,*s))) {
2373 idx = (int)(p - b64);
2374 byte_offset = (i*6)/8;
2375 bit_offset = (i*6)%8;
2376 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2377 if (bit_offset < 3) {
2378 d[byte_offset] |= (idx << (2-bit_offset));
2381 d[byte_offset] |= (idx >> (bit_offset-2));
2382 d[byte_offset+1] = 0;
2383 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2389 if ((n > 0) && (*s == '=')) {
2399 * Decode a base64 string in-place - wrapper for the above
2401 void base64_decode_inplace(char *s)
2403 DATA_BLOB decoded = base64_decode_data_blob(s);
2405 if ( decoded.length != 0 ) {
2406 memcpy(s, decoded.data, decoded.length);
2408 /* null terminate */
2409 s[decoded.length] = '\0';
2414 data_blob_free(&decoded);
2418 * Encode a base64 string into a talloc()ed string caller to free.
2420 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2424 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
2428 size_t out_cnt, len, output_len;
2431 if (!data.length || !data.data)
2436 output_len = data.length * 2;
2437 result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
2438 SMB_ASSERT(result != NULL);
2440 while (len-- && out_cnt < (data.length * 2) - 5) {
2441 int c = (unsigned char) *(data.data++);
2444 if (char_count == 3) {
2445 result[out_cnt++] = b64[bits >> 18];
2446 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2447 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2448 result[out_cnt++] = b64[bits & 0x3f];
2455 if (char_count != 0) {
2456 bits <<= 16 - (8 * char_count);
2457 result[out_cnt++] = b64[bits >> 18];
2458 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2459 if (char_count == 1) {
2460 result[out_cnt++] = '=';
2461 result[out_cnt++] = '=';
2463 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2464 result[out_cnt++] = '=';
2467 result[out_cnt] = '\0'; /* terminate */
2471 /* read a SMB_BIG_UINT from a string */
2472 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2475 SMB_BIG_UINT val = -1;
2476 const char *p = nptr;
2485 while (*p && isspace(*p))
2488 #ifdef LARGE_SMB_OFF_T
2489 sscanf(p,"%llu",&val);
2490 #else /* LARGE_SMB_OFF_T */
2491 sscanf(p,"%lu",&val);
2492 #endif /* LARGE_SMB_OFF_T */
2494 while (*p && isdigit(*p))
2502 /* Convert a size specification to a count of bytes. We accept the following
2504 * bytes if there is no suffix
2509 * pP whatever the ISO name for petabytes is
2511 * Returns 0 if the string can't be converted.
2513 SMB_OFF_T conv_str_size(const char * str)
2518 if (str == NULL || *str == '\0') {
2522 #ifdef HAVE_STRTOULL
2523 if (sizeof(SMB_OFF_T) == 8) {
2524 lval = strtoull(str, &end, 10 /* base */);
2526 lval = strtoul(str, &end, 10 /* base */);
2529 lval = strtoul(str, &end, 10 /* base */);
2532 if (end == NULL || end == str) {
2537 SMB_OFF_T lval_orig = lval;
2539 if (strwicmp(end, "K") == 0) {
2540 lval *= (SMB_OFF_T)1024;
2541 } else if (strwicmp(end, "M") == 0) {
2542 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2543 } else if (strwicmp(end, "G") == 0) {
2544 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2546 } else if (strwicmp(end, "T") == 0) {
2547 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2548 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2549 } else if (strwicmp(end, "P") == 0) {
2550 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2551 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2557 /* Primitive attempt to detect wrapping on platforms with
2558 * 4-byte SMB_OFF_T. It's better to let the caller handle
2559 * a failure than some random number.
2561 if (lval_orig <= lval) {
2569 void string_append(char **left, const char *right)
2571 int new_len = strlen(right) + 1;
2573 if (*left == NULL) {
2574 *left = (char *)SMB_MALLOC(new_len);
2577 new_len += strlen(*left);
2578 *left = (char *)SMB_REALLOC(*left, new_len);
2581 if (*left == NULL) {
2585 safe_strcat(*left, right, new_len-1);
2588 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2589 const char *str, const char ***strings,
2592 char *dup_str = talloc_strdup(mem_ctx, str);
2594 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2595 const char *, (*num)+1);
2597 if ((*strings == NULL) || (dup_str == NULL)) {
2602 (*strings)[*num] = dup_str;
2607 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2608 * error checking in between. The indiation that something weird happened is
2611 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2612 size_t *bufsize, const char *fmt, ...)
2619 /* len<0 is an internal marker that something failed */
2623 if (*string == NULL) {
2627 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2628 if (*string == NULL)
2633 ret = vasprintf(&newstr, fmt, ap);
2641 while ((*len)+ret >= *bufsize) {
2644 if (*bufsize >= (1024*1024*256))
2649 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2651 if (*string == NULL) {
2656 StrnCpy((*string)+(*len), newstr, ret);
2667 * asprintf into a string and strupper_m it after that.
2670 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2677 ret = vasprintf(&result, fmt, ap);
2688 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2694 ret = talloc_vasprintf(t, fmt, ap);
2705 Returns the substring from src between the first occurrence of
2706 the char "front" and the first occurence of the char "back".
2707 Mallocs the return string which must be freed. Not for use
2708 with wide character strings.
2710 char *sstring_sub(const char *src, char front, char back)
2712 char *temp1, *temp2, *temp3;
2715 temp1 = strchr(src, front);
2716 if (temp1 == NULL) return NULL;
2717 temp2 = strchr(src, back);
2718 if (temp2 == NULL) return NULL;
2719 len = temp2 - temp1;
2720 if (len <= 0) return NULL;
2721 temp3 = (char*)SMB_MALLOC(len);
2722 if (temp3 == NULL) {
2723 DEBUG(1,("Malloc failure in sstring_sub\n"));
2726 memcpy(temp3, temp1+1, len-1);
2727 temp3[len-1] = '\0';
2731 /********************************************************************
2732 Check a string for any occurrences of a specified list of invalid
2734 ********************************************************************/
2736 bool validate_net_name( const char *name,
2737 const char *invalid_chars,
2742 for ( i=0; i<max_len && name[i]; i++ ) {
2743 /* fail if strchr_m() finds one of the invalid characters */
2744 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2754 return the number of bytes occupied by a buffer in ASCII format
2755 the result includes the null termination
2756 limited by 'n' bytes
2758 size_t ascii_len_n(const char *src, size_t n)
2762 len = strnlen(src, n);
2771 return the number of bytes occupied by a buffer in CH_UTF16 format
2772 the result includes the null termination
2774 size_t utf16_len(const void *buf)
2778 for (len = 0; SVAL(buf,len); len += 2) ;
2784 return the number of bytes occupied by a buffer in CH_UTF16 format
2785 the result includes the null termination
2786 limited by 'n' bytes
2788 size_t utf16_len_n(const void *src, size_t n)
2792 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2801 /*******************************************************************
2802 Add a shell escape character '\' to any character not in a known list
2803 of characters. UNIX charset format.
2804 *******************************************************************/
2806 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2807 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2809 char *escape_shell_string(const char *src)
2811 size_t srclen = strlen(src);
2812 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2814 bool in_s_quote = false;
2815 bool in_d_quote = false;
2816 bool next_escaped = false;
2824 codepoint_t c = next_codepoint(src, &c_size);
2826 if (c == INVALID_CODEPOINT) {
2832 memcpy(dest, src, c_size);
2835 next_escaped = false;
2840 * Deal with backslash escaped state.
2841 * This only lasts for one character.
2846 next_escaped = false;
2851 * Deal with single quote state. The
2852 * only thing we care about is exiting
2865 * Deal with double quote state. The most
2866 * complex state. We must cope with \, meaning
2867 * possibly escape next char (depending what it
2868 * is), ", meaning exit this state, and possibly
2869 * add an \ escape to any unprotected character
2870 * (listed in INSIDE_DQUOTE_LIST).
2876 * Next character might be escaped.
2877 * We have to peek. Inside double
2878 * quotes only INSIDE_DQUOTE_LIST
2879 * characters are escaped by a \.
2884 c = next_codepoint(&src[1], &c_size);
2885 if (c == INVALID_CODEPOINT) {
2891 * Don't escape the next char.
2900 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2902 next_escaped = true;
2909 /* Exit double quote state. */
2916 * We know the character isn't \ or ",
2917 * so escape it if it's any of the other
2918 * possible unprotected characters.
2921 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2929 * From here to the end of the loop we're
2930 * not in the single or double quote state.
2934 /* Next character must be escaped. */
2935 next_escaped = true;
2941 /* Go into single quote state. */
2948 /* Go into double quote state. */
2954 /* Check if we need to escape the character. */
2956 if (!strchr(INCLUDE_LIST, (int)*src)) {