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_sub, 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_sub(char *string, const char *pattern,
1201 ssize_t ls,lp,li,ld, i;
1203 if (!insert || !pattern || !*pattern || !string || !*string)
1208 in = SMB_STRDUP(insert);
1210 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1213 ls = (ssize_t)strlen(s);
1214 lp = (ssize_t)strlen(pattern);
1215 li = (ssize_t)strlen(insert);
1217 for (i=0;i<li;i++) {
1234 while ((p = strstr_m(s,pattern))) {
1236 int offset = PTR_DIFF(s,string);
1237 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1239 DEBUG(0, ("realloc_string_sub: "
1240 "out of memory!\n"));
1244 p = string + offset + (p - s);
1247 memmove(p+li,p+lp,strlen(p+lp)+1);
1258 * Internal guts of talloc_string_sub and talloc_all_string_sub.
1259 * 'filter' differentiates between them.
1262 static char *talloc_string_sub_internal(TALLOC_CTX *mem_ctx, const char *src,
1263 const char *pattern, const char *insert, bool filter)
1268 ssize_t ls,lp,li,ld, i;
1270 if (!insert || !pattern || !*pattern || !src || !*src) {
1274 string = talloc_strdup(mem_ctx, src);
1275 if (string == NULL) {
1276 DEBUG(0, ("talloc_string_sub_internal: "
1277 "talloc_strdup failed\n"));
1283 in = SMB_STRDUP(insert);
1285 DEBUG(0, ("talloc_string_sub_internal: ENOMEM\n"));
1288 ls = (ssize_t)strlen(s);
1289 lp = (ssize_t)strlen(pattern);
1290 li = (ssize_t)strlen(insert);
1294 for (i=0;i<li;i++) {
1312 while ((p = strstr_m(s,pattern))) {
1314 int offset = PTR_DIFF(s,string);
1315 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1318 DEBUG(0, ("talloc_string_sub: out of "
1323 p = string + offset + (p - s);
1326 memmove(p+li,p+lp,strlen(p+lp)+1);
1336 /* Same as string_sub, but returns a talloc'ed string */
1338 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1339 const char *pattern, const char *insert)
1341 return talloc_string_sub_internal(mem_ctx, src, pattern, insert, true);
1345 Similar to string_sub() but allows for any character to be substituted.
1347 if len==0 then the string cannot be extended. This is different from the old
1348 use of len==0 which was for no length checks to be done.
1351 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1356 if (!insert || !pattern || !s)
1359 ls = (ssize_t)strlen(s);
1360 lp = (ssize_t)strlen(pattern);
1361 li = (ssize_t)strlen(insert);
1367 len = ls + 1; /* len is number of *bytes* */
1369 while (lp <= ls && (p = strstr_m(s,pattern))) {
1370 if (ls + (li-lp) >= len) {
1371 DEBUG(0,("ERROR: string overflow by "
1372 "%d in all_string_sub(%.50s, %d)\n",
1373 (int)(ls + (li-lp) - len),
1374 pattern, (int)len));
1378 memmove(p+li,p+lp,strlen(p+lp)+1);
1380 memcpy(p, insert, li);
1386 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1388 const char *pattern,
1391 return talloc_string_sub_internal(ctx, src, pattern, insert, false);
1395 Similar to all_string_sub but for unicode strings.
1396 Return a new allocated unicode string.
1397 similar to string_sub() but allows for any character to be substituted.
1401 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s,
1402 const smb_ucs2_t *pattern,
1403 const smb_ucs2_t *insert)
1406 const smb_ucs2_t *sp;
1407 size_t lr, lp, li, lt;
1409 if (!insert || !pattern || !*pattern || !s)
1412 lt = (size_t)strlen_w(s);
1413 lp = (size_t)strlen_w(pattern);
1414 li = (size_t)strlen_w(insert);
1417 const smb_ucs2_t *st = s;
1419 while ((sp = strstr_w(st, pattern))) {
1425 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1427 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1431 while ((sp = strstr_w(s, pattern))) {
1432 memcpy(rp, s, (sp - s));
1433 rp += ((sp - s) / sizeof(smb_ucs2_t));
1434 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1438 lr = ((rp - r) / sizeof(smb_ucs2_t));
1440 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1448 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1453 if (!insert || !pattern || !s)
1455 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1456 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1457 return all_string_sub_w(s, p, i);
1462 Splits out the front and back at a separator.
1465 static void split_at_last_component(char *path, char *front, char sep,
1468 char *p = strrchr_m(path, sep);
1474 pstrcpy(front, path);
1488 Write an octal as a string.
1491 const char *octal_string(int i)
1493 static char ret[64];
1496 slprintf(ret, sizeof(ret)-1, "0%o", i);
1502 Truncate a string at a specified length.
1505 char *string_truncate(char *s, unsigned int length)
1507 if (s && strlen(s) > length)
1513 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1514 We convert via ucs2 for now.
1517 char *strchr_m(const char *src, char c)
1519 smb_ucs2_t *ws = NULL;
1525 /* characters below 0x3F are guaranteed to not appear in
1526 non-initial position in multi-byte charsets */
1527 if ((c & 0xC0) == 0) {
1528 return strchr(src, c);
1531 /* this is quite a common operation, so we want it to be
1532 fast. We optimise for the ascii case, knowing that all our
1533 supported multi-byte character sets are ascii-compatible
1534 (ie. they match for the first 128 chars) */
1536 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1544 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1545 /* With compose characters we must restart from the beginning. JRA. */
1549 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1550 /* Wrong answer, but what can we do... */
1551 return strchr(src, c);
1553 p = strchr_w(ws, UCS2_CHAR(c));
1559 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1561 /* Wrong answer, but what can we do... */
1562 return strchr(src, c);
1564 ret = (char *)(s+strlen(s2));
1570 char *strrchr_m(const char *s, char c)
1572 /* characters below 0x3F are guaranteed to not appear in
1573 non-initial position in multi-byte charsets */
1574 if ((c & 0xC0) == 0) {
1575 return strrchr(s, c);
1578 /* this is quite a common operation, so we want it to be
1579 fast. We optimise for the ascii case, knowing that all our
1580 supported multi-byte character sets are ascii-compatible
1581 (ie. they match for the first 128 chars). Also, in Samba
1582 we only search for ascii characters in 'c' and that
1583 in all mb character sets with a compound character
1584 containing c, if 'c' is not a match at position
1585 p, then p[-1] > 0x7f. JRA. */
1588 size_t len = strlen(s);
1590 bool got_mb = false;
1597 /* Could be a match. Part of a multibyte ? */
1599 (((unsigned char)cp[-1]) & 0x80)) {
1600 /* Yep - go slow :-( */
1604 /* No - we have a match ! */
1607 } while (cp-- != s);
1612 /* String contained a non-ascii char. Slow path. */
1614 smb_ucs2_t *ws = NULL;
1619 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1620 /* Wrong answer, but what can we do. */
1621 return strrchr(s, c);
1623 p = strrchr_w(ws, UCS2_CHAR(c));
1629 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1631 /* Wrong answer, but what can we do. */
1632 return strrchr(s, c);
1634 ret = (char *)(s+strlen(s2));
1641 /***********************************************************************
1642 Return the equivalent of doing strrchr 'n' times - always going
1644 ***********************************************************************/
1646 char *strnrchr_m(const char *s, char c, unsigned int n)
1648 smb_ucs2_t *ws = NULL;
1653 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1654 /* Too hard to try and get right. */
1657 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1663 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1665 /* Too hard to try and get right. */
1668 ret = (char *)(s+strlen(s2));
1674 /***********************************************************************
1675 strstr_m - We convert via ucs2 for now.
1676 ***********************************************************************/
1678 char *strstr_m(const char *src, const char *findstr)
1681 smb_ucs2_t *src_w, *find_w;
1686 size_t findstr_len = 0;
1688 /* for correctness */
1693 /* Samba does single character findstr calls a *lot*. */
1694 if (findstr[1] == '\0')
1695 return strchr_m(src, *findstr);
1697 /* We optimise for the ascii case, knowing that all our
1698 supported multi-byte character sets are ascii-compatible
1699 (ie. they match for the first 128 chars) */
1701 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1702 if (*s == *findstr) {
1704 findstr_len = strlen(findstr);
1706 if (strncmp(s, findstr, findstr_len) == 0) {
1715 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1716 /* 'make check' fails unless we do this */
1718 /* With compose characters we must restart from the beginning. JRA. */
1722 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1723 DEBUG(0,("strstr_m: src malloc fail\n"));
1727 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1729 DEBUG(0,("strstr_m: find malloc fail\n"));
1733 p = strstr_w(src_w, find_w);
1742 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1745 DEBUG(0,("strstr_m: dest malloc fail\n"));
1748 retp = (char *)(s+strlen(s2));
1756 Convert a string to lower case.
1759 void strlower_m(char *s)
1764 /* this is quite a common operation, so we want it to be
1765 fast. We optimise for the ascii case, knowing that all our
1766 supported multi-byte character sets are ascii-compatible
1767 (ie. they match for the first 128 chars) */
1769 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1770 *s = tolower_ascii((unsigned char)*s);
1777 /* I assume that lowercased string takes the same number of bytes
1778 * as source string even in UTF-8 encoding. (VIV) */
1779 len = strlen(s) + 1;
1782 unix_strlower(s,len,s,len);
1783 /* Catch mb conversion errors that may not terminate. */
1790 Convert a string to upper case.
1793 void strupper_m(char *s)
1798 /* this is quite a common operation, so we want it to be
1799 fast. We optimise for the ascii case, knowing that all our
1800 supported multi-byte character sets are ascii-compatible
1801 (ie. they match for the first 128 chars) */
1803 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1804 *s = toupper_ascii((unsigned char)*s);
1811 /* I assume that lowercased string takes the same number of bytes
1812 * as source string even in multibyte encoding. (VIV) */
1813 len = strlen(s) + 1;
1816 unix_strupper(s,len,s,len);
1817 /* Catch mb conversion errors that may not terminate. */
1824 Count the number of UCS2 characters in a string. Normally this will
1825 be the same as the number of bytes in a string for single byte strings,
1826 but will be different for multibyte.
1829 size_t strlen_m(const char *s)
1837 while (*s && !(((uint8_t)*s) & 0x80)) {
1848 codepoint_t c = next_codepoint(s, &c_size);
1850 /* Unicode char fits into 16 bits. */
1853 /* Double-width unicode char - 32 bits. */
1863 Count the number of UCS2 characters in a string including the null
1867 size_t strlen_m_term(const char *s)
1872 return strlen_m(s) + 1;
1876 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1877 * if a string is there, include the terminator.
1880 size_t strlen_m_term_null(const char *s)
1894 Return a RFC2254 binary string representation of a buffer.
1895 Used in LDAP filters.
1899 char *binary_string_rfc2254(char *buf, int len)
1903 const char *hex = "0123456789ABCDEF";
1904 s = (char *)SMB_MALLOC(len * 3 + 1);
1907 for (j=i=0;i<len;i++) {
1909 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1910 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1917 char *binary_string(char *buf, int len)
1921 const char *hex = "0123456789ABCDEF";
1922 s = (char *)SMB_MALLOC(len * 2 + 1);
1925 for (j=i=0;i<len;i++) {
1926 s[j] = hex[((unsigned char)buf[i]) >> 4];
1927 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1934 Just a typesafety wrapper for snprintf into a pstring.
1937 int pstr_sprintf(pstring s, const char *fmt, ...)
1943 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1950 Just a typesafety wrapper for snprintf into a fstring.
1953 int fstr_sprintf(fstring s, const char *fmt, ...)
1959 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1965 List of Strings manipulation functions
1968 #define S_LIST_ABS 16 /* List Allocation Block Size */
1970 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
1974 char **list, **rlist;
1980 if (!string || !*string)
1983 s = talloc_strdup(mem_ctx, string);
1985 s = SMB_STRDUP(string);
1988 DEBUG(0,("str_list_make: Unable to allocate memory"));
1991 if (!sep) sep = LIST_SEP;
1997 while (next_token(&str, tok, sep, sizeof(tok))) {
1999 lsize += S_LIST_ABS;
2001 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
2004 /* We need to keep the old list on
2005 * error so we can free the elements
2006 if the realloc fails. */
2007 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2011 DEBUG(0,("str_list_make: "
2012 "Unable to allocate memory"));
2013 str_list_free(&list);
2023 memset (&list[num], 0,
2024 ((sizeof(char**)) * (S_LIST_ABS +1)));
2028 list[num] = talloc_strdup(mem_ctx, tok);
2030 list[num] = SMB_STRDUP(tok);
2034 DEBUG(0,("str_list_make: Unable to allocate memory"));
2035 str_list_free(&list);
2056 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
2060 return str_list_make_internal(mem_ctx, string, sep);
2063 char **str_list_make(const char *string, const char *sep)
2065 return str_list_make_internal(NULL, string, sep);
2068 bool str_list_copy(char ***dest, const char **src)
2070 char **list, **rlist;
2082 lsize += S_LIST_ABS;
2083 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2086 DEBUG(0,("str_list_copy: "
2087 "Unable to re-allocate memory"));
2088 str_list_free(&list);
2093 memset (&list[num], 0,
2094 ((sizeof(char **)) * (S_LIST_ABS +1)));
2097 list[num] = SMB_STRDUP(src[num]);
2099 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2100 str_list_free(&list);
2112 * Return true if all the elements of the list match exactly.
2114 bool str_list_compare(char **list1, char **list2)
2118 if (!list1 || !list2)
2119 return (list1 == list2);
2121 for (num = 0; list1[num]; num++) {
2124 if (!strcsequal(list1[num], list2[num]))
2128 return false; /* if list2 has more elements than list1 fail */
2133 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2137 if (!list || !*list)
2140 for(; *tlist; tlist++) {
2142 TALLOC_FREE(*tlist);
2148 TALLOC_FREE(*tlist);
2154 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2156 str_list_free_internal(mem_ctx, list);
2159 void str_list_free(char ***list)
2161 str_list_free_internal(NULL, list);
2164 /******************************************************************************
2165 *****************************************************************************/
2167 int str_list_count( const char **list )
2174 /* count the number of list members */
2176 for ( i=0; *list; i++, list++ );
2181 /******************************************************************************
2182 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2184 *****************************************************************************/
2186 bool str_list_sub_basic( char **list, const char *smb_name,
2187 const char *domain_name )
2193 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2195 DEBUG(0,("str_list_sub_basic: "
2196 "alloc_sub_basic() return NULL!\n"));
2209 /******************************************************************************
2210 substritute a specific pattern in a string list
2211 *****************************************************************************/
2213 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2216 ssize_t ls, lp, li, ld, i, d;
2225 lp = (ssize_t)strlen(pattern);
2226 li = (ssize_t)strlen(insert);
2231 ls = (ssize_t)strlen(s);
2233 while ((p = strstr_m(s, pattern))) {
2237 t = (char *) SMB_MALLOC(ls +ld +1);
2239 DEBUG(0,("str_list_substitute: "
2240 "Unable to allocate memory"));
2243 memcpy(t, *list, d);
2244 memcpy(t +d +li, p +lp, ls -d -lp +1);
2251 for (i = 0; i < li; i++) {
2252 switch (insert[i]) {
2264 t[d +i] = insert[i];
2276 #define IPSTR_LIST_SEP ","
2277 #define IPSTR_LIST_CHAR ','
2280 * Add ip string representation to ipstr list. Used also
2281 * as part of @function ipstr_list_make
2283 * @param ipstr_list pointer to string containing ip list;
2284 * MUST BE already allocated and IS reallocated if necessary
2285 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2286 * as a result of reallocation)
2287 * @param ip IP address which is to be added to list
2288 * @return pointer to string appended with new ip and possibly
2289 * reallocated to new length
2292 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2294 char *new_ipstr = NULL;
2295 char addr_buf[INET6_ADDRSTRLEN];
2297 /* arguments checking */
2298 if (!ipstr_list || !service) {
2302 print_sockaddr(addr_buf,
2306 /* attempt to convert ip to a string and append colon separator to it */
2308 if (service->ss.ss_family == AF_INET) {
2310 asprintf(&new_ipstr, "%s%s%s:%d",
2317 asprintf(&new_ipstr, "%s%s[%s]:%d",
2323 SAFE_FREE(*ipstr_list);
2325 if (service->ss.ss_family == AF_INET) {
2327 asprintf(&new_ipstr, "%s:%d",
2332 asprintf(&new_ipstr, "[%s]:%d",
2337 *ipstr_list = new_ipstr;
2342 * Allocate and initialise an ipstr list using ip adresses
2343 * passed as arguments.
2345 * @param ipstr_list pointer to string meant to be allocated and set
2346 * @param ip_list array of ip addresses to place in the list
2347 * @param ip_count number of addresses stored in ip_list
2348 * @return pointer to allocated ip string
2351 char *ipstr_list_make(char **ipstr_list,
2352 const struct ip_service *ip_list,
2357 /* arguments checking */
2358 if (!ip_list || !ipstr_list) {
2364 /* process ip addresses given as arguments */
2365 for (i = 0; i < ip_count; i++) {
2366 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2369 return (*ipstr_list);
2374 * Parse given ip string list into array of ip addresses
2375 * (as ip_service structures)
2376 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2378 * @param ipstr ip string list to be parsed
2379 * @param ip_list pointer to array of ip addresses which is
2380 * allocated by this function and must be freed by caller
2381 * @return number of succesfully parsed addresses
2384 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2390 if (!ipstr_list || !ip_list)
2393 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2394 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2395 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2396 (unsigned long)count));
2400 for ( i=0; next_token(&ipstr_list, token_str,
2401 IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
2402 char *s = token_str;
2403 char *p = strrchr(token_str, ':');
2407 (*ip_list)[i].port = atoi(p+1);
2410 /* convert single token to ip address */
2411 if (token_str[0] == '[') {
2414 p = strchr(token_str, ']');
2420 if (!interpret_string_addr(&(*ip_list)[i].ss,
2431 * Safely free ip string list
2433 * @param ipstr_list ip string list to be freed
2436 void ipstr_list_free(char* ipstr_list)
2438 SAFE_FREE(ipstr_list);
2442 Unescape a URL encoded string, in place.
2445 void rfc1738_unescape(char *buf)
2449 while (p && *p && (p=strchr_m(p,'%'))) {
2453 if (c1 >= '0' && c1 <= '9')
2455 else if (c1 >= 'A' && c1 <= 'F')
2457 else if (c1 >= 'a' && c1 <= 'f')
2459 else {p++; continue;}
2461 if (c2 >= '0' && c2 <= '9')
2463 else if (c2 >= 'A' && c2 <= 'F')
2465 else if (c2 >= 'a' && c2 <= 'f')
2467 else {p++; continue;}
2471 memmove(p+1, p+3, strlen(p+3)+1);
2476 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2479 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2481 DATA_BLOB base64_decode_data_blob(const char *s)
2483 int bit_offset, byte_offset, idx, i, n;
2484 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2485 unsigned char *d = decoded.data;
2490 while (*s && (p=strchr_m(b64,*s))) {
2491 idx = (int)(p - b64);
2492 byte_offset = (i*6)/8;
2493 bit_offset = (i*6)%8;
2494 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2495 if (bit_offset < 3) {
2496 d[byte_offset] |= (idx << (2-bit_offset));
2499 d[byte_offset] |= (idx >> (bit_offset-2));
2500 d[byte_offset+1] = 0;
2501 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2507 if ((n > 0) && (*s == '=')) {
2517 * Decode a base64 string in-place - wrapper for the above
2519 void base64_decode_inplace(char *s)
2521 DATA_BLOB decoded = base64_decode_data_blob(s);
2523 if ( decoded.length != 0 ) {
2524 memcpy(s, decoded.data, decoded.length);
2526 /* null terminate */
2527 s[decoded.length] = '\0';
2532 data_blob_free(&decoded);
2536 * Encode a base64 string into a malloc()ed string caller to free.
2538 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2542 char *base64_encode_data_blob(DATA_BLOB data)
2546 size_t out_cnt, len, output_len;
2549 if (!data.length || !data.data)
2554 output_len = data.length * 2;
2555 result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */
2556 SMB_ASSERT(result != NULL);
2558 while (len-- && out_cnt < (data.length * 2) - 5) {
2559 int c = (unsigned char) *(data.data++);
2562 if (char_count == 3) {
2563 result[out_cnt++] = b64[bits >> 18];
2564 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2565 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2566 result[out_cnt++] = b64[bits & 0x3f];
2573 if (char_count != 0) {
2574 bits <<= 16 - (8 * char_count);
2575 result[out_cnt++] = b64[bits >> 18];
2576 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2577 if (char_count == 1) {
2578 result[out_cnt++] = '=';
2579 result[out_cnt++] = '=';
2581 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2582 result[out_cnt++] = '=';
2585 result[out_cnt] = '\0'; /* terminate */
2589 /* read a SMB_BIG_UINT from a string */
2590 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2593 SMB_BIG_UINT val = -1;
2594 const char *p = nptr;
2603 while (*p && isspace(*p))
2606 #ifdef LARGE_SMB_OFF_T
2607 sscanf(p,"%llu",&val);
2608 #else /* LARGE_SMB_OFF_T */
2609 sscanf(p,"%lu",&val);
2610 #endif /* LARGE_SMB_OFF_T */
2612 while (*p && isdigit(*p))
2620 /* Convert a size specification to a count of bytes. We accept the following
2622 * bytes if there is no suffix
2627 * pP whatever the ISO name for petabytes is
2629 * Returns 0 if the string can't be converted.
2631 SMB_OFF_T conv_str_size(const char * str)
2636 if (str == NULL || *str == '\0') {
2640 #ifdef HAVE_STRTOULL
2641 if (sizeof(SMB_OFF_T) == 8) {
2642 lval = strtoull(str, &end, 10 /* base */);
2644 lval = strtoul(str, &end, 10 /* base */);
2647 lval = strtoul(str, &end, 10 /* base */);
2650 if (end == NULL || end == str) {
2655 SMB_OFF_T lval_orig = lval;
2657 if (strwicmp(end, "K") == 0) {
2658 lval *= (SMB_OFF_T)1024;
2659 } else if (strwicmp(end, "M") == 0) {
2660 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2661 } else if (strwicmp(end, "G") == 0) {
2662 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2664 } else if (strwicmp(end, "T") == 0) {
2665 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2666 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2667 } else if (strwicmp(end, "P") == 0) {
2668 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2669 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2675 /* Primitive attempt to detect wrapping on platforms with
2676 * 4-byte SMB_OFF_T. It's better to let the caller handle
2677 * a failure than some random number.
2679 if (lval_orig <= lval) {
2687 void string_append(char **left, const char *right)
2689 int new_len = strlen(right) + 1;
2691 if (*left == NULL) {
2692 *left = (char *)SMB_MALLOC(new_len);
2695 new_len += strlen(*left);
2696 *left = (char *)SMB_REALLOC(*left, new_len);
2699 if (*left == NULL) {
2703 safe_strcat(*left, right, new_len-1);
2706 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2707 const char *str, const char ***strings,
2710 char *dup_str = talloc_strdup(mem_ctx, str);
2712 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2713 const char *, (*num)+1);
2715 if ((*strings == NULL) || (dup_str == NULL)) {
2720 (*strings)[*num] = dup_str;
2725 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2726 * error checking in between. The indiation that something weird happened is
2729 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2730 size_t *bufsize, const char *fmt, ...)
2737 /* len<0 is an internal marker that something failed */
2741 if (*string == NULL) {
2745 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2746 if (*string == NULL)
2751 ret = vasprintf(&newstr, fmt, ap);
2759 while ((*len)+ret >= *bufsize) {
2762 if (*bufsize >= (1024*1024*256))
2767 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2769 if (*string == NULL) {
2774 StrnCpy((*string)+(*len), newstr, ret);
2785 Returns the substring from src between the first occurrence of
2786 the char "front" and the first occurence of the char "back".
2787 Mallocs the return string which must be freed. Not for use
2788 with wide character strings.
2790 char *sstring_sub(const char *src, char front, char back)
2792 char *temp1, *temp2, *temp3;
2795 temp1 = strchr(src, front);
2796 if (temp1 == NULL) return NULL;
2797 temp2 = strchr(src, back);
2798 if (temp2 == NULL) return NULL;
2799 len = temp2 - temp1;
2800 if (len <= 0) return NULL;
2801 temp3 = (char*)SMB_MALLOC(len);
2802 if (temp3 == NULL) {
2803 DEBUG(1,("Malloc failure in sstring_sub\n"));
2806 memcpy(temp3, temp1+1, len-1);
2807 temp3[len-1] = '\0';
2811 /********************************************************************
2812 Check a string for any occurrences of a specified list of invalid
2814 ********************************************************************/
2816 bool validate_net_name( const char *name,
2817 const char *invalid_chars,
2822 for ( i=0; i<max_len && name[i]; i++ ) {
2823 /* fail if strchr_m() finds one of the invalid characters */
2824 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2834 return the number of bytes occupied by a buffer in ASCII format
2835 the result includes the null termination
2836 limited by 'n' bytes
2838 size_t ascii_len_n(const char *src, size_t n)
2842 len = strnlen(src, n);
2851 return the number of bytes occupied by a buffer in CH_UTF16 format
2852 the result includes the null termination
2854 size_t utf16_len(const void *buf)
2858 for (len = 0; SVAL(buf,len); len += 2) ;
2864 return the number of bytes occupied by a buffer in CH_UTF16 format
2865 the result includes the null termination
2866 limited by 'n' bytes
2868 size_t utf16_len_n(const void *src, size_t n)
2872 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2881 /*******************************************************************
2882 Add a shell escape character '\' to any character not in a known list
2883 of characters. UNIX charset format.
2884 *******************************************************************/
2886 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2887 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2889 char *escape_shell_string(const char *src)
2891 size_t srclen = strlen(src);
2892 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2894 bool in_s_quote = false;
2895 bool in_d_quote = false;
2896 bool next_escaped = false;
2904 codepoint_t c = next_codepoint(src, &c_size);
2906 if (c == INVALID_CODEPOINT) {
2912 memcpy(dest, src, c_size);
2915 next_escaped = false;
2920 * Deal with backslash escaped state.
2921 * This only lasts for one character.
2926 next_escaped = false;
2931 * Deal with single quote state. The
2932 * only thing we care about is exiting
2945 * Deal with double quote state. The most
2946 * complex state. We must cope with \, meaning
2947 * possibly escape next char (depending what it
2948 * is), ", meaning exit this state, and possibly
2949 * add an \ escape to any unprotected character
2950 * (listed in INSIDE_DQUOTE_LIST).
2956 * Next character might be escaped.
2957 * We have to peek. Inside double
2958 * quotes only INSIDE_DQUOTE_LIST
2959 * characters are escaped by a \.
2964 c = next_codepoint(&src[1], &c_size);
2965 if (c == INVALID_CODEPOINT) {
2971 * Don't escape the next char.
2980 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2982 next_escaped = true;
2989 /* Exit double quote state. */
2996 * We know the character isn't \ or ",
2997 * so escape it if it's any of the other
2998 * possible unprotected characters.
3001 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
3009 * From here to the end of the loop we're
3010 * not in the single or double quote state.
3014 /* Next character must be escaped. */
3015 next_escaped = true;
3021 /* Go into single quote state. */
3028 /* Go into double quote state. */
3034 /* Check if we need to escape the character. */
3036 if (!strchr(INCLUDE_LIST, (int)*src)) {