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 && (quoted || !strchr_m(sep,*s)); s++) {
81 *ptr = (*s) ? s+1 : s;
88 * Get the next token from a string, return False if none found. Handles
89 * double-quotes. This version trims leading separator characters before
90 * looking for a token.
92 BOOL next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
94 return next_token_internal(ptr, buff, sep, bufsize, True);
98 * Get the next token from a string, return False if none found. Handles
99 * double-quotes. This version does not trim leading separator characters
100 * before looking for a token.
102 BOOL next_token_no_ltrim(const char **ptr,
107 return next_token_internal(ptr, buff, sep, bufsize, False);
111 This is like next_token but is not re-entrant and "remembers" the first
112 parameter so you can pass NULL. This is useful for user interface code
113 but beware the fact that it is not re-entrant!
116 static const char *last_ptr=NULL;
118 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
124 ret = next_token(ptr, buff, sep, bufsize);
129 void set_first_token(char *ptr)
135 Convert list of tokens to array; dependent on above routine.
136 Uses last_ptr from above - bit of a hack.
139 char **toktocliplist(int *ctok, const char *sep)
141 char *s=(char *)last_ptr;
148 while(*s && strchr_m(sep,*s))
157 while(*s && (!strchr_m(sep,*s)))
159 while(*s && strchr_m(sep,*s))
166 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
184 * Case insensitive string compararison.
186 * iconv does not directly give us a way to compare strings in
187 * arbitrary unix character sets -- all we can is convert and then
188 * compare. This is expensive.
190 * As an optimization, we do a first pass that considers only the
191 * prefix of the strings that is entirely 7-bit. Within this, we
192 * check whether they have the same value.
194 * Hopefully this will often give the answer without needing to copy.
195 * In particular it should speed comparisons to literal ascii strings
196 * or comparisons of strings that are "obviously" different.
198 * If we find a non-ascii character we fall back to converting via
201 * This should never be slower than convering the whole thing, and
204 * A different optimization would be to compare for bitwise equality
205 * in the binary encoding. (It would be possible thought hairy to do
206 * both simultaneously.) But in that case if they turn out to be
207 * different, we'd need to restart the whole thing.
209 * Even better is to implement strcasecmp for each encoding and use a
212 int StrCaseCmp(const char *s, const char *t)
217 smb_ucs2_t *buffer_s, *buffer_t;
220 for (ps = s, pt = t; ; ps++, pt++) {
224 return 0; /* both ended */
226 return -1; /* s is a prefix */
228 return +1; /* t is a prefix */
229 else if ((*ps & 0x80) || (*pt & 0x80))
230 /* not ascii anymore, do it the hard way from here on in */
233 us = toupper_ascii(*ps);
234 ut = toupper_ascii(*pt);
243 size = push_ucs2_allocate(&buffer_s, ps);
244 if (size == (size_t)-1) {
245 return strcmp(ps, pt);
246 /* Not quite the right answer, but finding the right one
247 under this failure case is expensive, and it's pretty close */
250 size = push_ucs2_allocate(&buffer_t, pt);
251 if (size == (size_t)-1) {
253 return strcmp(ps, pt);
254 /* Not quite the right answer, but finding the right one
255 under this failure case is expensive, and it's pretty close */
258 ret = strcasecmp_w(buffer_s, buffer_t);
266 Case insensitive string compararison, length limited.
268 int StrnCaseCmp(const char *s, const char *t, size_t len)
273 smb_ucs2_t *buffer_s, *buffer_t;
276 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
280 return 0; /* both ended */
282 return -1; /* s is a prefix */
284 return +1; /* t is a prefix */
285 else if ((*ps & 0x80) || (*pt & 0x80))
286 /* not ascii anymore, do it the
287 * hard way from here on in */
290 us = toupper_ascii(*ps);
291 ut = toupper_ascii(*pt);
304 size = push_ucs2_allocate(&buffer_s, ps);
305 if (size == (size_t)-1) {
306 return strncmp(ps, pt, len-n);
307 /* Not quite the right answer, but finding the right one
308 under this failure case is expensive,
309 and it's pretty close */
312 size = push_ucs2_allocate(&buffer_t, pt);
313 if (size == (size_t)-1) {
315 return strncmp(ps, pt, len-n);
316 /* Not quite the right answer, but finding the right one
317 under this failure case is expensive,
318 and it's pretty close */
321 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
330 * @note The comparison is case-insensitive.
332 BOOL strequal(const char *s1, const char *s2)
339 return(StrCaseCmp(s1,s2)==0);
343 * Compare 2 strings up to and including the nth char.
345 * @note The comparison is case-insensitive.
347 BOOL strnequal(const char *s1,const char *s2,size_t n)
351 if (!s1 || !s2 || !n)
354 return(StrnCaseCmp(s1,s2,n)==0);
358 Compare 2 strings (case sensitive).
361 BOOL strcsequal(const char *s1,const char *s2)
368 return(strcmp(s1,s2)==0);
372 Do a case-insensitive, whitespace-ignoring string compare.
375 int strwicmp(const char *psz1, const char *psz2)
377 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
378 /* appropriate value. */
381 else if (psz1 == NULL)
383 else if (psz2 == NULL)
386 /* sync the strings on first non-whitespace */
388 while (isspace((int)*psz1))
390 while (isspace((int)*psz2))
392 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
398 return (*psz1 - *psz2);
403 Convert a string to upper case, but don't modify it.
406 char *strupper_static(const char *s)
408 static char *str = NULL;
415 return CONST_DISCARD(char *,s);
422 Convert a string to "normal" form.
425 void strnorm(char *s, int case_default)
427 if (case_default == CASE_UPPER)
434 Check if a string is in "normal" case.
437 BOOL strisnormal(const char *s, int case_default)
439 if (case_default == CASE_UPPER)
440 return(!strhaslower(s));
442 return(!strhasupper(s));
448 NOTE: oldc and newc must be 7 bit characters
451 void string_replace( char *s, char oldc, char newc )
455 /* this is quite a common operation, so we want it to be
456 fast. We optimise for the ascii case, knowing that all our
457 supported multi-byte character sets are ascii-compatible
458 (ie. they match for the first 128 chars) */
460 for (p = s; *p; p++) {
461 if (*p & 0x80) /* mb string - slow path. */
471 /* Slow (mb) path. */
472 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
473 /* With compose characters we must restart from the beginning. JRA. */
479 next_codepoint(p, &c_size);
491 * Skip past some strings in a buffer - old version - no checks.
494 char *push_skip_string(char *buf)
496 buf += strlen(buf) + 1;
501 Skip past a string in a buffer. Buffer may not be
502 null terminated. end_ptr points to the first byte after
503 then end of the buffer.
506 char *skip_string(const char *base, size_t len, char *buf)
508 const char *end_ptr = base + len;
510 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
514 /* Skip the string */
517 if (buf >= end_ptr) {
527 Count the number of characters in a string. Normally this will
528 be the same as the number of bytes in a string for single byte strings,
529 but will be different for multibyte.
532 size_t str_charnum(const char *s)
535 smb_ucs2_t *tmpbuf2 = NULL;
536 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
539 ret = strlen_w(tmpbuf2);
545 Count the number of characters in a string. Normally this will
546 be the same as the number of bytes in a string for single byte strings,
547 but will be different for multibyte.
550 size_t str_ascii_charnum(const char *s)
553 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
554 return strlen(tmpbuf2);
557 BOOL trim_char(char *s,char cfront,char cback)
563 /* Ignore null or empty strings. */
564 if (!s || (s[0] == '\0'))
568 while (*fp && *fp == cfront)
571 /* We ate the string. */
579 ep = fp + strlen(fp) - 1;
581 /* Attempt ascii only. Bail for mb strings. */
582 while ((ep >= fp) && (*ep == cback)) {
584 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
585 /* Could be mb... bail back to tim_string. */
593 return trim_string(s, cfront ? fs : NULL, bs);
599 /* We ate the string. */
606 memmove(s, fp, ep-fp+2);
611 Trim the specified elements off the front and back of a string.
614 BOOL trim_string(char *s,const char *front,const char *back)
621 /* Ignore null or empty strings. */
622 if (!s || (s[0] == '\0'))
625 front_len = front? strlen(front) : 0;
626 back_len = back? strlen(back) : 0;
631 while (len && strncmp(s, front, front_len)==0) {
632 /* Must use memmove here as src & dest can
633 * easily overlap. Found by valgrind. JRA. */
634 memmove(s, s+front_len, (len-front_len)+1);
641 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
642 s[len-back_len]='\0';
651 Does a string have any uppercase chars in it?
654 BOOL strhasupper(const char *s)
659 if (push_ucs2_allocate(&tmp, s) == -1) {
663 for(p = tmp; *p != 0; p++) {
675 Does a string have any lowercase chars in it?
678 BOOL strhaslower(const char *s)
683 if (push_ucs2_allocate(&tmp, s) == -1) {
687 for(p = tmp; *p != 0; p++) {
699 Find the number of 'c' chars in a string
702 size_t count_chars(const char *s,char c)
706 smb_ucs2_t *alloc_tmpbuf = NULL;
708 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
712 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
713 if(*ptr==UCS2_CHAR(c))
716 SAFE_FREE(alloc_tmpbuf);
721 Safe string copy into a known length string. maxlength does not
722 include the terminating zero.
725 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
730 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
735 clobber_region(fn,line,dest, maxlength+1);
743 len = strnlen(src, maxlength+1);
745 if (len > maxlength) {
746 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
747 (unsigned long)(len-maxlength), (unsigned long)len,
748 (unsigned long)maxlength, src));
752 memmove(dest, src, len);
758 Safe string cat into a string. maxlength does not
759 include the terminating zero.
761 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
763 size_t src_len, dest_len;
766 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
773 src_len = strnlen(src, maxlength + 1);
774 dest_len = strnlen(dest, maxlength + 1);
777 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
780 if (src_len + dest_len > maxlength) {
781 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
782 (int)(src_len + dest_len - maxlength), src));
783 if (maxlength > dest_len) {
784 memcpy(&dest[dest_len], src, maxlength - dest_len);
790 memcpy(&dest[dest_len], src, src_len);
791 dest[dest_len + src_len] = 0;
796 Paranoid strcpy into a buffer of given length (includes terminating
797 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
798 and replaces with '_'. Deliberately does *NOT* check for multibyte
799 characters. Don't change it !
801 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
806 clobber_region(fn, line, dest, maxlength);
810 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
820 if (len >= maxlength)
823 if (!other_safe_chars)
824 other_safe_chars = "";
826 for(i = 0; i < len; i++) {
827 int val = (src[i] & 0xff);
828 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
840 Like strncpy but always null terminates. Make sure there is room!
841 The variable n should always be one less than the available size.
843 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
848 clobber_region(fn, line, dest, n+1);
852 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
861 while (n-- && (*d = *src)) {
872 Like strncpy but copies up to the character marker. always null terminates.
873 returns a pointer to the character marker in the source string (src).
876 static char *strncpyn(char *dest, const char *src, size_t n, char c)
882 clobber_region(dest, n+1);
884 p = strchr_m(src, c);
886 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
890 str_len = PTR_DIFF(p, src);
891 strncpy(dest, src, MIN(n, str_len));
892 dest[str_len] = '\0';
899 Routine to get hex characters and turn them into a 16 byte array.
900 the array can be variable length, and any non-hex-numeric
901 characters are skipped. "0xnn" or "0Xnn" is specially catered
904 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
908 size_t strhex_to_str(char *p, size_t len, const char *strhex)
911 size_t num_chars = 0;
912 unsigned char lonybble, hinybble;
913 const char *hexchars = "0123456789ABCDEF";
914 char *p1 = NULL, *p2 = NULL;
916 for (i = 0; i < len && strhex[i] != 0; i++) {
917 if (strnequal(hexchars, "0x", 2)) {
918 i++; /* skip two chars */
922 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
925 i++; /* next hex digit */
927 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
930 /* get the two nybbles */
931 hinybble = PTR_DIFF(p1, hexchars);
932 lonybble = PTR_DIFF(p2, hexchars);
934 p[num_chars] = (hinybble << 4) | lonybble;
943 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
948 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
950 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
952 ret_blob.length = strhex_to_str((char*)ret_blob.data,
960 * Routine to print a buffer as HEX digits, into an allocated string.
963 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
968 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
970 for (i = 0; i < len; i++)
971 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
977 Check if a string is part of a list.
980 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
984 size_t bufsize = strlen(list);
990 /* We know a token can't be larger
991 * than the entire list. */
993 tok = SMB_MALLOC(bufsize+1);
998 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1000 if (strcmp(tok,s) == 0) {
1005 if (StrCaseCmp(tok,s) == 0) {
1016 /* this is used to prevent lots of mallocs of size 1 */
1017 static const char *null_string = "";
1020 Set a string value, allocing the space for the string
1023 static BOOL string_init(char **dest,const char *src)
1033 *dest = CONST_DISCARD(char*, null_string);
1035 (*dest) = SMB_STRDUP(src);
1036 if ((*dest) == NULL) {
1037 DEBUG(0,("Out of memory in string_init\n"));
1045 Free a string value.
1048 void string_free(char **s)
1052 if (*s == null_string)
1058 Set a string value, deallocating any existing space, and allocing the space
1062 BOOL string_set(char **dest,const char *src)
1065 return(string_init(dest,src));
1069 Substitute a string for a pattern in another string. Make sure there is
1072 This routine looks for pattern in s and replaces it with
1073 insert. It may do multiple replacements or just one.
1075 Any of " ; ' $ or ` in the insert string are replaced with _
1076 if len==0 then the string cannot be extended. This is different from the old
1077 use of len==0 which was for no length checks to be done.
1080 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1081 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
1084 ssize_t ls,lp,li, i;
1086 if (!insert || !pattern || !*pattern || !s)
1089 ls = (ssize_t)strlen(s);
1090 lp = (ssize_t)strlen(pattern);
1091 li = (ssize_t)strlen(insert);
1094 len = ls + 1; /* len is number of *bytes* */
1096 while (lp <= ls && (p = strstr_m(s,pattern))) {
1097 if (ls + (li-lp) >= len) {
1098 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1099 (int)(ls + (li-lp) - len),
1100 pattern, (int)len));
1104 memmove(p+li,p+lp,strlen(p+lp)+1);
1106 for (i=0;i<li;i++) {
1107 switch (insert[i]) {
1113 /* allow a trailing $ (as in machine accounts) */
1114 if (allow_trailing_dollar && (i == li - 1 )) {
1121 if ( remove_unsafe_characters ) {
1123 /* yes this break should be here since we want to
1124 fall throw if not replacing unsafe chars */
1139 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1141 string_sub2( s, pattern, insert, len, True, True, False );
1144 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1146 string_sub2( s, pattern, insert, len, True, False, False );
1149 void fstring_sub(char *s,const char *pattern,const char *insert)
1151 string_sub(s, pattern, insert, sizeof(fstring));
1154 void pstring_sub(char *s,const char *pattern,const char *insert)
1156 string_sub(s, pattern, insert, sizeof(pstring));
1160 Similar to string_sub, but it will accept only allocated strings
1161 and may realloc them so pay attention at what you pass on no
1162 pointers inside strings, no pstrings or const may be passed
1166 char *realloc_string_sub(char *string, const char *pattern,
1171 ssize_t ls,lp,li,ld, i;
1173 if (!insert || !pattern || !*pattern || !string || !*string)
1178 in = SMB_STRDUP(insert);
1180 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1183 ls = (ssize_t)strlen(s);
1184 lp = (ssize_t)strlen(pattern);
1185 li = (ssize_t)strlen(insert);
1187 for (i=0;i<li;i++) {
1204 while ((p = strstr_m(s,pattern))) {
1206 int offset = PTR_DIFF(s,string);
1207 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1209 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1213 p = string + offset + (p - s);
1216 memmove(p+li,p+lp,strlen(p+lp)+1);
1226 /* Same as string_sub, but returns a talloc'ed string */
1228 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1229 const char *pattern, const char *insert)
1234 ssize_t ls,lp,li,ld, i;
1236 if (!insert || !pattern || !*pattern || !src || !*src)
1239 string = talloc_strdup(mem_ctx, src);
1240 if (string == NULL) {
1241 DEBUG(0, ("talloc_strdup failed\n"));
1247 in = SMB_STRDUP(insert);
1249 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1252 ls = (ssize_t)strlen(s);
1253 lp = (ssize_t)strlen(pattern);
1254 li = (ssize_t)strlen(insert);
1256 for (i=0;i<li;i++) {
1273 while ((p = strstr_m(s,pattern))) {
1275 int offset = PTR_DIFF(s,string);
1276 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1279 DEBUG(0, ("talloc_string_sub: out of "
1284 p = string + offset + (p - s);
1287 memmove(p+li,p+lp,strlen(p+lp)+1);
1298 Similar to string_sub() but allows for any character to be substituted.
1300 if len==0 then the string cannot be extended. This is different from the old
1301 use of len==0 which was for no length checks to be done.
1304 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1309 if (!insert || !pattern || !s)
1312 ls = (ssize_t)strlen(s);
1313 lp = (ssize_t)strlen(pattern);
1314 li = (ssize_t)strlen(insert);
1320 len = ls + 1; /* len is number of *bytes* */
1322 while (lp <= ls && (p = strstr_m(s,pattern))) {
1323 if (ls + (li-lp) >= len) {
1324 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1325 (int)(ls + (li-lp) - len),
1326 pattern, (int)len));
1330 memmove(p+li,p+lp,strlen(p+lp)+1);
1332 memcpy(p, insert, li);
1339 Similar to all_string_sub but for unicode strings.
1340 Return a new allocated unicode string.
1341 similar to string_sub() but allows for any character to be substituted.
1345 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1346 const smb_ucs2_t *insert)
1349 const smb_ucs2_t *sp;
1350 size_t lr, lp, li, lt;
1352 if (!insert || !pattern || !*pattern || !s)
1355 lt = (size_t)strlen_w(s);
1356 lp = (size_t)strlen_w(pattern);
1357 li = (size_t)strlen_w(insert);
1360 const smb_ucs2_t *st = s;
1362 while ((sp = strstr_w(st, pattern))) {
1368 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1370 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1374 while ((sp = strstr_w(s, pattern))) {
1375 memcpy(rp, s, (sp - s));
1376 rp += ((sp - s) / sizeof(smb_ucs2_t));
1377 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1381 lr = ((rp - r) / sizeof(smb_ucs2_t));
1383 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1391 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1396 if (!insert || !pattern || !s)
1398 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1399 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1400 return all_string_sub_w(s, p, i);
1405 Splits out the front and back at a separator.
1408 static void split_at_last_component(char *path, char *front, char sep, char *back)
1410 char *p = strrchr_m(path, sep);
1416 pstrcpy(front, path);
1430 Write an octal as a string.
1433 const char *octal_string(int i)
1435 static char ret[64];
1438 slprintf(ret, sizeof(ret)-1, "0%o", i);
1444 Truncate a string at a specified length.
1447 char *string_truncate(char *s, unsigned int length)
1449 if (s && strlen(s) > length)
1455 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1456 We convert via ucs2 for now.
1459 char *strchr_m(const char *src, char c)
1461 smb_ucs2_t *ws = NULL;
1467 /* characters below 0x3F are guaranteed to not appear in
1468 non-initial position in multi-byte charsets */
1469 if ((c & 0xC0) == 0) {
1470 return strchr(src, c);
1473 /* this is quite a common operation, so we want it to be
1474 fast. We optimise for the ascii case, knowing that all our
1475 supported multi-byte character sets are ascii-compatible
1476 (ie. they match for the first 128 chars) */
1478 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1486 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1487 /* With compose characters we must restart from the beginning. JRA. */
1491 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1492 /* Wrong answer, but what can we do... */
1493 return strchr(src, c);
1495 p = strchr_w(ws, UCS2_CHAR(c));
1501 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1503 /* Wrong answer, but what can we do... */
1504 return strchr(src, c);
1506 ret = (char *)(s+strlen(s2));
1512 char *strrchr_m(const char *s, char c)
1514 /* characters below 0x3F are guaranteed to not appear in
1515 non-initial position in multi-byte charsets */
1516 if ((c & 0xC0) == 0) {
1517 return strrchr(s, c);
1520 /* this is quite a common operation, so we want it to be
1521 fast. We optimise for the ascii case, knowing that all our
1522 supported multi-byte character sets are ascii-compatible
1523 (ie. they match for the first 128 chars). Also, in Samba
1524 we only search for ascii characters in 'c' and that
1525 in all mb character sets with a compound character
1526 containing c, if 'c' is not a match at position
1527 p, then p[-1] > 0x7f. JRA. */
1530 size_t len = strlen(s);
1532 BOOL got_mb = False;
1539 /* Could be a match. Part of a multibyte ? */
1540 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1541 /* Yep - go slow :-( */
1545 /* No - we have a match ! */
1548 } while (cp-- != s);
1553 /* String contained a non-ascii char. Slow path. */
1555 smb_ucs2_t *ws = NULL;
1560 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1561 /* Wrong answer, but what can we do. */
1562 return strrchr(s, c);
1564 p = strrchr_w(ws, UCS2_CHAR(c));
1570 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1572 /* Wrong answer, but what can we do. */
1573 return strrchr(s, c);
1575 ret = (char *)(s+strlen(s2));
1582 /***********************************************************************
1583 Return the equivalent of doing strrchr 'n' times - always going
1585 ***********************************************************************/
1587 char *strnrchr_m(const char *s, char c, unsigned int n)
1589 smb_ucs2_t *ws = NULL;
1594 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1595 /* Too hard to try and get right. */
1598 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1604 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1606 /* Too hard to try and get right. */
1609 ret = (char *)(s+strlen(s2));
1615 /***********************************************************************
1616 strstr_m - We convert via ucs2 for now.
1617 ***********************************************************************/
1619 char *strstr_m(const char *src, const char *findstr)
1622 smb_ucs2_t *src_w, *find_w;
1627 size_t findstr_len = 0;
1629 /* for correctness */
1634 /* Samba does single character findstr calls a *lot*. */
1635 if (findstr[1] == '\0')
1636 return strchr_m(src, *findstr);
1638 /* We optimise for the ascii case, knowing that all our
1639 supported multi-byte character sets are ascii-compatible
1640 (ie. they match for the first 128 chars) */
1642 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1643 if (*s == *findstr) {
1645 findstr_len = strlen(findstr);
1647 if (strncmp(s, findstr, findstr_len) == 0) {
1656 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1657 /* 'make check' fails unless we do this */
1659 /* With compose characters we must restart from the beginning. JRA. */
1663 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1664 DEBUG(0,("strstr_m: src malloc fail\n"));
1668 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1670 DEBUG(0,("strstr_m: find malloc fail\n"));
1674 p = strstr_w(src_w, find_w);
1683 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1686 DEBUG(0,("strstr_m: dest malloc fail\n"));
1689 retp = (char *)(s+strlen(s2));
1697 Convert a string to lower case.
1700 void strlower_m(char *s)
1705 /* this is quite a common operation, so we want it to be
1706 fast. We optimise for the ascii case, knowing that all our
1707 supported multi-byte character sets are ascii-compatible
1708 (ie. they match for the first 128 chars) */
1710 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1711 *s = tolower_ascii((unsigned char)*s);
1718 /* I assume that lowercased string takes the same number of bytes
1719 * as source string even in UTF-8 encoding. (VIV) */
1720 len = strlen(s) + 1;
1723 unix_strlower(s,len,s,len);
1724 /* Catch mb conversion errors that may not terminate. */
1731 Convert a string to upper case.
1734 void strupper_m(char *s)
1739 /* this is quite a common operation, so we want it to be
1740 fast. We optimise for the ascii case, knowing that all our
1741 supported multi-byte character sets are ascii-compatible
1742 (ie. they match for the first 128 chars) */
1744 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1745 *s = toupper_ascii((unsigned char)*s);
1752 /* I assume that lowercased string takes the same number of bytes
1753 * as source string even in multibyte encoding. (VIV) */
1754 len = strlen(s) + 1;
1757 unix_strupper(s,len,s,len);
1758 /* Catch mb conversion errors that may not terminate. */
1765 Count the number of UCS2 characters in a string. Normally this will
1766 be the same as the number of bytes in a string for single byte strings,
1767 but will be different for multibyte.
1770 size_t strlen_m(const char *s)
1778 while (*s && !(((uint8_t)*s) & 0x80)) {
1789 codepoint_t c = next_codepoint(s, &c_size);
1791 /* Unicode char fits into 16 bits. */
1794 /* Double-width unicode char - 32 bits. */
1804 Count the number of UCS2 characters in a string including the null
1808 size_t strlen_m_term(const char *s)
1813 return strlen_m(s) + 1;
1817 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1818 * if a string is there, include the terminator.
1821 size_t strlen_m_term_null(const char *s)
1835 Return a RFC2254 binary string representation of a buffer.
1836 Used in LDAP filters.
1840 char *binary_string_rfc2254(char *buf, int len)
1844 const char *hex = "0123456789ABCDEF";
1845 s = (char *)SMB_MALLOC(len * 3 + 1);
1848 for (j=i=0;i<len;i++) {
1850 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1851 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1858 char *binary_string(char *buf, int len)
1862 const char *hex = "0123456789ABCDEF";
1863 s = (char *)SMB_MALLOC(len * 2 + 1);
1866 for (j=i=0;i<len;i++) {
1867 s[j] = hex[((unsigned char)buf[i]) >> 4];
1868 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1875 Just a typesafety wrapper for snprintf into a pstring.
1878 int pstr_sprintf(pstring s, const char *fmt, ...)
1884 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1891 Just a typesafety wrapper for snprintf into a fstring.
1894 int fstr_sprintf(fstring s, const char *fmt, ...)
1900 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1906 List of Strings manipulation functions
1909 #define S_LIST_ABS 16 /* List Allocation Block Size */
1911 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1913 char **list, **rlist;
1919 if (!string || !*string)
1922 s = talloc_strdup(mem_ctx, string);
1924 s = SMB_STRDUP(string);
1927 DEBUG(0,("str_list_make: Unable to allocate memory"));
1930 if (!sep) sep = LIST_SEP;
1936 while (next_token(&str, tok, sep, sizeof(tok))) {
1938 lsize += S_LIST_ABS;
1940 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1942 /* We need to keep the old list on error so we can free the elements
1943 if the realloc fails. */
1944 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1947 DEBUG(0,("str_list_make: Unable to allocate memory"));
1948 str_list_free(&list);
1958 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1962 list[num] = talloc_strdup(mem_ctx, tok);
1964 list[num] = SMB_STRDUP(tok);
1968 DEBUG(0,("str_list_make: Unable to allocate memory"));
1969 str_list_free(&list);
1990 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1992 return str_list_make_internal(mem_ctx, string, sep);
1995 char **str_list_make(const char *string, const char *sep)
1997 return str_list_make_internal(NULL, string, sep);
2000 BOOL str_list_copy(char ***dest, const char **src)
2002 char **list, **rlist;
2014 lsize += S_LIST_ABS;
2015 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
2017 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
2018 str_list_free(&list);
2023 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
2026 list[num] = SMB_STRDUP(src[num]);
2028 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2029 str_list_free(&list);
2041 * Return true if all the elements of the list match exactly.
2043 BOOL str_list_compare(char **list1, char **list2)
2047 if (!list1 || !list2)
2048 return (list1 == list2);
2050 for (num = 0; list1[num]; num++) {
2053 if (!strcsequal(list1[num], list2[num]))
2057 return False; /* if list2 has more elements than list1 fail */
2062 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2066 if (!list || !*list)
2069 for(; *tlist; tlist++) {
2071 TALLOC_FREE(*tlist);
2077 TALLOC_FREE(*tlist);
2083 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2085 str_list_free_internal(mem_ctx, list);
2088 void str_list_free(char ***list)
2090 str_list_free_internal(NULL, list);
2093 /******************************************************************************
2094 *****************************************************************************/
2096 int str_list_count( const char **list )
2103 /* count the number of list members */
2105 for ( i=0; *list; i++, list++ );
2110 /******************************************************************************
2111 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2113 *****************************************************************************/
2115 BOOL str_list_sub_basic( char **list, const char *smb_name,
2116 const char *domain_name )
2122 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2124 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2137 /******************************************************************************
2138 substritute a specific pattern in a string list
2139 *****************************************************************************/
2141 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2144 ssize_t ls, lp, li, ld, i, d;
2153 lp = (ssize_t)strlen(pattern);
2154 li = (ssize_t)strlen(insert);
2159 ls = (ssize_t)strlen(s);
2161 while ((p = strstr_m(s, pattern))) {
2165 t = (char *) SMB_MALLOC(ls +ld +1);
2167 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2170 memcpy(t, *list, d);
2171 memcpy(t +d +li, p +lp, ls -d -lp +1);
2178 for (i = 0; i < li; i++) {
2179 switch (insert[i]) {
2191 t[d +i] = insert[i];
2204 #define IPSTR_LIST_SEP ","
2205 #define IPSTR_LIST_CHAR ','
2208 * Add ip string representation to ipstr list. Used also
2209 * as part of @function ipstr_list_make
2211 * @param ipstr_list pointer to string containing ip list;
2212 * MUST BE already allocated and IS reallocated if necessary
2213 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2214 * as a result of reallocation)
2215 * @param ip IP address which is to be added to list
2216 * @return pointer to string appended with new ip and possibly
2217 * reallocated to new length
2220 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2222 char* new_ipstr = NULL;
2224 /* arguments checking */
2225 if (!ipstr_list || !service) return NULL;
2227 /* attempt to convert ip to a string and append colon separator to it */
2229 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2230 inet_ntoa(service->ip), service->port);
2231 SAFE_FREE(*ipstr_list);
2233 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2235 *ipstr_list = new_ipstr;
2241 * Allocate and initialise an ipstr list using ip adresses
2242 * passed as arguments.
2244 * @param ipstr_list pointer to string meant to be allocated and set
2245 * @param ip_list array of ip addresses to place in the list
2246 * @param ip_count number of addresses stored in ip_list
2247 * @return pointer to allocated ip string
2250 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2254 /* arguments checking */
2255 if (!ip_list || !ipstr_list) return 0;
2259 /* process ip addresses given as arguments */
2260 for (i = 0; i < ip_count; i++)
2261 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2263 return (*ipstr_list);
2268 * Parse given ip string list into array of ip addresses
2269 * (as ip_service structures)
2270 * e.g. 192.168.1.100:389,192.168.1.78, ...
2272 * @param ipstr ip string list to be parsed
2273 * @param ip_list pointer to array of ip addresses which is
2274 * allocated by this function and must be freed by caller
2275 * @return number of succesfully parsed addresses
2278 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2284 if (!ipstr_list || !ip_list)
2287 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2288 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2289 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2294 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2297 struct in_addr addr;
2299 char *p = strchr(token_str, ':');
2306 /* convert single token to ip address */
2307 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2310 (*ip_list)[i].ip = addr;
2311 (*ip_list)[i].port = port;
2319 * Safely free ip string list
2321 * @param ipstr_list ip string list to be freed
2324 void ipstr_list_free(char* ipstr_list)
2326 SAFE_FREE(ipstr_list);
2331 Unescape a URL encoded string, in place.
2334 void rfc1738_unescape(char *buf)
2338 while (p && *p && (p=strchr_m(p,'%'))) {
2342 if (c1 >= '0' && c1 <= '9')
2344 else if (c1 >= 'A' && c1 <= 'F')
2346 else if (c1 >= 'a' && c1 <= 'f')
2348 else {p++; continue;}
2350 if (c2 >= '0' && c2 <= '9')
2352 else if (c2 >= 'A' && c2 <= 'F')
2354 else if (c2 >= 'a' && c2 <= 'f')
2356 else {p++; continue;}
2360 memmove(p+1, p+3, strlen(p+3)+1);
2365 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2368 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2370 DATA_BLOB base64_decode_data_blob(const char *s)
2372 int bit_offset, byte_offset, idx, i, n;
2373 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2374 unsigned char *d = decoded.data;
2379 while (*s && (p=strchr_m(b64,*s))) {
2380 idx = (int)(p - b64);
2381 byte_offset = (i*6)/8;
2382 bit_offset = (i*6)%8;
2383 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2384 if (bit_offset < 3) {
2385 d[byte_offset] |= (idx << (2-bit_offset));
2388 d[byte_offset] |= (idx >> (bit_offset-2));
2389 d[byte_offset+1] = 0;
2390 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2396 if ((n > 0) && (*s == '=')) {
2406 * Decode a base64 string in-place - wrapper for the above
2408 void base64_decode_inplace(char *s)
2410 DATA_BLOB decoded = base64_decode_data_blob(s);
2412 if ( decoded.length != 0 ) {
2413 memcpy(s, decoded.data, decoded.length);
2415 /* null terminate */
2416 s[decoded.length] = '\0';
2421 data_blob_free(&decoded);
2425 * Encode a base64 string into a malloc()ed string caller to free.
2427 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2429 char * base64_encode_data_blob(DATA_BLOB data)
2433 size_t out_cnt, len, output_len;
2436 if (!data.length || !data.data)
2441 output_len = data.length * 2;
2442 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2444 while (len-- && out_cnt < (data.length * 2) - 5) {
2445 int c = (unsigned char) *(data.data++);
2448 if (char_count == 3) {
2449 result[out_cnt++] = b64[bits >> 18];
2450 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2451 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2452 result[out_cnt++] = b64[bits & 0x3f];
2459 if (char_count != 0) {
2460 bits <<= 16 - (8 * char_count);
2461 result[out_cnt++] = b64[bits >> 18];
2462 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2463 if (char_count == 1) {
2464 result[out_cnt++] = '=';
2465 result[out_cnt++] = '=';
2467 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2468 result[out_cnt++] = '=';
2471 result[out_cnt] = '\0'; /* terminate */
2475 /* read a SMB_BIG_UINT from a string */
2476 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2479 SMB_BIG_UINT val = -1;
2480 const char *p = nptr;
2489 while (*p && isspace(*p))
2492 #ifdef LARGE_SMB_OFF_T
2493 sscanf(p,"%llu",&val);
2494 #else /* LARGE_SMB_OFF_T */
2495 sscanf(p,"%lu",&val);
2496 #endif /* LARGE_SMB_OFF_T */
2498 while (*p && isdigit(*p))
2506 /* Convert a size specification to a count of bytes. We accept the following
2508 * bytes if there is no suffix
2513 * pP whatever the ISO name for petabytes is
2515 * Returns 0 if the string can't be converted.
2517 SMB_OFF_T conv_str_size(const char * str)
2522 if (str == NULL || *str == '\0') {
2526 #ifdef HAVE_STRTOULL
2527 if (sizeof(SMB_OFF_T) == 8) {
2528 lval = strtoull(str, &end, 10 /* base */);
2530 lval = strtoul(str, &end, 10 /* base */);
2533 lval = strtoul(str, &end, 10 /* base */);
2536 if (end == NULL || end == str) {
2541 SMB_OFF_T lval_orig = lval;
2543 if (strwicmp(end, "K") == 0) {
2544 lval *= (SMB_OFF_T)1024;
2545 } else if (strwicmp(end, "M") == 0) {
2546 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2547 } else if (strwicmp(end, "G") == 0) {
2548 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2550 } else if (strwicmp(end, "T") == 0) {
2551 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2552 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2553 } else if (strwicmp(end, "P") == 0) {
2554 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2555 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2561 /* Primitive attempt to detect wrapping on platforms with
2562 * 4-byte SMB_OFF_T. It's better to let the caller handle
2563 * a failure than some random number.
2565 if (lval_orig <= lval) {
2573 void string_append(char **left, const char *right)
2575 int new_len = strlen(right) + 1;
2577 if (*left == NULL) {
2578 *left = (char *)SMB_MALLOC(new_len);
2581 new_len += strlen(*left);
2582 *left = (char *)SMB_REALLOC(*left, new_len);
2585 if (*left == NULL) {
2589 safe_strcat(*left, right, new_len-1);
2592 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2593 const char *str, const char ***strings,
2596 char *dup_str = talloc_strdup(mem_ctx, str);
2598 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2600 if ((*strings == NULL) || (dup_str == NULL)) {
2605 (*strings)[*num] = dup_str;
2610 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2611 * error checking in between. The indiation that something weird happened is
2614 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2615 size_t *bufsize, const char *fmt, ...)
2622 /* len<0 is an internal marker that something failed */
2626 if (*string == NULL) {
2630 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2631 if (*string == NULL)
2636 ret = vasprintf(&newstr, fmt, ap);
2644 while ((*len)+ret >= *bufsize) {
2647 if (*bufsize >= (1024*1024*256))
2652 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2654 if (*string == NULL) {
2659 StrnCpy((*string)+(*len), newstr, ret);
2670 Returns the substring from src between the first occurrence of
2671 the char "front" and the first occurence of the char "back".
2672 Mallocs the return string which must be freed. Not for use
2673 with wide character strings.
2675 char *sstring_sub(const char *src, char front, char back)
2677 char *temp1, *temp2, *temp3;
2680 temp1 = strchr(src, front);
2681 if (temp1 == NULL) return NULL;
2682 temp2 = strchr(src, back);
2683 if (temp2 == NULL) return NULL;
2684 len = temp2 - temp1;
2685 if (len <= 0) return NULL;
2686 temp3 = (char*)SMB_MALLOC(len);
2687 if (temp3 == NULL) {
2688 DEBUG(1,("Malloc failure in sstring_sub\n"));
2691 memcpy(temp3, temp1+1, len-1);
2692 temp3[len-1] = '\0';
2696 /********************************************************************
2697 Check a string for any occurrences of a specified list of invalid
2699 ********************************************************************/
2701 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2705 for ( i=0; i<max_len && name[i]; i++ ) {
2706 /* fail if strchr_m() finds one of the invalid characters */
2707 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2717 return the number of bytes occupied by a buffer in ASCII format
2718 the result includes the null termination
2719 limited by 'n' bytes
2721 size_t ascii_len_n(const char *src, size_t n)
2725 len = strnlen(src, n);
2734 return the number of bytes occupied by a buffer in CH_UTF16 format
2735 the result includes the null termination
2737 size_t utf16_len(const void *buf)
2741 for (len = 0; SVAL(buf,len); len += 2) ;
2747 return the number of bytes occupied by a buffer in CH_UTF16 format
2748 the result includes the null termination
2749 limited by 'n' bytes
2751 size_t utf16_len_n(const void *src, size_t n)
2755 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2764 /*******************************************************************
2765 Add a shell escape character '\' to any character not in a known list
2766 of characters. UNIX charset format.
2767 *******************************************************************/
2769 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2770 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2772 char *escape_shell_string(const char *src)
2774 size_t srclen = strlen(src);
2775 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2777 BOOL in_s_quote = False;
2778 BOOL in_d_quote = False;
2779 BOOL next_escaped = False;
2787 codepoint_t c = next_codepoint(src, &c_size);
2789 if (c == INVALID_CODEPOINT) {
2795 memcpy(dest, src, c_size);
2798 next_escaped = False;
2803 * Deal with backslash escaped state.
2804 * This only lasts for one character.
2809 next_escaped = False;
2814 * Deal with single quote state. The
2815 * only thing we care about is exiting
2828 * Deal with double quote state. The most
2829 * complex state. We must cope with \, meaning
2830 * possibly escape next char (depending what it
2831 * is), ", meaning exit this state, and possibly
2832 * add an \ escape to any unprotected character
2833 * (listed in INSIDE_DQUOTE_LIST).
2839 * Next character might be escaped.
2840 * We have to peek. Inside double
2841 * quotes only INSIDE_DQUOTE_LIST
2842 * characters are escaped by a \.
2847 c = next_codepoint(&src[1], &c_size);
2848 if (c == INVALID_CODEPOINT) {
2854 * Don't escape the next char.
2863 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2864 next_escaped = True;
2871 /* Exit double quote state. */
2878 * We know the character isn't \ or ",
2879 * so escape it if it's any of the other
2880 * possible unprotected characters.
2883 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2891 * From here to the end of the loop we're
2892 * not in the single or double quote state.
2896 /* Next character must be escaped. */
2897 next_escaped = True;
2903 /* Go into single quote state. */
2910 /* Go into double quote state. */
2916 /* Check if we need to escape the character. */
2918 if (!strchr(INCLUDE_LIST, (int)*src)) {