r23432: Remove superfluous comment.
[Samba/bb.git] / source3 / lib / util_str.c
blob52cdbfceddc694ff95424a313e4c4c171ea0c960
1 /*
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.
25 #include "includes.h"
27 /**
28 * @file
29 * @brief String utilities.
30 **/
32 /**
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,
41 char *buff,
42 const char *sep,
43 size_t bufsize,
44 BOOL ltrim)
46 char *s;
47 char *pbuf;
48 BOOL quoted;
49 size_t len=1;
51 if (!ptr)
52 return(False);
54 s = (char *)*ptr;
56 /* default to simple separators */
57 if (!sep)
58 sep = " \t\n\r";
60 /* find the first non sep char, if left-trimming is requested */
61 if (ltrim) {
62 while (*s && strchr_m(sep,*s))
63 s++;
66 /* nothing left? */
67 if (! *s)
68 return(False);
70 /* copy over the token */
71 pbuf = buff;
72 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
73 if ( *s == '\"' ) {
74 quoted = !quoted;
75 } else {
76 len++;
77 *pbuf++ = *s;
81 *ptr = (*s) ? s+1 : s;
82 *pbuf = 0;
84 return(True);
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,
103 char *buff,
104 const char *sep,
105 size_t bufsize)
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)
120 BOOL ret;
121 if (!ptr)
122 ptr = &last_ptr;
124 ret = next_token(ptr, buff, sep, bufsize);
125 last_ptr = *ptr;
126 return ret;
129 static uint16 tmpbuf[sizeof(pstring)];
131 void set_first_token(char *ptr)
133 last_ptr = ptr;
137 Convert list of tokens to array; dependent on above routine.
138 Uses last_ptr from above - bit of a hack.
141 char **toktocliplist(int *ctok, const char *sep)
143 char *s=(char *)last_ptr;
144 int ictok=0;
145 char **ret, **iret;
147 if (!sep)
148 sep = " \t\n\r";
150 while(*s && strchr_m(sep,*s))
151 s++;
153 /* nothing left? */
154 if (!*s)
155 return(NULL);
157 do {
158 ictok++;
159 while(*s && (!strchr_m(sep,*s)))
160 s++;
161 while(*s && strchr_m(sep,*s))
162 *s++=0;
163 } while(*s);
165 *ctok=ictok;
166 s=(char *)last_ptr;
168 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
169 return NULL;
171 while(ictok--) {
172 *iret++=s;
173 if (ictok > 0) {
174 while(*s++)
176 while(!*s)
177 s++;
181 ret[*ctok] = NULL;
182 return ret;
186 * Case insensitive string compararison.
188 * iconv does not directly give us a way to compare strings in
189 * arbitrary unix character sets -- all we can is convert and then
190 * compare. This is expensive.
192 * As an optimization, we do a first pass that considers only the
193 * prefix of the strings that is entirely 7-bit. Within this, we
194 * check whether they have the same value.
196 * Hopefully this will often give the answer without needing to copy.
197 * In particular it should speed comparisons to literal ascii strings
198 * or comparisons of strings that are "obviously" different.
200 * If we find a non-ascii character we fall back to converting via
201 * iconv.
203 * This should never be slower than convering the whole thing, and
204 * often faster.
206 * A different optimization would be to compare for bitwise equality
207 * in the binary encoding. (It would be possible thought hairy to do
208 * both simultaneously.) But in that case if they turn out to be
209 * different, we'd need to restart the whole thing.
211 * Even better is to implement strcasecmp for each encoding and use a
212 * function pointer.
214 int StrCaseCmp(const char *s, const char *t)
217 const char *ps, *pt;
218 size_t size;
219 smb_ucs2_t *buffer_s, *buffer_t;
220 int ret;
222 for (ps = s, pt = t; ; ps++, pt++) {
223 char us, ut;
225 if (!*ps && !*pt)
226 return 0; /* both ended */
227 else if (!*ps)
228 return -1; /* s is a prefix */
229 else if (!*pt)
230 return +1; /* t is a prefix */
231 else if ((*ps & 0x80) || (*pt & 0x80))
232 /* not ascii anymore, do it the hard way from here on in */
233 break;
235 us = toupper_ascii(*ps);
236 ut = toupper_ascii(*pt);
237 if (us == ut)
238 continue;
239 else if (us < ut)
240 return -1;
241 else if (us > ut)
242 return +1;
245 size = push_ucs2_allocate(&buffer_s, ps);
246 if (size == (size_t)-1) {
247 return strcmp(ps, pt);
248 /* Not quite the right answer, but finding the right one
249 under this failure case is expensive, and it's pretty close */
252 size = push_ucs2_allocate(&buffer_t, pt);
253 if (size == (size_t)-1) {
254 SAFE_FREE(buffer_s);
255 return strcmp(ps, pt);
256 /* Not quite the right answer, but finding the right one
257 under this failure case is expensive, and it's pretty close */
260 ret = strcasecmp_w(buffer_s, buffer_t);
261 SAFE_FREE(buffer_s);
262 SAFE_FREE(buffer_t);
263 return ret;
268 Case insensitive string compararison, length limited.
270 int StrnCaseCmp(const char *s, const char *t, size_t n)
272 pstring buf1, buf2;
273 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
274 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
275 return strncmp(buf1,buf2,n);
279 * Compare 2 strings.
281 * @note The comparison is case-insensitive.
283 BOOL strequal(const char *s1, const char *s2)
285 if (s1 == s2)
286 return(True);
287 if (!s1 || !s2)
288 return(False);
290 return(StrCaseCmp(s1,s2)==0);
294 * Compare 2 strings up to and including the nth char.
296 * @note The comparison is case-insensitive.
298 BOOL strnequal(const char *s1,const char *s2,size_t n)
300 if (s1 == s2)
301 return(True);
302 if (!s1 || !s2 || !n)
303 return(False);
305 return(StrnCaseCmp(s1,s2,n)==0);
309 Compare 2 strings (case sensitive).
312 BOOL strcsequal(const char *s1,const char *s2)
314 if (s1 == s2)
315 return(True);
316 if (!s1 || !s2)
317 return(False);
319 return(strcmp(s1,s2)==0);
323 Do a case-insensitive, whitespace-ignoring string compare.
326 int strwicmp(const char *psz1, const char *psz2)
328 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
329 /* appropriate value. */
330 if (psz1 == psz2)
331 return (0);
332 else if (psz1 == NULL)
333 return (-1);
334 else if (psz2 == NULL)
335 return (1);
337 /* sync the strings on first non-whitespace */
338 while (1) {
339 while (isspace((int)*psz1))
340 psz1++;
341 while (isspace((int)*psz2))
342 psz2++;
343 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
344 || *psz2 == '\0')
345 break;
346 psz1++;
347 psz2++;
349 return (*psz1 - *psz2);
354 Convert a string to upper case, but don't modify it.
357 char *strupper_static(const char *s)
359 static pstring str;
361 pstrcpy(str, s);
362 strupper_m(str);
364 return str;
368 Convert a string to "normal" form.
371 void strnorm(char *s, int case_default)
373 if (case_default == CASE_UPPER)
374 strupper_m(s);
375 else
376 strlower_m(s);
380 Check if a string is in "normal" case.
383 BOOL strisnormal(const char *s, int case_default)
385 if (case_default == CASE_UPPER)
386 return(!strhaslower(s));
388 return(!strhasupper(s));
393 String replace.
394 NOTE: oldc and newc must be 7 bit characters
397 void string_replace( pstring s, char oldc, char newc )
399 char *p;
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. */
408 break;
409 if (*p == oldc)
410 *p = newc;
413 if (!*p)
414 return;
416 /* Slow (mb) path. */
417 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
418 /* With compose characters we must restart from the beginning. JRA. */
419 p = s;
420 #endif
421 push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
422 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
423 pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
427 * Skip past some strings in a buffer - old version - no checks.
428 * **/
430 char *push_skip_string(char *buf)
432 buf += strlen(buf) + 1;
433 return(buf);
437 Skip past a string in a buffer. Buffer may not be
438 null terminated. end_ptr points to the first byte after
439 then end of the buffer.
442 char *skip_string(const char *base, size_t len, char *buf)
444 const char *end_ptr = base + len;
446 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
447 return NULL;
450 /* Skip the string */
451 while (*buf) {
452 buf++;
453 if (buf >= end_ptr) {
454 return NULL;
457 /* Skip the '\0' */
458 buf++;
459 return buf;
463 Count the number of characters in a string. Normally this will
464 be the same as the number of bytes in a string for single byte strings,
465 but will be different for multibyte.
468 size_t str_charnum(const char *s)
470 uint16 tmpbuf2[sizeof(pstring)];
471 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
472 return strlen_w(tmpbuf2);
476 Count the number of characters in a string. Normally this will
477 be the same as the number of bytes in a string for single byte strings,
478 but will be different for multibyte.
481 size_t str_ascii_charnum(const char *s)
483 pstring tmpbuf2;
484 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
485 return strlen(tmpbuf2);
488 BOOL trim_char(char *s,char cfront,char cback)
490 BOOL ret = False;
491 char *ep;
492 char *fp = s;
494 /* Ignore null or empty strings. */
495 if (!s || (s[0] == '\0'))
496 return False;
498 if (cfront) {
499 while (*fp && *fp == cfront)
500 fp++;
501 if (!*fp) {
502 /* We ate the string. */
503 s[0] = '\0';
504 return True;
506 if (fp != s)
507 ret = True;
510 ep = fp + strlen(fp) - 1;
511 if (cback) {
512 /* Attempt ascii only. Bail for mb strings. */
513 while ((ep >= fp) && (*ep == cback)) {
514 ret = True;
515 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
516 /* Could be mb... bail back to tim_string. */
517 char fs[2], bs[2];
518 if (cfront) {
519 fs[0] = cfront;
520 fs[1] = '\0';
522 bs[0] = cback;
523 bs[1] = '\0';
524 return trim_string(s, cfront ? fs : NULL, bs);
525 } else {
526 ep--;
529 if (ep < fp) {
530 /* We ate the string. */
531 s[0] = '\0';
532 return True;
536 ep[1] = '\0';
537 memmove(s, fp, ep-fp+2);
538 return ret;
542 Trim the specified elements off the front and back of a string.
545 BOOL trim_string(char *s,const char *front,const char *back)
547 BOOL ret = False;
548 size_t front_len;
549 size_t back_len;
550 size_t len;
552 /* Ignore null or empty strings. */
553 if (!s || (s[0] == '\0'))
554 return False;
556 front_len = front? strlen(front) : 0;
557 back_len = back? strlen(back) : 0;
559 len = strlen(s);
561 if (front_len) {
562 while (len && strncmp(s, front, front_len)==0) {
563 /* Must use memmove here as src & dest can
564 * easily overlap. Found by valgrind. JRA. */
565 memmove(s, s+front_len, (len-front_len)+1);
566 len -= front_len;
567 ret=True;
571 if (back_len) {
572 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
573 s[len-back_len]='\0';
574 len -= back_len;
575 ret=True;
578 return ret;
582 Does a string have any uppercase chars in it?
585 BOOL strhasupper(const char *s)
587 smb_ucs2_t *ptr;
588 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
589 for(ptr=tmpbuf;*ptr;ptr++)
590 if(isupper_w(*ptr))
591 return True;
592 return(False);
596 Does a string have any lowercase chars in it?
599 BOOL strhaslower(const char *s)
601 smb_ucs2_t *ptr;
602 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
603 for(ptr=tmpbuf;*ptr;ptr++)
604 if(islower_w(*ptr))
605 return True;
606 return(False);
610 Find the number of 'c' chars in a string
613 size_t count_chars(const char *s,char c)
615 smb_ucs2_t *ptr;
616 int count;
617 smb_ucs2_t *alloc_tmpbuf = NULL;
619 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
620 return 0;
623 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
624 if(*ptr==UCS2_CHAR(c))
625 count++;
627 SAFE_FREE(alloc_tmpbuf);
628 return(count);
632 Safe string copy into a known length string. maxlength does not
633 include the terminating zero.
636 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
638 size_t len;
640 if (!dest) {
641 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
642 return NULL;
645 #ifdef DEVELOPER
646 clobber_region(fn,line,dest, maxlength+1);
647 #endif
649 if (!src) {
650 *dest = 0;
651 return dest;
654 len = strnlen(src, maxlength+1);
656 if (len > maxlength) {
657 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
658 (unsigned long)(len-maxlength), (unsigned long)len,
659 (unsigned long)maxlength, src));
660 len = maxlength;
663 memmove(dest, src, len);
664 dest[len] = 0;
665 return dest;
669 Safe string cat into a string. maxlength does not
670 include the terminating zero.
672 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
674 size_t src_len, dest_len;
676 if (!dest) {
677 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
678 return NULL;
681 if (!src)
682 return dest;
684 src_len = strnlen(src, maxlength + 1);
685 dest_len = strnlen(dest, maxlength + 1);
687 #ifdef DEVELOPER
688 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
689 #endif
691 if (src_len + dest_len > maxlength) {
692 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
693 (int)(src_len + dest_len - maxlength), src));
694 if (maxlength > dest_len) {
695 memcpy(&dest[dest_len], src, maxlength - dest_len);
697 dest[maxlength] = 0;
698 return NULL;
701 memcpy(&dest[dest_len], src, src_len);
702 dest[dest_len + src_len] = 0;
703 return dest;
707 Paranoid strcpy into a buffer of given length (includes terminating
708 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
709 and replaces with '_'. Deliberately does *NOT* check for multibyte
710 characters. Don't change it !
712 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
714 size_t len, i;
716 #ifdef DEVELOPER
717 clobber_region(fn, line, dest, maxlength);
718 #endif
720 if (!dest) {
721 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
722 return NULL;
725 if (!src) {
726 *dest = 0;
727 return dest;
730 len = strlen(src);
731 if (len >= maxlength)
732 len = maxlength - 1;
734 if (!other_safe_chars)
735 other_safe_chars = "";
737 for(i = 0; i < len; i++) {
738 int val = (src[i] & 0xff);
739 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
740 dest[i] = src[i];
741 else
742 dest[i] = '_';
745 dest[i] = '\0';
747 return dest;
751 Like strncpy but always null terminates. Make sure there is room!
752 The variable n should always be one less than the available size.
754 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
756 char *d = dest;
758 #ifdef DEVELOPER
759 clobber_region(fn, line, dest, n+1);
760 #endif
762 if (!dest) {
763 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
764 return(NULL);
767 if (!src) {
768 *dest = 0;
769 return(dest);
772 while (n-- && (*d = *src)) {
773 d++;
774 src++;
777 *d = 0;
778 return(dest);
781 #if 0
783 Like strncpy but copies up to the character marker. always null terminates.
784 returns a pointer to the character marker in the source string (src).
787 static char *strncpyn(char *dest, const char *src, size_t n, char c)
789 char *p;
790 size_t str_len;
792 #ifdef DEVELOPER
793 clobber_region(dest, n+1);
794 #endif
795 p = strchr_m(src, c);
796 if (p == NULL) {
797 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
798 return NULL;
801 str_len = PTR_DIFF(p, src);
802 strncpy(dest, src, MIN(n, str_len));
803 dest[str_len] = '\0';
805 return p;
807 #endif
810 Routine to get hex characters and turn them into a 16 byte array.
811 the array can be variable length, and any non-hex-numeric
812 characters are skipped. "0xnn" or "0Xnn" is specially catered
813 for.
815 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
819 size_t strhex_to_str(char *p, size_t len, const char *strhex)
821 size_t i;
822 size_t num_chars = 0;
823 unsigned char lonybble, hinybble;
824 const char *hexchars = "0123456789ABCDEF";
825 char *p1 = NULL, *p2 = NULL;
827 for (i = 0; i < len && strhex[i] != 0; i++) {
828 if (strnequal(hexchars, "0x", 2)) {
829 i++; /* skip two chars */
830 continue;
833 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
834 break;
836 i++; /* next hex digit */
838 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
839 break;
841 /* get the two nybbles */
842 hinybble = PTR_DIFF(p1, hexchars);
843 lonybble = PTR_DIFF(p2, hexchars);
845 p[num_chars] = (hinybble << 4) | lonybble;
846 num_chars++;
848 p1 = NULL;
849 p2 = NULL;
851 return num_chars;
854 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
856 DATA_BLOB ret_blob;
858 if (mem_ctx != NULL)
859 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
860 else
861 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
863 ret_blob.length = strhex_to_str((char*)ret_blob.data,
864 strlen(strhex),
865 strhex);
867 return ret_blob;
871 * Routine to print a buffer as HEX digits, into an allocated string.
874 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
876 int i;
877 char *hex_buffer;
879 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
881 for (i = 0; i < len; i++)
882 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
884 return hex_buffer;
888 Check if a string is part of a list.
891 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
893 pstring tok;
894 const char *p=list;
896 if (!list)
897 return(False);
899 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
900 if (casesensitive) {
901 if (strcmp(tok,s) == 0)
902 return(True);
903 } else {
904 if (StrCaseCmp(tok,s) == 0)
905 return(True);
908 return(False);
911 /* this is used to prevent lots of mallocs of size 1 */
912 static const char *null_string = "";
915 Set a string value, allocing the space for the string
918 static BOOL string_init(char **dest,const char *src)
920 size_t l;
922 if (!src)
923 src = "";
925 l = strlen(src);
927 if (l == 0) {
928 *dest = CONST_DISCARD(char*, null_string);
929 } else {
930 (*dest) = SMB_STRDUP(src);
931 if ((*dest) == NULL) {
932 DEBUG(0,("Out of memory in string_init\n"));
933 return False;
936 return(True);
940 Free a string value.
943 void string_free(char **s)
945 if (!s || !(*s))
946 return;
947 if (*s == null_string)
948 *s = NULL;
949 SAFE_FREE(*s);
953 Set a string value, deallocating any existing space, and allocing the space
954 for the string
957 BOOL string_set(char **dest,const char *src)
959 string_free(dest);
960 return(string_init(dest,src));
964 Substitute a string for a pattern in another string. Make sure there is
965 enough room!
967 This routine looks for pattern in s and replaces it with
968 insert. It may do multiple replacements or just one.
970 Any of " ; ' $ or ` in the insert string are replaced with _
971 if len==0 then the string cannot be extended. This is different from the old
972 use of len==0 which was for no length checks to be done.
975 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
976 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
978 char *p;
979 ssize_t ls,lp,li, i;
981 if (!insert || !pattern || !*pattern || !s)
982 return;
984 ls = (ssize_t)strlen(s);
985 lp = (ssize_t)strlen(pattern);
986 li = (ssize_t)strlen(insert);
988 if (len == 0)
989 len = ls + 1; /* len is number of *bytes* */
991 while (lp <= ls && (p = strstr_m(s,pattern))) {
992 if (ls + (li-lp) >= len) {
993 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
994 (int)(ls + (li-lp) - len),
995 pattern, (int)len));
996 break;
998 if (li != lp) {
999 memmove(p+li,p+lp,strlen(p+lp)+1);
1001 for (i=0;i<li;i++) {
1002 switch (insert[i]) {
1003 case '`':
1004 case '"':
1005 case '\'':
1006 case ';':
1007 case '$':
1008 /* allow a trailing $ (as in machine accounts) */
1009 if (allow_trailing_dollar && (i == li - 1 )) {
1010 p[i] = insert[i];
1011 break;
1013 case '%':
1014 case '\r':
1015 case '\n':
1016 if ( remove_unsafe_characters ) {
1017 p[i] = '_';
1018 /* yes this break should be here since we want to
1019 fall throw if not replacing unsafe chars */
1020 break;
1022 default:
1023 p[i] = insert[i];
1026 s = p + li;
1027 ls += (li-lp);
1029 if (replace_once)
1030 break;
1034 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1036 string_sub2( s, pattern, insert, len, True, True, False );
1039 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1041 string_sub2( s, pattern, insert, len, True, False, False );
1044 void fstring_sub(char *s,const char *pattern,const char *insert)
1046 string_sub(s, pattern, insert, sizeof(fstring));
1049 void pstring_sub(char *s,const char *pattern,const char *insert)
1051 string_sub(s, pattern, insert, sizeof(pstring));
1055 Similar to string_sub, but it will accept only allocated strings
1056 and may realloc them so pay attention at what you pass on no
1057 pointers inside strings, no pstrings or const may be passed
1058 as string.
1061 char *realloc_string_sub(char *string, const char *pattern,
1062 const char *insert)
1064 char *p, *in;
1065 char *s;
1066 ssize_t ls,lp,li,ld, i;
1068 if (!insert || !pattern || !*pattern || !string || !*string)
1069 return NULL;
1071 s = string;
1073 in = SMB_STRDUP(insert);
1074 if (!in) {
1075 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1076 return NULL;
1078 ls = (ssize_t)strlen(s);
1079 lp = (ssize_t)strlen(pattern);
1080 li = (ssize_t)strlen(insert);
1081 ld = li - lp;
1082 for (i=0;i<li;i++) {
1083 switch (in[i]) {
1084 case '`':
1085 case '"':
1086 case '\'':
1087 case ';':
1088 case '$':
1089 case '%':
1090 case '\r':
1091 case '\n':
1092 in[i] = '_';
1093 default:
1094 /* ok */
1095 break;
1099 while ((p = strstr_m(s,pattern))) {
1100 if (ld > 0) {
1101 int offset = PTR_DIFF(s,string);
1102 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1103 if (!string) {
1104 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1105 SAFE_FREE(in);
1106 return NULL;
1108 p = string + offset + (p - s);
1110 if (li != lp) {
1111 memmove(p+li,p+lp,strlen(p+lp)+1);
1113 memcpy(p, in, li);
1114 s = p + li;
1115 ls += ld;
1117 SAFE_FREE(in);
1118 return string;
1121 /* Same as string_sub, but returns a talloc'ed string */
1123 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1124 const char *pattern, const char *insert)
1126 char *p, *in;
1127 char *s;
1128 char *string;
1129 ssize_t ls,lp,li,ld, i;
1131 if (!insert || !pattern || !*pattern || !src || !*src)
1132 return NULL;
1134 string = talloc_strdup(mem_ctx, src);
1135 if (string == NULL) {
1136 DEBUG(0, ("talloc_strdup failed\n"));
1137 return NULL;
1140 s = string;
1142 in = SMB_STRDUP(insert);
1143 if (!in) {
1144 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1145 return NULL;
1147 ls = (ssize_t)strlen(s);
1148 lp = (ssize_t)strlen(pattern);
1149 li = (ssize_t)strlen(insert);
1150 ld = li - lp;
1151 for (i=0;i<li;i++) {
1152 switch (in[i]) {
1153 case '`':
1154 case '"':
1155 case '\'':
1156 case ';':
1157 case '$':
1158 case '%':
1159 case '\r':
1160 case '\n':
1161 in[i] = '_';
1162 default:
1163 /* ok */
1164 break;
1168 while ((p = strstr_m(s,pattern))) {
1169 if (ld > 0) {
1170 int offset = PTR_DIFF(s,string);
1171 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1172 ls + ld + 1);
1173 if (!string) {
1174 DEBUG(0, ("talloc_string_sub: out of "
1175 "memory!\n"));
1176 SAFE_FREE(in);
1177 return NULL;
1179 p = string + offset + (p - s);
1181 if (li != lp) {
1182 memmove(p+li,p+lp,strlen(p+lp)+1);
1184 memcpy(p, in, li);
1185 s = p + li;
1186 ls += ld;
1188 SAFE_FREE(in);
1189 return string;
1193 Similar to string_sub() but allows for any character to be substituted.
1194 Use with caution!
1195 if len==0 then the string cannot be extended. This is different from the old
1196 use of len==0 which was for no length checks to be done.
1199 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1201 char *p;
1202 ssize_t ls,lp,li;
1204 if (!insert || !pattern || !s)
1205 return;
1207 ls = (ssize_t)strlen(s);
1208 lp = (ssize_t)strlen(pattern);
1209 li = (ssize_t)strlen(insert);
1211 if (!*pattern)
1212 return;
1214 if (len == 0)
1215 len = ls + 1; /* len is number of *bytes* */
1217 while (lp <= ls && (p = strstr_m(s,pattern))) {
1218 if (ls + (li-lp) >= len) {
1219 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1220 (int)(ls + (li-lp) - len),
1221 pattern, (int)len));
1222 break;
1224 if (li != lp) {
1225 memmove(p+li,p+lp,strlen(p+lp)+1);
1227 memcpy(p, insert, li);
1228 s = p + li;
1229 ls += (li-lp);
1234 Similar to all_string_sub but for unicode strings.
1235 Return a new allocated unicode string.
1236 similar to string_sub() but allows for any character to be substituted.
1237 Use with caution!
1240 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1241 const smb_ucs2_t *insert)
1243 smb_ucs2_t *r, *rp;
1244 const smb_ucs2_t *sp;
1245 size_t lr, lp, li, lt;
1247 if (!insert || !pattern || !*pattern || !s)
1248 return NULL;
1250 lt = (size_t)strlen_w(s);
1251 lp = (size_t)strlen_w(pattern);
1252 li = (size_t)strlen_w(insert);
1254 if (li > lp) {
1255 const smb_ucs2_t *st = s;
1256 int ld = li - lp;
1257 while ((sp = strstr_w(st, pattern))) {
1258 st = sp + lp;
1259 lt += ld;
1263 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1264 if (!r) {
1265 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1266 return NULL;
1269 while ((sp = strstr_w(s, pattern))) {
1270 memcpy(rp, s, (sp - s));
1271 rp += ((sp - s) / sizeof(smb_ucs2_t));
1272 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1273 s = sp + lp;
1274 rp += li;
1276 lr = ((rp - r) / sizeof(smb_ucs2_t));
1277 if (lr < lt) {
1278 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1279 rp += (lt - lr);
1281 *rp = 0;
1283 return r;
1286 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1287 const char *insert)
1289 wpstring p, i;
1291 if (!insert || !pattern || !s)
1292 return NULL;
1293 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1294 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1295 return all_string_sub_w(s, p, i);
1298 #if 0
1300 Splits out the front and back at a separator.
1303 static void split_at_last_component(char *path, char *front, char sep, char *back)
1305 char *p = strrchr_m(path, sep);
1307 if (p != NULL)
1308 *p = 0;
1310 if (front != NULL)
1311 pstrcpy(front, path);
1313 if (p != NULL) {
1314 if (back != NULL)
1315 pstrcpy(back, p+1);
1316 *p = '\\';
1317 } else {
1318 if (back != NULL)
1319 back[0] = 0;
1322 #endif
1325 Write an octal as a string.
1328 const char *octal_string(int i)
1330 static char ret[64];
1331 if (i == -1)
1332 return "-1";
1333 slprintf(ret, sizeof(ret)-1, "0%o", i);
1334 return ret;
1339 Truncate a string at a specified length.
1342 char *string_truncate(char *s, unsigned int length)
1344 if (s && strlen(s) > length)
1345 s[length] = 0;
1346 return s;
1350 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1351 We convert via ucs2 for now.
1354 char *strchr_m(const char *src, char c)
1356 wpstring ws;
1357 pstring s2;
1358 smb_ucs2_t *p;
1359 const char *s;
1361 /* characters below 0x3F are guaranteed to not appear in
1362 non-initial position in multi-byte charsets */
1363 if ((c & 0xC0) == 0) {
1364 return strchr(src, c);
1367 /* this is quite a common operation, so we want it to be
1368 fast. We optimise for the ascii case, knowing that all our
1369 supported multi-byte character sets are ascii-compatible
1370 (ie. they match for the first 128 chars) */
1372 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1373 if (*s == c)
1374 return (char *)s;
1377 if (!*s)
1378 return NULL;
1380 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1381 /* With compose characters we must restart from the beginning. JRA. */
1382 s = src;
1383 #endif
1385 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1386 p = strchr_w(ws, UCS2_CHAR(c));
1387 if (!p)
1388 return NULL;
1389 *p = 0;
1390 pull_ucs2_pstring(s2, ws);
1391 return (char *)(s+strlen(s2));
1394 char *strrchr_m(const char *s, char c)
1396 /* characters below 0x3F are guaranteed to not appear in
1397 non-initial position in multi-byte charsets */
1398 if ((c & 0xC0) == 0) {
1399 return strrchr(s, c);
1402 /* this is quite a common operation, so we want it to be
1403 fast. We optimise for the ascii case, knowing that all our
1404 supported multi-byte character sets are ascii-compatible
1405 (ie. they match for the first 128 chars). Also, in Samba
1406 we only search for ascii characters in 'c' and that
1407 in all mb character sets with a compound character
1408 containing c, if 'c' is not a match at position
1409 p, then p[-1] > 0x7f. JRA. */
1412 size_t len = strlen(s);
1413 const char *cp = s;
1414 BOOL got_mb = False;
1416 if (len == 0)
1417 return NULL;
1418 cp += (len - 1);
1419 do {
1420 if (c == *cp) {
1421 /* Could be a match. Part of a multibyte ? */
1422 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1423 /* Yep - go slow :-( */
1424 got_mb = True;
1425 break;
1427 /* No - we have a match ! */
1428 return (char *)cp;
1430 } while (cp-- != s);
1431 if (!got_mb)
1432 return NULL;
1435 /* String contained a non-ascii char. Slow path. */
1437 wpstring ws;
1438 pstring s2;
1439 smb_ucs2_t *p;
1441 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1442 p = strrchr_w(ws, UCS2_CHAR(c));
1443 if (!p)
1444 return NULL;
1445 *p = 0;
1446 pull_ucs2_pstring(s2, ws);
1447 return (char *)(s+strlen(s2));
1451 /***********************************************************************
1452 Return the equivalent of doing strrchr 'n' times - always going
1453 backwards.
1454 ***********************************************************************/
1456 char *strnrchr_m(const char *s, char c, unsigned int n)
1458 wpstring ws;
1459 pstring s2;
1460 smb_ucs2_t *p;
1462 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1463 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1464 if (!p)
1465 return NULL;
1466 *p = 0;
1467 pull_ucs2_pstring(s2, ws);
1468 return (char *)(s+strlen(s2));
1471 /***********************************************************************
1472 strstr_m - We convert via ucs2 for now.
1473 ***********************************************************************/
1475 char *strstr_m(const char *src, const char *findstr)
1477 smb_ucs2_t *p;
1478 smb_ucs2_t *src_w, *find_w;
1479 const char *s;
1480 char *s2;
1481 char *retp;
1483 size_t findstr_len = 0;
1485 /* for correctness */
1486 if (!findstr[0]) {
1487 return (char*)src;
1490 /* Samba does single character findstr calls a *lot*. */
1491 if (findstr[1] == '\0')
1492 return strchr_m(src, *findstr);
1494 /* We optimise for the ascii case, knowing that all our
1495 supported multi-byte character sets are ascii-compatible
1496 (ie. they match for the first 128 chars) */
1498 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1499 if (*s == *findstr) {
1500 if (!findstr_len)
1501 findstr_len = strlen(findstr);
1503 if (strncmp(s, findstr, findstr_len) == 0) {
1504 return (char *)s;
1509 if (!*s)
1510 return NULL;
1512 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1513 /* 'make check' fails unless we do this */
1515 /* With compose characters we must restart from the beginning. JRA. */
1516 s = src;
1517 #endif
1519 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1520 DEBUG(0,("strstr_m: src malloc fail\n"));
1521 return NULL;
1524 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1525 SAFE_FREE(src_w);
1526 DEBUG(0,("strstr_m: find malloc fail\n"));
1527 return NULL;
1530 p = strstr_w(src_w, find_w);
1532 if (!p) {
1533 SAFE_FREE(src_w);
1534 SAFE_FREE(find_w);
1535 return NULL;
1538 *p = 0;
1539 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1540 SAFE_FREE(src_w);
1541 SAFE_FREE(find_w);
1542 DEBUG(0,("strstr_m: dest malloc fail\n"));
1543 return NULL;
1545 retp = (char *)(s+strlen(s2));
1546 SAFE_FREE(src_w);
1547 SAFE_FREE(find_w);
1548 SAFE_FREE(s2);
1549 return retp;
1553 Convert a string to lower case.
1556 void strlower_m(char *s)
1558 size_t len;
1559 int errno_save;
1561 /* this is quite a common operation, so we want it to be
1562 fast. We optimise for the ascii case, knowing that all our
1563 supported multi-byte character sets are ascii-compatible
1564 (ie. they match for the first 128 chars) */
1566 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1567 *s = tolower_ascii((unsigned char)*s);
1568 s++;
1571 if (!*s)
1572 return;
1574 /* I assume that lowercased string takes the same number of bytes
1575 * as source string even in UTF-8 encoding. (VIV) */
1576 len = strlen(s) + 1;
1577 errno_save = errno;
1578 errno = 0;
1579 unix_strlower(s,len,s,len);
1580 /* Catch mb conversion errors that may not terminate. */
1581 if (errno)
1582 s[len-1] = '\0';
1583 errno = errno_save;
1587 Convert a string to upper case.
1590 void strupper_m(char *s)
1592 size_t len;
1593 int errno_save;
1595 /* this is quite a common operation, so we want it to be
1596 fast. We optimise for the ascii case, knowing that all our
1597 supported multi-byte character sets are ascii-compatible
1598 (ie. they match for the first 128 chars) */
1600 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1601 *s = toupper_ascii((unsigned char)*s);
1602 s++;
1605 if (!*s)
1606 return;
1608 /* I assume that lowercased string takes the same number of bytes
1609 * as source string even in multibyte encoding. (VIV) */
1610 len = strlen(s) + 1;
1611 errno_save = errno;
1612 errno = 0;
1613 unix_strupper(s,len,s,len);
1614 /* Catch mb conversion errors that may not terminate. */
1615 if (errno)
1616 s[len-1] = '\0';
1617 errno = errno_save;
1621 Count the number of UCS2 characters in a string. Normally this will
1622 be the same as the number of bytes in a string for single byte strings,
1623 but will be different for multibyte.
1626 size_t strlen_m(const char *s)
1628 size_t count = 0;
1630 if (!s) {
1631 return 0;
1634 while (*s && !(((uint8_t)*s) & 0x80)) {
1635 s++;
1636 count++;
1639 if (!*s) {
1640 return count;
1643 while (*s) {
1644 size_t c_size;
1645 codepoint_t c = next_codepoint(s, &c_size);
1646 if (c < 0x10000) {
1647 /* Unicode char fits into 16 bits. */
1648 count += 1;
1649 } else {
1650 /* Double-width unicode char - 32 bits. */
1651 count += 2;
1653 s += c_size;
1656 return count;
1660 Count the number of UCS2 characters in a string including the null
1661 terminator.
1664 size_t strlen_m_term(const char *s)
1666 if (!s) {
1667 return 0;
1669 return strlen_m(s) + 1;
1673 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1674 * if a string is there, include the terminator.
1677 size_t strlen_m_term_null(const char *s)
1679 size_t len;
1680 if (!s) {
1681 return 0;
1683 len = strlen_m(s);
1684 if (len == 0) {
1685 return 0;
1688 return len+1;
1691 Return a RFC2254 binary string representation of a buffer.
1692 Used in LDAP filters.
1693 Caller must free.
1696 char *binary_string_rfc2254(char *buf, int len)
1698 char *s;
1699 int i, j;
1700 const char *hex = "0123456789ABCDEF";
1701 s = (char *)SMB_MALLOC(len * 3 + 1);
1702 if (!s)
1703 return NULL;
1704 for (j=i=0;i<len;i++) {
1705 s[j] = '\\';
1706 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1707 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1708 j += 3;
1710 s[j] = 0;
1711 return s;
1714 char *binary_string(char *buf, int len)
1716 char *s;
1717 int i, j;
1718 const char *hex = "0123456789ABCDEF";
1719 s = (char *)SMB_MALLOC(len * 2 + 1);
1720 if (!s)
1721 return NULL;
1722 for (j=i=0;i<len;i++) {
1723 s[j] = hex[((unsigned char)buf[i]) >> 4];
1724 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1725 j += 2;
1727 s[j] = 0;
1728 return s;
1731 Just a typesafety wrapper for snprintf into a pstring.
1734 int pstr_sprintf(pstring s, const char *fmt, ...)
1736 va_list ap;
1737 int ret;
1739 va_start(ap, fmt);
1740 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1741 va_end(ap);
1742 return ret;
1747 Just a typesafety wrapper for snprintf into a fstring.
1750 int fstr_sprintf(fstring s, const char *fmt, ...)
1752 va_list ap;
1753 int ret;
1755 va_start(ap, fmt);
1756 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1757 va_end(ap);
1758 return ret;
1762 List of Strings manipulation functions
1765 #define S_LIST_ABS 16 /* List Allocation Block Size */
1767 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1769 char **list, **rlist;
1770 const char *str;
1771 char *s;
1772 int num, lsize;
1773 pstring tok;
1775 if (!string || !*string)
1776 return NULL;
1777 if (mem_ctx) {
1778 s = talloc_strdup(mem_ctx, string);
1779 } else {
1780 s = SMB_STRDUP(string);
1782 if (!s) {
1783 DEBUG(0,("str_list_make: Unable to allocate memory"));
1784 return NULL;
1786 if (!sep) sep = LIST_SEP;
1788 num = lsize = 0;
1789 list = NULL;
1791 str = s;
1792 while (next_token(&str, tok, sep, sizeof(tok))) {
1793 if (num == lsize) {
1794 lsize += S_LIST_ABS;
1795 if (mem_ctx) {
1796 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1797 } else {
1798 /* We need to keep the old list on error so we can free the elements
1799 if the realloc fails. */
1800 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1802 if (!rlist) {
1803 DEBUG(0,("str_list_make: Unable to allocate memory"));
1804 str_list_free(&list);
1805 if (mem_ctx) {
1806 TALLOC_FREE(s);
1807 } else {
1808 SAFE_FREE(s);
1810 return NULL;
1811 } else {
1812 list = rlist;
1814 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1817 if (mem_ctx) {
1818 list[num] = talloc_strdup(mem_ctx, tok);
1819 } else {
1820 list[num] = SMB_STRDUP(tok);
1823 if (!list[num]) {
1824 DEBUG(0,("str_list_make: Unable to allocate memory"));
1825 str_list_free(&list);
1826 if (mem_ctx) {
1827 TALLOC_FREE(s);
1828 } else {
1829 SAFE_FREE(s);
1831 return NULL;
1834 num++;
1837 if (mem_ctx) {
1838 TALLOC_FREE(s);
1839 } else {
1840 SAFE_FREE(s);
1843 return list;
1846 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1848 return str_list_make_internal(mem_ctx, string, sep);
1851 char **str_list_make(const char *string, const char *sep)
1853 return str_list_make_internal(NULL, string, sep);
1856 BOOL str_list_copy(char ***dest, const char **src)
1858 char **list, **rlist;
1859 int num, lsize;
1861 *dest = NULL;
1862 if (!src)
1863 return False;
1865 num = lsize = 0;
1866 list = NULL;
1868 while (src[num]) {
1869 if (num == lsize) {
1870 lsize += S_LIST_ABS;
1871 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1872 if (!rlist) {
1873 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1874 str_list_free(&list);
1875 return False;
1876 } else {
1877 list = rlist;
1879 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1882 list[num] = SMB_STRDUP(src[num]);
1883 if (!list[num]) {
1884 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1885 str_list_free(&list);
1886 return False;
1889 num++;
1892 *dest = list;
1893 return True;
1897 * Return true if all the elements of the list match exactly.
1899 BOOL str_list_compare(char **list1, char **list2)
1901 int num;
1903 if (!list1 || !list2)
1904 return (list1 == list2);
1906 for (num = 0; list1[num]; num++) {
1907 if (!list2[num])
1908 return False;
1909 if (!strcsequal(list1[num], list2[num]))
1910 return False;
1912 if (list2[num])
1913 return False; /* if list2 has more elements than list1 fail */
1915 return True;
1918 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1920 char **tlist;
1922 if (!list || !*list)
1923 return;
1924 tlist = *list;
1925 for(; *tlist; tlist++) {
1926 if (mem_ctx) {
1927 TALLOC_FREE(*tlist);
1928 } else {
1929 SAFE_FREE(*tlist);
1932 if (mem_ctx) {
1933 TALLOC_FREE(*tlist);
1934 } else {
1935 SAFE_FREE(*list);
1939 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1941 str_list_free_internal(mem_ctx, list);
1944 void str_list_free(char ***list)
1946 str_list_free_internal(NULL, list);
1949 /******************************************************************************
1950 *****************************************************************************/
1952 int str_list_count( const char **list )
1954 int i = 0;
1956 if ( ! list )
1957 return 0;
1959 /* count the number of list members */
1961 for ( i=0; *list; i++, list++ );
1963 return i;
1966 /******************************************************************************
1967 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1968 for the work
1969 *****************************************************************************/
1971 BOOL str_list_sub_basic( char **list, const char *smb_name,
1972 const char *domain_name )
1974 char *s, *tmpstr;
1976 while ( *list ) {
1977 s = *list;
1978 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
1979 if ( !tmpstr ) {
1980 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1981 return False;
1984 SAFE_FREE(*list);
1985 *list = tmpstr;
1987 list++;
1990 return True;
1993 /******************************************************************************
1994 substritute a specific pattern in a string list
1995 *****************************************************************************/
1997 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1999 char *p, *s, *t;
2000 ssize_t ls, lp, li, ld, i, d;
2002 if (!list)
2003 return False;
2004 if (!pattern)
2005 return False;
2006 if (!insert)
2007 return False;
2009 lp = (ssize_t)strlen(pattern);
2010 li = (ssize_t)strlen(insert);
2011 ld = li -lp;
2013 while (*list) {
2014 s = *list;
2015 ls = (ssize_t)strlen(s);
2017 while ((p = strstr_m(s, pattern))) {
2018 t = *list;
2019 d = p -t;
2020 if (ld) {
2021 t = (char *) SMB_MALLOC(ls +ld +1);
2022 if (!t) {
2023 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2024 return False;
2026 memcpy(t, *list, d);
2027 memcpy(t +d +li, p +lp, ls -d -lp +1);
2028 SAFE_FREE(*list);
2029 *list = t;
2030 ls += ld;
2031 s = t +d +li;
2034 for (i = 0; i < li; i++) {
2035 switch (insert[i]) {
2036 case '`':
2037 case '"':
2038 case '\'':
2039 case ';':
2040 case '$':
2041 case '%':
2042 case '\r':
2043 case '\n':
2044 t[d +i] = '_';
2045 break;
2046 default:
2047 t[d +i] = insert[i];
2053 list++;
2056 return True;
2060 #define IPSTR_LIST_SEP ","
2061 #define IPSTR_LIST_CHAR ','
2064 * Add ip string representation to ipstr list. Used also
2065 * as part of @function ipstr_list_make
2067 * @param ipstr_list pointer to string containing ip list;
2068 * MUST BE already allocated and IS reallocated if necessary
2069 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2070 * as a result of reallocation)
2071 * @param ip IP address which is to be added to list
2072 * @return pointer to string appended with new ip and possibly
2073 * reallocated to new length
2076 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2078 char* new_ipstr = NULL;
2080 /* arguments checking */
2081 if (!ipstr_list || !service) return NULL;
2083 /* attempt to convert ip to a string and append colon separator to it */
2084 if (*ipstr_list) {
2085 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2086 inet_ntoa(service->ip), service->port);
2087 SAFE_FREE(*ipstr_list);
2088 } else {
2089 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2091 *ipstr_list = new_ipstr;
2092 return *ipstr_list;
2097 * Allocate and initialise an ipstr list using ip adresses
2098 * passed as arguments.
2100 * @param ipstr_list pointer to string meant to be allocated and set
2101 * @param ip_list array of ip addresses to place in the list
2102 * @param ip_count number of addresses stored in ip_list
2103 * @return pointer to allocated ip string
2106 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2108 int i;
2110 /* arguments checking */
2111 if (!ip_list || !ipstr_list) return 0;
2113 *ipstr_list = NULL;
2115 /* process ip addresses given as arguments */
2116 for (i = 0; i < ip_count; i++)
2117 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2119 return (*ipstr_list);
2124 * Parse given ip string list into array of ip addresses
2125 * (as ip_service structures)
2126 * e.g. 192.168.1.100:389,192.168.1.78, ...
2128 * @param ipstr ip string list to be parsed
2129 * @param ip_list pointer to array of ip addresses which is
2130 * allocated by this function and must be freed by caller
2131 * @return number of succesfully parsed addresses
2134 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2136 fstring token_str;
2137 size_t count;
2138 int i;
2140 if (!ipstr_list || !ip_list)
2141 return 0;
2143 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2144 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2145 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2146 return 0;
2149 for ( i=0;
2150 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2151 i++ )
2153 struct in_addr addr;
2154 unsigned port = 0;
2155 char *p = strchr(token_str, ':');
2157 if (p) {
2158 *p = 0;
2159 port = atoi(p+1);
2162 /* convert single token to ip address */
2163 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2164 break;
2166 (*ip_list)[i].ip = addr;
2167 (*ip_list)[i].port = port;
2170 return count;
2175 * Safely free ip string list
2177 * @param ipstr_list ip string list to be freed
2180 void ipstr_list_free(char* ipstr_list)
2182 SAFE_FREE(ipstr_list);
2187 Unescape a URL encoded string, in place.
2190 void rfc1738_unescape(char *buf)
2192 char *p=buf;
2194 while (p && *p && (p=strchr_m(p,'%'))) {
2195 int c1 = p[1];
2196 int c2 = p[2];
2198 if (c1 >= '0' && c1 <= '9')
2199 c1 = c1 - '0';
2200 else if (c1 >= 'A' && c1 <= 'F')
2201 c1 = 10 + c1 - 'A';
2202 else if (c1 >= 'a' && c1 <= 'f')
2203 c1 = 10 + c1 - 'a';
2204 else {p++; continue;}
2206 if (c2 >= '0' && c2 <= '9')
2207 c2 = c2 - '0';
2208 else if (c2 >= 'A' && c2 <= 'F')
2209 c2 = 10 + c2 - 'A';
2210 else if (c2 >= 'a' && c2 <= 'f')
2211 c2 = 10 + c2 - 'a';
2212 else {p++; continue;}
2214 *p = (c1<<4) | c2;
2216 memmove(p+1, p+3, strlen(p+3)+1);
2217 p++;
2221 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2224 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2226 DATA_BLOB base64_decode_data_blob(const char *s)
2228 int bit_offset, byte_offset, idx, i, n;
2229 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2230 unsigned char *d = decoded.data;
2231 char *p;
2233 n=i=0;
2235 while (*s && (p=strchr_m(b64,*s))) {
2236 idx = (int)(p - b64);
2237 byte_offset = (i*6)/8;
2238 bit_offset = (i*6)%8;
2239 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2240 if (bit_offset < 3) {
2241 d[byte_offset] |= (idx << (2-bit_offset));
2242 n = byte_offset+1;
2243 } else {
2244 d[byte_offset] |= (idx >> (bit_offset-2));
2245 d[byte_offset+1] = 0;
2246 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2247 n = byte_offset+2;
2249 s++; i++;
2252 if ((n > 0) && (*s == '=')) {
2253 n -= 1;
2256 /* fix up length */
2257 decoded.length = n;
2258 return decoded;
2262 * Decode a base64 string in-place - wrapper for the above
2264 void base64_decode_inplace(char *s)
2266 DATA_BLOB decoded = base64_decode_data_blob(s);
2268 if ( decoded.length != 0 ) {
2269 memcpy(s, decoded.data, decoded.length);
2271 /* null terminate */
2272 s[decoded.length] = '\0';
2273 } else {
2274 *s = '\0';
2277 data_blob_free(&decoded);
2281 * Encode a base64 string into a malloc()ed string caller to free.
2283 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2285 char * base64_encode_data_blob(DATA_BLOB data)
2287 int bits = 0;
2288 int char_count = 0;
2289 size_t out_cnt, len, output_len;
2290 char *result;
2292 if (!data.length || !data.data)
2293 return NULL;
2295 out_cnt = 0;
2296 len = data.length;
2297 output_len = data.length * 2;
2298 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2300 while (len-- && out_cnt < (data.length * 2) - 5) {
2301 int c = (unsigned char) *(data.data++);
2302 bits += c;
2303 char_count++;
2304 if (char_count == 3) {
2305 result[out_cnt++] = b64[bits >> 18];
2306 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2307 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2308 result[out_cnt++] = b64[bits & 0x3f];
2309 bits = 0;
2310 char_count = 0;
2311 } else {
2312 bits <<= 8;
2315 if (char_count != 0) {
2316 bits <<= 16 - (8 * char_count);
2317 result[out_cnt++] = b64[bits >> 18];
2318 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2319 if (char_count == 1) {
2320 result[out_cnt++] = '=';
2321 result[out_cnt++] = '=';
2322 } else {
2323 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2324 result[out_cnt++] = '=';
2327 result[out_cnt] = '\0'; /* terminate */
2328 return result;
2331 /* read a SMB_BIG_UINT from a string */
2332 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2335 SMB_BIG_UINT val = -1;
2336 const char *p = nptr;
2338 if (!p) {
2339 if (entptr) {
2340 *entptr = p;
2342 return val;
2345 while (*p && isspace(*p))
2346 p++;
2348 #ifdef LARGE_SMB_OFF_T
2349 sscanf(p,"%llu",&val);
2350 #else /* LARGE_SMB_OFF_T */
2351 sscanf(p,"%lu",&val);
2352 #endif /* LARGE_SMB_OFF_T */
2353 if (entptr) {
2354 while (*p && isdigit(*p))
2355 p++;
2356 *entptr = p;
2359 return val;
2362 /* Convert a size specification to a count of bytes. We accept the following
2363 * suffixes:
2364 * bytes if there is no suffix
2365 * kK kibibytes
2366 * mM mebibytes
2367 * gG gibibytes
2368 * tT tibibytes
2369 * pP whatever the ISO name for petabytes is
2371 * Returns 0 if the string can't be converted.
2373 SMB_OFF_T conv_str_size(const char * str)
2375 SMB_OFF_T lval;
2376 char * end;
2378 if (str == NULL || *str == '\0') {
2379 return 0;
2382 #ifdef HAVE_STRTOULL
2383 if (sizeof(SMB_OFF_T) == 8) {
2384 lval = strtoull(str, &end, 10 /* base */);
2385 } else {
2386 lval = strtoul(str, &end, 10 /* base */);
2388 #else
2389 lval = strtoul(str, &end, 10 /* base */);
2390 #endif
2392 if (end == NULL || end == str) {
2393 return 0;
2396 if (*end) {
2397 SMB_OFF_T lval_orig = lval;
2399 if (strwicmp(end, "K") == 0) {
2400 lval *= (SMB_OFF_T)1024;
2401 } else if (strwicmp(end, "M") == 0) {
2402 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2403 } else if (strwicmp(end, "G") == 0) {
2404 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2405 (SMB_OFF_T)1024);
2406 } else if (strwicmp(end, "T") == 0) {
2407 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2408 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2409 } else if (strwicmp(end, "P") == 0) {
2410 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2411 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2412 (SMB_OFF_T)1024);
2413 } else {
2414 return 0;
2417 /* Primitive attempt to detect wrapping on platforms with
2418 * 4-byte SMB_OFF_T. It's better to let the caller handle
2419 * a failure than some random number.
2421 if (lval_orig <= lval) {
2422 return 0;
2426 return lval;
2429 void string_append(char **left, const char *right)
2431 int new_len = strlen(right) + 1;
2433 if (*left == NULL) {
2434 *left = (char *)SMB_MALLOC(new_len);
2435 *left[0] = '\0';
2436 } else {
2437 new_len += strlen(*left);
2438 *left = (char *)SMB_REALLOC(*left, new_len);
2441 if (*left == NULL) {
2442 return;
2445 safe_strcat(*left, right, new_len-1);
2448 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2449 const char *str, const char ***strings,
2450 int *num)
2452 char *dup_str = talloc_strdup(mem_ctx, str);
2454 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2456 if ((*strings == NULL) || (dup_str == NULL)) {
2457 *num = 0;
2458 return False;
2461 (*strings)[*num] = dup_str;
2462 *num += 1;
2463 return True;
2466 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2467 * error checking in between. The indiation that something weird happened is
2468 * string==NULL */
2470 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2471 size_t *bufsize, const char *fmt, ...)
2473 va_list ap;
2474 char *newstr;
2475 int ret;
2476 BOOL increased;
2478 /* len<0 is an internal marker that something failed */
2479 if (*len < 0)
2480 goto error;
2482 if (*string == NULL) {
2483 if (*bufsize == 0)
2484 *bufsize = 128;
2486 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2487 if (*string == NULL)
2488 goto error;
2491 va_start(ap, fmt);
2492 ret = vasprintf(&newstr, fmt, ap);
2493 va_end(ap);
2495 if (ret < 0)
2496 goto error;
2498 increased = False;
2500 while ((*len)+ret >= *bufsize) {
2501 increased = True;
2502 *bufsize *= 2;
2503 if (*bufsize >= (1024*1024*256))
2504 goto error;
2507 if (increased) {
2508 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2509 *bufsize);
2510 if (*string == NULL) {
2511 goto error;
2515 StrnCpy((*string)+(*len), newstr, ret);
2516 (*len) += ret;
2517 free(newstr);
2518 return;
2520 error:
2521 *len = -1;
2522 *string = NULL;
2526 Returns the substring from src between the first occurrence of
2527 the char "front" and the first occurence of the char "back".
2528 Mallocs the return string which must be freed. Not for use
2529 with wide character strings.
2531 char *sstring_sub(const char *src, char front, char back)
2533 char *temp1, *temp2, *temp3;
2534 ptrdiff_t len;
2536 temp1 = strchr(src, front);
2537 if (temp1 == NULL) return NULL;
2538 temp2 = strchr(src, back);
2539 if (temp2 == NULL) return NULL;
2540 len = temp2 - temp1;
2541 if (len <= 0) return NULL;
2542 temp3 = (char*)SMB_MALLOC(len);
2543 if (temp3 == NULL) {
2544 DEBUG(1,("Malloc failure in sstring_sub\n"));
2545 return NULL;
2547 memcpy(temp3, temp1+1, len-1);
2548 temp3[len-1] = '\0';
2549 return temp3;
2552 /********************************************************************
2553 Check a string for any occurrences of a specified list of invalid
2554 characters.
2555 ********************************************************************/
2557 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2559 int i;
2561 for ( i=0; i<max_len && name[i]; i++ ) {
2562 /* fail if strchr_m() finds one of the invalid characters */
2563 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2564 return False;
2568 return True;
2573 return the number of bytes occupied by a buffer in ASCII format
2574 the result includes the null termination
2575 limited by 'n' bytes
2577 size_t ascii_len_n(const char *src, size_t n)
2579 size_t len;
2581 len = strnlen(src, n);
2582 if (len+1 <= n) {
2583 len += 1;
2586 return len;
2590 return the number of bytes occupied by a buffer in CH_UTF16 format
2591 the result includes the null termination
2593 size_t utf16_len(const void *buf)
2595 size_t len;
2597 for (len = 0; SVAL(buf,len); len += 2) ;
2599 return len + 2;
2603 return the number of bytes occupied by a buffer in CH_UTF16 format
2604 the result includes the null termination
2605 limited by 'n' bytes
2607 size_t utf16_len_n(const void *src, size_t n)
2609 size_t len;
2611 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2613 if (len+2 <= n) {
2614 len += 2;
2617 return len;
2620 /*******************************************************************
2621 Add a shell escape character '\' to any character not in a known list
2622 of characters. UNIX charset format.
2623 *******************************************************************/
2625 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2626 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2628 char *escape_shell_string(const char *src)
2630 size_t srclen = strlen(src);
2631 char *ret = SMB_MALLOC((srclen * 2) + 1);
2632 char *dest = ret;
2633 BOOL in_s_quote = False;
2634 BOOL in_d_quote = False;
2635 BOOL next_escaped = False;
2637 if (!ret) {
2638 return NULL;
2641 while (*src) {
2642 size_t c_size;
2643 codepoint_t c = next_codepoint(src, &c_size);
2645 if (c == INVALID_CODEPOINT) {
2646 SAFE_FREE(ret);
2647 return NULL;
2650 if (c_size > 1) {
2651 memcpy(dest, src, c_size);
2652 src += c_size;
2653 dest += c_size;
2654 next_escaped = False;
2655 continue;
2659 * Deal with backslash escaped state.
2660 * This only lasts for one character.
2663 if (next_escaped) {
2664 *dest++ = *src++;
2665 next_escaped = False;
2666 continue;
2670 * Deal with single quote state. The
2671 * only thing we care about is exiting
2672 * this state.
2675 if (in_s_quote) {
2676 if (*src == '\'') {
2677 in_s_quote = False;
2679 *dest++ = *src++;
2680 continue;
2684 * Deal with double quote state. The most
2685 * complex state. We must cope with \, meaning
2686 * possibly escape next char (depending what it
2687 * is), ", meaning exit this state, and possibly
2688 * add an \ escape to any unprotected character
2689 * (listed in INSIDE_DQUOTE_LIST).
2692 if (in_d_quote) {
2693 if (*src == '\\') {
2695 * Next character might be escaped.
2696 * We have to peek. Inside double
2697 * quotes only INSIDE_DQUOTE_LIST
2698 * characters are escaped by a \.
2701 char nextchar;
2703 c = next_codepoint(&src[1], &c_size);
2704 if (c == INVALID_CODEPOINT) {
2705 SAFE_FREE(ret);
2706 return NULL;
2708 if (c_size > 1) {
2710 * Don't escape the next char.
2711 * Just copy the \.
2713 *dest++ = *src++;
2714 continue;
2717 nextchar = src[1];
2719 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2720 next_escaped = True;
2722 *dest++ = *src++;
2723 continue;
2726 if (*src == '\"') {
2727 /* Exit double quote state. */
2728 in_d_quote = False;
2729 *dest++ = *src++;
2730 continue;
2734 * We know the character isn't \ or ",
2735 * so escape it if it's any of the other
2736 * possible unprotected characters.
2739 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2740 *dest++ = '\\';
2742 *dest++ = *src++;
2743 continue;
2747 * From here to the end of the loop we're
2748 * not in the single or double quote state.
2751 if (*src == '\\') {
2752 /* Next character must be escaped. */
2753 next_escaped = True;
2754 *dest++ = *src++;
2755 continue;
2758 if (*src == '\'') {
2759 /* Go into single quote state. */
2760 in_s_quote = True;
2761 *dest++ = *src++;
2762 continue;
2765 if (*src == '\"') {
2766 /* Go into double quote state. */
2767 in_d_quote = True;
2768 *dest++ = *src++;
2769 continue;
2772 /* Check if we need to escape the character. */
2774 if (!strchr(INCLUDE_LIST, (int)*src)) {
2775 *dest++ = '\\';
2777 *dest++ = *src++;
2779 *dest++ = '\0';
2780 return ret;