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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 n)
271 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
272 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
273 return strncmp(buf1,buf2,n);
279 * @note The comparison is case-insensitive.
281 BOOL strequal(const char *s1, const char *s2)
288 return(StrCaseCmp(s1,s2)==0);
292 * Compare 2 strings up to and including the nth char.
294 * @note The comparison is case-insensitive.
296 BOOL strnequal(const char *s1,const char *s2,size_t n)
300 if (!s1 || !s2 || !n)
303 return(StrnCaseCmp(s1,s2,n)==0);
307 Compare 2 strings (case sensitive).
310 BOOL strcsequal(const char *s1,const char *s2)
317 return(strcmp(s1,s2)==0);
321 Do a case-insensitive, whitespace-ignoring string compare.
324 int strwicmp(const char *psz1, const char *psz2)
326 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
327 /* appropriate value. */
330 else if (psz1 == NULL)
332 else if (psz2 == NULL)
335 /* sync the strings on first non-whitespace */
337 while (isspace((int)*psz1))
339 while (isspace((int)*psz2))
341 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
347 return (*psz1 - *psz2);
352 Convert a string to upper case, but don't modify it.
355 char *strupper_static(const char *s)
366 Convert a string to "normal" form.
369 void strnorm(char *s, int case_default)
371 if (case_default == CASE_UPPER)
378 Check if a string is in "normal" case.
381 BOOL strisnormal(const char *s, int case_default)
383 if (case_default == CASE_UPPER)
384 return(!strhaslower(s));
386 return(!strhasupper(s));
392 NOTE: oldc and newc must be 7 bit characters
395 void string_replace( char *s, char oldc, char newc )
401 /* this is quite a common operation, so we want it to be
402 fast. We optimise for the ascii case, knowing that all our
403 supported multi-byte character sets are ascii-compatible
404 (ie. they match for the first 128 chars) */
406 for (p = s; *p; p++) {
407 if (*p & 0x80) /* mb string - slow path. */
416 /* Slow (mb) path. */
417 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
418 /* With compose characters we must restart from the beginning. JRA. */
422 len = push_ucs2_allocate(&tmp, p);
426 string_replace_w(tmp, UCS2_CHAR(oldc), UCS2_CHAR(newc));
427 pull_ucs2(NULL, p, tmp, src_len+1, -1, STR_TERMINATE);
432 * Skip past some strings in a buffer - old version - no checks.
435 char *push_skip_string(char *buf)
437 buf += strlen(buf) + 1;
442 Skip past a string in a buffer. Buffer may not be
443 null terminated. end_ptr points to the first byte after
444 then end of the buffer.
447 char *skip_string(const char *base, size_t len, char *buf)
449 const char *end_ptr = base + len;
451 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
455 /* Skip the string */
458 if (buf >= end_ptr) {
468 Count the number of characters in a string. Normally this will
469 be the same as the number of bytes in a string for single byte strings,
470 but will be different for multibyte.
473 size_t str_charnum(const char *s)
475 uint16 tmpbuf2[sizeof(pstring)];
476 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
477 return strlen_w(tmpbuf2);
481 Count the number of characters in a string. Normally this will
482 be the same as the number of bytes in a string for single byte strings,
483 but will be different for multibyte.
486 size_t str_ascii_charnum(const char *s)
489 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
490 return strlen(tmpbuf2);
493 BOOL trim_char(char *s,char cfront,char cback)
499 /* Ignore null or empty strings. */
500 if (!s || (s[0] == '\0'))
504 while (*fp && *fp == cfront)
507 /* We ate the string. */
515 ep = fp + strlen(fp) - 1;
517 /* Attempt ascii only. Bail for mb strings. */
518 while ((ep >= fp) && (*ep == cback)) {
520 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
521 /* Could be mb... bail back to tim_string. */
529 return trim_string(s, cfront ? fs : NULL, bs);
535 /* We ate the string. */
542 memmove(s, fp, ep-fp+2);
547 Trim the specified elements off the front and back of a string.
550 BOOL trim_string(char *s,const char *front,const char *back)
557 /* Ignore null or empty strings. */
558 if (!s || (s[0] == '\0'))
561 front_len = front? strlen(front) : 0;
562 back_len = back? strlen(back) : 0;
567 while (len && strncmp(s, front, front_len)==0) {
568 /* Must use memmove here as src & dest can
569 * easily overlap. Found by valgrind. JRA. */
570 memmove(s, s+front_len, (len-front_len)+1);
577 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
578 s[len-back_len]='\0';
587 Does a string have any uppercase chars in it?
590 BOOL strhasupper(const char *s)
595 if (push_ucs2_allocate(&tmp, s) == -1) {
599 for(p = tmp; *p != 0; p++) {
611 Does a string have any lowercase chars in it?
614 BOOL strhaslower(const char *s)
619 if (push_ucs2_allocate(&tmp, s) == -1) {
623 for(p = tmp; *p != 0; p++) {
635 Find the number of 'c' chars in a string
638 size_t count_chars(const char *s,char c)
642 smb_ucs2_t *alloc_tmpbuf = NULL;
644 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
648 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
649 if(*ptr==UCS2_CHAR(c))
652 SAFE_FREE(alloc_tmpbuf);
657 Safe string copy into a known length string. maxlength does not
658 include the terminating zero.
661 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
666 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
671 clobber_region(fn,line,dest, maxlength+1);
679 len = strnlen(src, maxlength+1);
681 if (len > maxlength) {
682 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
683 (unsigned long)(len-maxlength), (unsigned long)len,
684 (unsigned long)maxlength, src));
688 memmove(dest, src, len);
694 Safe string cat into a string. maxlength does not
695 include the terminating zero.
697 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
699 size_t src_len, dest_len;
702 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
709 src_len = strnlen(src, maxlength + 1);
710 dest_len = strnlen(dest, maxlength + 1);
713 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
716 if (src_len + dest_len > maxlength) {
717 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
718 (int)(src_len + dest_len - maxlength), src));
719 if (maxlength > dest_len) {
720 memcpy(&dest[dest_len], src, maxlength - dest_len);
726 memcpy(&dest[dest_len], src, src_len);
727 dest[dest_len + src_len] = 0;
732 Paranoid strcpy into a buffer of given length (includes terminating
733 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
734 and replaces with '_'. Deliberately does *NOT* check for multibyte
735 characters. Don't change it !
737 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
742 clobber_region(fn, line, dest, maxlength);
746 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
756 if (len >= maxlength)
759 if (!other_safe_chars)
760 other_safe_chars = "";
762 for(i = 0; i < len; i++) {
763 int val = (src[i] & 0xff);
764 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
776 Like strncpy but always null terminates. Make sure there is room!
777 The variable n should always be one less than the available size.
779 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
784 clobber_region(fn, line, dest, n+1);
788 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
797 while (n-- && (*d = *src)) {
808 Like strncpy but copies up to the character marker. always null terminates.
809 returns a pointer to the character marker in the source string (src).
812 static char *strncpyn(char *dest, const char *src, size_t n, char c)
818 clobber_region(dest, n+1);
820 p = strchr_m(src, c);
822 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
826 str_len = PTR_DIFF(p, src);
827 strncpy(dest, src, MIN(n, str_len));
828 dest[str_len] = '\0';
835 Routine to get hex characters and turn them into a 16 byte array.
836 the array can be variable length, and any non-hex-numeric
837 characters are skipped. "0xnn" or "0Xnn" is specially catered
840 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
844 size_t strhex_to_str(char *p, size_t len, const char *strhex)
847 size_t num_chars = 0;
848 unsigned char lonybble, hinybble;
849 const char *hexchars = "0123456789ABCDEF";
850 char *p1 = NULL, *p2 = NULL;
852 for (i = 0; i < len && strhex[i] != 0; i++) {
853 if (strnequal(hexchars, "0x", 2)) {
854 i++; /* skip two chars */
858 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
861 i++; /* next hex digit */
863 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
866 /* get the two nybbles */
867 hinybble = PTR_DIFF(p1, hexchars);
868 lonybble = PTR_DIFF(p2, hexchars);
870 p[num_chars] = (hinybble << 4) | lonybble;
879 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
884 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
886 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
888 ret_blob.length = strhex_to_str((char*)ret_blob.data,
896 * Routine to print a buffer as HEX digits, into an allocated string.
899 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
904 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
906 for (i = 0; i < len; i++)
907 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
913 Check if a string is part of a list.
916 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
924 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
926 if (strcmp(tok,s) == 0)
929 if (StrCaseCmp(tok,s) == 0)
936 /* this is used to prevent lots of mallocs of size 1 */
937 static const char *null_string = "";
940 Set a string value, allocing the space for the string
943 static BOOL string_init(char **dest,const char *src)
953 *dest = CONST_DISCARD(char*, null_string);
955 (*dest) = SMB_STRDUP(src);
956 if ((*dest) == NULL) {
957 DEBUG(0,("Out of memory in string_init\n"));
968 void string_free(char **s)
972 if (*s == null_string)
978 Set a string value, deallocating any existing space, and allocing the space
982 BOOL string_set(char **dest,const char *src)
985 return(string_init(dest,src));
989 Substitute a string for a pattern in another string. Make sure there is
992 This routine looks for pattern in s and replaces it with
993 insert. It may do multiple replacements or just one.
995 Any of " ; ' $ or ` in the insert string are replaced with _
996 if len==0 then the string cannot be extended. This is different from the old
997 use of len==0 which was for no length checks to be done.
1000 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1001 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
1004 ssize_t ls,lp,li, i;
1006 if (!insert || !pattern || !*pattern || !s)
1009 ls = (ssize_t)strlen(s);
1010 lp = (ssize_t)strlen(pattern);
1011 li = (ssize_t)strlen(insert);
1014 len = ls + 1; /* len is number of *bytes* */
1016 while (lp <= ls && (p = strstr_m(s,pattern))) {
1017 if (ls + (li-lp) >= len) {
1018 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1019 (int)(ls + (li-lp) - len),
1020 pattern, (int)len));
1024 memmove(p+li,p+lp,strlen(p+lp)+1);
1026 for (i=0;i<li;i++) {
1027 switch (insert[i]) {
1033 /* allow a trailing $ (as in machine accounts) */
1034 if (allow_trailing_dollar && (i == li - 1 )) {
1041 if ( remove_unsafe_characters ) {
1043 /* yes this break should be here since we want to
1044 fall throw if not replacing unsafe chars */
1059 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1061 string_sub2( s, pattern, insert, len, True, True, False );
1064 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1066 string_sub2( s, pattern, insert, len, True, False, False );
1069 void fstring_sub(char *s,const char *pattern,const char *insert)
1071 string_sub(s, pattern, insert, sizeof(fstring));
1074 void pstring_sub(char *s,const char *pattern,const char *insert)
1076 string_sub(s, pattern, insert, sizeof(pstring));
1080 Similar to string_sub, but it will accept only allocated strings
1081 and may realloc them so pay attention at what you pass on no
1082 pointers inside strings, no pstrings or const may be passed
1086 char *realloc_string_sub(char *string, const char *pattern,
1091 ssize_t ls,lp,li,ld, i;
1093 if (!insert || !pattern || !*pattern || !string || !*string)
1098 in = SMB_STRDUP(insert);
1100 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1103 ls = (ssize_t)strlen(s);
1104 lp = (ssize_t)strlen(pattern);
1105 li = (ssize_t)strlen(insert);
1107 for (i=0;i<li;i++) {
1124 while ((p = strstr_m(s,pattern))) {
1126 int offset = PTR_DIFF(s,string);
1127 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1129 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1133 p = string + offset + (p - s);
1136 memmove(p+li,p+lp,strlen(p+lp)+1);
1146 /* Same as string_sub, but returns a talloc'ed string */
1148 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1149 const char *pattern, const char *insert)
1154 ssize_t ls,lp,li,ld, i;
1156 if (!insert || !pattern || !*pattern || !src || !*src)
1159 string = talloc_strdup(mem_ctx, src);
1160 if (string == NULL) {
1161 DEBUG(0, ("talloc_strdup failed\n"));
1167 in = SMB_STRDUP(insert);
1169 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1172 ls = (ssize_t)strlen(s);
1173 lp = (ssize_t)strlen(pattern);
1174 li = (ssize_t)strlen(insert);
1176 for (i=0;i<li;i++) {
1193 while ((p = strstr_m(s,pattern))) {
1195 int offset = PTR_DIFF(s,string);
1196 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1199 DEBUG(0, ("talloc_string_sub: out of "
1204 p = string + offset + (p - s);
1207 memmove(p+li,p+lp,strlen(p+lp)+1);
1218 Similar to string_sub() but allows for any character to be substituted.
1220 if len==0 then the string cannot be extended. This is different from the old
1221 use of len==0 which was for no length checks to be done.
1224 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1229 if (!insert || !pattern || !s)
1232 ls = (ssize_t)strlen(s);
1233 lp = (ssize_t)strlen(pattern);
1234 li = (ssize_t)strlen(insert);
1240 len = ls + 1; /* len is number of *bytes* */
1242 while (lp <= ls && (p = strstr_m(s,pattern))) {
1243 if (ls + (li-lp) >= len) {
1244 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1245 (int)(ls + (li-lp) - len),
1246 pattern, (int)len));
1250 memmove(p+li,p+lp,strlen(p+lp)+1);
1252 memcpy(p, insert, li);
1259 Similar to all_string_sub but for unicode strings.
1260 Return a new allocated unicode string.
1261 similar to string_sub() but allows for any character to be substituted.
1265 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1266 const smb_ucs2_t *insert)
1269 const smb_ucs2_t *sp;
1270 size_t lr, lp, li, lt;
1272 if (!insert || !pattern || !*pattern || !s)
1275 lt = (size_t)strlen_w(s);
1276 lp = (size_t)strlen_w(pattern);
1277 li = (size_t)strlen_w(insert);
1280 const smb_ucs2_t *st = s;
1282 while ((sp = strstr_w(st, pattern))) {
1288 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1290 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1294 while ((sp = strstr_w(s, pattern))) {
1295 memcpy(rp, s, (sp - s));
1296 rp += ((sp - s) / sizeof(smb_ucs2_t));
1297 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1301 lr = ((rp - r) / sizeof(smb_ucs2_t));
1303 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1311 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1316 if (!insert || !pattern || !s)
1318 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1319 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1320 return all_string_sub_w(s, p, i);
1325 Splits out the front and back at a separator.
1328 static void split_at_last_component(char *path, char *front, char sep, char *back)
1330 char *p = strrchr_m(path, sep);
1336 pstrcpy(front, path);
1350 Write an octal as a string.
1353 const char *octal_string(int i)
1355 static char ret[64];
1358 slprintf(ret, sizeof(ret)-1, "0%o", i);
1364 Truncate a string at a specified length.
1367 char *string_truncate(char *s, unsigned int length)
1369 if (s && strlen(s) > length)
1375 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1376 We convert via ucs2 for now.
1379 char *strchr_m(const char *src, char c)
1386 /* characters below 0x3F are guaranteed to not appear in
1387 non-initial position in multi-byte charsets */
1388 if ((c & 0xC0) == 0) {
1389 return strchr(src, c);
1392 /* this is quite a common operation, so we want it to be
1393 fast. We optimise for the ascii case, knowing that all our
1394 supported multi-byte character sets are ascii-compatible
1395 (ie. they match for the first 128 chars) */
1397 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1405 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1406 /* With compose characters we must restart from the beginning. JRA. */
1410 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1411 p = strchr_w(ws, UCS2_CHAR(c));
1415 pull_ucs2_pstring(s2, ws);
1416 return (char *)(s+strlen(s2));
1419 char *strrchr_m(const char *s, char c)
1421 /* characters below 0x3F are guaranteed to not appear in
1422 non-initial position in multi-byte charsets */
1423 if ((c & 0xC0) == 0) {
1424 return strrchr(s, c);
1427 /* this is quite a common operation, so we want it to be
1428 fast. We optimise for the ascii case, knowing that all our
1429 supported multi-byte character sets are ascii-compatible
1430 (ie. they match for the first 128 chars). Also, in Samba
1431 we only search for ascii characters in 'c' and that
1432 in all mb character sets with a compound character
1433 containing c, if 'c' is not a match at position
1434 p, then p[-1] > 0x7f. JRA. */
1437 size_t len = strlen(s);
1439 BOOL got_mb = False;
1446 /* Could be a match. Part of a multibyte ? */
1447 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1448 /* Yep - go slow :-( */
1452 /* No - we have a match ! */
1455 } while (cp-- != s);
1460 /* String contained a non-ascii char. Slow path. */
1466 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1467 p = strrchr_w(ws, UCS2_CHAR(c));
1471 pull_ucs2_pstring(s2, ws);
1472 return (char *)(s+strlen(s2));
1476 /***********************************************************************
1477 Return the equivalent of doing strrchr 'n' times - always going
1479 ***********************************************************************/
1481 char *strnrchr_m(const char *s, char c, unsigned int n)
1487 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1488 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1492 pull_ucs2_pstring(s2, ws);
1493 return (char *)(s+strlen(s2));
1496 /***********************************************************************
1497 strstr_m - We convert via ucs2 for now.
1498 ***********************************************************************/
1500 char *strstr_m(const char *src, const char *findstr)
1503 smb_ucs2_t *src_w, *find_w;
1508 size_t findstr_len = 0;
1510 /* for correctness */
1515 /* Samba does single character findstr calls a *lot*. */
1516 if (findstr[1] == '\0')
1517 return strchr_m(src, *findstr);
1519 /* We optimise for the ascii case, knowing that all our
1520 supported multi-byte character sets are ascii-compatible
1521 (ie. they match for the first 128 chars) */
1523 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1524 if (*s == *findstr) {
1526 findstr_len = strlen(findstr);
1528 if (strncmp(s, findstr, findstr_len) == 0) {
1537 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1538 /* 'make check' fails unless we do this */
1540 /* With compose characters we must restart from the beginning. JRA. */
1544 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1545 DEBUG(0,("strstr_m: src malloc fail\n"));
1549 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1551 DEBUG(0,("strstr_m: find malloc fail\n"));
1555 p = strstr_w(src_w, find_w);
1564 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1567 DEBUG(0,("strstr_m: dest malloc fail\n"));
1570 retp = (char *)(s+strlen(s2));
1578 Convert a string to lower case.
1581 void strlower_m(char *s)
1586 /* this is quite a common operation, so we want it to be
1587 fast. We optimise for the ascii case, knowing that all our
1588 supported multi-byte character sets are ascii-compatible
1589 (ie. they match for the first 128 chars) */
1591 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1592 *s = tolower_ascii((unsigned char)*s);
1599 /* I assume that lowercased string takes the same number of bytes
1600 * as source string even in UTF-8 encoding. (VIV) */
1601 len = strlen(s) + 1;
1604 unix_strlower(s,len,s,len);
1605 /* Catch mb conversion errors that may not terminate. */
1612 Convert a string to upper case.
1615 void strupper_m(char *s)
1620 /* this is quite a common operation, so we want it to be
1621 fast. We optimise for the ascii case, knowing that all our
1622 supported multi-byte character sets are ascii-compatible
1623 (ie. they match for the first 128 chars) */
1625 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1626 *s = toupper_ascii((unsigned char)*s);
1633 /* I assume that lowercased string takes the same number of bytes
1634 * as source string even in multibyte encoding. (VIV) */
1635 len = strlen(s) + 1;
1638 unix_strupper(s,len,s,len);
1639 /* Catch mb conversion errors that may not terminate. */
1646 Count the number of UCS2 characters in a string. Normally this will
1647 be the same as the number of bytes in a string for single byte strings,
1648 but will be different for multibyte.
1651 size_t strlen_m(const char *s)
1659 while (*s && !(((uint8_t)*s) & 0x80)) {
1670 codepoint_t c = next_codepoint(s, &c_size);
1672 /* Unicode char fits into 16 bits. */
1675 /* Double-width unicode char - 32 bits. */
1685 Count the number of UCS2 characters in a string including the null
1689 size_t strlen_m_term(const char *s)
1694 return strlen_m(s) + 1;
1698 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1699 * if a string is there, include the terminator.
1702 size_t strlen_m_term_null(const char *s)
1716 Return a RFC2254 binary string representation of a buffer.
1717 Used in LDAP filters.
1721 char *binary_string_rfc2254(char *buf, int len)
1725 const char *hex = "0123456789ABCDEF";
1726 s = (char *)SMB_MALLOC(len * 3 + 1);
1729 for (j=i=0;i<len;i++) {
1731 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1732 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1739 char *binary_string(char *buf, int len)
1743 const char *hex = "0123456789ABCDEF";
1744 s = (char *)SMB_MALLOC(len * 2 + 1);
1747 for (j=i=0;i<len;i++) {
1748 s[j] = hex[((unsigned char)buf[i]) >> 4];
1749 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1756 Just a typesafety wrapper for snprintf into a pstring.
1759 int pstr_sprintf(pstring s, const char *fmt, ...)
1765 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1772 Just a typesafety wrapper for snprintf into a fstring.
1775 int fstr_sprintf(fstring s, const char *fmt, ...)
1781 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1787 List of Strings manipulation functions
1790 #define S_LIST_ABS 16 /* List Allocation Block Size */
1792 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1794 char **list, **rlist;
1800 if (!string || !*string)
1803 s = talloc_strdup(mem_ctx, string);
1805 s = SMB_STRDUP(string);
1808 DEBUG(0,("str_list_make: Unable to allocate memory"));
1811 if (!sep) sep = LIST_SEP;
1817 while (next_token(&str, tok, sep, sizeof(tok))) {
1819 lsize += S_LIST_ABS;
1821 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1823 /* We need to keep the old list on error so we can free the elements
1824 if the realloc fails. */
1825 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1828 DEBUG(0,("str_list_make: Unable to allocate memory"));
1829 str_list_free(&list);
1839 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1843 list[num] = talloc_strdup(mem_ctx, tok);
1845 list[num] = SMB_STRDUP(tok);
1849 DEBUG(0,("str_list_make: Unable to allocate memory"));
1850 str_list_free(&list);
1871 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1873 return str_list_make_internal(mem_ctx, string, sep);
1876 char **str_list_make(const char *string, const char *sep)
1878 return str_list_make_internal(NULL, string, sep);
1881 BOOL str_list_copy(char ***dest, const char **src)
1883 char **list, **rlist;
1895 lsize += S_LIST_ABS;
1896 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1898 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1899 str_list_free(&list);
1904 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1907 list[num] = SMB_STRDUP(src[num]);
1909 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1910 str_list_free(&list);
1922 * Return true if all the elements of the list match exactly.
1924 BOOL str_list_compare(char **list1, char **list2)
1928 if (!list1 || !list2)
1929 return (list1 == list2);
1931 for (num = 0; list1[num]; num++) {
1934 if (!strcsequal(list1[num], list2[num]))
1938 return False; /* if list2 has more elements than list1 fail */
1943 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1947 if (!list || !*list)
1950 for(; *tlist; tlist++) {
1952 TALLOC_FREE(*tlist);
1958 TALLOC_FREE(*tlist);
1964 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1966 str_list_free_internal(mem_ctx, list);
1969 void str_list_free(char ***list)
1971 str_list_free_internal(NULL, list);
1974 /******************************************************************************
1975 *****************************************************************************/
1977 int str_list_count( const char **list )
1984 /* count the number of list members */
1986 for ( i=0; *list; i++, list++ );
1991 /******************************************************************************
1992 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1994 *****************************************************************************/
1996 BOOL str_list_sub_basic( char **list, const char *smb_name,
1997 const char *domain_name )
2003 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2005 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2018 /******************************************************************************
2019 substritute a specific pattern in a string list
2020 *****************************************************************************/
2022 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2025 ssize_t ls, lp, li, ld, i, d;
2034 lp = (ssize_t)strlen(pattern);
2035 li = (ssize_t)strlen(insert);
2040 ls = (ssize_t)strlen(s);
2042 while ((p = strstr_m(s, pattern))) {
2046 t = (char *) SMB_MALLOC(ls +ld +1);
2048 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2051 memcpy(t, *list, d);
2052 memcpy(t +d +li, p +lp, ls -d -lp +1);
2059 for (i = 0; i < li; i++) {
2060 switch (insert[i]) {
2072 t[d +i] = insert[i];
2085 #define IPSTR_LIST_SEP ","
2086 #define IPSTR_LIST_CHAR ','
2089 * Add ip string representation to ipstr list. Used also
2090 * as part of @function ipstr_list_make
2092 * @param ipstr_list pointer to string containing ip list;
2093 * MUST BE already allocated and IS reallocated if necessary
2094 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2095 * as a result of reallocation)
2096 * @param ip IP address which is to be added to list
2097 * @return pointer to string appended with new ip and possibly
2098 * reallocated to new length
2101 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2103 char* new_ipstr = NULL;
2105 /* arguments checking */
2106 if (!ipstr_list || !service) return NULL;
2108 /* attempt to convert ip to a string and append colon separator to it */
2110 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2111 inet_ntoa(service->ip), service->port);
2112 SAFE_FREE(*ipstr_list);
2114 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2116 *ipstr_list = new_ipstr;
2122 * Allocate and initialise an ipstr list using ip adresses
2123 * passed as arguments.
2125 * @param ipstr_list pointer to string meant to be allocated and set
2126 * @param ip_list array of ip addresses to place in the list
2127 * @param ip_count number of addresses stored in ip_list
2128 * @return pointer to allocated ip string
2131 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2135 /* arguments checking */
2136 if (!ip_list || !ipstr_list) return 0;
2140 /* process ip addresses given as arguments */
2141 for (i = 0; i < ip_count; i++)
2142 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2144 return (*ipstr_list);
2149 * Parse given ip string list into array of ip addresses
2150 * (as ip_service structures)
2151 * e.g. 192.168.1.100:389,192.168.1.78, ...
2153 * @param ipstr ip string list to be parsed
2154 * @param ip_list pointer to array of ip addresses which is
2155 * allocated by this function and must be freed by caller
2156 * @return number of succesfully parsed addresses
2159 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2165 if (!ipstr_list || !ip_list)
2168 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2169 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2170 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2175 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2178 struct in_addr addr;
2180 char *p = strchr(token_str, ':');
2187 /* convert single token to ip address */
2188 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2191 (*ip_list)[i].ip = addr;
2192 (*ip_list)[i].port = port;
2200 * Safely free ip string list
2202 * @param ipstr_list ip string list to be freed
2205 void ipstr_list_free(char* ipstr_list)
2207 SAFE_FREE(ipstr_list);
2212 Unescape a URL encoded string, in place.
2215 void rfc1738_unescape(char *buf)
2219 while (p && *p && (p=strchr_m(p,'%'))) {
2223 if (c1 >= '0' && c1 <= '9')
2225 else if (c1 >= 'A' && c1 <= 'F')
2227 else if (c1 >= 'a' && c1 <= 'f')
2229 else {p++; continue;}
2231 if (c2 >= '0' && c2 <= '9')
2233 else if (c2 >= 'A' && c2 <= 'F')
2235 else if (c2 >= 'a' && c2 <= 'f')
2237 else {p++; continue;}
2241 memmove(p+1, p+3, strlen(p+3)+1);
2246 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2249 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2251 DATA_BLOB base64_decode_data_blob(const char *s)
2253 int bit_offset, byte_offset, idx, i, n;
2254 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2255 unsigned char *d = decoded.data;
2260 while (*s && (p=strchr_m(b64,*s))) {
2261 idx = (int)(p - b64);
2262 byte_offset = (i*6)/8;
2263 bit_offset = (i*6)%8;
2264 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2265 if (bit_offset < 3) {
2266 d[byte_offset] |= (idx << (2-bit_offset));
2269 d[byte_offset] |= (idx >> (bit_offset-2));
2270 d[byte_offset+1] = 0;
2271 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2277 if ((n > 0) && (*s == '=')) {
2287 * Decode a base64 string in-place - wrapper for the above
2289 void base64_decode_inplace(char *s)
2291 DATA_BLOB decoded = base64_decode_data_blob(s);
2293 if ( decoded.length != 0 ) {
2294 memcpy(s, decoded.data, decoded.length);
2296 /* null terminate */
2297 s[decoded.length] = '\0';
2302 data_blob_free(&decoded);
2306 * Encode a base64 string into a malloc()ed string caller to free.
2308 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2310 char * base64_encode_data_blob(DATA_BLOB data)
2314 size_t out_cnt, len, output_len;
2317 if (!data.length || !data.data)
2322 output_len = data.length * 2;
2323 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2325 while (len-- && out_cnt < (data.length * 2) - 5) {
2326 int c = (unsigned char) *(data.data++);
2329 if (char_count == 3) {
2330 result[out_cnt++] = b64[bits >> 18];
2331 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2332 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2333 result[out_cnt++] = b64[bits & 0x3f];
2340 if (char_count != 0) {
2341 bits <<= 16 - (8 * char_count);
2342 result[out_cnt++] = b64[bits >> 18];
2343 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2344 if (char_count == 1) {
2345 result[out_cnt++] = '=';
2346 result[out_cnt++] = '=';
2348 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2349 result[out_cnt++] = '=';
2352 result[out_cnt] = '\0'; /* terminate */
2356 /* read a SMB_BIG_UINT from a string */
2357 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2360 SMB_BIG_UINT val = -1;
2361 const char *p = nptr;
2370 while (*p && isspace(*p))
2373 #ifdef LARGE_SMB_OFF_T
2374 sscanf(p,"%llu",&val);
2375 #else /* LARGE_SMB_OFF_T */
2376 sscanf(p,"%lu",&val);
2377 #endif /* LARGE_SMB_OFF_T */
2379 while (*p && isdigit(*p))
2387 /* Convert a size specification to a count of bytes. We accept the following
2389 * bytes if there is no suffix
2394 * pP whatever the ISO name for petabytes is
2396 * Returns 0 if the string can't be converted.
2398 SMB_OFF_T conv_str_size(const char * str)
2403 if (str == NULL || *str == '\0') {
2407 #ifdef HAVE_STRTOULL
2408 if (sizeof(SMB_OFF_T) == 8) {
2409 lval = strtoull(str, &end, 10 /* base */);
2411 lval = strtoul(str, &end, 10 /* base */);
2414 lval = strtoul(str, &end, 10 /* base */);
2417 if (end == NULL || end == str) {
2422 SMB_OFF_T lval_orig = lval;
2424 if (strwicmp(end, "K") == 0) {
2425 lval *= (SMB_OFF_T)1024;
2426 } else if (strwicmp(end, "M") == 0) {
2427 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2428 } else if (strwicmp(end, "G") == 0) {
2429 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2431 } else if (strwicmp(end, "T") == 0) {
2432 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2433 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2434 } else if (strwicmp(end, "P") == 0) {
2435 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2436 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2442 /* Primitive attempt to detect wrapping on platforms with
2443 * 4-byte SMB_OFF_T. It's better to let the caller handle
2444 * a failure than some random number.
2446 if (lval_orig <= lval) {
2454 void string_append(char **left, const char *right)
2456 int new_len = strlen(right) + 1;
2458 if (*left == NULL) {
2459 *left = (char *)SMB_MALLOC(new_len);
2462 new_len += strlen(*left);
2463 *left = (char *)SMB_REALLOC(*left, new_len);
2466 if (*left == NULL) {
2470 safe_strcat(*left, right, new_len-1);
2473 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2474 const char *str, const char ***strings,
2477 char *dup_str = talloc_strdup(mem_ctx, str);
2479 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2481 if ((*strings == NULL) || (dup_str == NULL)) {
2486 (*strings)[*num] = dup_str;
2491 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2492 * error checking in between. The indiation that something weird happened is
2495 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2496 size_t *bufsize, const char *fmt, ...)
2503 /* len<0 is an internal marker that something failed */
2507 if (*string == NULL) {
2511 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2512 if (*string == NULL)
2517 ret = vasprintf(&newstr, fmt, ap);
2525 while ((*len)+ret >= *bufsize) {
2528 if (*bufsize >= (1024*1024*256))
2533 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2535 if (*string == NULL) {
2540 StrnCpy((*string)+(*len), newstr, ret);
2551 Returns the substring from src between the first occurrence of
2552 the char "front" and the first occurence of the char "back".
2553 Mallocs the return string which must be freed. Not for use
2554 with wide character strings.
2556 char *sstring_sub(const char *src, char front, char back)
2558 char *temp1, *temp2, *temp3;
2561 temp1 = strchr(src, front);
2562 if (temp1 == NULL) return NULL;
2563 temp2 = strchr(src, back);
2564 if (temp2 == NULL) return NULL;
2565 len = temp2 - temp1;
2566 if (len <= 0) return NULL;
2567 temp3 = (char*)SMB_MALLOC(len);
2568 if (temp3 == NULL) {
2569 DEBUG(1,("Malloc failure in sstring_sub\n"));
2572 memcpy(temp3, temp1+1, len-1);
2573 temp3[len-1] = '\0';
2577 /********************************************************************
2578 Check a string for any occurrences of a specified list of invalid
2580 ********************************************************************/
2582 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2586 for ( i=0; i<max_len && name[i]; i++ ) {
2587 /* fail if strchr_m() finds one of the invalid characters */
2588 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2598 return the number of bytes occupied by a buffer in ASCII format
2599 the result includes the null termination
2600 limited by 'n' bytes
2602 size_t ascii_len_n(const char *src, size_t n)
2606 len = strnlen(src, n);
2615 return the number of bytes occupied by a buffer in CH_UTF16 format
2616 the result includes the null termination
2618 size_t utf16_len(const void *buf)
2622 for (len = 0; SVAL(buf,len); len += 2) ;
2628 return the number of bytes occupied by a buffer in CH_UTF16 format
2629 the result includes the null termination
2630 limited by 'n' bytes
2632 size_t utf16_len_n(const void *src, size_t n)
2636 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2645 /*******************************************************************
2646 Add a shell escape character '\' to any character not in a known list
2647 of characters. UNIX charset format.
2648 *******************************************************************/
2650 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2651 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2653 char *escape_shell_string(const char *src)
2655 size_t srclen = strlen(src);
2656 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2658 BOOL in_s_quote = False;
2659 BOOL in_d_quote = False;
2660 BOOL next_escaped = False;
2668 codepoint_t c = next_codepoint(src, &c_size);
2670 if (c == INVALID_CODEPOINT) {
2676 memcpy(dest, src, c_size);
2679 next_escaped = False;
2684 * Deal with backslash escaped state.
2685 * This only lasts for one character.
2690 next_escaped = False;
2695 * Deal with single quote state. The
2696 * only thing we care about is exiting
2709 * Deal with double quote state. The most
2710 * complex state. We must cope with \, meaning
2711 * possibly escape next char (depending what it
2712 * is), ", meaning exit this state, and possibly
2713 * add an \ escape to any unprotected character
2714 * (listed in INSIDE_DQUOTE_LIST).
2720 * Next character might be escaped.
2721 * We have to peek. Inside double
2722 * quotes only INSIDE_DQUOTE_LIST
2723 * characters are escaped by a \.
2728 c = next_codepoint(&src[1], &c_size);
2729 if (c == INVALID_CODEPOINT) {
2735 * Don't escape the next char.
2744 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2745 next_escaped = True;
2752 /* Exit double quote state. */
2759 * We know the character isn't \ or ",
2760 * so escape it if it's any of the other
2761 * possible unprotected characters.
2764 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2772 * From here to the end of the loop we're
2773 * not in the single or double quote state.
2777 /* Next character must be escaped. */
2778 next_escaped = True;
2784 /* Go into single quote state. */
2791 /* Go into double quote state. */
2797 /* Check if we need to escape the character. */
2799 if (!strchr(INCLUDE_LIST, (int)*src)) {