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 char *tmpbuf2 = NULL;
554 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
557 ret = strlen(tmpbuf2);
562 BOOL trim_char(char *s,char cfront,char cback)
568 /* Ignore null or empty strings. */
569 if (!s || (s[0] == '\0'))
573 while (*fp && *fp == cfront)
576 /* We ate the string. */
584 ep = fp + strlen(fp) - 1;
586 /* Attempt ascii only. Bail for mb strings. */
587 while ((ep >= fp) && (*ep == cback)) {
589 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
590 /* Could be mb... bail back to tim_string. */
598 return trim_string(s, cfront ? fs : NULL, bs);
604 /* We ate the string. */
611 memmove(s, fp, ep-fp+2);
616 Trim the specified elements off the front and back of a string.
619 BOOL trim_string(char *s,const char *front,const char *back)
626 /* Ignore null or empty strings. */
627 if (!s || (s[0] == '\0'))
630 front_len = front? strlen(front) : 0;
631 back_len = back? strlen(back) : 0;
636 while (len && strncmp(s, front, front_len)==0) {
637 /* Must use memmove here as src & dest can
638 * easily overlap. Found by valgrind. JRA. */
639 memmove(s, s+front_len, (len-front_len)+1);
646 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
647 s[len-back_len]='\0';
656 Does a string have any uppercase chars in it?
659 BOOL strhasupper(const char *s)
664 if (push_ucs2_allocate(&tmp, s) == -1) {
668 for(p = tmp; *p != 0; p++) {
680 Does a string have any lowercase chars in it?
683 BOOL strhaslower(const char *s)
688 if (push_ucs2_allocate(&tmp, s) == -1) {
692 for(p = tmp; *p != 0; p++) {
704 Find the number of 'c' chars in a string
707 size_t count_chars(const char *s,char c)
711 smb_ucs2_t *alloc_tmpbuf = NULL;
713 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
717 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
718 if(*ptr==UCS2_CHAR(c))
721 SAFE_FREE(alloc_tmpbuf);
726 Safe string copy into a known length string. maxlength does not
727 include the terminating zero.
730 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
735 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
740 clobber_region(fn,line,dest, maxlength+1);
748 len = strnlen(src, maxlength+1);
750 if (len > maxlength) {
751 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
752 (unsigned long)(len-maxlength), (unsigned long)len,
753 (unsigned long)maxlength, src));
757 memmove(dest, src, len);
763 Safe string cat into a string. maxlength does not
764 include the terminating zero.
766 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
768 size_t src_len, dest_len;
771 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
778 src_len = strnlen(src, maxlength + 1);
779 dest_len = strnlen(dest, maxlength + 1);
782 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
785 if (src_len + dest_len > maxlength) {
786 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
787 (int)(src_len + dest_len - maxlength), src));
788 if (maxlength > dest_len) {
789 memcpy(&dest[dest_len], src, maxlength - dest_len);
795 memcpy(&dest[dest_len], src, src_len);
796 dest[dest_len + src_len] = 0;
801 Paranoid strcpy into a buffer of given length (includes terminating
802 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
803 and replaces with '_'. Deliberately does *NOT* check for multibyte
804 characters. Don't change it !
806 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
811 clobber_region(fn, line, dest, maxlength);
815 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
825 if (len >= maxlength)
828 if (!other_safe_chars)
829 other_safe_chars = "";
831 for(i = 0; i < len; i++) {
832 int val = (src[i] & 0xff);
833 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
845 Like strncpy but always null terminates. Make sure there is room!
846 The variable n should always be one less than the available size.
848 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
853 clobber_region(fn, line, dest, n+1);
857 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
866 while (n-- && (*d = *src)) {
877 Like strncpy but copies up to the character marker. always null terminates.
878 returns a pointer to the character marker in the source string (src).
881 static char *strncpyn(char *dest, const char *src, size_t n, char c)
887 clobber_region(dest, n+1);
889 p = strchr_m(src, c);
891 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
895 str_len = PTR_DIFF(p, src);
896 strncpy(dest, src, MIN(n, str_len));
897 dest[str_len] = '\0';
904 Routine to get hex characters and turn them into a 16 byte array.
905 the array can be variable length, and any non-hex-numeric
906 characters are skipped. "0xnn" or "0Xnn" is specially catered
909 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
913 size_t strhex_to_str(char *p, size_t len, const char *strhex)
916 size_t num_chars = 0;
917 unsigned char lonybble, hinybble;
918 const char *hexchars = "0123456789ABCDEF";
919 char *p1 = NULL, *p2 = NULL;
921 for (i = 0; i < len && strhex[i] != 0; i++) {
922 if (strnequal(hexchars, "0x", 2)) {
923 i++; /* skip two chars */
927 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
930 i++; /* next hex digit */
932 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
935 /* get the two nybbles */
936 hinybble = PTR_DIFF(p1, hexchars);
937 lonybble = PTR_DIFF(p2, hexchars);
939 p[num_chars] = (hinybble << 4) | lonybble;
948 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
953 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
955 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
957 ret_blob.length = strhex_to_str((char*)ret_blob.data,
965 * Routine to print a buffer as HEX digits, into an allocated string.
968 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
973 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
975 for (i = 0; i < len; i++)
976 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
982 Check if a string is part of a list.
985 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
989 size_t bufsize = strlen(list);
995 /* We know a token can't be larger
996 * than the entire list. */
998 tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1003 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1004 if (casesensitive) {
1005 if (strcmp(tok,s) == 0) {
1010 if (StrCaseCmp(tok,s) == 0) {
1021 /* this is used to prevent lots of mallocs of size 1 */
1022 static const char *null_string = "";
1025 Set a string value, allocing the space for the string
1028 static BOOL string_init(char **dest,const char *src)
1038 *dest = CONST_DISCARD(char*, null_string);
1040 (*dest) = SMB_STRDUP(src);
1041 if ((*dest) == NULL) {
1042 DEBUG(0,("Out of memory in string_init\n"));
1050 Free a string value.
1053 void string_free(char **s)
1057 if (*s == null_string)
1063 Set a string value, deallocating any existing space, and allocing the space
1067 BOOL string_set(char **dest,const char *src)
1070 return(string_init(dest,src));
1074 Substitute a string for a pattern in another string. Make sure there is
1077 This routine looks for pattern in s and replaces it with
1078 insert. It may do multiple replacements or just one.
1080 Any of " ; ' $ or ` in the insert string are replaced with _
1081 if len==0 then the string cannot be extended. This is different from the old
1082 use of len==0 which was for no length checks to be done.
1085 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1086 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
1089 ssize_t ls,lp,li, i;
1091 if (!insert || !pattern || !*pattern || !s)
1094 ls = (ssize_t)strlen(s);
1095 lp = (ssize_t)strlen(pattern);
1096 li = (ssize_t)strlen(insert);
1099 len = ls + 1; /* len is number of *bytes* */
1101 while (lp <= ls && (p = strstr_m(s,pattern))) {
1102 if (ls + (li-lp) >= len) {
1103 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1104 (int)(ls + (li-lp) - len),
1105 pattern, (int)len));
1109 memmove(p+li,p+lp,strlen(p+lp)+1);
1111 for (i=0;i<li;i++) {
1112 switch (insert[i]) {
1118 /* allow a trailing $ (as in machine accounts) */
1119 if (allow_trailing_dollar && (i == li - 1 )) {
1126 if ( remove_unsafe_characters ) {
1128 /* yes this break should be here since we want to
1129 fall throw if not replacing unsafe chars */
1144 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1146 string_sub2( s, pattern, insert, len, True, True, False );
1149 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1151 string_sub2( s, pattern, insert, len, True, False, False );
1154 void fstring_sub(char *s,const char *pattern,const char *insert)
1156 string_sub(s, pattern, insert, sizeof(fstring));
1159 void pstring_sub(char *s,const char *pattern,const char *insert)
1161 string_sub(s, pattern, insert, sizeof(pstring));
1165 Similar to string_sub, but it will accept only allocated strings
1166 and may realloc them so pay attention at what you pass on no
1167 pointers inside strings, no pstrings or const may be passed
1171 char *realloc_string_sub(char *string, const char *pattern,
1176 ssize_t ls,lp,li,ld, i;
1178 if (!insert || !pattern || !*pattern || !string || !*string)
1183 in = SMB_STRDUP(insert);
1185 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1188 ls = (ssize_t)strlen(s);
1189 lp = (ssize_t)strlen(pattern);
1190 li = (ssize_t)strlen(insert);
1192 for (i=0;i<li;i++) {
1209 while ((p = strstr_m(s,pattern))) {
1211 int offset = PTR_DIFF(s,string);
1212 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1214 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1218 p = string + offset + (p - s);
1221 memmove(p+li,p+lp,strlen(p+lp)+1);
1231 /* Same as string_sub, but returns a talloc'ed string */
1233 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1234 const char *pattern, const char *insert)
1239 ssize_t ls,lp,li,ld, i;
1241 if (!insert || !pattern || !*pattern || !src || !*src)
1244 string = talloc_strdup(mem_ctx, src);
1245 if (string == NULL) {
1246 DEBUG(0, ("talloc_strdup failed\n"));
1252 in = SMB_STRDUP(insert);
1254 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1257 ls = (ssize_t)strlen(s);
1258 lp = (ssize_t)strlen(pattern);
1259 li = (ssize_t)strlen(insert);
1261 for (i=0;i<li;i++) {
1278 while ((p = strstr_m(s,pattern))) {
1280 int offset = PTR_DIFF(s,string);
1281 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1284 DEBUG(0, ("talloc_string_sub: out of "
1289 p = string + offset + (p - s);
1292 memmove(p+li,p+lp,strlen(p+lp)+1);
1303 Similar to string_sub() but allows for any character to be substituted.
1305 if len==0 then the string cannot be extended. This is different from the old
1306 use of len==0 which was for no length checks to be done.
1309 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1314 if (!insert || !pattern || !s)
1317 ls = (ssize_t)strlen(s);
1318 lp = (ssize_t)strlen(pattern);
1319 li = (ssize_t)strlen(insert);
1325 len = ls + 1; /* len is number of *bytes* */
1327 while (lp <= ls && (p = strstr_m(s,pattern))) {
1328 if (ls + (li-lp) >= len) {
1329 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1330 (int)(ls + (li-lp) - len),
1331 pattern, (int)len));
1335 memmove(p+li,p+lp,strlen(p+lp)+1);
1337 memcpy(p, insert, li);
1344 Similar to all_string_sub but for unicode strings.
1345 Return a new allocated unicode string.
1346 similar to string_sub() but allows for any character to be substituted.
1350 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1351 const smb_ucs2_t *insert)
1354 const smb_ucs2_t *sp;
1355 size_t lr, lp, li, lt;
1357 if (!insert || !pattern || !*pattern || !s)
1360 lt = (size_t)strlen_w(s);
1361 lp = (size_t)strlen_w(pattern);
1362 li = (size_t)strlen_w(insert);
1365 const smb_ucs2_t *st = s;
1367 while ((sp = strstr_w(st, pattern))) {
1373 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1375 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1379 while ((sp = strstr_w(s, pattern))) {
1380 memcpy(rp, s, (sp - s));
1381 rp += ((sp - s) / sizeof(smb_ucs2_t));
1382 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1386 lr = ((rp - r) / sizeof(smb_ucs2_t));
1388 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1396 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1401 if (!insert || !pattern || !s)
1403 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1404 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1405 return all_string_sub_w(s, p, i);
1410 Splits out the front and back at a separator.
1413 static void split_at_last_component(char *path, char *front, char sep, char *back)
1415 char *p = strrchr_m(path, sep);
1421 pstrcpy(front, path);
1435 Write an octal as a string.
1438 const char *octal_string(int i)
1440 static char ret[64];
1443 slprintf(ret, sizeof(ret)-1, "0%o", i);
1449 Truncate a string at a specified length.
1452 char *string_truncate(char *s, unsigned int length)
1454 if (s && strlen(s) > length)
1460 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1461 We convert via ucs2 for now.
1464 char *strchr_m(const char *src, char c)
1466 smb_ucs2_t *ws = NULL;
1472 /* characters below 0x3F are guaranteed to not appear in
1473 non-initial position in multi-byte charsets */
1474 if ((c & 0xC0) == 0) {
1475 return strchr(src, c);
1478 /* this is quite a common operation, so we want it to be
1479 fast. We optimise for the ascii case, knowing that all our
1480 supported multi-byte character sets are ascii-compatible
1481 (ie. they match for the first 128 chars) */
1483 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1491 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1492 /* With compose characters we must restart from the beginning. JRA. */
1496 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1497 /* Wrong answer, but what can we do... */
1498 return strchr(src, c);
1500 p = strchr_w(ws, UCS2_CHAR(c));
1506 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1508 /* Wrong answer, but what can we do... */
1509 return strchr(src, c);
1511 ret = (char *)(s+strlen(s2));
1517 char *strrchr_m(const char *s, char c)
1519 /* characters below 0x3F are guaranteed to not appear in
1520 non-initial position in multi-byte charsets */
1521 if ((c & 0xC0) == 0) {
1522 return strrchr(s, c);
1525 /* this is quite a common operation, so we want it to be
1526 fast. We optimise for the ascii case, knowing that all our
1527 supported multi-byte character sets are ascii-compatible
1528 (ie. they match for the first 128 chars). Also, in Samba
1529 we only search for ascii characters in 'c' and that
1530 in all mb character sets with a compound character
1531 containing c, if 'c' is not a match at position
1532 p, then p[-1] > 0x7f. JRA. */
1535 size_t len = strlen(s);
1537 BOOL got_mb = False;
1544 /* Could be a match. Part of a multibyte ? */
1545 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1546 /* Yep - go slow :-( */
1550 /* No - we have a match ! */
1553 } while (cp-- != s);
1558 /* String contained a non-ascii char. Slow path. */
1560 smb_ucs2_t *ws = NULL;
1565 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1566 /* Wrong answer, but what can we do. */
1567 return strrchr(s, c);
1569 p = strrchr_w(ws, UCS2_CHAR(c));
1575 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1577 /* Wrong answer, but what can we do. */
1578 return strrchr(s, c);
1580 ret = (char *)(s+strlen(s2));
1587 /***********************************************************************
1588 Return the equivalent of doing strrchr 'n' times - always going
1590 ***********************************************************************/
1592 char *strnrchr_m(const char *s, char c, unsigned int n)
1594 smb_ucs2_t *ws = NULL;
1599 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1600 /* Too hard to try and get right. */
1603 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1609 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1611 /* Too hard to try and get right. */
1614 ret = (char *)(s+strlen(s2));
1620 /***********************************************************************
1621 strstr_m - We convert via ucs2 for now.
1622 ***********************************************************************/
1624 char *strstr_m(const char *src, const char *findstr)
1627 smb_ucs2_t *src_w, *find_w;
1632 size_t findstr_len = 0;
1634 /* for correctness */
1639 /* Samba does single character findstr calls a *lot*. */
1640 if (findstr[1] == '\0')
1641 return strchr_m(src, *findstr);
1643 /* We optimise for the ascii case, knowing that all our
1644 supported multi-byte character sets are ascii-compatible
1645 (ie. they match for the first 128 chars) */
1647 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1648 if (*s == *findstr) {
1650 findstr_len = strlen(findstr);
1652 if (strncmp(s, findstr, findstr_len) == 0) {
1661 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1662 /* 'make check' fails unless we do this */
1664 /* With compose characters we must restart from the beginning. JRA. */
1668 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1669 DEBUG(0,("strstr_m: src malloc fail\n"));
1673 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1675 DEBUG(0,("strstr_m: find malloc fail\n"));
1679 p = strstr_w(src_w, find_w);
1688 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1691 DEBUG(0,("strstr_m: dest malloc fail\n"));
1694 retp = (char *)(s+strlen(s2));
1702 Convert a string to lower case.
1705 void strlower_m(char *s)
1710 /* this is quite a common operation, so we want it to be
1711 fast. We optimise for the ascii case, knowing that all our
1712 supported multi-byte character sets are ascii-compatible
1713 (ie. they match for the first 128 chars) */
1715 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1716 *s = tolower_ascii((unsigned char)*s);
1723 /* I assume that lowercased string takes the same number of bytes
1724 * as source string even in UTF-8 encoding. (VIV) */
1725 len = strlen(s) + 1;
1728 unix_strlower(s,len,s,len);
1729 /* Catch mb conversion errors that may not terminate. */
1736 Convert a string to upper case.
1739 void strupper_m(char *s)
1744 /* this is quite a common operation, so we want it to be
1745 fast. We optimise for the ascii case, knowing that all our
1746 supported multi-byte character sets are ascii-compatible
1747 (ie. they match for the first 128 chars) */
1749 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1750 *s = toupper_ascii((unsigned char)*s);
1757 /* I assume that lowercased string takes the same number of bytes
1758 * as source string even in multibyte encoding. (VIV) */
1759 len = strlen(s) + 1;
1762 unix_strupper(s,len,s,len);
1763 /* Catch mb conversion errors that may not terminate. */
1770 Count the number of UCS2 characters in a string. Normally this will
1771 be the same as the number of bytes in a string for single byte strings,
1772 but will be different for multibyte.
1775 size_t strlen_m(const char *s)
1783 while (*s && !(((uint8_t)*s) & 0x80)) {
1794 codepoint_t c = next_codepoint(s, &c_size);
1796 /* Unicode char fits into 16 bits. */
1799 /* Double-width unicode char - 32 bits. */
1809 Count the number of UCS2 characters in a string including the null
1813 size_t strlen_m_term(const char *s)
1818 return strlen_m(s) + 1;
1822 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1823 * if a string is there, include the terminator.
1826 size_t strlen_m_term_null(const char *s)
1840 Return a RFC2254 binary string representation of a buffer.
1841 Used in LDAP filters.
1845 char *binary_string_rfc2254(char *buf, int len)
1849 const char *hex = "0123456789ABCDEF";
1850 s = (char *)SMB_MALLOC(len * 3 + 1);
1853 for (j=i=0;i<len;i++) {
1855 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1856 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1863 char *binary_string(char *buf, int len)
1867 const char *hex = "0123456789ABCDEF";
1868 s = (char *)SMB_MALLOC(len * 2 + 1);
1871 for (j=i=0;i<len;i++) {
1872 s[j] = hex[((unsigned char)buf[i]) >> 4];
1873 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1880 Just a typesafety wrapper for snprintf into a pstring.
1883 int pstr_sprintf(pstring s, const char *fmt, ...)
1889 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1896 Just a typesafety wrapper for snprintf into a fstring.
1899 int fstr_sprintf(fstring s, const char *fmt, ...)
1905 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1911 List of Strings manipulation functions
1914 #define S_LIST_ABS 16 /* List Allocation Block Size */
1916 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1918 char **list, **rlist;
1924 if (!string || !*string)
1927 s = talloc_strdup(mem_ctx, string);
1929 s = SMB_STRDUP(string);
1932 DEBUG(0,("str_list_make: Unable to allocate memory"));
1935 if (!sep) sep = LIST_SEP;
1941 while (next_token(&str, tok, sep, sizeof(tok))) {
1943 lsize += S_LIST_ABS;
1945 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1947 /* We need to keep the old list on error so we can free the elements
1948 if the realloc fails. */
1949 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1952 DEBUG(0,("str_list_make: Unable to allocate memory"));
1953 str_list_free(&list);
1963 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1967 list[num] = talloc_strdup(mem_ctx, tok);
1969 list[num] = SMB_STRDUP(tok);
1973 DEBUG(0,("str_list_make: Unable to allocate memory"));
1974 str_list_free(&list);
1995 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1997 return str_list_make_internal(mem_ctx, string, sep);
2000 char **str_list_make(const char *string, const char *sep)
2002 return str_list_make_internal(NULL, string, sep);
2005 BOOL str_list_copy(char ***dest, const char **src)
2007 char **list, **rlist;
2019 lsize += S_LIST_ABS;
2020 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
2022 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
2023 str_list_free(&list);
2028 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
2031 list[num] = SMB_STRDUP(src[num]);
2033 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2034 str_list_free(&list);
2046 * Return true if all the elements of the list match exactly.
2048 BOOL str_list_compare(char **list1, char **list2)
2052 if (!list1 || !list2)
2053 return (list1 == list2);
2055 for (num = 0; list1[num]; num++) {
2058 if (!strcsequal(list1[num], list2[num]))
2062 return False; /* if list2 has more elements than list1 fail */
2067 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2071 if (!list || !*list)
2074 for(; *tlist; tlist++) {
2076 TALLOC_FREE(*tlist);
2082 TALLOC_FREE(*tlist);
2088 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2090 str_list_free_internal(mem_ctx, list);
2093 void str_list_free(char ***list)
2095 str_list_free_internal(NULL, list);
2098 /******************************************************************************
2099 *****************************************************************************/
2101 int str_list_count( const char **list )
2108 /* count the number of list members */
2110 for ( i=0; *list; i++, list++ );
2115 /******************************************************************************
2116 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2118 *****************************************************************************/
2120 BOOL str_list_sub_basic( char **list, const char *smb_name,
2121 const char *domain_name )
2127 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2129 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2142 /******************************************************************************
2143 substritute a specific pattern in a string list
2144 *****************************************************************************/
2146 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2149 ssize_t ls, lp, li, ld, i, d;
2158 lp = (ssize_t)strlen(pattern);
2159 li = (ssize_t)strlen(insert);
2164 ls = (ssize_t)strlen(s);
2166 while ((p = strstr_m(s, pattern))) {
2170 t = (char *) SMB_MALLOC(ls +ld +1);
2172 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2175 memcpy(t, *list, d);
2176 memcpy(t +d +li, p +lp, ls -d -lp +1);
2183 for (i = 0; i < li; i++) {
2184 switch (insert[i]) {
2196 t[d +i] = insert[i];
2209 #define IPSTR_LIST_SEP ","
2210 #define IPSTR_LIST_CHAR ','
2213 * Add ip string representation to ipstr list. Used also
2214 * as part of @function ipstr_list_make
2216 * @param ipstr_list pointer to string containing ip list;
2217 * MUST BE already allocated and IS reallocated if necessary
2218 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2219 * as a result of reallocation)
2220 * @param ip IP address which is to be added to list
2221 * @return pointer to string appended with new ip and possibly
2222 * reallocated to new length
2225 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2227 char* new_ipstr = NULL;
2229 /* arguments checking */
2230 if (!ipstr_list || !service) return NULL;
2232 /* attempt to convert ip to a string and append colon separator to it */
2234 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2235 inet_ntoa(service->ip), service->port);
2236 SAFE_FREE(*ipstr_list);
2238 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2240 *ipstr_list = new_ipstr;
2246 * Allocate and initialise an ipstr list using ip adresses
2247 * passed as arguments.
2249 * @param ipstr_list pointer to string meant to be allocated and set
2250 * @param ip_list array of ip addresses to place in the list
2251 * @param ip_count number of addresses stored in ip_list
2252 * @return pointer to allocated ip string
2255 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2259 /* arguments checking */
2260 if (!ip_list || !ipstr_list) return 0;
2264 /* process ip addresses given as arguments */
2265 for (i = 0; i < ip_count; i++)
2266 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2268 return (*ipstr_list);
2273 * Parse given ip string list into array of ip addresses
2274 * (as ip_service structures)
2275 * e.g. 192.168.1.100:389,192.168.1.78, ...
2277 * @param ipstr ip string list to be parsed
2278 * @param ip_list pointer to array of ip addresses which is
2279 * allocated by this function and must be freed by caller
2280 * @return number of succesfully parsed addresses
2283 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2289 if (!ipstr_list || !ip_list)
2292 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2293 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2294 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2299 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2302 struct in_addr addr;
2304 char *p = strchr(token_str, ':');
2311 /* convert single token to ip address */
2312 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2315 (*ip_list)[i].ip = addr;
2316 (*ip_list)[i].port = port;
2324 * Safely free ip string list
2326 * @param ipstr_list ip string list to be freed
2329 void ipstr_list_free(char* ipstr_list)
2331 SAFE_FREE(ipstr_list);
2336 Unescape a URL encoded string, in place.
2339 void rfc1738_unescape(char *buf)
2343 while (p && *p && (p=strchr_m(p,'%'))) {
2347 if (c1 >= '0' && c1 <= '9')
2349 else if (c1 >= 'A' && c1 <= 'F')
2351 else if (c1 >= 'a' && c1 <= 'f')
2353 else {p++; continue;}
2355 if (c2 >= '0' && c2 <= '9')
2357 else if (c2 >= 'A' && c2 <= 'F')
2359 else if (c2 >= 'a' && c2 <= 'f')
2361 else {p++; continue;}
2365 memmove(p+1, p+3, strlen(p+3)+1);
2370 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2373 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2375 DATA_BLOB base64_decode_data_blob(const char *s)
2377 int bit_offset, byte_offset, idx, i, n;
2378 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2379 unsigned char *d = decoded.data;
2384 while (*s && (p=strchr_m(b64,*s))) {
2385 idx = (int)(p - b64);
2386 byte_offset = (i*6)/8;
2387 bit_offset = (i*6)%8;
2388 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2389 if (bit_offset < 3) {
2390 d[byte_offset] |= (idx << (2-bit_offset));
2393 d[byte_offset] |= (idx >> (bit_offset-2));
2394 d[byte_offset+1] = 0;
2395 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2401 if ((n > 0) && (*s == '=')) {
2411 * Decode a base64 string in-place - wrapper for the above
2413 void base64_decode_inplace(char *s)
2415 DATA_BLOB decoded = base64_decode_data_blob(s);
2417 if ( decoded.length != 0 ) {
2418 memcpy(s, decoded.data, decoded.length);
2420 /* null terminate */
2421 s[decoded.length] = '\0';
2426 data_blob_free(&decoded);
2430 * Encode a base64 string into a malloc()ed string caller to free.
2432 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2434 char * base64_encode_data_blob(DATA_BLOB data)
2438 size_t out_cnt, len, output_len;
2441 if (!data.length || !data.data)
2446 output_len = data.length * 2;
2447 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2449 while (len-- && out_cnt < (data.length * 2) - 5) {
2450 int c = (unsigned char) *(data.data++);
2453 if (char_count == 3) {
2454 result[out_cnt++] = b64[bits >> 18];
2455 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2456 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2457 result[out_cnt++] = b64[bits & 0x3f];
2464 if (char_count != 0) {
2465 bits <<= 16 - (8 * char_count);
2466 result[out_cnt++] = b64[bits >> 18];
2467 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2468 if (char_count == 1) {
2469 result[out_cnt++] = '=';
2470 result[out_cnt++] = '=';
2472 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2473 result[out_cnt++] = '=';
2476 result[out_cnt] = '\0'; /* terminate */
2480 /* read a SMB_BIG_UINT from a string */
2481 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2484 SMB_BIG_UINT val = -1;
2485 const char *p = nptr;
2494 while (*p && isspace(*p))
2497 #ifdef LARGE_SMB_OFF_T
2498 sscanf(p,"%llu",&val);
2499 #else /* LARGE_SMB_OFF_T */
2500 sscanf(p,"%lu",&val);
2501 #endif /* LARGE_SMB_OFF_T */
2503 while (*p && isdigit(*p))
2511 /* Convert a size specification to a count of bytes. We accept the following
2513 * bytes if there is no suffix
2518 * pP whatever the ISO name for petabytes is
2520 * Returns 0 if the string can't be converted.
2522 SMB_OFF_T conv_str_size(const char * str)
2527 if (str == NULL || *str == '\0') {
2531 #ifdef HAVE_STRTOULL
2532 if (sizeof(SMB_OFF_T) == 8) {
2533 lval = strtoull(str, &end, 10 /* base */);
2535 lval = strtoul(str, &end, 10 /* base */);
2538 lval = strtoul(str, &end, 10 /* base */);
2541 if (end == NULL || end == str) {
2546 SMB_OFF_T lval_orig = lval;
2548 if (strwicmp(end, "K") == 0) {
2549 lval *= (SMB_OFF_T)1024;
2550 } else if (strwicmp(end, "M") == 0) {
2551 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2552 } else if (strwicmp(end, "G") == 0) {
2553 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2555 } else if (strwicmp(end, "T") == 0) {
2556 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2557 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2558 } else if (strwicmp(end, "P") == 0) {
2559 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2560 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2566 /* Primitive attempt to detect wrapping on platforms with
2567 * 4-byte SMB_OFF_T. It's better to let the caller handle
2568 * a failure than some random number.
2570 if (lval_orig <= lval) {
2578 void string_append(char **left, const char *right)
2580 int new_len = strlen(right) + 1;
2582 if (*left == NULL) {
2583 *left = (char *)SMB_MALLOC(new_len);
2586 new_len += strlen(*left);
2587 *left = (char *)SMB_REALLOC(*left, new_len);
2590 if (*left == NULL) {
2594 safe_strcat(*left, right, new_len-1);
2597 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2598 const char *str, const char ***strings,
2601 char *dup_str = talloc_strdup(mem_ctx, str);
2603 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2605 if ((*strings == NULL) || (dup_str == NULL)) {
2610 (*strings)[*num] = dup_str;
2615 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2616 * error checking in between. The indiation that something weird happened is
2619 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2620 size_t *bufsize, const char *fmt, ...)
2627 /* len<0 is an internal marker that something failed */
2631 if (*string == NULL) {
2635 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2636 if (*string == NULL)
2641 ret = vasprintf(&newstr, fmt, ap);
2649 while ((*len)+ret >= *bufsize) {
2652 if (*bufsize >= (1024*1024*256))
2657 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2659 if (*string == NULL) {
2664 StrnCpy((*string)+(*len), newstr, ret);
2675 Returns the substring from src between the first occurrence of
2676 the char "front" and the first occurence of the char "back".
2677 Mallocs the return string which must be freed. Not for use
2678 with wide character strings.
2680 char *sstring_sub(const char *src, char front, char back)
2682 char *temp1, *temp2, *temp3;
2685 temp1 = strchr(src, front);
2686 if (temp1 == NULL) return NULL;
2687 temp2 = strchr(src, back);
2688 if (temp2 == NULL) return NULL;
2689 len = temp2 - temp1;
2690 if (len <= 0) return NULL;
2691 temp3 = (char*)SMB_MALLOC(len);
2692 if (temp3 == NULL) {
2693 DEBUG(1,("Malloc failure in sstring_sub\n"));
2696 memcpy(temp3, temp1+1, len-1);
2697 temp3[len-1] = '\0';
2701 /********************************************************************
2702 Check a string for any occurrences of a specified list of invalid
2704 ********************************************************************/
2706 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2710 for ( i=0; i<max_len && name[i]; i++ ) {
2711 /* fail if strchr_m() finds one of the invalid characters */
2712 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2722 return the number of bytes occupied by a buffer in ASCII format
2723 the result includes the null termination
2724 limited by 'n' bytes
2726 size_t ascii_len_n(const char *src, size_t n)
2730 len = strnlen(src, n);
2739 return the number of bytes occupied by a buffer in CH_UTF16 format
2740 the result includes the null termination
2742 size_t utf16_len(const void *buf)
2746 for (len = 0; SVAL(buf,len); len += 2) ;
2752 return the number of bytes occupied by a buffer in CH_UTF16 format
2753 the result includes the null termination
2754 limited by 'n' bytes
2756 size_t utf16_len_n(const void *src, size_t n)
2760 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2769 /*******************************************************************
2770 Add a shell escape character '\' to any character not in a known list
2771 of characters. UNIX charset format.
2772 *******************************************************************/
2774 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2775 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2777 char *escape_shell_string(const char *src)
2779 size_t srclen = strlen(src);
2780 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2782 BOOL in_s_quote = False;
2783 BOOL in_d_quote = False;
2784 BOOL next_escaped = False;
2792 codepoint_t c = next_codepoint(src, &c_size);
2794 if (c == INVALID_CODEPOINT) {
2800 memcpy(dest, src, c_size);
2803 next_escaped = False;
2808 * Deal with backslash escaped state.
2809 * This only lasts for one character.
2814 next_escaped = False;
2819 * Deal with single quote state. The
2820 * only thing we care about is exiting
2833 * Deal with double quote state. The most
2834 * complex state. We must cope with \, meaning
2835 * possibly escape next char (depending what it
2836 * is), ", meaning exit this state, and possibly
2837 * add an \ escape to any unprotected character
2838 * (listed in INSIDE_DQUOTE_LIST).
2844 * Next character might be escaped.
2845 * We have to peek. Inside double
2846 * quotes only INSIDE_DQUOTE_LIST
2847 * characters are escaped by a \.
2852 c = next_codepoint(&src[1], &c_size);
2853 if (c == INVALID_CODEPOINT) {
2859 * Don't escape the next char.
2868 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2869 next_escaped = True;
2876 /* Exit double quote state. */
2883 * We know the character isn't \ or ",
2884 * so escape it if it's any of the other
2885 * possible unprotected characters.
2888 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2896 * From here to the end of the loop we're
2897 * not in the single or double quote state.
2901 /* Next character must be escaped. */
2902 next_escaped = True;
2908 /* Go into single quote state. */
2915 /* Go into double quote state. */
2921 /* Check if we need to escape the character. */
2923 if (!strchr(INCLUDE_LIST, (int)*src)) {