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
450 void string_replace( char *s, char oldc, char newc )
454 /* this is quite a common operation, so we want it to be
455 fast. We optimise for the ascii case, knowing that all our
456 supported multi-byte character sets are ascii-compatible
457 (ie. they match for the first 128 chars) */
459 for (p = s; *p; p++) {
460 if (*p & 0x80) /* mb string - slow path. */
470 /* Slow (mb) path. */
471 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
472 /* With compose characters we must restart from the beginning. JRA. */
478 next_codepoint(p, &c_size);
490 * Skip past some strings in a buffer - old version - no checks.
493 char *push_skip_string(char *buf)
495 buf += strlen(buf) + 1;
500 Skip past a string in a buffer. Buffer may not be
501 null terminated. end_ptr points to the first byte after
502 then end of the buffer.
505 char *skip_string(const char *base, size_t len, char *buf)
507 const char *end_ptr = base + len;
509 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
513 /* Skip the string */
516 if (buf >= end_ptr) {
526 Count the number of characters in a string. Normally this will
527 be the same as the number of bytes in a string for single byte strings,
528 but will be different for multibyte.
531 size_t str_charnum(const char *s)
534 smb_ucs2_t *tmpbuf2 = NULL;
535 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
538 ret = strlen_w(tmpbuf2);
544 Count the number of characters in a string. Normally this will
545 be the same as the number of bytes in a string for single byte strings,
546 but will be different for multibyte.
549 size_t str_ascii_charnum(const char *s)
552 char *tmpbuf2 = NULL;
553 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
556 ret = strlen(tmpbuf2);
561 BOOL trim_char(char *s,char cfront,char cback)
567 /* Ignore null or empty strings. */
568 if (!s || (s[0] == '\0'))
572 while (*fp && *fp == cfront)
575 /* We ate the string. */
583 ep = fp + strlen(fp) - 1;
585 /* Attempt ascii only. Bail for mb strings. */
586 while ((ep >= fp) && (*ep == cback)) {
588 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
589 /* Could be mb... bail back to tim_string. */
597 return trim_string(s, cfront ? fs : NULL, bs);
603 /* We ate the string. */
610 memmove(s, fp, ep-fp+2);
615 Trim the specified elements off the front and back of a string.
618 BOOL trim_string(char *s,const char *front,const char *back)
625 /* Ignore null or empty strings. */
626 if (!s || (s[0] == '\0'))
629 front_len = front? strlen(front) : 0;
630 back_len = back? strlen(back) : 0;
635 while (len && strncmp(s, front, front_len)==0) {
636 /* Must use memmove here as src & dest can
637 * easily overlap. Found by valgrind. JRA. */
638 memmove(s, s+front_len, (len-front_len)+1);
645 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
646 s[len-back_len]='\0';
655 Does a string have any uppercase chars in it?
658 BOOL strhasupper(const char *s)
663 if (push_ucs2_allocate(&tmp, s) == -1) {
667 for(p = tmp; *p != 0; p++) {
679 Does a string have any lowercase chars in it?
682 BOOL strhaslower(const char *s)
687 if (push_ucs2_allocate(&tmp, s) == -1) {
691 for(p = tmp; *p != 0; p++) {
703 Find the number of 'c' chars in a string
706 size_t count_chars(const char *s,char c)
710 smb_ucs2_t *alloc_tmpbuf = NULL;
712 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
716 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
717 if(*ptr==UCS2_CHAR(c))
720 SAFE_FREE(alloc_tmpbuf);
725 Safe string copy into a known length string. maxlength does not
726 include the terminating zero.
729 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
734 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
739 clobber_region(fn,line,dest, maxlength+1);
747 len = strnlen(src, maxlength+1);
749 if (len > maxlength) {
750 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
751 (unsigned long)(len-maxlength), (unsigned long)len,
752 (unsigned long)maxlength, src));
756 memmove(dest, src, len);
762 Safe string cat into a string. maxlength does not
763 include the terminating zero.
765 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
767 size_t src_len, dest_len;
770 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
777 src_len = strnlen(src, maxlength + 1);
778 dest_len = strnlen(dest, maxlength + 1);
781 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
784 if (src_len + dest_len > maxlength) {
785 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
786 (int)(src_len + dest_len - maxlength), src));
787 if (maxlength > dest_len) {
788 memcpy(&dest[dest_len], src, maxlength - dest_len);
794 memcpy(&dest[dest_len], src, src_len);
795 dest[dest_len + src_len] = 0;
800 Paranoid strcpy into a buffer of given length (includes terminating
801 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
802 and replaces with '_'. Deliberately does *NOT* check for multibyte
803 characters. Don't change it !
805 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
810 clobber_region(fn, line, dest, maxlength);
814 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
824 if (len >= maxlength)
827 if (!other_safe_chars)
828 other_safe_chars = "";
830 for(i = 0; i < len; i++) {
831 int val = (src[i] & 0xff);
832 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
844 Like strncpy but always null terminates. Make sure there is room!
845 The variable n should always be one less than the available size.
847 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
852 clobber_region(fn, line, dest, n+1);
856 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
865 while (n-- && (*d = *src)) {
876 Like strncpy but copies up to the character marker. always null terminates.
877 returns a pointer to the character marker in the source string (src).
880 static char *strncpyn(char *dest, const char *src, size_t n, char c)
886 clobber_region(dest, n+1);
888 p = strchr_m(src, c);
890 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
894 str_len = PTR_DIFF(p, src);
895 strncpy(dest, src, MIN(n, str_len));
896 dest[str_len] = '\0';
903 Routine to get hex characters and turn them into a 16 byte array.
904 the array can be variable length, and any non-hex-numeric
905 characters are skipped. "0xnn" or "0Xnn" is specially catered
908 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
912 size_t strhex_to_str(char *p, size_t len, const char *strhex)
915 size_t num_chars = 0;
916 unsigned char lonybble, hinybble;
917 const char *hexchars = "0123456789ABCDEF";
918 char *p1 = NULL, *p2 = NULL;
920 for (i = 0; i < len && strhex[i] != 0; i++) {
921 if (strnequal(hexchars, "0x", 2)) {
922 i++; /* skip two chars */
926 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
929 i++; /* next hex digit */
931 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
934 /* get the two nybbles */
935 hinybble = PTR_DIFF(p1, hexchars);
936 lonybble = PTR_DIFF(p2, hexchars);
938 p[num_chars] = (hinybble << 4) | lonybble;
947 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
952 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
954 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
956 ret_blob.length = strhex_to_str((char*)ret_blob.data,
964 * Routine to print a buffer as HEX digits, into an allocated string.
967 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
972 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
974 for (i = 0; i < len; i++)
975 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
981 Check if a string is part of a list.
984 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
988 size_t bufsize = strlen(list);
994 /* We know a token can't be larger
995 * than the entire list. */
997 tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1002 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1003 if (casesensitive) {
1004 if (strcmp(tok,s) == 0) {
1009 if (StrCaseCmp(tok,s) == 0) {
1020 /* this is used to prevent lots of mallocs of size 1 */
1021 static const char *null_string = "";
1024 Set a string value, allocing the space for the string
1027 static BOOL string_init(char **dest,const char *src)
1037 *dest = CONST_DISCARD(char*, null_string);
1039 (*dest) = SMB_STRDUP(src);
1040 if ((*dest) == NULL) {
1041 DEBUG(0,("Out of memory in string_init\n"));
1049 Free a string value.
1052 void string_free(char **s)
1056 if (*s == null_string)
1062 Set a string value, deallocating any existing space, and allocing the space
1066 BOOL string_set(char **dest,const char *src)
1069 return(string_init(dest,src));
1073 Substitute a string for a pattern in another string. Make sure there is
1076 This routine looks for pattern in s and replaces it with
1077 insert. It may do multiple replacements or just one.
1079 Any of " ; ' $ or ` in the insert string are replaced with _
1080 if len==0 then the string cannot be extended. This is different from the old
1081 use of len==0 which was for no length checks to be done.
1084 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1085 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
1088 ssize_t ls,lp,li, i;
1090 if (!insert || !pattern || !*pattern || !s)
1093 ls = (ssize_t)strlen(s);
1094 lp = (ssize_t)strlen(pattern);
1095 li = (ssize_t)strlen(insert);
1098 len = ls + 1; /* len is number of *bytes* */
1100 while (lp <= ls && (p = strstr_m(s,pattern))) {
1101 if (ls + (li-lp) >= len) {
1102 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1103 (int)(ls + (li-lp) - len),
1104 pattern, (int)len));
1108 memmove(p+li,p+lp,strlen(p+lp)+1);
1110 for (i=0;i<li;i++) {
1111 switch (insert[i]) {
1117 /* allow a trailing $ (as in machine accounts) */
1118 if (allow_trailing_dollar && (i == li - 1 )) {
1125 if ( remove_unsafe_characters ) {
1127 /* yes this break should be here since we want to
1128 fall throw if not replacing unsafe chars */
1143 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1145 string_sub2( s, pattern, insert, len, True, True, False );
1148 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1150 string_sub2( s, pattern, insert, len, True, False, False );
1153 void fstring_sub(char *s,const char *pattern,const char *insert)
1155 string_sub(s, pattern, insert, sizeof(fstring));
1158 void pstring_sub(char *s,const char *pattern,const char *insert)
1160 string_sub(s, pattern, insert, sizeof(pstring));
1164 Similar to string_sub, but it will accept only allocated strings
1165 and may realloc them so pay attention at what you pass on no
1166 pointers inside strings, no pstrings or const may be passed
1170 char *realloc_string_sub(char *string, const char *pattern,
1175 ssize_t ls,lp,li,ld, i;
1177 if (!insert || !pattern || !*pattern || !string || !*string)
1182 in = SMB_STRDUP(insert);
1184 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1187 ls = (ssize_t)strlen(s);
1188 lp = (ssize_t)strlen(pattern);
1189 li = (ssize_t)strlen(insert);
1191 for (i=0;i<li;i++) {
1208 while ((p = strstr_m(s,pattern))) {
1210 int offset = PTR_DIFF(s,string);
1211 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1213 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1217 p = string + offset + (p - s);
1220 memmove(p+li,p+lp,strlen(p+lp)+1);
1230 /* Same as string_sub, but returns a talloc'ed string */
1232 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1233 const char *pattern, const char *insert)
1238 ssize_t ls,lp,li,ld, i;
1240 if (!insert || !pattern || !*pattern || !src || !*src)
1243 string = talloc_strdup(mem_ctx, src);
1244 if (string == NULL) {
1245 DEBUG(0, ("talloc_strdup failed\n"));
1251 in = SMB_STRDUP(insert);
1253 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1256 ls = (ssize_t)strlen(s);
1257 lp = (ssize_t)strlen(pattern);
1258 li = (ssize_t)strlen(insert);
1260 for (i=0;i<li;i++) {
1277 while ((p = strstr_m(s,pattern))) {
1279 int offset = PTR_DIFF(s,string);
1280 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1283 DEBUG(0, ("talloc_string_sub: out of "
1288 p = string + offset + (p - s);
1291 memmove(p+li,p+lp,strlen(p+lp)+1);
1302 Similar to string_sub() but allows for any character to be substituted.
1304 if len==0 then the string cannot be extended. This is different from the old
1305 use of len==0 which was for no length checks to be done.
1308 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1313 if (!insert || !pattern || !s)
1316 ls = (ssize_t)strlen(s);
1317 lp = (ssize_t)strlen(pattern);
1318 li = (ssize_t)strlen(insert);
1324 len = ls + 1; /* len is number of *bytes* */
1326 while (lp <= ls && (p = strstr_m(s,pattern))) {
1327 if (ls + (li-lp) >= len) {
1328 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1329 (int)(ls + (li-lp) - len),
1330 pattern, (int)len));
1334 memmove(p+li,p+lp,strlen(p+lp)+1);
1336 memcpy(p, insert, li);
1343 Similar to all_string_sub but for unicode strings.
1344 Return a new allocated unicode string.
1345 similar to string_sub() but allows for any character to be substituted.
1349 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1350 const smb_ucs2_t *insert)
1353 const smb_ucs2_t *sp;
1354 size_t lr, lp, li, lt;
1356 if (!insert || !pattern || !*pattern || !s)
1359 lt = (size_t)strlen_w(s);
1360 lp = (size_t)strlen_w(pattern);
1361 li = (size_t)strlen_w(insert);
1364 const smb_ucs2_t *st = s;
1366 while ((sp = strstr_w(st, pattern))) {
1372 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1374 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1378 while ((sp = strstr_w(s, pattern))) {
1379 memcpy(rp, s, (sp - s));
1380 rp += ((sp - s) / sizeof(smb_ucs2_t));
1381 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1385 lr = ((rp - r) / sizeof(smb_ucs2_t));
1387 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1395 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1400 if (!insert || !pattern || !s)
1402 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1403 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1404 return all_string_sub_w(s, p, i);
1409 Splits out the front and back at a separator.
1412 static void split_at_last_component(char *path, char *front, char sep, char *back)
1414 char *p = strrchr_m(path, sep);
1420 pstrcpy(front, path);
1434 Write an octal as a string.
1437 const char *octal_string(int i)
1439 static char ret[64];
1442 slprintf(ret, sizeof(ret)-1, "0%o", i);
1448 Truncate a string at a specified length.
1451 char *string_truncate(char *s, unsigned int length)
1453 if (s && strlen(s) > length)
1459 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1460 We convert via ucs2 for now.
1463 char *strchr_m(const char *src, char c)
1465 smb_ucs2_t *ws = NULL;
1471 /* characters below 0x3F are guaranteed to not appear in
1472 non-initial position in multi-byte charsets */
1473 if ((c & 0xC0) == 0) {
1474 return strchr(src, c);
1477 /* this is quite a common operation, so we want it to be
1478 fast. We optimise for the ascii case, knowing that all our
1479 supported multi-byte character sets are ascii-compatible
1480 (ie. they match for the first 128 chars) */
1482 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1490 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1491 /* With compose characters we must restart from the beginning. JRA. */
1495 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1496 /* Wrong answer, but what can we do... */
1497 return strchr(src, c);
1499 p = strchr_w(ws, UCS2_CHAR(c));
1505 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1507 /* Wrong answer, but what can we do... */
1508 return strchr(src, c);
1510 ret = (char *)(s+strlen(s2));
1516 char *strrchr_m(const char *s, char c)
1518 /* characters below 0x3F are guaranteed to not appear in
1519 non-initial position in multi-byte charsets */
1520 if ((c & 0xC0) == 0) {
1521 return strrchr(s, c);
1524 /* this is quite a common operation, so we want it to be
1525 fast. We optimise for the ascii case, knowing that all our
1526 supported multi-byte character sets are ascii-compatible
1527 (ie. they match for the first 128 chars). Also, in Samba
1528 we only search for ascii characters in 'c' and that
1529 in all mb character sets with a compound character
1530 containing c, if 'c' is not a match at position
1531 p, then p[-1] > 0x7f. JRA. */
1534 size_t len = strlen(s);
1536 BOOL got_mb = False;
1543 /* Could be a match. Part of a multibyte ? */
1544 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1545 /* Yep - go slow :-( */
1549 /* No - we have a match ! */
1552 } while (cp-- != s);
1557 /* String contained a non-ascii char. Slow path. */
1559 smb_ucs2_t *ws = NULL;
1564 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1565 /* Wrong answer, but what can we do. */
1566 return strrchr(s, c);
1568 p = strrchr_w(ws, UCS2_CHAR(c));
1574 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1576 /* Wrong answer, but what can we do. */
1577 return strrchr(s, c);
1579 ret = (char *)(s+strlen(s2));
1586 /***********************************************************************
1587 Return the equivalent of doing strrchr 'n' times - always going
1589 ***********************************************************************/
1591 char *strnrchr_m(const char *s, char c, unsigned int n)
1593 smb_ucs2_t *ws = NULL;
1598 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1599 /* Too hard to try and get right. */
1602 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1608 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1610 /* Too hard to try and get right. */
1613 ret = (char *)(s+strlen(s2));
1619 /***********************************************************************
1620 strstr_m - We convert via ucs2 for now.
1621 ***********************************************************************/
1623 char *strstr_m(const char *src, const char *findstr)
1626 smb_ucs2_t *src_w, *find_w;
1631 size_t findstr_len = 0;
1633 /* for correctness */
1638 /* Samba does single character findstr calls a *lot*. */
1639 if (findstr[1] == '\0')
1640 return strchr_m(src, *findstr);
1642 /* We optimise for the ascii case, knowing that all our
1643 supported multi-byte character sets are ascii-compatible
1644 (ie. they match for the first 128 chars) */
1646 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1647 if (*s == *findstr) {
1649 findstr_len = strlen(findstr);
1651 if (strncmp(s, findstr, findstr_len) == 0) {
1660 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1661 /* 'make check' fails unless we do this */
1663 /* With compose characters we must restart from the beginning. JRA. */
1667 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1668 DEBUG(0,("strstr_m: src malloc fail\n"));
1672 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1674 DEBUG(0,("strstr_m: find malloc fail\n"));
1678 p = strstr_w(src_w, find_w);
1687 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1690 DEBUG(0,("strstr_m: dest malloc fail\n"));
1693 retp = (char *)(s+strlen(s2));
1701 Convert a string to lower case.
1704 void strlower_m(char *s)
1709 /* this is quite a common operation, so we want it to be
1710 fast. We optimise for the ascii case, knowing that all our
1711 supported multi-byte character sets are ascii-compatible
1712 (ie. they match for the first 128 chars) */
1714 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1715 *s = tolower_ascii((unsigned char)*s);
1722 /* I assume that lowercased string takes the same number of bytes
1723 * as source string even in UTF-8 encoding. (VIV) */
1724 len = strlen(s) + 1;
1727 unix_strlower(s,len,s,len);
1728 /* Catch mb conversion errors that may not terminate. */
1735 Convert a string to upper case.
1738 void strupper_m(char *s)
1743 /* this is quite a common operation, so we want it to be
1744 fast. We optimise for the ascii case, knowing that all our
1745 supported multi-byte character sets are ascii-compatible
1746 (ie. they match for the first 128 chars) */
1748 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1749 *s = toupper_ascii((unsigned char)*s);
1756 /* I assume that lowercased string takes the same number of bytes
1757 * as source string even in multibyte encoding. (VIV) */
1758 len = strlen(s) + 1;
1761 unix_strupper(s,len,s,len);
1762 /* Catch mb conversion errors that may not terminate. */
1769 Count the number of UCS2 characters in a string. Normally this will
1770 be the same as the number of bytes in a string for single byte strings,
1771 but will be different for multibyte.
1774 size_t strlen_m(const char *s)
1782 while (*s && !(((uint8_t)*s) & 0x80)) {
1793 codepoint_t c = next_codepoint(s, &c_size);
1795 /* Unicode char fits into 16 bits. */
1798 /* Double-width unicode char - 32 bits. */
1808 Count the number of UCS2 characters in a string including the null
1812 size_t strlen_m_term(const char *s)
1817 return strlen_m(s) + 1;
1821 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1822 * if a string is there, include the terminator.
1825 size_t strlen_m_term_null(const char *s)
1839 Return a RFC2254 binary string representation of a buffer.
1840 Used in LDAP filters.
1844 char *binary_string_rfc2254(char *buf, int len)
1848 const char *hex = "0123456789ABCDEF";
1849 s = (char *)SMB_MALLOC(len * 3 + 1);
1852 for (j=i=0;i<len;i++) {
1854 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1855 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1862 char *binary_string(char *buf, int len)
1866 const char *hex = "0123456789ABCDEF";
1867 s = (char *)SMB_MALLOC(len * 2 + 1);
1870 for (j=i=0;i<len;i++) {
1871 s[j] = hex[((unsigned char)buf[i]) >> 4];
1872 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1879 Just a typesafety wrapper for snprintf into a pstring.
1882 int pstr_sprintf(pstring s, const char *fmt, ...)
1888 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1895 Just a typesafety wrapper for snprintf into a fstring.
1898 int fstr_sprintf(fstring s, const char *fmt, ...)
1904 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1910 List of Strings manipulation functions
1913 #define S_LIST_ABS 16 /* List Allocation Block Size */
1915 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1917 char **list, **rlist;
1923 if (!string || !*string)
1926 s = talloc_strdup(mem_ctx, string);
1928 s = SMB_STRDUP(string);
1931 DEBUG(0,("str_list_make: Unable to allocate memory"));
1934 if (!sep) sep = LIST_SEP;
1940 while (next_token(&str, tok, sep, sizeof(tok))) {
1942 lsize += S_LIST_ABS;
1944 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1946 /* We need to keep the old list on error so we can free the elements
1947 if the realloc fails. */
1948 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1951 DEBUG(0,("str_list_make: Unable to allocate memory"));
1952 str_list_free(&list);
1962 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1966 list[num] = talloc_strdup(mem_ctx, tok);
1968 list[num] = SMB_STRDUP(tok);
1972 DEBUG(0,("str_list_make: Unable to allocate memory"));
1973 str_list_free(&list);
1994 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1996 return str_list_make_internal(mem_ctx, string, sep);
1999 char **str_list_make(const char *string, const char *sep)
2001 return str_list_make_internal(NULL, string, sep);
2004 BOOL str_list_copy(char ***dest, const char **src)
2006 char **list, **rlist;
2018 lsize += S_LIST_ABS;
2019 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
2021 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
2022 str_list_free(&list);
2027 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
2030 list[num] = SMB_STRDUP(src[num]);
2032 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2033 str_list_free(&list);
2045 * Return true if all the elements of the list match exactly.
2047 BOOL str_list_compare(char **list1, char **list2)
2051 if (!list1 || !list2)
2052 return (list1 == list2);
2054 for (num = 0; list1[num]; num++) {
2057 if (!strcsequal(list1[num], list2[num]))
2061 return False; /* if list2 has more elements than list1 fail */
2066 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2070 if (!list || !*list)
2073 for(; *tlist; tlist++) {
2075 TALLOC_FREE(*tlist);
2081 TALLOC_FREE(*tlist);
2087 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2089 str_list_free_internal(mem_ctx, list);
2092 void str_list_free(char ***list)
2094 str_list_free_internal(NULL, list);
2097 /******************************************************************************
2098 *****************************************************************************/
2100 int str_list_count( const char **list )
2107 /* count the number of list members */
2109 for ( i=0; *list; i++, list++ );
2114 /******************************************************************************
2115 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2117 *****************************************************************************/
2119 BOOL str_list_sub_basic( char **list, const char *smb_name,
2120 const char *domain_name )
2126 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2128 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2141 /******************************************************************************
2142 substritute a specific pattern in a string list
2143 *****************************************************************************/
2145 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2148 ssize_t ls, lp, li, ld, i, d;
2157 lp = (ssize_t)strlen(pattern);
2158 li = (ssize_t)strlen(insert);
2163 ls = (ssize_t)strlen(s);
2165 while ((p = strstr_m(s, pattern))) {
2169 t = (char *) SMB_MALLOC(ls +ld +1);
2171 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2174 memcpy(t, *list, d);
2175 memcpy(t +d +li, p +lp, ls -d -lp +1);
2182 for (i = 0; i < li; i++) {
2183 switch (insert[i]) {
2195 t[d +i] = insert[i];
2208 #define IPSTR_LIST_SEP ","
2209 #define IPSTR_LIST_CHAR ','
2212 * Add ip string representation to ipstr list. Used also
2213 * as part of @function ipstr_list_make
2215 * @param ipstr_list pointer to string containing ip list;
2216 * MUST BE already allocated and IS reallocated if necessary
2217 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2218 * as a result of reallocation)
2219 * @param ip IP address which is to be added to list
2220 * @return pointer to string appended with new ip and possibly
2221 * reallocated to new length
2224 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2226 char* new_ipstr = NULL;
2228 /* arguments checking */
2229 if (!ipstr_list || !service) return NULL;
2231 /* attempt to convert ip to a string and append colon separator to it */
2233 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2234 inet_ntoa(service->ip), service->port);
2235 SAFE_FREE(*ipstr_list);
2237 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2239 *ipstr_list = new_ipstr;
2245 * Allocate and initialise an ipstr list using ip adresses
2246 * passed as arguments.
2248 * @param ipstr_list pointer to string meant to be allocated and set
2249 * @param ip_list array of ip addresses to place in the list
2250 * @param ip_count number of addresses stored in ip_list
2251 * @return pointer to allocated ip string
2254 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2258 /* arguments checking */
2259 if (!ip_list || !ipstr_list) return 0;
2263 /* process ip addresses given as arguments */
2264 for (i = 0; i < ip_count; i++)
2265 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2267 return (*ipstr_list);
2272 * Parse given ip string list into array of ip addresses
2273 * (as ip_service structures)
2274 * e.g. 192.168.1.100:389,192.168.1.78, ...
2276 * @param ipstr ip string list to be parsed
2277 * @param ip_list pointer to array of ip addresses which is
2278 * allocated by this function and must be freed by caller
2279 * @return number of succesfully parsed addresses
2282 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2288 if (!ipstr_list || !ip_list)
2291 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2292 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2293 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2298 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2301 struct in_addr addr;
2303 char *p = strchr(token_str, ':');
2310 /* convert single token to ip address */
2311 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2314 (*ip_list)[i].ip = addr;
2315 (*ip_list)[i].port = port;
2323 * Safely free ip string list
2325 * @param ipstr_list ip string list to be freed
2328 void ipstr_list_free(char* ipstr_list)
2330 SAFE_FREE(ipstr_list);
2335 Unescape a URL encoded string, in place.
2338 void rfc1738_unescape(char *buf)
2342 while (p && *p && (p=strchr_m(p,'%'))) {
2346 if (c1 >= '0' && c1 <= '9')
2348 else if (c1 >= 'A' && c1 <= 'F')
2350 else if (c1 >= 'a' && c1 <= 'f')
2352 else {p++; continue;}
2354 if (c2 >= '0' && c2 <= '9')
2356 else if (c2 >= 'A' && c2 <= 'F')
2358 else if (c2 >= 'a' && c2 <= 'f')
2360 else {p++; continue;}
2364 memmove(p+1, p+3, strlen(p+3)+1);
2369 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2372 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2374 DATA_BLOB base64_decode_data_blob(const char *s)
2376 int bit_offset, byte_offset, idx, i, n;
2377 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2378 unsigned char *d = decoded.data;
2383 while (*s && (p=strchr_m(b64,*s))) {
2384 idx = (int)(p - b64);
2385 byte_offset = (i*6)/8;
2386 bit_offset = (i*6)%8;
2387 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2388 if (bit_offset < 3) {
2389 d[byte_offset] |= (idx << (2-bit_offset));
2392 d[byte_offset] |= (idx >> (bit_offset-2));
2393 d[byte_offset+1] = 0;
2394 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2400 if ((n > 0) && (*s == '=')) {
2410 * Decode a base64 string in-place - wrapper for the above
2412 void base64_decode_inplace(char *s)
2414 DATA_BLOB decoded = base64_decode_data_blob(s);
2416 if ( decoded.length != 0 ) {
2417 memcpy(s, decoded.data, decoded.length);
2419 /* null terminate */
2420 s[decoded.length] = '\0';
2425 data_blob_free(&decoded);
2429 * Encode a base64 string into a malloc()ed string caller to free.
2431 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2433 char * base64_encode_data_blob(DATA_BLOB data)
2437 size_t out_cnt, len, output_len;
2440 if (!data.length || !data.data)
2445 output_len = data.length * 2;
2446 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2448 while (len-- && out_cnt < (data.length * 2) - 5) {
2449 int c = (unsigned char) *(data.data++);
2452 if (char_count == 3) {
2453 result[out_cnt++] = b64[bits >> 18];
2454 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2455 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2456 result[out_cnt++] = b64[bits & 0x3f];
2463 if (char_count != 0) {
2464 bits <<= 16 - (8 * char_count);
2465 result[out_cnt++] = b64[bits >> 18];
2466 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2467 if (char_count == 1) {
2468 result[out_cnt++] = '=';
2469 result[out_cnt++] = '=';
2471 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2472 result[out_cnt++] = '=';
2475 result[out_cnt] = '\0'; /* terminate */
2479 /* read a SMB_BIG_UINT from a string */
2480 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2483 SMB_BIG_UINT val = -1;
2484 const char *p = nptr;
2493 while (*p && isspace(*p))
2496 #ifdef LARGE_SMB_OFF_T
2497 sscanf(p,"%llu",&val);
2498 #else /* LARGE_SMB_OFF_T */
2499 sscanf(p,"%lu",&val);
2500 #endif /* LARGE_SMB_OFF_T */
2502 while (*p && isdigit(*p))
2510 /* Convert a size specification to a count of bytes. We accept the following
2512 * bytes if there is no suffix
2517 * pP whatever the ISO name for petabytes is
2519 * Returns 0 if the string can't be converted.
2521 SMB_OFF_T conv_str_size(const char * str)
2526 if (str == NULL || *str == '\0') {
2530 #ifdef HAVE_STRTOULL
2531 if (sizeof(SMB_OFF_T) == 8) {
2532 lval = strtoull(str, &end, 10 /* base */);
2534 lval = strtoul(str, &end, 10 /* base */);
2537 lval = strtoul(str, &end, 10 /* base */);
2540 if (end == NULL || end == str) {
2545 SMB_OFF_T lval_orig = lval;
2547 if (strwicmp(end, "K") == 0) {
2548 lval *= (SMB_OFF_T)1024;
2549 } else if (strwicmp(end, "M") == 0) {
2550 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2551 } else if (strwicmp(end, "G") == 0) {
2552 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2554 } else if (strwicmp(end, "T") == 0) {
2555 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2556 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2557 } else if (strwicmp(end, "P") == 0) {
2558 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2559 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2565 /* Primitive attempt to detect wrapping on platforms with
2566 * 4-byte SMB_OFF_T. It's better to let the caller handle
2567 * a failure than some random number.
2569 if (lval_orig <= lval) {
2577 void string_append(char **left, const char *right)
2579 int new_len = strlen(right) + 1;
2581 if (*left == NULL) {
2582 *left = (char *)SMB_MALLOC(new_len);
2585 new_len += strlen(*left);
2586 *left = (char *)SMB_REALLOC(*left, new_len);
2589 if (*left == NULL) {
2593 safe_strcat(*left, right, new_len-1);
2596 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2597 const char *str, const char ***strings,
2600 char *dup_str = talloc_strdup(mem_ctx, str);
2602 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2604 if ((*strings == NULL) || (dup_str == NULL)) {
2609 (*strings)[*num] = dup_str;
2614 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2615 * error checking in between. The indiation that something weird happened is
2618 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2619 size_t *bufsize, const char *fmt, ...)
2626 /* len<0 is an internal marker that something failed */
2630 if (*string == NULL) {
2634 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2635 if (*string == NULL)
2640 ret = vasprintf(&newstr, fmt, ap);
2648 while ((*len)+ret >= *bufsize) {
2651 if (*bufsize >= (1024*1024*256))
2656 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2658 if (*string == NULL) {
2663 StrnCpy((*string)+(*len), newstr, ret);
2674 Returns the substring from src between the first occurrence of
2675 the char "front" and the first occurence of the char "back".
2676 Mallocs the return string which must be freed. Not for use
2677 with wide character strings.
2679 char *sstring_sub(const char *src, char front, char back)
2681 char *temp1, *temp2, *temp3;
2684 temp1 = strchr(src, front);
2685 if (temp1 == NULL) return NULL;
2686 temp2 = strchr(src, back);
2687 if (temp2 == NULL) return NULL;
2688 len = temp2 - temp1;
2689 if (len <= 0) return NULL;
2690 temp3 = (char*)SMB_MALLOC(len);
2691 if (temp3 == NULL) {
2692 DEBUG(1,("Malloc failure in sstring_sub\n"));
2695 memcpy(temp3, temp1+1, len-1);
2696 temp3[len-1] = '\0';
2700 /********************************************************************
2701 Check a string for any occurrences of a specified list of invalid
2703 ********************************************************************/
2705 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2709 for ( i=0; i<max_len && name[i]; i++ ) {
2710 /* fail if strchr_m() finds one of the invalid characters */
2711 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2721 return the number of bytes occupied by a buffer in ASCII format
2722 the result includes the null termination
2723 limited by 'n' bytes
2725 size_t ascii_len_n(const char *src, size_t n)
2729 len = strnlen(src, n);
2738 return the number of bytes occupied by a buffer in CH_UTF16 format
2739 the result includes the null termination
2741 size_t utf16_len(const void *buf)
2745 for (len = 0; SVAL(buf,len); len += 2) ;
2751 return the number of bytes occupied by a buffer in CH_UTF16 format
2752 the result includes the null termination
2753 limited by 'n' bytes
2755 size_t utf16_len_n(const void *src, size_t n)
2759 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2768 /*******************************************************************
2769 Add a shell escape character '\' to any character not in a known list
2770 of characters. UNIX charset format.
2771 *******************************************************************/
2773 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2774 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2776 char *escape_shell_string(const char *src)
2778 size_t srclen = strlen(src);
2779 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2781 BOOL in_s_quote = False;
2782 BOOL in_d_quote = False;
2783 BOOL next_escaped = False;
2791 codepoint_t c = next_codepoint(src, &c_size);
2793 if (c == INVALID_CODEPOINT) {
2799 memcpy(dest, src, c_size);
2802 next_escaped = False;
2807 * Deal with backslash escaped state.
2808 * This only lasts for one character.
2813 next_escaped = False;
2818 * Deal with single quote state. The
2819 * only thing we care about is exiting
2832 * Deal with double quote state. The most
2833 * complex state. We must cope with \, meaning
2834 * possibly escape next char (depending what it
2835 * is), ", meaning exit this state, and possibly
2836 * add an \ escape to any unprotected character
2837 * (listed in INSIDE_DQUOTE_LIST).
2843 * Next character might be escaped.
2844 * We have to peek. Inside double
2845 * quotes only INSIDE_DQUOTE_LIST
2846 * characters are escaped by a \.
2851 c = next_codepoint(&src[1], &c_size);
2852 if (c == INVALID_CODEPOINT) {
2858 * Don't escape the next char.
2867 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2868 next_escaped = True;
2875 /* Exit double quote state. */
2882 * We know the character isn't \ or ",
2883 * so escape it if it's any of the other
2884 * possible unprotected characters.
2887 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2895 * From here to the end of the loop we're
2896 * not in the single or double quote state.
2900 /* Next character must be escaped. */
2901 next_escaped = True;
2907 /* Go into single quote state. */
2914 /* Go into double quote state. */
2920 /* Check if we need to escape the character. */
2922 if (!strchr(INCLUDE_LIST, (int)*src)) {