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 3 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, see <http://www.gnu.org/licenses/>.
28 * @brief String utilities.
32 * Internal function to get the next token from a string, return False if none
33 * found. Handles double-quotes. This is the work horse function called by
34 * next_token() and next_token_no_ltrim().
36 * Based on a routine by GJC@VILLAGE.COM.
37 * Extensively modified by Andrew.Tridgell@anu.edu.au
39 static BOOL next_token_internal(const char **ptr,
55 /* default to simple separators */
59 /* find the first non sep char, if left-trimming is requested */
61 while (*s && strchr_m(sep,*s))
69 /* copy over the token */
71 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
80 *ptr = (*s) ? s+1 : s;
87 * Get the next token from a string, return False if none found. Handles
88 * double-quotes. This version trims leading separator characters before
89 * looking for a token.
91 BOOL next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
93 return next_token_internal(ptr, buff, sep, bufsize, True);
97 * Get the next token from a string, return False if none found. Handles
98 * double-quotes. This version does not trim leading separator characters
99 * before looking for a token.
101 BOOL next_token_no_ltrim(const char **ptr,
106 return next_token_internal(ptr, buff, sep, bufsize, False);
110 This is like next_token but is not re-entrant and "remembers" the first
111 parameter so you can pass NULL. This is useful for user interface code
112 but beware the fact that it is not re-entrant!
115 static const char *last_ptr=NULL;
117 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
123 ret = next_token(ptr, buff, sep, bufsize);
128 void set_first_token(char *ptr)
134 Convert list of tokens to array; dependent on above routine.
135 Uses last_ptr from above - bit of a hack.
138 char **toktocliplist(int *ctok, const char *sep)
140 char *s=(char *)last_ptr;
147 while(*s && strchr_m(sep,*s))
156 while(*s && (!strchr_m(sep,*s)))
158 while(*s && strchr_m(sep,*s))
165 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
183 * Case insensitive string compararison.
185 * iconv does not directly give us a way to compare strings in
186 * arbitrary unix character sets -- all we can is convert and then
187 * compare. This is expensive.
189 * As an optimization, we do a first pass that considers only the
190 * prefix of the strings that is entirely 7-bit. Within this, we
191 * check whether they have the same value.
193 * Hopefully this will often give the answer without needing to copy.
194 * In particular it should speed comparisons to literal ascii strings
195 * or comparisons of strings that are "obviously" different.
197 * If we find a non-ascii character we fall back to converting via
200 * This should never be slower than convering the whole thing, and
203 * A different optimization would be to compare for bitwise equality
204 * in the binary encoding. (It would be possible thought hairy to do
205 * both simultaneously.) But in that case if they turn out to be
206 * different, we'd need to restart the whole thing.
208 * Even better is to implement strcasecmp for each encoding and use a
211 int StrCaseCmp(const char *s, const char *t)
216 smb_ucs2_t *buffer_s, *buffer_t;
219 for (ps = s, pt = t; ; ps++, pt++) {
223 return 0; /* both ended */
225 return -1; /* s is a prefix */
227 return +1; /* t is a prefix */
228 else if ((*ps & 0x80) || (*pt & 0x80))
229 /* not ascii anymore, do it the hard way from here on in */
232 us = toupper_ascii(*ps);
233 ut = toupper_ascii(*pt);
242 size = push_ucs2_allocate(&buffer_s, ps);
243 if (size == (size_t)-1) {
244 return strcmp(ps, pt);
245 /* Not quite the right answer, but finding the right one
246 under this failure case is expensive, and it's pretty close */
249 size = push_ucs2_allocate(&buffer_t, pt);
250 if (size == (size_t)-1) {
252 return strcmp(ps, pt);
253 /* Not quite the right answer, but finding the right one
254 under this failure case is expensive, and it's pretty close */
257 ret = strcasecmp_w(buffer_s, buffer_t);
265 Case insensitive string compararison, length limited.
267 int StrnCaseCmp(const char *s, const char *t, size_t n)
270 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
271 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
272 return strncmp(buf1,buf2,n);
278 * @note The comparison is case-insensitive.
280 BOOL strequal(const char *s1, const char *s2)
287 return(StrCaseCmp(s1,s2)==0);
291 * Compare 2 strings up to and including the nth char.
293 * @note The comparison is case-insensitive.
295 BOOL strnequal(const char *s1,const char *s2,size_t n)
299 if (!s1 || !s2 || !n)
302 return(StrnCaseCmp(s1,s2,n)==0);
306 Compare 2 strings (case sensitive).
309 BOOL strcsequal(const char *s1,const char *s2)
316 return(strcmp(s1,s2)==0);
320 Do a case-insensitive, whitespace-ignoring string compare.
323 int strwicmp(const char *psz1, const char *psz2)
325 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
326 /* appropriate value. */
329 else if (psz1 == NULL)
331 else if (psz2 == NULL)
334 /* sync the strings on first non-whitespace */
336 while (isspace((int)*psz1))
338 while (isspace((int)*psz2))
340 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
346 return (*psz1 - *psz2);
351 Convert a string to upper case, but don't modify it.
354 char *strupper_static(const char *s)
365 Convert a string to "normal" form.
368 void strnorm(char *s, int case_default)
370 if (case_default == CASE_UPPER)
377 Check if a string is in "normal" case.
380 BOOL strisnormal(const char *s, int case_default)
382 if (case_default == CASE_UPPER)
383 return(!strhaslower(s));
385 return(!strhasupper(s));
391 NOTE: oldc and newc must be 7 bit characters
394 void string_replace( char *s, char oldc, char newc )
400 /* this is quite a common operation, so we want it to be
401 fast. We optimise for the ascii case, knowing that all our
402 supported multi-byte character sets are ascii-compatible
403 (ie. they match for the first 128 chars) */
405 for (p = s; *p; p++) {
406 if (*p & 0x80) /* mb string - slow path. */
415 /* Slow (mb) path. */
416 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
417 /* With compose characters we must restart from the beginning. JRA. */
421 len = push_ucs2_allocate(&tmp, p);
425 string_replace_w(tmp, UCS2_CHAR(oldc), UCS2_CHAR(newc));
426 pull_ucs2(NULL, p, tmp, src_len+1, -1, STR_TERMINATE);
431 * Skip past some strings in a buffer - old version - no checks.
434 char *push_skip_string(char *buf)
436 buf += strlen(buf) + 1;
441 Skip past a string in a buffer. Buffer may not be
442 null terminated. end_ptr points to the first byte after
443 then end of the buffer.
446 char *skip_string(const char *base, size_t len, char *buf)
448 const char *end_ptr = base + len;
450 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
454 /* Skip the string */
457 if (buf >= end_ptr) {
467 Count the number of characters in a string. Normally this will
468 be the same as the number of bytes in a string for single byte strings,
469 but will be different for multibyte.
472 size_t str_charnum(const char *s)
474 uint16 tmpbuf2[sizeof(pstring)];
475 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
476 return strlen_w(tmpbuf2);
480 Count the number of characters in a string. Normally this will
481 be the same as the number of bytes in a string for single byte strings,
482 but will be different for multibyte.
485 size_t str_ascii_charnum(const char *s)
488 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
489 return strlen(tmpbuf2);
492 BOOL trim_char(char *s,char cfront,char cback)
498 /* Ignore null or empty strings. */
499 if (!s || (s[0] == '\0'))
503 while (*fp && *fp == cfront)
506 /* We ate the string. */
514 ep = fp + strlen(fp) - 1;
516 /* Attempt ascii only. Bail for mb strings. */
517 while ((ep >= fp) && (*ep == cback)) {
519 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
520 /* Could be mb... bail back to tim_string. */
528 return trim_string(s, cfront ? fs : NULL, bs);
534 /* We ate the string. */
541 memmove(s, fp, ep-fp+2);
546 Trim the specified elements off the front and back of a string.
549 BOOL trim_string(char *s,const char *front,const char *back)
556 /* Ignore null or empty strings. */
557 if (!s || (s[0] == '\0'))
560 front_len = front? strlen(front) : 0;
561 back_len = back? strlen(back) : 0;
566 while (len && strncmp(s, front, front_len)==0) {
567 /* Must use memmove here as src & dest can
568 * easily overlap. Found by valgrind. JRA. */
569 memmove(s, s+front_len, (len-front_len)+1);
576 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
577 s[len-back_len]='\0';
586 Does a string have any uppercase chars in it?
589 BOOL strhasupper(const char *s)
594 if (push_ucs2_allocate(&tmp, s) == -1) {
598 for(p = tmp; *p != 0; p++) {
610 Does a string have any lowercase chars in it?
613 BOOL strhaslower(const char *s)
618 if (push_ucs2_allocate(&tmp, s) == -1) {
622 for(p = tmp; *p != 0; p++) {
634 Find the number of 'c' chars in a string
637 size_t count_chars(const char *s,char c)
641 smb_ucs2_t *alloc_tmpbuf = NULL;
643 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
647 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
648 if(*ptr==UCS2_CHAR(c))
651 SAFE_FREE(alloc_tmpbuf);
656 Safe string copy into a known length string. maxlength does not
657 include the terminating zero.
660 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
665 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
670 clobber_region(fn,line,dest, maxlength+1);
678 len = strnlen(src, maxlength+1);
680 if (len > maxlength) {
681 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
682 (unsigned long)(len-maxlength), (unsigned long)len,
683 (unsigned long)maxlength, src));
687 memmove(dest, src, len);
693 Safe string cat into a string. maxlength does not
694 include the terminating zero.
696 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
698 size_t src_len, dest_len;
701 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
708 src_len = strnlen(src, maxlength + 1);
709 dest_len = strnlen(dest, maxlength + 1);
712 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
715 if (src_len + dest_len > maxlength) {
716 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
717 (int)(src_len + dest_len - maxlength), src));
718 if (maxlength > dest_len) {
719 memcpy(&dest[dest_len], src, maxlength - dest_len);
725 memcpy(&dest[dest_len], src, src_len);
726 dest[dest_len + src_len] = 0;
731 Paranoid strcpy into a buffer of given length (includes terminating
732 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
733 and replaces with '_'. Deliberately does *NOT* check for multibyte
734 characters. Don't change it !
736 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
741 clobber_region(fn, line, dest, maxlength);
745 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
755 if (len >= maxlength)
758 if (!other_safe_chars)
759 other_safe_chars = "";
761 for(i = 0; i < len; i++) {
762 int val = (src[i] & 0xff);
763 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
775 Like strncpy but always null terminates. Make sure there is room!
776 The variable n should always be one less than the available size.
778 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
783 clobber_region(fn, line, dest, n+1);
787 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
796 while (n-- && (*d = *src)) {
807 Like strncpy but copies up to the character marker. always null terminates.
808 returns a pointer to the character marker in the source string (src).
811 static char *strncpyn(char *dest, const char *src, size_t n, char c)
817 clobber_region(dest, n+1);
819 p = strchr_m(src, c);
821 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
825 str_len = PTR_DIFF(p, src);
826 strncpy(dest, src, MIN(n, str_len));
827 dest[str_len] = '\0';
834 Routine to get hex characters and turn them into a 16 byte array.
835 the array can be variable length, and any non-hex-numeric
836 characters are skipped. "0xnn" or "0Xnn" is specially catered
839 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
843 size_t strhex_to_str(char *p, size_t len, const char *strhex)
846 size_t num_chars = 0;
847 unsigned char lonybble, hinybble;
848 const char *hexchars = "0123456789ABCDEF";
849 char *p1 = NULL, *p2 = NULL;
851 for (i = 0; i < len && strhex[i] != 0; i++) {
852 if (strnequal(hexchars, "0x", 2)) {
853 i++; /* skip two chars */
857 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
860 i++; /* next hex digit */
862 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
865 /* get the two nybbles */
866 hinybble = PTR_DIFF(p1, hexchars);
867 lonybble = PTR_DIFF(p2, hexchars);
869 p[num_chars] = (hinybble << 4) | lonybble;
878 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
883 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
885 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
887 ret_blob.length = strhex_to_str((char*)ret_blob.data,
895 * Routine to print a buffer as HEX digits, into an allocated string.
898 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
903 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
905 for (i = 0; i < len; i++)
906 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
912 Check if a string is part of a list.
915 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
923 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
925 if (strcmp(tok,s) == 0)
928 if (StrCaseCmp(tok,s) == 0)
935 /* this is used to prevent lots of mallocs of size 1 */
936 static const char *null_string = "";
939 Set a string value, allocing the space for the string
942 static BOOL string_init(char **dest,const char *src)
952 *dest = CONST_DISCARD(char*, null_string);
954 (*dest) = SMB_STRDUP(src);
955 if ((*dest) == NULL) {
956 DEBUG(0,("Out of memory in string_init\n"));
967 void string_free(char **s)
971 if (*s == null_string)
977 Set a string value, deallocating any existing space, and allocing the space
981 BOOL string_set(char **dest,const char *src)
984 return(string_init(dest,src));
988 Substitute a string for a pattern in another string. Make sure there is
991 This routine looks for pattern in s and replaces it with
992 insert. It may do multiple replacements or just one.
994 Any of " ; ' $ or ` in the insert string are replaced with _
995 if len==0 then the string cannot be extended. This is different from the old
996 use of len==0 which was for no length checks to be done.
999 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1000 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
1003 ssize_t ls,lp,li, i;
1005 if (!insert || !pattern || !*pattern || !s)
1008 ls = (ssize_t)strlen(s);
1009 lp = (ssize_t)strlen(pattern);
1010 li = (ssize_t)strlen(insert);
1013 len = ls + 1; /* len is number of *bytes* */
1015 while (lp <= ls && (p = strstr_m(s,pattern))) {
1016 if (ls + (li-lp) >= len) {
1017 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1018 (int)(ls + (li-lp) - len),
1019 pattern, (int)len));
1023 memmove(p+li,p+lp,strlen(p+lp)+1);
1025 for (i=0;i<li;i++) {
1026 switch (insert[i]) {
1032 /* allow a trailing $ (as in machine accounts) */
1033 if (allow_trailing_dollar && (i == li - 1 )) {
1040 if ( remove_unsafe_characters ) {
1042 /* yes this break should be here since we want to
1043 fall throw if not replacing unsafe chars */
1058 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1060 string_sub2( s, pattern, insert, len, True, True, False );
1063 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1065 string_sub2( s, pattern, insert, len, True, False, False );
1068 void fstring_sub(char *s,const char *pattern,const char *insert)
1070 string_sub(s, pattern, insert, sizeof(fstring));
1073 void pstring_sub(char *s,const char *pattern,const char *insert)
1075 string_sub(s, pattern, insert, sizeof(pstring));
1079 Similar to string_sub, but it will accept only allocated strings
1080 and may realloc them so pay attention at what you pass on no
1081 pointers inside strings, no pstrings or const may be passed
1085 char *realloc_string_sub(char *string, const char *pattern,
1090 ssize_t ls,lp,li,ld, i;
1092 if (!insert || !pattern || !*pattern || !string || !*string)
1097 in = SMB_STRDUP(insert);
1099 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1102 ls = (ssize_t)strlen(s);
1103 lp = (ssize_t)strlen(pattern);
1104 li = (ssize_t)strlen(insert);
1106 for (i=0;i<li;i++) {
1123 while ((p = strstr_m(s,pattern))) {
1125 int offset = PTR_DIFF(s,string);
1126 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1128 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1132 p = string + offset + (p - s);
1135 memmove(p+li,p+lp,strlen(p+lp)+1);
1145 /* Same as string_sub, but returns a talloc'ed string */
1147 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1148 const char *pattern, const char *insert)
1153 ssize_t ls,lp,li,ld, i;
1155 if (!insert || !pattern || !*pattern || !src || !*src)
1158 string = talloc_strdup(mem_ctx, src);
1159 if (string == NULL) {
1160 DEBUG(0, ("talloc_strdup failed\n"));
1166 in = SMB_STRDUP(insert);
1168 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1171 ls = (ssize_t)strlen(s);
1172 lp = (ssize_t)strlen(pattern);
1173 li = (ssize_t)strlen(insert);
1175 for (i=0;i<li;i++) {
1192 while ((p = strstr_m(s,pattern))) {
1194 int offset = PTR_DIFF(s,string);
1195 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1198 DEBUG(0, ("talloc_string_sub: out of "
1203 p = string + offset + (p - s);
1206 memmove(p+li,p+lp,strlen(p+lp)+1);
1217 Similar to string_sub() but allows for any character to be substituted.
1219 if len==0 then the string cannot be extended. This is different from the old
1220 use of len==0 which was for no length checks to be done.
1223 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1228 if (!insert || !pattern || !s)
1231 ls = (ssize_t)strlen(s);
1232 lp = (ssize_t)strlen(pattern);
1233 li = (ssize_t)strlen(insert);
1239 len = ls + 1; /* len is number of *bytes* */
1241 while (lp <= ls && (p = strstr_m(s,pattern))) {
1242 if (ls + (li-lp) >= len) {
1243 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1244 (int)(ls + (li-lp) - len),
1245 pattern, (int)len));
1249 memmove(p+li,p+lp,strlen(p+lp)+1);
1251 memcpy(p, insert, li);
1258 Similar to all_string_sub but for unicode strings.
1259 Return a new allocated unicode string.
1260 similar to string_sub() but allows for any character to be substituted.
1264 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1265 const smb_ucs2_t *insert)
1268 const smb_ucs2_t *sp;
1269 size_t lr, lp, li, lt;
1271 if (!insert || !pattern || !*pattern || !s)
1274 lt = (size_t)strlen_w(s);
1275 lp = (size_t)strlen_w(pattern);
1276 li = (size_t)strlen_w(insert);
1279 const smb_ucs2_t *st = s;
1281 while ((sp = strstr_w(st, pattern))) {
1287 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1289 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1293 while ((sp = strstr_w(s, pattern))) {
1294 memcpy(rp, s, (sp - s));
1295 rp += ((sp - s) / sizeof(smb_ucs2_t));
1296 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1300 lr = ((rp - r) / sizeof(smb_ucs2_t));
1302 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1310 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1315 if (!insert || !pattern || !s)
1317 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1318 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1319 return all_string_sub_w(s, p, i);
1324 Splits out the front and back at a separator.
1327 static void split_at_last_component(char *path, char *front, char sep, char *back)
1329 char *p = strrchr_m(path, sep);
1335 pstrcpy(front, path);
1349 Write an octal as a string.
1352 const char *octal_string(int i)
1354 static char ret[64];
1357 slprintf(ret, sizeof(ret)-1, "0%o", i);
1363 Truncate a string at a specified length.
1366 char *string_truncate(char *s, unsigned int length)
1368 if (s && strlen(s) > length)
1374 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1375 We convert via ucs2 for now.
1378 char *strchr_m(const char *src, char c)
1385 /* characters below 0x3F are guaranteed to not appear in
1386 non-initial position in multi-byte charsets */
1387 if ((c & 0xC0) == 0) {
1388 return strchr(src, c);
1391 /* this is quite a common operation, so we want it to be
1392 fast. We optimise for the ascii case, knowing that all our
1393 supported multi-byte character sets are ascii-compatible
1394 (ie. they match for the first 128 chars) */
1396 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1404 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1405 /* With compose characters we must restart from the beginning. JRA. */
1409 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1410 p = strchr_w(ws, UCS2_CHAR(c));
1414 pull_ucs2_pstring(s2, ws);
1415 return (char *)(s+strlen(s2));
1418 char *strrchr_m(const char *s, char c)
1420 /* characters below 0x3F are guaranteed to not appear in
1421 non-initial position in multi-byte charsets */
1422 if ((c & 0xC0) == 0) {
1423 return strrchr(s, c);
1426 /* this is quite a common operation, so we want it to be
1427 fast. We optimise for the ascii case, knowing that all our
1428 supported multi-byte character sets are ascii-compatible
1429 (ie. they match for the first 128 chars). Also, in Samba
1430 we only search for ascii characters in 'c' and that
1431 in all mb character sets with a compound character
1432 containing c, if 'c' is not a match at position
1433 p, then p[-1] > 0x7f. JRA. */
1436 size_t len = strlen(s);
1438 BOOL got_mb = False;
1445 /* Could be a match. Part of a multibyte ? */
1446 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1447 /* Yep - go slow :-( */
1451 /* No - we have a match ! */
1454 } while (cp-- != s);
1459 /* String contained a non-ascii char. Slow path. */
1465 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1466 p = strrchr_w(ws, UCS2_CHAR(c));
1470 pull_ucs2_pstring(s2, ws);
1471 return (char *)(s+strlen(s2));
1475 /***********************************************************************
1476 Return the equivalent of doing strrchr 'n' times - always going
1478 ***********************************************************************/
1480 char *strnrchr_m(const char *s, char c, unsigned int n)
1486 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1487 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1491 pull_ucs2_pstring(s2, ws);
1492 return (char *)(s+strlen(s2));
1495 /***********************************************************************
1496 strstr_m - We convert via ucs2 for now.
1497 ***********************************************************************/
1499 char *strstr_m(const char *src, const char *findstr)
1502 smb_ucs2_t *src_w, *find_w;
1507 size_t findstr_len = 0;
1509 /* for correctness */
1514 /* Samba does single character findstr calls a *lot*. */
1515 if (findstr[1] == '\0')
1516 return strchr_m(src, *findstr);
1518 /* We optimise for the ascii case, knowing that all our
1519 supported multi-byte character sets are ascii-compatible
1520 (ie. they match for the first 128 chars) */
1522 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1523 if (*s == *findstr) {
1525 findstr_len = strlen(findstr);
1527 if (strncmp(s, findstr, findstr_len) == 0) {
1536 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1537 /* 'make check' fails unless we do this */
1539 /* With compose characters we must restart from the beginning. JRA. */
1543 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1544 DEBUG(0,("strstr_m: src malloc fail\n"));
1548 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1550 DEBUG(0,("strstr_m: find malloc fail\n"));
1554 p = strstr_w(src_w, find_w);
1563 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1566 DEBUG(0,("strstr_m: dest malloc fail\n"));
1569 retp = (char *)(s+strlen(s2));
1577 Convert a string to lower case.
1580 void strlower_m(char *s)
1585 /* this is quite a common operation, so we want it to be
1586 fast. We optimise for the ascii case, knowing that all our
1587 supported multi-byte character sets are ascii-compatible
1588 (ie. they match for the first 128 chars) */
1590 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1591 *s = tolower_ascii((unsigned char)*s);
1598 /* I assume that lowercased string takes the same number of bytes
1599 * as source string even in UTF-8 encoding. (VIV) */
1600 len = strlen(s) + 1;
1603 unix_strlower(s,len,s,len);
1604 /* Catch mb conversion errors that may not terminate. */
1611 Convert a string to upper case.
1614 void strupper_m(char *s)
1619 /* this is quite a common operation, so we want it to be
1620 fast. We optimise for the ascii case, knowing that all our
1621 supported multi-byte character sets are ascii-compatible
1622 (ie. they match for the first 128 chars) */
1624 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1625 *s = toupper_ascii((unsigned char)*s);
1632 /* I assume that lowercased string takes the same number of bytes
1633 * as source string even in multibyte encoding. (VIV) */
1634 len = strlen(s) + 1;
1637 unix_strupper(s,len,s,len);
1638 /* Catch mb conversion errors that may not terminate. */
1645 Count the number of UCS2 characters in a string. Normally this will
1646 be the same as the number of bytes in a string for single byte strings,
1647 but will be different for multibyte.
1650 size_t strlen_m(const char *s)
1658 while (*s && !(((uint8_t)*s) & 0x80)) {
1669 codepoint_t c = next_codepoint(s, &c_size);
1671 /* Unicode char fits into 16 bits. */
1674 /* Double-width unicode char - 32 bits. */
1684 Count the number of UCS2 characters in a string including the null
1688 size_t strlen_m_term(const char *s)
1693 return strlen_m(s) + 1;
1697 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1698 * if a string is there, include the terminator.
1701 size_t strlen_m_term_null(const char *s)
1715 Return a RFC2254 binary string representation of a buffer.
1716 Used in LDAP filters.
1720 char *binary_string_rfc2254(char *buf, int len)
1724 const char *hex = "0123456789ABCDEF";
1725 s = (char *)SMB_MALLOC(len * 3 + 1);
1728 for (j=i=0;i<len;i++) {
1730 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1731 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1738 char *binary_string(char *buf, int len)
1742 const char *hex = "0123456789ABCDEF";
1743 s = (char *)SMB_MALLOC(len * 2 + 1);
1746 for (j=i=0;i<len;i++) {
1747 s[j] = hex[((unsigned char)buf[i]) >> 4];
1748 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1755 Just a typesafety wrapper for snprintf into a pstring.
1758 int pstr_sprintf(pstring s, const char *fmt, ...)
1764 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1771 Just a typesafety wrapper for snprintf into a fstring.
1774 int fstr_sprintf(fstring s, const char *fmt, ...)
1780 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1786 List of Strings manipulation functions
1789 #define S_LIST_ABS 16 /* List Allocation Block Size */
1791 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1793 char **list, **rlist;
1799 if (!string || !*string)
1802 s = talloc_strdup(mem_ctx, string);
1804 s = SMB_STRDUP(string);
1807 DEBUG(0,("str_list_make: Unable to allocate memory"));
1810 if (!sep) sep = LIST_SEP;
1816 while (next_token(&str, tok, sep, sizeof(tok))) {
1818 lsize += S_LIST_ABS;
1820 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1822 /* We need to keep the old list on error so we can free the elements
1823 if the realloc fails. */
1824 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1827 DEBUG(0,("str_list_make: Unable to allocate memory"));
1828 str_list_free(&list);
1838 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1842 list[num] = talloc_strdup(mem_ctx, tok);
1844 list[num] = SMB_STRDUP(tok);
1848 DEBUG(0,("str_list_make: Unable to allocate memory"));
1849 str_list_free(&list);
1870 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1872 return str_list_make_internal(mem_ctx, string, sep);
1875 char **str_list_make(const char *string, const char *sep)
1877 return str_list_make_internal(NULL, string, sep);
1880 BOOL str_list_copy(char ***dest, const char **src)
1882 char **list, **rlist;
1894 lsize += S_LIST_ABS;
1895 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1897 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1898 str_list_free(&list);
1903 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1906 list[num] = SMB_STRDUP(src[num]);
1908 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1909 str_list_free(&list);
1921 * Return true if all the elements of the list match exactly.
1923 BOOL str_list_compare(char **list1, char **list2)
1927 if (!list1 || !list2)
1928 return (list1 == list2);
1930 for (num = 0; list1[num]; num++) {
1933 if (!strcsequal(list1[num], list2[num]))
1937 return False; /* if list2 has more elements than list1 fail */
1942 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1946 if (!list || !*list)
1949 for(; *tlist; tlist++) {
1951 TALLOC_FREE(*tlist);
1957 TALLOC_FREE(*tlist);
1963 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1965 str_list_free_internal(mem_ctx, list);
1968 void str_list_free(char ***list)
1970 str_list_free_internal(NULL, list);
1973 /******************************************************************************
1974 *****************************************************************************/
1976 int str_list_count( const char **list )
1983 /* count the number of list members */
1985 for ( i=0; *list; i++, list++ );
1990 /******************************************************************************
1991 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1993 *****************************************************************************/
1995 BOOL str_list_sub_basic( char **list, const char *smb_name,
1996 const char *domain_name )
2002 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2004 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2017 /******************************************************************************
2018 substritute a specific pattern in a string list
2019 *****************************************************************************/
2021 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2024 ssize_t ls, lp, li, ld, i, d;
2033 lp = (ssize_t)strlen(pattern);
2034 li = (ssize_t)strlen(insert);
2039 ls = (ssize_t)strlen(s);
2041 while ((p = strstr_m(s, pattern))) {
2045 t = (char *) SMB_MALLOC(ls +ld +1);
2047 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2050 memcpy(t, *list, d);
2051 memcpy(t +d +li, p +lp, ls -d -lp +1);
2058 for (i = 0; i < li; i++) {
2059 switch (insert[i]) {
2071 t[d +i] = insert[i];
2084 #define IPSTR_LIST_SEP ","
2085 #define IPSTR_LIST_CHAR ','
2088 * Add ip string representation to ipstr list. Used also
2089 * as part of @function ipstr_list_make
2091 * @param ipstr_list pointer to string containing ip list;
2092 * MUST BE already allocated and IS reallocated if necessary
2093 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2094 * as a result of reallocation)
2095 * @param ip IP address which is to be added to list
2096 * @return pointer to string appended with new ip and possibly
2097 * reallocated to new length
2100 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2102 char* new_ipstr = NULL;
2104 /* arguments checking */
2105 if (!ipstr_list || !service) return NULL;
2107 /* attempt to convert ip to a string and append colon separator to it */
2109 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2110 inet_ntoa(service->ip), service->port);
2111 SAFE_FREE(*ipstr_list);
2113 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2115 *ipstr_list = new_ipstr;
2121 * Allocate and initialise an ipstr list using ip adresses
2122 * passed as arguments.
2124 * @param ipstr_list pointer to string meant to be allocated and set
2125 * @param ip_list array of ip addresses to place in the list
2126 * @param ip_count number of addresses stored in ip_list
2127 * @return pointer to allocated ip string
2130 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2134 /* arguments checking */
2135 if (!ip_list || !ipstr_list) return 0;
2139 /* process ip addresses given as arguments */
2140 for (i = 0; i < ip_count; i++)
2141 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2143 return (*ipstr_list);
2148 * Parse given ip string list into array of ip addresses
2149 * (as ip_service structures)
2150 * e.g. 192.168.1.100:389,192.168.1.78, ...
2152 * @param ipstr ip string list to be parsed
2153 * @param ip_list pointer to array of ip addresses which is
2154 * allocated by this function and must be freed by caller
2155 * @return number of succesfully parsed addresses
2158 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2164 if (!ipstr_list || !ip_list)
2167 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2168 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2169 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2174 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2177 struct in_addr addr;
2179 char *p = strchr(token_str, ':');
2186 /* convert single token to ip address */
2187 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2190 (*ip_list)[i].ip = addr;
2191 (*ip_list)[i].port = port;
2199 * Safely free ip string list
2201 * @param ipstr_list ip string list to be freed
2204 void ipstr_list_free(char* ipstr_list)
2206 SAFE_FREE(ipstr_list);
2211 Unescape a URL encoded string, in place.
2214 void rfc1738_unescape(char *buf)
2218 while (p && *p && (p=strchr_m(p,'%'))) {
2222 if (c1 >= '0' && c1 <= '9')
2224 else if (c1 >= 'A' && c1 <= 'F')
2226 else if (c1 >= 'a' && c1 <= 'f')
2228 else {p++; continue;}
2230 if (c2 >= '0' && c2 <= '9')
2232 else if (c2 >= 'A' && c2 <= 'F')
2234 else if (c2 >= 'a' && c2 <= 'f')
2236 else {p++; continue;}
2240 memmove(p+1, p+3, strlen(p+3)+1);
2245 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2248 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2250 DATA_BLOB base64_decode_data_blob(const char *s)
2252 int bit_offset, byte_offset, idx, i, n;
2253 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2254 unsigned char *d = decoded.data;
2259 while (*s && (p=strchr_m(b64,*s))) {
2260 idx = (int)(p - b64);
2261 byte_offset = (i*6)/8;
2262 bit_offset = (i*6)%8;
2263 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2264 if (bit_offset < 3) {
2265 d[byte_offset] |= (idx << (2-bit_offset));
2268 d[byte_offset] |= (idx >> (bit_offset-2));
2269 d[byte_offset+1] = 0;
2270 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2276 if ((n > 0) && (*s == '=')) {
2286 * Decode a base64 string in-place - wrapper for the above
2288 void base64_decode_inplace(char *s)
2290 DATA_BLOB decoded = base64_decode_data_blob(s);
2292 if ( decoded.length != 0 ) {
2293 memcpy(s, decoded.data, decoded.length);
2295 /* null terminate */
2296 s[decoded.length] = '\0';
2301 data_blob_free(&decoded);
2305 * Encode a base64 string into a malloc()ed string caller to free.
2307 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2309 char * base64_encode_data_blob(DATA_BLOB data)
2313 size_t out_cnt, len, output_len;
2316 if (!data.length || !data.data)
2321 output_len = data.length * 2;
2322 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2324 while (len-- && out_cnt < (data.length * 2) - 5) {
2325 int c = (unsigned char) *(data.data++);
2328 if (char_count == 3) {
2329 result[out_cnt++] = b64[bits >> 18];
2330 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2331 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2332 result[out_cnt++] = b64[bits & 0x3f];
2339 if (char_count != 0) {
2340 bits <<= 16 - (8 * char_count);
2341 result[out_cnt++] = b64[bits >> 18];
2342 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2343 if (char_count == 1) {
2344 result[out_cnt++] = '=';
2345 result[out_cnt++] = '=';
2347 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2348 result[out_cnt++] = '=';
2351 result[out_cnt] = '\0'; /* terminate */
2355 /* read a SMB_BIG_UINT from a string */
2356 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2359 SMB_BIG_UINT val = -1;
2360 const char *p = nptr;
2369 while (*p && isspace(*p))
2372 #ifdef LARGE_SMB_OFF_T
2373 sscanf(p,"%llu",&val);
2374 #else /* LARGE_SMB_OFF_T */
2375 sscanf(p,"%lu",&val);
2376 #endif /* LARGE_SMB_OFF_T */
2378 while (*p && isdigit(*p))
2386 /* Convert a size specification to a count of bytes. We accept the following
2388 * bytes if there is no suffix
2393 * pP whatever the ISO name for petabytes is
2395 * Returns 0 if the string can't be converted.
2397 SMB_OFF_T conv_str_size(const char * str)
2402 if (str == NULL || *str == '\0') {
2406 #ifdef HAVE_STRTOULL
2407 if (sizeof(SMB_OFF_T) == 8) {
2408 lval = strtoull(str, &end, 10 /* base */);
2410 lval = strtoul(str, &end, 10 /* base */);
2413 lval = strtoul(str, &end, 10 /* base */);
2416 if (end == NULL || end == str) {
2421 SMB_OFF_T lval_orig = lval;
2423 if (strwicmp(end, "K") == 0) {
2424 lval *= (SMB_OFF_T)1024;
2425 } else if (strwicmp(end, "M") == 0) {
2426 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2427 } else if (strwicmp(end, "G") == 0) {
2428 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2430 } else if (strwicmp(end, "T") == 0) {
2431 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2432 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2433 } else if (strwicmp(end, "P") == 0) {
2434 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2435 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2441 /* Primitive attempt to detect wrapping on platforms with
2442 * 4-byte SMB_OFF_T. It's better to let the caller handle
2443 * a failure than some random number.
2445 if (lval_orig <= lval) {
2453 void string_append(char **left, const char *right)
2455 int new_len = strlen(right) + 1;
2457 if (*left == NULL) {
2458 *left = (char *)SMB_MALLOC(new_len);
2461 new_len += strlen(*left);
2462 *left = (char *)SMB_REALLOC(*left, new_len);
2465 if (*left == NULL) {
2469 safe_strcat(*left, right, new_len-1);
2472 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2473 const char *str, const char ***strings,
2476 char *dup_str = talloc_strdup(mem_ctx, str);
2478 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2480 if ((*strings == NULL) || (dup_str == NULL)) {
2485 (*strings)[*num] = dup_str;
2490 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2491 * error checking in between. The indiation that something weird happened is
2494 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2495 size_t *bufsize, const char *fmt, ...)
2502 /* len<0 is an internal marker that something failed */
2506 if (*string == NULL) {
2510 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2511 if (*string == NULL)
2516 ret = vasprintf(&newstr, fmt, ap);
2524 while ((*len)+ret >= *bufsize) {
2527 if (*bufsize >= (1024*1024*256))
2532 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2534 if (*string == NULL) {
2539 StrnCpy((*string)+(*len), newstr, ret);
2550 Returns the substring from src between the first occurrence of
2551 the char "front" and the first occurence of the char "back".
2552 Mallocs the return string which must be freed. Not for use
2553 with wide character strings.
2555 char *sstring_sub(const char *src, char front, char back)
2557 char *temp1, *temp2, *temp3;
2560 temp1 = strchr(src, front);
2561 if (temp1 == NULL) return NULL;
2562 temp2 = strchr(src, back);
2563 if (temp2 == NULL) return NULL;
2564 len = temp2 - temp1;
2565 if (len <= 0) return NULL;
2566 temp3 = (char*)SMB_MALLOC(len);
2567 if (temp3 == NULL) {
2568 DEBUG(1,("Malloc failure in sstring_sub\n"));
2571 memcpy(temp3, temp1+1, len-1);
2572 temp3[len-1] = '\0';
2576 /********************************************************************
2577 Check a string for any occurrences of a specified list of invalid
2579 ********************************************************************/
2581 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2585 for ( i=0; i<max_len && name[i]; i++ ) {
2586 /* fail if strchr_m() finds one of the invalid characters */
2587 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2597 return the number of bytes occupied by a buffer in ASCII format
2598 the result includes the null termination
2599 limited by 'n' bytes
2601 size_t ascii_len_n(const char *src, size_t n)
2605 len = strnlen(src, n);
2614 return the number of bytes occupied by a buffer in CH_UTF16 format
2615 the result includes the null termination
2617 size_t utf16_len(const void *buf)
2621 for (len = 0; SVAL(buf,len); len += 2) ;
2627 return the number of bytes occupied by a buffer in CH_UTF16 format
2628 the result includes the null termination
2629 limited by 'n' bytes
2631 size_t utf16_len_n(const void *src, size_t n)
2635 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2644 /*******************************************************************
2645 Add a shell escape character '\' to any character not in a known list
2646 of characters. UNIX charset format.
2647 *******************************************************************/
2649 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2650 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2652 char *escape_shell_string(const char *src)
2654 size_t srclen = strlen(src);
2655 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2657 BOOL in_s_quote = False;
2658 BOOL in_d_quote = False;
2659 BOOL next_escaped = False;
2667 codepoint_t c = next_codepoint(src, &c_size);
2669 if (c == INVALID_CODEPOINT) {
2675 memcpy(dest, src, c_size);
2678 next_escaped = False;
2683 * Deal with backslash escaped state.
2684 * This only lasts for one character.
2689 next_escaped = False;
2694 * Deal with single quote state. The
2695 * only thing we care about is exiting
2708 * Deal with double quote state. The most
2709 * complex state. We must cope with \, meaning
2710 * possibly escape next char (depending what it
2711 * is), ", meaning exit this state, and possibly
2712 * add an \ escape to any unprotected character
2713 * (listed in INSIDE_DQUOTE_LIST).
2719 * Next character might be escaped.
2720 * We have to peek. Inside double
2721 * quotes only INSIDE_DQUOTE_LIST
2722 * characters are escaped by a \.
2727 c = next_codepoint(&src[1], &c_size);
2728 if (c == INVALID_CODEPOINT) {
2734 * Don't escape the next char.
2743 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2744 next_escaped = True;
2751 /* Exit double quote state. */
2758 * We know the character isn't \ or ",
2759 * so escape it if it's any of the other
2760 * possible unprotected characters.
2763 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2771 * From here to the end of the loop we're
2772 * not in the single or double quote state.
2776 /* Next character must be escaped. */
2777 next_escaped = True;
2783 /* Go into single quote state. */
2790 /* Go into double quote state. */
2796 /* Check if we need to escape the character. */
2798 if (!strchr(INCLUDE_LIST, (int)*src)) {