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;
89 * Get the next token from a string, return false if none found. Handles
90 * double-quotes. This version trims leading separator characters before
91 * looking for a token.
93 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
95 return next_token_internal(ptr, buff, sep, bufsize, true);
99 * Get the next token from a string, return false if none found. Handles
100 * double-quotes. This version does not trim leading separator characters
101 * before looking for a token.
103 bool next_token_no_ltrim(const char **ptr,
108 return next_token_internal(ptr, buff, sep, bufsize, false);
112 This is like next_token but is not re-entrant and "remembers" the first
113 parameter so you can pass NULL. This is useful for user interface code
114 but beware the fact that it is not re-entrant!
117 static const char *last_ptr=NULL;
119 bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
125 ret = next_token(ptr, buff, sep, bufsize);
130 void set_first_token(char *ptr)
136 Convert list of tokens to array; dependent on above routine.
137 Uses last_ptr from above - bit of a hack.
140 char **toktocliplist(int *ctok, const char *sep)
142 char *s=(char *)last_ptr;
149 while(*s && strchr_m(sep,*s))
158 while(*s && (!strchr_m(sep,*s)))
160 while(*s && strchr_m(sep,*s))
167 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
185 * Case insensitive string compararison.
187 * iconv does not directly give us a way to compare strings in
188 * arbitrary unix character sets -- all we can is convert and then
189 * compare. This is expensive.
191 * As an optimization, we do a first pass that considers only the
192 * prefix of the strings that is entirely 7-bit. Within this, we
193 * check whether they have the same value.
195 * Hopefully this will often give the answer without needing to copy.
196 * In particular it should speed comparisons to literal ascii strings
197 * or comparisons of strings that are "obviously" different.
199 * If we find a non-ascii character we fall back to converting via
202 * This should never be slower than convering the whole thing, and
205 * A different optimization would be to compare for bitwise equality
206 * in the binary encoding. (It would be possible thought hairy to do
207 * both simultaneously.) But in that case if they turn out to be
208 * different, we'd need to restart the whole thing.
210 * Even better is to implement strcasecmp for each encoding and use a
213 int StrCaseCmp(const char *s, const char *t)
218 smb_ucs2_t *buffer_s, *buffer_t;
221 for (ps = s, pt = t; ; ps++, pt++) {
225 return 0; /* both ended */
227 return -1; /* s is a prefix */
229 return +1; /* t is a prefix */
230 else if ((*ps & 0x80) || (*pt & 0x80))
231 /* not ascii anymore, do it the hard way
235 us = toupper_ascii(*ps);
236 ut = toupper_ascii(*pt);
245 size = push_ucs2_allocate(&buffer_s, ps);
246 if (size == (size_t)-1) {
247 return strcmp(ps, pt);
248 /* Not quite the right answer, but finding the right one
249 under this failure case is expensive, and it's pretty
253 size = push_ucs2_allocate(&buffer_t, pt);
254 if (size == (size_t)-1) {
256 return strcmp(ps, pt);
257 /* Not quite the right answer, but finding the right one
258 under this failure case is expensive, and it's pretty
262 ret = strcasecmp_w(buffer_s, buffer_t);
270 Case insensitive string compararison, length limited.
272 int StrnCaseCmp(const char *s, const char *t, size_t len)
277 smb_ucs2_t *buffer_s, *buffer_t;
280 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
284 return 0; /* both ended */
286 return -1; /* s is a prefix */
288 return +1; /* t is a prefix */
289 else if ((*ps & 0x80) || (*pt & 0x80))
290 /* not ascii anymore, do it the
291 * hard way from here on in */
294 us = toupper_ascii(*ps);
295 ut = toupper_ascii(*pt);
308 size = push_ucs2_allocate(&buffer_s, ps);
309 if (size == (size_t)-1) {
310 return strncmp(ps, pt, len-n);
311 /* Not quite the right answer, but finding the right one
312 under this failure case is expensive,
313 and it's pretty close */
316 size = push_ucs2_allocate(&buffer_t, pt);
317 if (size == (size_t)-1) {
319 return strncmp(ps, pt, len-n);
320 /* Not quite the right answer, but finding the right one
321 under this failure case is expensive,
322 and it's pretty close */
325 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
334 * @note The comparison is case-insensitive.
336 bool strequal(const char *s1, const char *s2)
343 return(StrCaseCmp(s1,s2)==0);
347 * Compare 2 strings up to and including the nth char.
349 * @note The comparison is case-insensitive.
351 bool strnequal(const char *s1,const char *s2,size_t n)
355 if (!s1 || !s2 || !n)
358 return(StrnCaseCmp(s1,s2,n)==0);
362 Compare 2 strings (case sensitive).
365 bool strcsequal(const char *s1,const char *s2)
372 return(strcmp(s1,s2)==0);
376 Do a case-insensitive, whitespace-ignoring string compare.
379 int strwicmp(const char *psz1, const char *psz2)
381 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
382 /* appropriate value. */
385 else if (psz1 == NULL)
387 else if (psz2 == NULL)
390 /* sync the strings on first non-whitespace */
392 while (isspace((int)*psz1))
394 while (isspace((int)*psz2))
396 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
397 *psz1 == '\0' || *psz2 == '\0')
402 return (*psz1 - *psz2);
407 Convert a string to upper case, but don't modify it.
410 char *strupper_static(const char *s)
412 static char *str = NULL;
421 Convert a string to "normal" form.
424 void strnorm(char *s, int case_default)
426 if (case_default == CASE_UPPER)
433 Check if a string is in "normal" case.
436 bool strisnormal(const char *s, int case_default)
438 if (case_default == CASE_UPPER)
439 return(!strhaslower(s));
441 return(!strhasupper(s));
447 NOTE: oldc and newc must be 7 bit characters
449 void string_replace( char *s, char oldc, char newc )
453 /* this is quite a common operation, so we want it to be
454 fast. We optimise for the ascii case, knowing that all our
455 supported multi-byte character sets are ascii-compatible
456 (ie. they match for the first 128 chars) */
458 for (p = s; *p; p++) {
459 if (*p & 0x80) /* mb string - slow path. */
469 /* Slow (mb) path. */
470 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
471 /* With compose characters we must restart from the beginning. JRA. */
477 next_codepoint(p, &c_size);
489 * Skip past some strings in a buffer - old version - no checks.
492 char *push_skip_string(char *buf)
494 buf += strlen(buf) + 1;
499 Skip past a string in a buffer. Buffer may not be
500 null terminated. end_ptr points to the first byte after
501 then end of the buffer.
504 char *skip_string(const char *base, size_t len, char *buf)
506 const char *end_ptr = base + len;
508 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
512 /* Skip the string */
515 if (buf >= end_ptr) {
525 Count the number of characters in a string. Normally this will
526 be the same as the number of bytes in a string for single byte strings,
527 but will be different for multibyte.
530 size_t str_charnum(const char *s)
533 smb_ucs2_t *tmpbuf2 = NULL;
534 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
537 ret = strlen_w(tmpbuf2);
543 Count the number of characters in a string. Normally this will
544 be the same as the number of bytes in a string for single byte strings,
545 but will be different for multibyte.
548 size_t str_ascii_charnum(const char *s)
551 char *tmpbuf2 = NULL;
552 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
555 ret = strlen(tmpbuf2);
560 bool trim_char(char *s,char cfront,char cback)
566 /* Ignore null or empty strings. */
567 if (!s || (s[0] == '\0'))
571 while (*fp && *fp == cfront)
574 /* We ate the string. */
582 ep = fp + strlen(fp) - 1;
584 /* Attempt ascii only. Bail for mb strings. */
585 while ((ep >= fp) && (*ep == cback)) {
587 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
588 /* Could be mb... bail back to tim_string. */
596 return trim_string(s, cfront ? fs : NULL, bs);
602 /* We ate the string. */
609 memmove(s, fp, ep-fp+2);
614 Trim the specified elements off the front and back of a string.
617 bool trim_string(char *s,const char *front,const char *back)
624 /* Ignore null or empty strings. */
625 if (!s || (s[0] == '\0'))
628 front_len = front? strlen(front) : 0;
629 back_len = back? strlen(back) : 0;
634 while (len && strncmp(s, front, front_len)==0) {
635 /* Must use memmove here as src & dest can
636 * easily overlap. Found by valgrind. JRA. */
637 memmove(s, s+front_len, (len-front_len)+1);
644 while ((len >= back_len) &&
645 strncmp(s+len-back_len,back,back_len)==0) {
646 s[len-back_len]='\0';
655 Does a string have any uppercase chars in it?
658 bool strhasupper(const char *s)
663 if (push_ucs2_allocate(&tmp, s) == -1) {
667 for(p = tmp; *p != 0; p++) {
679 Does a string have any lowercase chars in it?
682 bool strhaslower(const char *s)
687 if (push_ucs2_allocate(&tmp, s) == -1) {
691 for(p = tmp; *p != 0; p++) {
703 Find the number of 'c' chars in a string
706 size_t count_chars(const char *s,char c)
710 smb_ucs2_t *alloc_tmpbuf = NULL;
712 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
716 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
717 if(*ptr==UCS2_CHAR(c))
720 SAFE_FREE(alloc_tmpbuf);
725 Safe string copy into a known length string. maxlength does not
726 include the terminating zero.
729 char *safe_strcpy_fn(const char *fn,
738 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
739 "called from [%s][%d]\n", fn, line));
744 clobber_region(fn,line,dest, maxlength+1);
752 len = strnlen(src, maxlength+1);
754 if (len > maxlength) {
755 DEBUG(0,("ERROR: string overflow by "
756 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
757 (unsigned long)(len-maxlength), (unsigned long)len,
758 (unsigned long)maxlength, src));
762 memmove(dest, src, len);
768 Safe string cat into a string. maxlength does not
769 include the terminating zero.
771 char *safe_strcat_fn(const char *fn,
777 size_t src_len, dest_len;
780 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
781 "called from [%s][%d]\n", fn, line));
788 src_len = strnlen(src, maxlength + 1);
789 dest_len = strnlen(dest, maxlength + 1);
792 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
795 if (src_len + dest_len > maxlength) {
796 DEBUG(0,("ERROR: string overflow by %d "
797 "in safe_strcat [%.50s]\n",
798 (int)(src_len + dest_len - maxlength), src));
799 if (maxlength > dest_len) {
800 memcpy(&dest[dest_len], src, maxlength - dest_len);
806 memcpy(&dest[dest_len], src, src_len);
807 dest[dest_len + src_len] = 0;
812 Paranoid strcpy into a buffer of given length (includes terminating
813 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
814 and replaces with '_'. Deliberately does *NOT* check for multibyte
815 characters. Don't change it !
818 char *alpha_strcpy_fn(const char *fn,
822 const char *other_safe_chars,
828 clobber_region(fn, line, dest, maxlength);
832 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
833 "called from [%s][%d]\n", fn, line));
843 if (len >= maxlength)
846 if (!other_safe_chars)
847 other_safe_chars = "";
849 for(i = 0; i < len; i++) {
850 int val = (src[i] & 0xff);
851 if (isupper_ascii(val) || islower_ascii(val) ||
852 isdigit(val) || strchr_m(other_safe_chars, val))
864 Like strncpy but always null terminates. Make sure there is room!
865 The variable n should always be one less than the available size.
867 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
872 clobber_region(fn, line, dest, n+1);
876 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
877 "called from [%s][%d]\n", fn, line));
886 while (n-- && (*d = *src)) {
897 Like strncpy but copies up to the character marker. always null terminates.
898 returns a pointer to the character marker in the source string (src).
901 static char *strncpyn(char *dest, const char *src, size_t n, char c)
907 clobber_region(dest, n+1);
909 p = strchr_m(src, c);
911 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
915 str_len = PTR_DIFF(p, src);
916 strncpy(dest, src, MIN(n, str_len));
917 dest[str_len] = '\0';
924 Routine to get hex characters and turn them into a 16 byte array.
925 the array can be variable length, and any non-hex-numeric
926 characters are skipped. "0xnn" or "0Xnn" is specially catered
929 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
933 size_t strhex_to_str(char *p, size_t len, const char *strhex)
936 size_t num_chars = 0;
937 unsigned char lonybble, hinybble;
938 const char *hexchars = "0123456789ABCDEF";
939 char *p1 = NULL, *p2 = NULL;
941 for (i = 0; i < len && strhex[i] != 0; i++) {
942 if (strnequal(hexchars, "0x", 2)) {
943 i++; /* skip two chars */
947 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
950 i++; /* next hex digit */
952 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
955 /* get the two nybbles */
956 hinybble = PTR_DIFF(p1, hexchars);
957 lonybble = PTR_DIFF(p2, hexchars);
959 p[num_chars] = (hinybble << 4) | lonybble;
968 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
973 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
975 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
977 ret_blob.length = strhex_to_str((char*)ret_blob.data,
985 * Routine to print a buffer as HEX digits, into an allocated string.
988 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
993 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
995 for (i = 0; i < len; i++)
996 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
1002 Check if a string is part of a list.
1005 bool in_list(const char *s, const char *list, bool casesensitive)
1009 size_t bufsize = strlen(list);
1015 /* We know a token can't be larger
1016 * than the entire list. */
1018 tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1023 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1024 if (casesensitive) {
1025 if (strcmp(tok,s) == 0) {
1030 if (StrCaseCmp(tok,s) == 0) {
1041 /* this is used to prevent lots of mallocs of size 1 */
1042 static const char *null_string = "";
1045 Set a string value, allocing the space for the string
1048 static bool string_init(char **dest,const char *src)
1058 *dest = CONST_DISCARD(char*, null_string);
1060 (*dest) = SMB_STRDUP(src);
1061 if ((*dest) == NULL) {
1062 DEBUG(0,("Out of memory in string_init\n"));
1070 Free a string value.
1073 void string_free(char **s)
1077 if (*s == null_string)
1083 Set a string value, deallocating any existing space, and allocing the space
1087 bool string_set(char **dest,const char *src)
1090 return(string_init(dest,src));
1094 Substitute a string for a pattern in another string. Make sure there is
1097 This routine looks for pattern in s and replaces it with
1098 insert. It may do multiple replacements or just one.
1100 Any of " ; ' $ or ` in the insert string are replaced with _
1101 if len==0 then the string cannot be extended. This is different from the old
1102 use of len==0 which was for no length checks to be done.
1105 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1106 bool remove_unsafe_characters, bool replace_once,
1107 bool allow_trailing_dollar)
1110 ssize_t ls,lp,li, i;
1112 if (!insert || !pattern || !*pattern || !s)
1115 ls = (ssize_t)strlen(s);
1116 lp = (ssize_t)strlen(pattern);
1117 li = (ssize_t)strlen(insert);
1120 len = ls + 1; /* len is number of *bytes* */
1122 while (lp <= ls && (p = strstr_m(s,pattern))) {
1123 if (ls + (li-lp) >= len) {
1124 DEBUG(0,("ERROR: string overflow by "
1125 "%d in string_sub(%.50s, %d)\n",
1126 (int)(ls + (li-lp) - len),
1127 pattern, (int)len));
1131 memmove(p+li,p+lp,strlen(p+lp)+1);
1133 for (i=0;i<li;i++) {
1134 switch (insert[i]) {
1140 /* allow a trailing $
1141 * (as in machine accounts) */
1142 if (allow_trailing_dollar && (i == li - 1 )) {
1149 if ( remove_unsafe_characters ) {
1151 /* yes this break should be here
1152 * since we want to fall throw if
1153 * not replacing unsafe chars */
1168 void string_sub_once(char *s, const char *pattern,
1169 const char *insert, size_t len)
1171 string_sub2( s, pattern, insert, len, true, true, false );
1174 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1176 string_sub2( s, pattern, insert, len, true, false, false );
1179 void fstring_sub(char *s,const char *pattern,const char *insert)
1181 string_sub(s, pattern, insert, sizeof(fstring));
1184 void pstring_sub(char *s,const char *pattern,const char *insert)
1186 string_sub(s, pattern, insert, sizeof(pstring));
1190 Similar to string_sub2, but it will accept only allocated strings
1191 and may realloc them so pay attention at what you pass on no
1192 pointers inside strings, no pstrings or const may be passed
1196 char *realloc_string_sub2(char *string,
1197 const char *pattern,
1199 bool remove_unsafe_characters,
1200 bool allow_trailing_dollar)
1204 ssize_t ls,lp,li,ld, i;
1206 if (!insert || !pattern || !*pattern || !string || !*string)
1211 in = SMB_STRDUP(insert);
1213 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1216 ls = (ssize_t)strlen(s);
1217 lp = (ssize_t)strlen(pattern);
1218 li = (ssize_t)strlen(insert);
1220 for (i=0;i<li;i++) {
1227 /* allow a trailing $
1228 * (as in machine accounts) */
1229 if (allow_trailing_dollar && (i == li - 1 )) {
1235 if ( remove_unsafe_characters ) {
1245 while ((p = strstr_m(s,pattern))) {
1247 int offset = PTR_DIFF(s,string);
1248 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1250 DEBUG(0, ("realloc_string_sub: "
1251 "out of memory!\n"));
1255 p = string + offset + (p - s);
1258 memmove(p+li,p+lp,strlen(p+lp)+1);
1268 char *realloc_string_sub(char *string,
1269 const char *pattern,
1272 return realloc_string_sub2(string, pattern, insert, true, false);
1276 * Internal guts of talloc_string_sub and talloc_all_string_sub.
1277 * 'filter' differentiates between them.
1280 static char *talloc_string_sub_internal(TALLOC_CTX *mem_ctx, const char *src,
1281 const char *pattern, const char *insert, bool filter)
1286 ssize_t ls,lp,li,ld, i;
1288 if (!insert || !pattern || !*pattern || !src || !*src) {
1292 string = talloc_strdup(mem_ctx, src);
1293 if (string == NULL) {
1294 DEBUG(0, ("talloc_string_sub_internal: "
1295 "talloc_strdup failed\n"));
1301 in = SMB_STRDUP(insert);
1303 DEBUG(0, ("talloc_string_sub_internal: ENOMEM\n"));
1306 ls = (ssize_t)strlen(s);
1307 lp = (ssize_t)strlen(pattern);
1308 li = (ssize_t)strlen(insert);
1312 for (i=0;i<li;i++) {
1330 while ((p = strstr_m(s,pattern))) {
1332 int offset = PTR_DIFF(s,string);
1333 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1336 DEBUG(0, ("talloc_string_sub: out of "
1341 p = string + offset + (p - s);
1344 memmove(p+li,p+lp,strlen(p+lp)+1);
1354 /* Same as string_sub, but returns a talloc'ed string */
1356 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1357 const char *pattern, const char *insert)
1359 return talloc_string_sub_internal(mem_ctx, src, pattern, insert, true);
1363 Similar to string_sub() but allows for any character to be substituted.
1365 if len==0 then the string cannot be extended. This is different from the old
1366 use of len==0 which was for no length checks to be done.
1369 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1374 if (!insert || !pattern || !s)
1377 ls = (ssize_t)strlen(s);
1378 lp = (ssize_t)strlen(pattern);
1379 li = (ssize_t)strlen(insert);
1385 len = ls + 1; /* len is number of *bytes* */
1387 while (lp <= ls && (p = strstr_m(s,pattern))) {
1388 if (ls + (li-lp) >= len) {
1389 DEBUG(0,("ERROR: string overflow by "
1390 "%d in all_string_sub(%.50s, %d)\n",
1391 (int)(ls + (li-lp) - len),
1392 pattern, (int)len));
1396 memmove(p+li,p+lp,strlen(p+lp)+1);
1398 memcpy(p, insert, li);
1404 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1406 const char *pattern,
1409 return talloc_string_sub_internal(ctx, src, pattern, insert, false);
1413 Similar to all_string_sub but for unicode strings.
1414 Return a new allocated unicode string.
1415 similar to string_sub() but allows for any character to be substituted.
1419 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s,
1420 const smb_ucs2_t *pattern,
1421 const smb_ucs2_t *insert)
1424 const smb_ucs2_t *sp;
1425 size_t lr, lp, li, lt;
1427 if (!insert || !pattern || !*pattern || !s)
1430 lt = (size_t)strlen_w(s);
1431 lp = (size_t)strlen_w(pattern);
1432 li = (size_t)strlen_w(insert);
1435 const smb_ucs2_t *st = s;
1437 while ((sp = strstr_w(st, pattern))) {
1443 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1445 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1449 while ((sp = strstr_w(s, pattern))) {
1450 memcpy(rp, s, (sp - s));
1451 rp += ((sp - s) / sizeof(smb_ucs2_t));
1452 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1456 lr = ((rp - r) / sizeof(smb_ucs2_t));
1458 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1466 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1471 if (!insert || !pattern || !s)
1473 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1474 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1475 return all_string_sub_w(s, p, i);
1480 Splits out the front and back at a separator.
1483 static void split_at_last_component(char *path, char *front, char sep,
1486 char *p = strrchr_m(path, sep);
1492 pstrcpy(front, path);
1506 Write an octal as a string.
1509 const char *octal_string(int i)
1511 static char ret[64];
1514 slprintf(ret, sizeof(ret)-1, "0%o", i);
1520 Truncate a string at a specified length.
1523 char *string_truncate(char *s, unsigned int length)
1525 if (s && strlen(s) > length)
1531 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1532 We convert via ucs2 for now.
1535 char *strchr_m(const char *src, char c)
1537 smb_ucs2_t *ws = NULL;
1543 /* characters below 0x3F are guaranteed to not appear in
1544 non-initial position in multi-byte charsets */
1545 if ((c & 0xC0) == 0) {
1546 return strchr(src, c);
1549 /* this is quite a common operation, so we want it to be
1550 fast. We optimise for the ascii case, knowing that all our
1551 supported multi-byte character sets are ascii-compatible
1552 (ie. they match for the first 128 chars) */
1554 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1562 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1563 /* With compose characters we must restart from the beginning. JRA. */
1567 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1568 /* Wrong answer, but what can we do... */
1569 return strchr(src, c);
1571 p = strchr_w(ws, UCS2_CHAR(c));
1577 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1579 /* Wrong answer, but what can we do... */
1580 return strchr(src, c);
1582 ret = (char *)(s+strlen(s2));
1588 char *strrchr_m(const char *s, char c)
1590 /* characters below 0x3F are guaranteed to not appear in
1591 non-initial position in multi-byte charsets */
1592 if ((c & 0xC0) == 0) {
1593 return strrchr(s, c);
1596 /* this is quite a common operation, so we want it to be
1597 fast. We optimise for the ascii case, knowing that all our
1598 supported multi-byte character sets are ascii-compatible
1599 (ie. they match for the first 128 chars). Also, in Samba
1600 we only search for ascii characters in 'c' and that
1601 in all mb character sets with a compound character
1602 containing c, if 'c' is not a match at position
1603 p, then p[-1] > 0x7f. JRA. */
1606 size_t len = strlen(s);
1608 bool got_mb = false;
1615 /* Could be a match. Part of a multibyte ? */
1617 (((unsigned char)cp[-1]) & 0x80)) {
1618 /* Yep - go slow :-( */
1622 /* No - we have a match ! */
1625 } while (cp-- != s);
1630 /* String contained a non-ascii char. Slow path. */
1632 smb_ucs2_t *ws = NULL;
1637 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1638 /* Wrong answer, but what can we do. */
1639 return strrchr(s, c);
1641 p = strrchr_w(ws, UCS2_CHAR(c));
1647 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1649 /* Wrong answer, but what can we do. */
1650 return strrchr(s, c);
1652 ret = (char *)(s+strlen(s2));
1659 /***********************************************************************
1660 Return the equivalent of doing strrchr 'n' times - always going
1662 ***********************************************************************/
1664 char *strnrchr_m(const char *s, char c, unsigned int n)
1666 smb_ucs2_t *ws = NULL;
1671 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1672 /* Too hard to try and get right. */
1675 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1681 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1683 /* Too hard to try and get right. */
1686 ret = (char *)(s+strlen(s2));
1692 /***********************************************************************
1693 strstr_m - We convert via ucs2 for now.
1694 ***********************************************************************/
1696 char *strstr_m(const char *src, const char *findstr)
1699 smb_ucs2_t *src_w, *find_w;
1704 size_t findstr_len = 0;
1706 /* for correctness */
1711 /* Samba does single character findstr calls a *lot*. */
1712 if (findstr[1] == '\0')
1713 return strchr_m(src, *findstr);
1715 /* We optimise for the ascii case, knowing that all our
1716 supported multi-byte character sets are ascii-compatible
1717 (ie. they match for the first 128 chars) */
1719 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1720 if (*s == *findstr) {
1722 findstr_len = strlen(findstr);
1724 if (strncmp(s, findstr, findstr_len) == 0) {
1733 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1734 /* 'make check' fails unless we do this */
1736 /* With compose characters we must restart from the beginning. JRA. */
1740 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1741 DEBUG(0,("strstr_m: src malloc fail\n"));
1745 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1747 DEBUG(0,("strstr_m: find malloc fail\n"));
1751 p = strstr_w(src_w, find_w);
1760 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1763 DEBUG(0,("strstr_m: dest malloc fail\n"));
1766 retp = (char *)(s+strlen(s2));
1774 Convert a string to lower case.
1777 void strlower_m(char *s)
1782 /* this is quite a common operation, so we want it to be
1783 fast. We optimise for the ascii case, knowing that all our
1784 supported multi-byte character sets are ascii-compatible
1785 (ie. they match for the first 128 chars) */
1787 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1788 *s = tolower_ascii((unsigned char)*s);
1795 /* I assume that lowercased string takes the same number of bytes
1796 * as source string even in UTF-8 encoding. (VIV) */
1797 len = strlen(s) + 1;
1800 unix_strlower(s,len,s,len);
1801 /* Catch mb conversion errors that may not terminate. */
1808 Convert a string to upper case.
1811 void strupper_m(char *s)
1816 /* this is quite a common operation, so we want it to be
1817 fast. We optimise for the ascii case, knowing that all our
1818 supported multi-byte character sets are ascii-compatible
1819 (ie. they match for the first 128 chars) */
1821 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1822 *s = toupper_ascii((unsigned char)*s);
1829 /* I assume that lowercased string takes the same number of bytes
1830 * as source string even in multibyte encoding. (VIV) */
1831 len = strlen(s) + 1;
1834 unix_strupper(s,len,s,len);
1835 /* Catch mb conversion errors that may not terminate. */
1842 Count the number of UCS2 characters in a string. Normally this will
1843 be the same as the number of bytes in a string for single byte strings,
1844 but will be different for multibyte.
1847 size_t strlen_m(const char *s)
1855 while (*s && !(((uint8_t)*s) & 0x80)) {
1866 codepoint_t c = next_codepoint(s, &c_size);
1868 /* Unicode char fits into 16 bits. */
1871 /* Double-width unicode char - 32 bits. */
1881 Count the number of UCS2 characters in a string including the null
1885 size_t strlen_m_term(const char *s)
1890 return strlen_m(s) + 1;
1894 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1895 * if a string is there, include the terminator.
1898 size_t strlen_m_term_null(const char *s)
1912 Return a RFC2254 binary string representation of a buffer.
1913 Used in LDAP filters.
1917 char *binary_string_rfc2254(char *buf, int len)
1921 const char *hex = "0123456789ABCDEF";
1922 s = (char *)SMB_MALLOC(len * 3 + 1);
1925 for (j=i=0;i<len;i++) {
1927 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1928 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1935 char *binary_string(char *buf, int len)
1939 const char *hex = "0123456789ABCDEF";
1940 s = (char *)SMB_MALLOC(len * 2 + 1);
1943 for (j=i=0;i<len;i++) {
1944 s[j] = hex[((unsigned char)buf[i]) >> 4];
1945 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1952 Just a typesafety wrapper for snprintf into a pstring.
1955 int pstr_sprintf(pstring s, const char *fmt, ...)
1961 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1968 Just a typesafety wrapper for snprintf into a fstring.
1971 int fstr_sprintf(fstring s, const char *fmt, ...)
1977 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1983 List of Strings manipulation functions
1986 #define S_LIST_ABS 16 /* List Allocation Block Size */
1988 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
1992 char **list, **rlist;
1998 if (!string || !*string)
2001 s = talloc_strdup(mem_ctx, string);
2003 s = SMB_STRDUP(string);
2006 DEBUG(0,("str_list_make: Unable to allocate memory"));
2009 if (!sep) sep = LIST_SEP;
2015 while (next_token(&str, tok, sep, sizeof(tok))) {
2017 lsize += S_LIST_ABS;
2019 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
2022 /* We need to keep the old list on
2023 * error so we can free the elements
2024 if the realloc fails. */
2025 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2029 DEBUG(0,("str_list_make: "
2030 "Unable to allocate memory"));
2031 str_list_free(&list);
2041 memset (&list[num], 0,
2042 ((sizeof(char**)) * (S_LIST_ABS +1)));
2046 list[num] = talloc_strdup(mem_ctx, tok);
2048 list[num] = SMB_STRDUP(tok);
2052 DEBUG(0,("str_list_make: Unable to allocate memory"));
2053 str_list_free(&list);
2074 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
2078 return str_list_make_internal(mem_ctx, string, sep);
2081 char **str_list_make(const char *string, const char *sep)
2083 return str_list_make_internal(NULL, string, sep);
2086 bool str_list_copy(char ***dest, const char **src)
2088 char **list, **rlist;
2100 lsize += S_LIST_ABS;
2101 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2104 DEBUG(0,("str_list_copy: "
2105 "Unable to re-allocate memory"));
2106 str_list_free(&list);
2111 memset (&list[num], 0,
2112 ((sizeof(char **)) * (S_LIST_ABS +1)));
2115 list[num] = SMB_STRDUP(src[num]);
2117 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2118 str_list_free(&list);
2130 * Return true if all the elements of the list match exactly.
2132 bool str_list_compare(char **list1, char **list2)
2136 if (!list1 || !list2)
2137 return (list1 == list2);
2139 for (num = 0; list1[num]; num++) {
2142 if (!strcsequal(list1[num], list2[num]))
2146 return false; /* if list2 has more elements than list1 fail */
2151 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2155 if (!list || !*list)
2158 for(; *tlist; tlist++) {
2160 TALLOC_FREE(*tlist);
2166 TALLOC_FREE(*tlist);
2172 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2174 str_list_free_internal(mem_ctx, list);
2177 void str_list_free(char ***list)
2179 str_list_free_internal(NULL, list);
2182 /******************************************************************************
2183 *****************************************************************************/
2185 int str_list_count( const char **list )
2192 /* count the number of list members */
2194 for ( i=0; *list; i++, list++ );
2199 /******************************************************************************
2200 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2202 *****************************************************************************/
2204 bool str_list_sub_basic( char **list, const char *smb_name,
2205 const char *domain_name )
2211 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2213 DEBUG(0,("str_list_sub_basic: "
2214 "alloc_sub_basic() return NULL!\n"));
2227 /******************************************************************************
2228 substritute a specific pattern in a string list
2229 *****************************************************************************/
2231 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2234 ssize_t ls, lp, li, ld, i, d;
2243 lp = (ssize_t)strlen(pattern);
2244 li = (ssize_t)strlen(insert);
2249 ls = (ssize_t)strlen(s);
2251 while ((p = strstr_m(s, pattern))) {
2255 t = (char *) SMB_MALLOC(ls +ld +1);
2257 DEBUG(0,("str_list_substitute: "
2258 "Unable to allocate memory"));
2261 memcpy(t, *list, d);
2262 memcpy(t +d +li, p +lp, ls -d -lp +1);
2269 for (i = 0; i < li; i++) {
2270 switch (insert[i]) {
2282 t[d +i] = insert[i];
2294 #define IPSTR_LIST_SEP ","
2295 #define IPSTR_LIST_CHAR ','
2298 * Add ip string representation to ipstr list. Used also
2299 * as part of @function ipstr_list_make
2301 * @param ipstr_list pointer to string containing ip list;
2302 * MUST BE already allocated and IS reallocated if necessary
2303 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2304 * as a result of reallocation)
2305 * @param ip IP address which is to be added to list
2306 * @return pointer to string appended with new ip and possibly
2307 * reallocated to new length
2310 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2312 char *new_ipstr = NULL;
2313 char addr_buf[INET6_ADDRSTRLEN];
2315 /* arguments checking */
2316 if (!ipstr_list || !service) {
2320 print_sockaddr(addr_buf,
2324 /* attempt to convert ip to a string and append colon separator to it */
2326 if (service->ss.ss_family == AF_INET) {
2328 asprintf(&new_ipstr, "%s%s%s:%d",
2335 asprintf(&new_ipstr, "%s%s[%s]:%d",
2341 SAFE_FREE(*ipstr_list);
2343 if (service->ss.ss_family == AF_INET) {
2345 asprintf(&new_ipstr, "%s:%d",
2350 asprintf(&new_ipstr, "[%s]:%d",
2355 *ipstr_list = new_ipstr;
2360 * Allocate and initialise an ipstr list using ip adresses
2361 * passed as arguments.
2363 * @param ipstr_list pointer to string meant to be allocated and set
2364 * @param ip_list array of ip addresses to place in the list
2365 * @param ip_count number of addresses stored in ip_list
2366 * @return pointer to allocated ip string
2369 char *ipstr_list_make(char **ipstr_list,
2370 const struct ip_service *ip_list,
2375 /* arguments checking */
2376 if (!ip_list || !ipstr_list) {
2382 /* process ip addresses given as arguments */
2383 for (i = 0; i < ip_count; i++) {
2384 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2387 return (*ipstr_list);
2392 * Parse given ip string list into array of ip addresses
2393 * (as ip_service structures)
2394 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2396 * @param ipstr ip string list to be parsed
2397 * @param ip_list pointer to array of ip addresses which is
2398 * allocated by this function and must be freed by caller
2399 * @return number of succesfully parsed addresses
2402 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2408 if (!ipstr_list || !ip_list)
2411 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2412 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2413 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2414 (unsigned long)count));
2418 for ( i=0; next_token(&ipstr_list, token_str,
2419 IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
2420 char *s = token_str;
2421 char *p = strrchr(token_str, ':');
2425 (*ip_list)[i].port = atoi(p+1);
2428 /* convert single token to ip address */
2429 if (token_str[0] == '[') {
2432 p = strchr(token_str, ']');
2438 if (!interpret_string_addr(&(*ip_list)[i].ss,
2449 * Safely free ip string list
2451 * @param ipstr_list ip string list to be freed
2454 void ipstr_list_free(char* ipstr_list)
2456 SAFE_FREE(ipstr_list);
2460 Unescape a URL encoded string, in place.
2463 void rfc1738_unescape(char *buf)
2467 while (p && *p && (p=strchr_m(p,'%'))) {
2471 if (c1 >= '0' && c1 <= '9')
2473 else if (c1 >= 'A' && c1 <= 'F')
2475 else if (c1 >= 'a' && c1 <= 'f')
2477 else {p++; continue;}
2479 if (c2 >= '0' && c2 <= '9')
2481 else if (c2 >= 'A' && c2 <= 'F')
2483 else if (c2 >= 'a' && c2 <= 'f')
2485 else {p++; continue;}
2489 memmove(p+1, p+3, strlen(p+3)+1);
2494 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2497 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2499 DATA_BLOB base64_decode_data_blob(const char *s)
2501 int bit_offset, byte_offset, idx, i, n;
2502 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2503 unsigned char *d = decoded.data;
2508 while (*s && (p=strchr_m(b64,*s))) {
2509 idx = (int)(p - b64);
2510 byte_offset = (i*6)/8;
2511 bit_offset = (i*6)%8;
2512 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2513 if (bit_offset < 3) {
2514 d[byte_offset] |= (idx << (2-bit_offset));
2517 d[byte_offset] |= (idx >> (bit_offset-2));
2518 d[byte_offset+1] = 0;
2519 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2525 if ((n > 0) && (*s == '=')) {
2535 * Decode a base64 string in-place - wrapper for the above
2537 void base64_decode_inplace(char *s)
2539 DATA_BLOB decoded = base64_decode_data_blob(s);
2541 if ( decoded.length != 0 ) {
2542 memcpy(s, decoded.data, decoded.length);
2544 /* null terminate */
2545 s[decoded.length] = '\0';
2550 data_blob_free(&decoded);
2554 * Encode a base64 string into a malloc()ed string caller to free.
2556 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2560 char *base64_encode_data_blob(DATA_BLOB data)
2564 size_t out_cnt, len, output_len;
2567 if (!data.length || !data.data)
2572 output_len = data.length * 2;
2573 result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */
2574 SMB_ASSERT(result != NULL);
2576 while (len-- && out_cnt < (data.length * 2) - 5) {
2577 int c = (unsigned char) *(data.data++);
2580 if (char_count == 3) {
2581 result[out_cnt++] = b64[bits >> 18];
2582 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2583 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2584 result[out_cnt++] = b64[bits & 0x3f];
2591 if (char_count != 0) {
2592 bits <<= 16 - (8 * char_count);
2593 result[out_cnt++] = b64[bits >> 18];
2594 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2595 if (char_count == 1) {
2596 result[out_cnt++] = '=';
2597 result[out_cnt++] = '=';
2599 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2600 result[out_cnt++] = '=';
2603 result[out_cnt] = '\0'; /* terminate */
2607 /* read a SMB_BIG_UINT from a string */
2608 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2611 SMB_BIG_UINT val = -1;
2612 const char *p = nptr;
2621 while (*p && isspace(*p))
2624 #ifdef LARGE_SMB_OFF_T
2625 sscanf(p,"%llu",&val);
2626 #else /* LARGE_SMB_OFF_T */
2627 sscanf(p,"%lu",&val);
2628 #endif /* LARGE_SMB_OFF_T */
2630 while (*p && isdigit(*p))
2638 /* Convert a size specification to a count of bytes. We accept the following
2640 * bytes if there is no suffix
2645 * pP whatever the ISO name for petabytes is
2647 * Returns 0 if the string can't be converted.
2649 SMB_OFF_T conv_str_size(const char * str)
2654 if (str == NULL || *str == '\0') {
2658 #ifdef HAVE_STRTOULL
2659 if (sizeof(SMB_OFF_T) == 8) {
2660 lval = strtoull(str, &end, 10 /* base */);
2662 lval = strtoul(str, &end, 10 /* base */);
2665 lval = strtoul(str, &end, 10 /* base */);
2668 if (end == NULL || end == str) {
2673 SMB_OFF_T lval_orig = lval;
2675 if (strwicmp(end, "K") == 0) {
2676 lval *= (SMB_OFF_T)1024;
2677 } else if (strwicmp(end, "M") == 0) {
2678 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2679 } else if (strwicmp(end, "G") == 0) {
2680 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2682 } else if (strwicmp(end, "T") == 0) {
2683 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2684 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2685 } else if (strwicmp(end, "P") == 0) {
2686 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2687 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2693 /* Primitive attempt to detect wrapping on platforms with
2694 * 4-byte SMB_OFF_T. It's better to let the caller handle
2695 * a failure than some random number.
2697 if (lval_orig <= lval) {
2705 void string_append(char **left, const char *right)
2707 int new_len = strlen(right) + 1;
2709 if (*left == NULL) {
2710 *left = (char *)SMB_MALLOC(new_len);
2713 new_len += strlen(*left);
2714 *left = (char *)SMB_REALLOC(*left, new_len);
2717 if (*left == NULL) {
2721 safe_strcat(*left, right, new_len-1);
2724 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2725 const char *str, const char ***strings,
2728 char *dup_str = talloc_strdup(mem_ctx, str);
2730 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2731 const char *, (*num)+1);
2733 if ((*strings == NULL) || (dup_str == NULL)) {
2738 (*strings)[*num] = dup_str;
2743 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2744 * error checking in between. The indiation that something weird happened is
2747 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2748 size_t *bufsize, const char *fmt, ...)
2755 /* len<0 is an internal marker that something failed */
2759 if (*string == NULL) {
2763 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2764 if (*string == NULL)
2769 ret = vasprintf(&newstr, fmt, ap);
2777 while ((*len)+ret >= *bufsize) {
2780 if (*bufsize >= (1024*1024*256))
2785 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2787 if (*string == NULL) {
2792 StrnCpy((*string)+(*len), newstr, ret);
2803 Returns the substring from src between the first occurrence of
2804 the char "front" and the first occurence of the char "back".
2805 Mallocs the return string which must be freed. Not for use
2806 with wide character strings.
2808 char *sstring_sub(const char *src, char front, char back)
2810 char *temp1, *temp2, *temp3;
2813 temp1 = strchr(src, front);
2814 if (temp1 == NULL) return NULL;
2815 temp2 = strchr(src, back);
2816 if (temp2 == NULL) return NULL;
2817 len = temp2 - temp1;
2818 if (len <= 0) return NULL;
2819 temp3 = (char*)SMB_MALLOC(len);
2820 if (temp3 == NULL) {
2821 DEBUG(1,("Malloc failure in sstring_sub\n"));
2824 memcpy(temp3, temp1+1, len-1);
2825 temp3[len-1] = '\0';
2829 /********************************************************************
2830 Check a string for any occurrences of a specified list of invalid
2832 ********************************************************************/
2834 bool validate_net_name( const char *name,
2835 const char *invalid_chars,
2840 for ( i=0; i<max_len && name[i]; i++ ) {
2841 /* fail if strchr_m() finds one of the invalid characters */
2842 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2852 return the number of bytes occupied by a buffer in ASCII format
2853 the result includes the null termination
2854 limited by 'n' bytes
2856 size_t ascii_len_n(const char *src, size_t n)
2860 len = strnlen(src, n);
2869 return the number of bytes occupied by a buffer in CH_UTF16 format
2870 the result includes the null termination
2872 size_t utf16_len(const void *buf)
2876 for (len = 0; SVAL(buf,len); len += 2) ;
2882 return the number of bytes occupied by a buffer in CH_UTF16 format
2883 the result includes the null termination
2884 limited by 'n' bytes
2886 size_t utf16_len_n(const void *src, size_t n)
2890 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2899 /*******************************************************************
2900 Add a shell escape character '\' to any character not in a known list
2901 of characters. UNIX charset format.
2902 *******************************************************************/
2904 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2905 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2907 char *escape_shell_string(const char *src)
2909 size_t srclen = strlen(src);
2910 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2912 bool in_s_quote = false;
2913 bool in_d_quote = false;
2914 bool next_escaped = false;
2922 codepoint_t c = next_codepoint(src, &c_size);
2924 if (c == INVALID_CODEPOINT) {
2930 memcpy(dest, src, c_size);
2933 next_escaped = false;
2938 * Deal with backslash escaped state.
2939 * This only lasts for one character.
2944 next_escaped = false;
2949 * Deal with single quote state. The
2950 * only thing we care about is exiting
2963 * Deal with double quote state. The most
2964 * complex state. We must cope with \, meaning
2965 * possibly escape next char (depending what it
2966 * is), ", meaning exit this state, and possibly
2967 * add an \ escape to any unprotected character
2968 * (listed in INSIDE_DQUOTE_LIST).
2974 * Next character might be escaped.
2975 * We have to peek. Inside double
2976 * quotes only INSIDE_DQUOTE_LIST
2977 * characters are escaped by a \.
2982 c = next_codepoint(&src[1], &c_size);
2983 if (c == INVALID_CODEPOINT) {
2989 * Don't escape the next char.
2998 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
3000 next_escaped = true;
3007 /* Exit double quote state. */
3014 * We know the character isn't \ or ",
3015 * so escape it if it's any of the other
3016 * possible unprotected characters.
3019 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
3027 * From here to the end of the loop we're
3028 * not in the single or double quote state.
3032 /* Next character must be escaped. */
3033 next_escaped = true;
3039 /* Go into single quote state. */
3046 /* Go into double quote state. */
3052 /* Check if we need to escape the character. */
3054 if (!strchr(INCLUDE_LIST, (int)*src)) {