dnscrypto-proxy: Support files updated.
[tomato.git] / release / src / router / samba3 / source / lib / util_str.c
blobc4d67c6b7c925a70e2cd21af19b0cc647692b7df
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
398 String replace.
399 NOTE: oldc and newc must be 7 bit characters
401 void string_replace( char *s, char oldc, char newc )
403 char *p;
405 /* this is quite a common operation, so we want it to be
406 fast. We optimise for the ascii case, knowing that all our
407 supported multi-byte character sets are ascii-compatible
408 (ie. they match for the first 128 chars) */
410 for (p = s; *p; p++) {
411 if (*p & 0x80) /* mb string - slow path. */
412 break;
413 if (*p == oldc) {
414 *p = newc;
418 if (!*p)
419 return;
421 /* Slow (mb) path. */
422 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
423 /* With compose characters we must restart from the beginning. JRA. */
424 p = s;
425 #endif
427 while (*p) {
428 size_t c_size;
429 next_codepoint(p, &c_size);
431 if (c_size == 1) {
432 if (*p == oldc) {
433 *p = newc;
436 p += c_size;
441 * Skip past some strings in a buffer - old version - no checks.
442 * **/
444 char *push_skip_string(char *buf)
446 buf += strlen(buf) + 1;
447 return(buf);
451 Skip past a string in a buffer. Buffer may not be
452 null terminated. end_ptr points to the first byte after
453 then end of the buffer.
456 char *skip_string(const char *base, size_t len, char *buf)
458 const char *end_ptr = base + len;
460 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
461 return NULL;
464 /* Skip the string */
465 while (*buf) {
466 buf++;
467 if (buf >= end_ptr) {
468 return NULL;
471 /* Skip the '\0' */
472 buf++;
473 return buf;
477 Count the number of characters in a string. Normally this will
478 be the same as the number of bytes in a string for single byte strings,
479 but will be different for multibyte.
482 size_t str_charnum(const char *s)
484 uint16 tmpbuf2[sizeof(pstring)];
485 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
486 return strlen_w(tmpbuf2);
490 Count the number of characters in a string. Normally this will
491 be the same as the number of bytes in a string for single byte strings,
492 but will be different for multibyte.
495 size_t str_ascii_charnum(const char *s)
497 pstring tmpbuf2;
498 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
499 return strlen(tmpbuf2);
502 BOOL trim_char(char *s,char cfront,char cback)
504 BOOL ret = False;
505 char *ep;
506 char *fp = s;
508 /* Ignore null or empty strings. */
509 if (!s || (s[0] == '\0'))
510 return False;
512 if (cfront) {
513 while (*fp && *fp == cfront)
514 fp++;
515 if (!*fp) {
516 /* We ate the string. */
517 s[0] = '\0';
518 return True;
520 if (fp != s)
521 ret = True;
524 ep = fp + strlen(fp) - 1;
525 if (cback) {
526 /* Attempt ascii only. Bail for mb strings. */
527 while ((ep >= fp) && (*ep == cback)) {
528 ret = True;
529 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
530 /* Could be mb... bail back to tim_string. */
531 char fs[2], bs[2];
532 if (cfront) {
533 fs[0] = cfront;
534 fs[1] = '\0';
536 bs[0] = cback;
537 bs[1] = '\0';
538 return trim_string(s, cfront ? fs : NULL, bs);
539 } else {
540 ep--;
543 if (ep < fp) {
544 /* We ate the string. */
545 s[0] = '\0';
546 return True;
550 ep[1] = '\0';
551 memmove(s, fp, ep-fp+2);
552 return ret;
556 Trim the specified elements off the front and back of a string.
559 BOOL trim_string(char *s,const char *front,const char *back)
561 BOOL ret = False;
562 size_t front_len;
563 size_t back_len;
564 size_t len;
566 /* Ignore null or empty strings. */
567 if (!s || (s[0] == '\0'))
568 return False;
570 front_len = front? strlen(front) : 0;
571 back_len = back? strlen(back) : 0;
573 len = strlen(s);
575 if (front_len) {
576 while (len && strncmp(s, front, front_len)==0) {
577 /* Must use memmove here as src & dest can
578 * easily overlap. Found by valgrind. JRA. */
579 memmove(s, s+front_len, (len-front_len)+1);
580 len -= front_len;
581 ret=True;
585 if (back_len) {
586 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
587 s[len-back_len]='\0';
588 len -= back_len;
589 ret=True;
592 return ret;
596 Does a string have any uppercase chars in it?
599 BOOL strhasupper(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(isupper_w(*ptr))
605 return True;
606 return(False);
610 Does a string have any lowercase chars in it?
613 BOOL strhaslower(const char *s)
615 smb_ucs2_t *ptr;
616 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
617 for(ptr=tmpbuf;*ptr;ptr++)
618 if(islower_w(*ptr))
619 return True;
620 return(False);
624 Find the number of 'c' chars in a string
627 size_t count_chars(const char *s,char c)
629 smb_ucs2_t *ptr;
630 int count;
631 smb_ucs2_t *alloc_tmpbuf = NULL;
633 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
634 return 0;
637 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
638 if(*ptr==UCS2_CHAR(c))
639 count++;
641 SAFE_FREE(alloc_tmpbuf);
642 return(count);
646 Safe string copy into a known length string. maxlength does not
647 include the terminating zero.
650 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
652 size_t len;
654 if (!dest) {
655 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
656 return NULL;
659 #ifdef DEVELOPER
660 clobber_region(fn,line,dest, maxlength+1);
661 #endif
663 if (!src) {
664 *dest = 0;
665 return dest;
668 len = strnlen(src, maxlength+1);
670 if (len > maxlength) {
671 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
672 (unsigned long)(len-maxlength), (unsigned long)len,
673 (unsigned long)maxlength, src));
674 len = maxlength;
677 memmove(dest, src, len);
678 dest[len] = 0;
679 return dest;
683 Safe string cat into a string. maxlength does not
684 include the terminating zero.
686 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
688 size_t src_len, dest_len;
690 if (!dest) {
691 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
692 return NULL;
695 if (!src)
696 return dest;
698 src_len = strnlen(src, maxlength + 1);
699 dest_len = strnlen(dest, maxlength + 1);
701 #ifdef DEVELOPER
702 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
703 #endif
705 if (src_len + dest_len > maxlength) {
706 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
707 (int)(src_len + dest_len - maxlength), src));
708 if (maxlength > dest_len) {
709 memcpy(&dest[dest_len], src, maxlength - dest_len);
711 dest[maxlength] = 0;
712 return NULL;
715 memcpy(&dest[dest_len], src, src_len);
716 dest[dest_len + src_len] = 0;
717 return dest;
721 Paranoid strcpy into a buffer of given length (includes terminating
722 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
723 and replaces with '_'. Deliberately does *NOT* check for multibyte
724 characters. Don't change it !
726 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
728 size_t len, i;
730 #ifdef DEVELOPER
731 clobber_region(fn, line, dest, maxlength);
732 #endif
734 if (!dest) {
735 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
736 return NULL;
739 if (!src) {
740 *dest = 0;
741 return dest;
744 len = strlen(src);
745 if (len >= maxlength)
746 len = maxlength - 1;
748 if (!other_safe_chars)
749 other_safe_chars = "";
751 for(i = 0; i < len; i++) {
752 int val = (src[i] & 0xff);
753 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
754 dest[i] = src[i];
755 else
756 dest[i] = '_';
759 dest[i] = '\0';
761 return dest;
765 Like strncpy but always null terminates. Make sure there is room!
766 The variable n should always be one less than the available size.
768 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
770 char *d = dest;
772 #ifdef DEVELOPER
773 clobber_region(fn, line, dest, n+1);
774 #endif
776 if (!dest) {
777 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
778 return(NULL);
781 if (!src) {
782 *dest = 0;
783 return(dest);
786 while (n-- && (*d = *src)) {
787 d++;
788 src++;
791 *d = 0;
792 return(dest);
795 #if 0
797 Like strncpy but copies up to the character marker. always null terminates.
798 returns a pointer to the character marker in the source string (src).
801 static char *strncpyn(char *dest, const char *src, size_t n, char c)
803 char *p;
804 size_t str_len;
806 #ifdef DEVELOPER
807 clobber_region(dest, n+1);
808 #endif
809 p = strchr_m(src, c);
810 if (p == NULL) {
811 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
812 return NULL;
815 str_len = PTR_DIFF(p, src);
816 strncpy(dest, src, MIN(n, str_len));
817 dest[str_len] = '\0';
819 return p;
821 #endif
824 Routine to get hex characters and turn them into a 16 byte array.
825 the array can be variable length, and any non-hex-numeric
826 characters are skipped. "0xnn" or "0Xnn" is specially catered
827 for.
829 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
833 size_t strhex_to_str(char *p, size_t len, const char *strhex)
835 size_t i;
836 size_t num_chars = 0;
837 unsigned char lonybble, hinybble;
838 const char *hexchars = "0123456789ABCDEF";
839 char *p1 = NULL, *p2 = NULL;
841 for (i = 0; i < len && strhex[i] != 0; i++) {
842 if (strnequal(hexchars, "0x", 2)) {
843 i++; /* skip two chars */
844 continue;
847 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
848 break;
850 i++; /* next hex digit */
852 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
853 break;
855 /* get the two nybbles */
856 hinybble = PTR_DIFF(p1, hexchars);
857 lonybble = PTR_DIFF(p2, hexchars);
859 p[num_chars] = (hinybble << 4) | lonybble;
860 num_chars++;
862 p1 = NULL;
863 p2 = NULL;
865 return num_chars;
868 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
870 DATA_BLOB ret_blob;
872 if (mem_ctx != NULL)
873 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
874 else
875 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
877 ret_blob.length = strhex_to_str((char*)ret_blob.data,
878 strlen(strhex),
879 strhex);
881 return ret_blob;
885 * Routine to print a buffer as HEX digits, into an allocated string.
888 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
890 int i;
891 char *hex_buffer;
893 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
895 for (i = 0; i < len; i++)
896 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
898 return hex_buffer;
902 Check if a string is part of a list.
905 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
907 pstring tok;
908 const char *p=list;
910 if (!list)
911 return(False);
913 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
914 if (casesensitive) {
915 if (strcmp(tok,s) == 0)
916 return(True);
917 } else {
918 if (StrCaseCmp(tok,s) == 0)
919 return(True);
922 return(False);
925 /* this is used to prevent lots of mallocs of size 1 */
926 static const char *null_string = "";
929 Set a string value, allocing the space for the string
932 static BOOL string_init(char **dest,const char *src)
934 size_t l;
936 if (!src)
937 src = "";
939 l = strlen(src);
941 if (l == 0) {
942 *dest = CONST_DISCARD(char*, null_string);
943 } else {
944 (*dest) = SMB_STRDUP(src);
945 if ((*dest) == NULL) {
946 DEBUG(0,("Out of memory in string_init\n"));
947 return False;
950 return(True);
954 Free a string value.
957 void string_free(char **s)
959 if (!s || !(*s))
960 return;
961 if (*s == null_string)
962 *s = NULL;
963 SAFE_FREE(*s);
967 Set a string value, deallocating any existing space, and allocing the space
968 for the string
971 BOOL string_set(char **dest,const char *src)
973 string_free(dest);
974 return(string_init(dest,src));
978 Substitute a string for a pattern in another string. Make sure there is
979 enough room!
981 This routine looks for pattern in s and replaces it with
982 insert. It may do multiple replacements or just one.
984 Any of " ; ' $ or ` in the insert string are replaced with _
985 if len==0 then the string cannot be extended. This is different from the old
986 use of len==0 which was for no length checks to be done.
989 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
990 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
992 char *p;
993 ssize_t ls,lp,li, i;
995 if (!insert || !pattern || !*pattern || !s)
996 return;
998 ls = (ssize_t)strlen(s);
999 lp = (ssize_t)strlen(pattern);
1000 li = (ssize_t)strlen(insert);
1002 if (len == 0)
1003 len = ls + 1; /* len is number of *bytes* */
1005 while (lp <= ls && (p = strstr_m(s,pattern))) {
1006 if (ls + (li-lp) >= len) {
1007 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1008 (int)(ls + (li-lp) - len),
1009 pattern, (int)len));
1010 break;
1012 if (li != lp) {
1013 memmove(p+li,p+lp,strlen(p+lp)+1);
1015 for (i=0;i<li;i++) {
1016 switch (insert[i]) {
1017 case '`':
1018 case '"':
1019 case '\'':
1020 case ';':
1021 case '$':
1022 /* allow a trailing $ (as in machine accounts) */
1023 if (allow_trailing_dollar && (i == li - 1 )) {
1024 p[i] = insert[i];
1025 break;
1027 case '%':
1028 case '\r':
1029 case '\n':
1030 if ( remove_unsafe_characters ) {
1031 p[i] = '_';
1032 /* yes this break should be here since we want to
1033 fall throw if not replacing unsafe chars */
1034 break;
1036 default:
1037 p[i] = insert[i];
1040 s = p + li;
1041 ls += (li-lp);
1043 if (replace_once)
1044 break;
1048 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1050 string_sub2( s, pattern, insert, len, True, True, False );
1053 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1055 string_sub2( s, pattern, insert, len, True, False, False );
1058 void fstring_sub(char *s,const char *pattern,const char *insert)
1060 string_sub(s, pattern, insert, sizeof(fstring));
1063 void pstring_sub(char *s,const char *pattern,const char *insert)
1065 string_sub(s, pattern, insert, sizeof(pstring));
1069 Similar to string_sub, but it will accept only allocated strings
1070 and may realloc them so pay attention at what you pass on no
1071 pointers inside strings, no pstrings or const may be passed
1072 as string.
1075 char *realloc_string_sub(char *string, const char *pattern,
1076 const char *insert)
1078 char *p, *in;
1079 char *s;
1080 ssize_t ls,lp,li,ld, i;
1082 if (!insert || !pattern || !*pattern || !string || !*string)
1083 return NULL;
1085 s = string;
1087 in = SMB_STRDUP(insert);
1088 if (!in) {
1089 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1090 return NULL;
1092 ls = (ssize_t)strlen(s);
1093 lp = (ssize_t)strlen(pattern);
1094 li = (ssize_t)strlen(insert);
1095 ld = li - lp;
1096 for (i=0;i<li;i++) {
1097 switch (in[i]) {
1098 case '`':
1099 case '"':
1100 case '\'':
1101 case ';':
1102 case '$':
1103 case '%':
1104 case '\r':
1105 case '\n':
1106 in[i] = '_';
1107 default:
1108 /* ok */
1109 break;
1113 while ((p = strstr_m(s,pattern))) {
1114 if (ld > 0) {
1115 int offset = PTR_DIFF(s,string);
1116 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1117 if (!string) {
1118 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1119 SAFE_FREE(in);
1120 return NULL;
1122 p = string + offset + (p - s);
1124 if (li != lp) {
1125 memmove(p+li,p+lp,strlen(p+lp)+1);
1127 memcpy(p, in, li);
1128 s = p + li;
1129 ls += ld;
1131 SAFE_FREE(in);
1132 return string;
1135 /* Same as string_sub, but returns a talloc'ed string */
1137 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1138 const char *pattern, const char *insert)
1140 char *p, *in;
1141 char *s;
1142 char *string;
1143 ssize_t ls,lp,li,ld, i;
1145 if (!insert || !pattern || !*pattern || !src || !*src)
1146 return NULL;
1148 string = talloc_strdup(mem_ctx, src);
1149 if (string == NULL) {
1150 DEBUG(0, ("talloc_strdup failed\n"));
1151 return NULL;
1154 s = string;
1156 in = SMB_STRDUP(insert);
1157 if (!in) {
1158 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1159 return NULL;
1161 ls = (ssize_t)strlen(s);
1162 lp = (ssize_t)strlen(pattern);
1163 li = (ssize_t)strlen(insert);
1164 ld = li - lp;
1165 for (i=0;i<li;i++) {
1166 switch (in[i]) {
1167 case '`':
1168 case '"':
1169 case '\'':
1170 case ';':
1171 case '$':
1172 case '%':
1173 case '\r':
1174 case '\n':
1175 in[i] = '_';
1176 default:
1177 /* ok */
1178 break;
1182 while ((p = strstr_m(s,pattern))) {
1183 if (ld > 0) {
1184 int offset = PTR_DIFF(s,string);
1185 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1186 ls + ld + 1);
1187 if (!string) {
1188 DEBUG(0, ("talloc_string_sub: out of "
1189 "memory!\n"));
1190 SAFE_FREE(in);
1191 return NULL;
1193 p = string + offset + (p - s);
1195 if (li != lp) {
1196 memmove(p+li,p+lp,strlen(p+lp)+1);
1198 memcpy(p, in, li);
1199 s = p + li;
1200 ls += ld;
1202 SAFE_FREE(in);
1203 return string;
1207 Similar to string_sub() but allows for any character to be substituted.
1208 Use with caution!
1209 if len==0 then the string cannot be extended. This is different from the old
1210 use of len==0 which was for no length checks to be done.
1213 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1215 char *p;
1216 ssize_t ls,lp,li;
1218 if (!insert || !pattern || !s)
1219 return;
1221 ls = (ssize_t)strlen(s);
1222 lp = (ssize_t)strlen(pattern);
1223 li = (ssize_t)strlen(insert);
1225 if (!*pattern)
1226 return;
1228 if (len == 0)
1229 len = ls + 1; /* len is number of *bytes* */
1231 while (lp <= ls && (p = strstr_m(s,pattern))) {
1232 if (ls + (li-lp) >= len) {
1233 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1234 (int)(ls + (li-lp) - len),
1235 pattern, (int)len));
1236 break;
1238 if (li != lp) {
1239 memmove(p+li,p+lp,strlen(p+lp)+1);
1241 memcpy(p, insert, li);
1242 s = p + li;
1243 ls += (li-lp);
1248 Similar to all_string_sub but for unicode strings.
1249 Return a new allocated unicode string.
1250 similar to string_sub() but allows for any character to be substituted.
1251 Use with caution!
1254 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1255 const smb_ucs2_t *insert)
1257 smb_ucs2_t *r, *rp;
1258 const smb_ucs2_t *sp;
1259 size_t lr, lp, li, lt;
1261 if (!insert || !pattern || !*pattern || !s)
1262 return NULL;
1264 lt = (size_t)strlen_w(s);
1265 lp = (size_t)strlen_w(pattern);
1266 li = (size_t)strlen_w(insert);
1268 if (li > lp) {
1269 const smb_ucs2_t *st = s;
1270 int ld = li - lp;
1271 while ((sp = strstr_w(st, pattern))) {
1272 st = sp + lp;
1273 lt += ld;
1277 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1278 if (!r) {
1279 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1280 return NULL;
1283 while ((sp = strstr_w(s, pattern))) {
1284 memcpy(rp, s, (sp - s));
1285 rp += ((sp - s) / sizeof(smb_ucs2_t));
1286 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1287 s = sp + lp;
1288 rp += li;
1290 lr = ((rp - r) / sizeof(smb_ucs2_t));
1291 if (lr < lt) {
1292 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1293 rp += (lt - lr);
1295 *rp = 0;
1297 return r;
1300 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1301 const char *insert)
1303 wpstring p, i;
1305 if (!insert || !pattern || !s)
1306 return NULL;
1307 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1308 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1309 return all_string_sub_w(s, p, i);
1312 #if 0
1314 Splits out the front and back at a separator.
1317 static void split_at_last_component(char *path, char *front, char sep, char *back)
1319 char *p = strrchr_m(path, sep);
1321 if (p != NULL)
1322 *p = 0;
1324 if (front != NULL)
1325 pstrcpy(front, path);
1327 if (p != NULL) {
1328 if (back != NULL)
1329 pstrcpy(back, p+1);
1330 *p = '\\';
1331 } else {
1332 if (back != NULL)
1333 back[0] = 0;
1336 #endif
1339 Write an octal as a string.
1342 const char *octal_string(int i)
1344 static char ret[64];
1345 if (i == -1)
1346 return "-1";
1347 slprintf(ret, sizeof(ret)-1, "0%o", i);
1348 return ret;
1353 Truncate a string at a specified length.
1356 char *string_truncate(char *s, unsigned int length)
1358 if (s && strlen(s) > length)
1359 s[length] = 0;
1360 return s;
1364 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1365 We convert via ucs2 for now.
1368 char *strchr_m(const char *src, char c)
1370 wpstring ws;
1371 pstring s2;
1372 smb_ucs2_t *p;
1373 const char *s;
1375 /* characters below 0x3F are guaranteed to not appear in
1376 non-initial position in multi-byte charsets */
1377 if ((c & 0xC0) == 0) {
1378 return strchr(src, c);
1381 /* this is quite a common operation, so we want it to be
1382 fast. We optimise for the ascii case, knowing that all our
1383 supported multi-byte character sets are ascii-compatible
1384 (ie. they match for the first 128 chars) */
1386 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1387 if (*s == c)
1388 return (char *)s;
1391 if (!*s)
1392 return NULL;
1394 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1395 /* With compose characters we must restart from the beginning. JRA. */
1396 s = src;
1397 #endif
1399 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1400 p = strchr_w(ws, UCS2_CHAR(c));
1401 if (!p)
1402 return NULL;
1403 *p = 0;
1404 pull_ucs2_pstring(s2, ws);
1405 return (char *)(s+strlen(s2));
1408 char *strrchr_m(const char *s, char c)
1410 /* characters below 0x3F are guaranteed to not appear in
1411 non-initial position in multi-byte charsets */
1412 if ((c & 0xC0) == 0) {
1413 return strrchr(s, c);
1416 /* this is quite a common operation, so we want it to be
1417 fast. We optimise for the ascii case, knowing that all our
1418 supported multi-byte character sets are ascii-compatible
1419 (ie. they match for the first 128 chars). Also, in Samba
1420 we only search for ascii characters in 'c' and that
1421 in all mb character sets with a compound character
1422 containing c, if 'c' is not a match at position
1423 p, then p[-1] > 0x7f. JRA. */
1426 size_t len = strlen(s);
1427 const char *cp = s;
1428 BOOL got_mb = False;
1430 if (len == 0)
1431 return NULL;
1432 cp += (len - 1);
1433 do {
1434 if (c == *cp) {
1435 /* Could be a match. Part of a multibyte ? */
1436 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1437 /* Yep - go slow :-( */
1438 got_mb = True;
1439 break;
1441 /* No - we have a match ! */
1442 return (char *)cp;
1444 } while (cp-- != s);
1445 if (!got_mb)
1446 return NULL;
1449 /* String contained a non-ascii char. Slow path. */
1451 wpstring ws;
1452 pstring s2;
1453 smb_ucs2_t *p;
1455 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1456 p = strrchr_w(ws, UCS2_CHAR(c));
1457 if (!p)
1458 return NULL;
1459 *p = 0;
1460 pull_ucs2_pstring(s2, ws);
1461 return (char *)(s+strlen(s2));
1465 /***********************************************************************
1466 Return the equivalent of doing strrchr 'n' times - always going
1467 backwards.
1468 ***********************************************************************/
1470 char *strnrchr_m(const char *s, char c, unsigned int n)
1472 wpstring ws;
1473 pstring s2;
1474 smb_ucs2_t *p;
1476 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1477 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1478 if (!p)
1479 return NULL;
1480 *p = 0;
1481 pull_ucs2_pstring(s2, ws);
1482 return (char *)(s+strlen(s2));
1485 /***********************************************************************
1486 strstr_m - We convert via ucs2 for now.
1487 ***********************************************************************/
1489 char *strstr_m(const char *src, const char *findstr)
1491 smb_ucs2_t *p;
1492 smb_ucs2_t *src_w, *find_w;
1493 const char *s;
1494 char *s2;
1495 char *retp;
1497 size_t findstr_len = 0;
1499 /* for correctness */
1500 if (!findstr[0]) {
1501 return (char*)src;
1504 /* Samba does single character findstr calls a *lot*. */
1505 if (findstr[1] == '\0')
1506 return strchr_m(src, *findstr);
1508 /* We optimise for the ascii case, knowing that all our
1509 supported multi-byte character sets are ascii-compatible
1510 (ie. they match for the first 128 chars) */
1512 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1513 if (*s == *findstr) {
1514 if (!findstr_len)
1515 findstr_len = strlen(findstr);
1517 if (strncmp(s, findstr, findstr_len) == 0) {
1518 return (char *)s;
1523 if (!*s)
1524 return NULL;
1526 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1527 /* 'make check' fails unless we do this */
1529 /* With compose characters we must restart from the beginning. JRA. */
1530 s = src;
1531 #endif
1533 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1534 DEBUG(0,("strstr_m: src malloc fail\n"));
1535 return NULL;
1538 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1539 SAFE_FREE(src_w);
1540 DEBUG(0,("strstr_m: find malloc fail\n"));
1541 return NULL;
1544 p = strstr_w(src_w, find_w);
1546 if (!p) {
1547 SAFE_FREE(src_w);
1548 SAFE_FREE(find_w);
1549 return NULL;
1552 *p = 0;
1553 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1554 SAFE_FREE(src_w);
1555 SAFE_FREE(find_w);
1556 DEBUG(0,("strstr_m: dest malloc fail\n"));
1557 return NULL;
1559 retp = (char *)(s+strlen(s2));
1560 SAFE_FREE(src_w);
1561 SAFE_FREE(find_w);
1562 SAFE_FREE(s2);
1563 return retp;
1567 Convert a string to lower case.
1570 void strlower_m(char *s)
1572 size_t len;
1573 int errno_save;
1575 /* this is quite a common operation, so we want it to be
1576 fast. We optimise for the ascii case, knowing that all our
1577 supported multi-byte character sets are ascii-compatible
1578 (ie. they match for the first 128 chars) */
1580 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1581 *s = tolower_ascii((unsigned char)*s);
1582 s++;
1585 if (!*s)
1586 return;
1588 /* I assume that lowercased string takes the same number of bytes
1589 * as source string even in UTF-8 encoding. (VIV) */
1590 len = strlen(s) + 1;
1591 errno_save = errno;
1592 errno = 0;
1593 unix_strlower(s,len,s,len);
1594 /* Catch mb conversion errors that may not terminate. */
1595 if (errno)
1596 s[len-1] = '\0';
1597 errno = errno_save;
1601 Convert a string to upper case.
1604 void strupper_m(char *s)
1606 size_t len;
1607 int errno_save;
1609 /* this is quite a common operation, so we want it to be
1610 fast. We optimise for the ascii case, knowing that all our
1611 supported multi-byte character sets are ascii-compatible
1612 (ie. they match for the first 128 chars) */
1614 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1615 *s = toupper_ascii((unsigned char)*s);
1616 s++;
1619 if (!*s)
1620 return;
1622 /* I assume that lowercased string takes the same number of bytes
1623 * as source string even in multibyte encoding. (VIV) */
1624 len = strlen(s) + 1;
1625 errno_save = errno;
1626 errno = 0;
1627 unix_strupper(s,len,s,len);
1628 /* Catch mb conversion errors that may not terminate. */
1629 if (errno)
1630 s[len-1] = '\0';
1631 errno = errno_save;
1635 Count the number of UCS2 characters in a string. Normally this will
1636 be the same as the number of bytes in a string for single byte strings,
1637 but will be different for multibyte.
1640 size_t strlen_m(const char *s)
1642 size_t count = 0;
1644 if (!s) {
1645 return 0;
1648 while (*s && !(((uint8_t)*s) & 0x80)) {
1649 s++;
1650 count++;
1653 if (!*s) {
1654 return count;
1657 while (*s) {
1658 size_t c_size;
1659 codepoint_t c = next_codepoint(s, &c_size);
1660 if (c < 0x10000) {
1661 /* Unicode char fits into 16 bits. */
1662 count += 1;
1663 } else {
1664 /* Double-width unicode char - 32 bits. */
1665 count += 2;
1667 s += c_size;
1670 return count;
1674 Count the number of UCS2 characters in a string including the null
1675 terminator.
1678 size_t strlen_m_term(const char *s)
1680 if (!s) {
1681 return 0;
1683 return strlen_m(s) + 1;
1687 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1688 * if a string is there, include the terminator.
1691 size_t strlen_m_term_null(const char *s)
1693 size_t len;
1694 if (!s) {
1695 return 0;
1697 len = strlen_m(s);
1698 if (len == 0) {
1699 return 0;
1702 return len+1;
1705 Return a RFC2254 binary string representation of a buffer.
1706 Used in LDAP filters.
1707 Caller must free.
1710 char *binary_string_rfc2254(char *buf, int len)
1712 char *s;
1713 int i, j;
1714 const char *hex = "0123456789ABCDEF";
1715 s = (char *)SMB_MALLOC(len * 3 + 1);
1716 if (!s)
1717 return NULL;
1718 for (j=i=0;i<len;i++) {
1719 s[j] = '\\';
1720 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1721 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1722 j += 3;
1724 s[j] = 0;
1725 return s;
1728 char *binary_string(char *buf, int len)
1730 char *s;
1731 int i, j;
1732 const char *hex = "0123456789ABCDEF";
1733 s = (char *)SMB_MALLOC(len * 2 + 1);
1734 if (!s)
1735 return NULL;
1736 for (j=i=0;i<len;i++) {
1737 s[j] = hex[((unsigned char)buf[i]) >> 4];
1738 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1739 j += 2;
1741 s[j] = 0;
1742 return s;
1745 Just a typesafety wrapper for snprintf into a pstring.
1748 int pstr_sprintf(pstring s, const char *fmt, ...)
1750 va_list ap;
1751 int ret;
1753 va_start(ap, fmt);
1754 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1755 va_end(ap);
1756 return ret;
1761 Just a typesafety wrapper for snprintf into a fstring.
1764 int fstr_sprintf(fstring s, const char *fmt, ...)
1766 va_list ap;
1767 int ret;
1769 va_start(ap, fmt);
1770 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1771 va_end(ap);
1772 return ret;
1776 List of Strings manipulation functions
1779 #define S_LIST_ABS 16 /* List Allocation Block Size */
1781 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1783 char **list, **rlist;
1784 const char *str;
1785 char *s;
1786 int num, lsize;
1787 pstring tok;
1789 if (!string || !*string)
1790 return NULL;
1791 if (mem_ctx) {
1792 s = talloc_strdup(mem_ctx, string);
1793 } else {
1794 s = SMB_STRDUP(string);
1796 if (!s) {
1797 DEBUG(0,("str_list_make: Unable to allocate memory"));
1798 return NULL;
1800 if (!sep) sep = LIST_SEP;
1802 num = lsize = 0;
1803 list = NULL;
1805 str = s;
1806 while (next_token(&str, tok, sep, sizeof(tok))) {
1807 if (num == lsize) {
1808 lsize += S_LIST_ABS;
1809 if (mem_ctx) {
1810 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1811 } else {
1812 /* We need to keep the old list on error so we can free the elements
1813 if the realloc fails. */
1814 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1816 if (!rlist) {
1817 DEBUG(0,("str_list_make: Unable to allocate memory"));
1818 str_list_free(&list);
1819 if (mem_ctx) {
1820 TALLOC_FREE(s);
1821 } else {
1822 SAFE_FREE(s);
1824 return NULL;
1825 } else {
1826 list = rlist;
1828 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1831 if (mem_ctx) {
1832 list[num] = talloc_strdup(mem_ctx, tok);
1833 } else {
1834 list[num] = SMB_STRDUP(tok);
1837 if (!list[num]) {
1838 DEBUG(0,("str_list_make: Unable to allocate memory"));
1839 str_list_free(&list);
1840 if (mem_ctx) {
1841 TALLOC_FREE(s);
1842 } else {
1843 SAFE_FREE(s);
1845 return NULL;
1848 num++;
1851 if (mem_ctx) {
1852 TALLOC_FREE(s);
1853 } else {
1854 SAFE_FREE(s);
1857 return list;
1860 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1862 return str_list_make_internal(mem_ctx, string, sep);
1865 char **str_list_make(const char *string, const char *sep)
1867 return str_list_make_internal(NULL, string, sep);
1870 BOOL str_list_copy(char ***dest, const char **src)
1872 char **list, **rlist;
1873 int num, lsize;
1875 *dest = NULL;
1876 if (!src)
1877 return False;
1879 num = lsize = 0;
1880 list = NULL;
1882 while (src[num]) {
1883 if (num == lsize) {
1884 lsize += S_LIST_ABS;
1885 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1886 if (!rlist) {
1887 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1888 str_list_free(&list);
1889 return False;
1890 } else {
1891 list = rlist;
1893 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1896 list[num] = SMB_STRDUP(src[num]);
1897 if (!list[num]) {
1898 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1899 str_list_free(&list);
1900 return False;
1903 num++;
1906 *dest = list;
1907 return True;
1911 * Return true if all the elements of the list match exactly.
1913 BOOL str_list_compare(char **list1, char **list2)
1915 int num;
1917 if (!list1 || !list2)
1918 return (list1 == list2);
1920 for (num = 0; list1[num]; num++) {
1921 if (!list2[num])
1922 return False;
1923 if (!strcsequal(list1[num], list2[num]))
1924 return False;
1926 if (list2[num])
1927 return False; /* if list2 has more elements than list1 fail */
1929 return True;
1932 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1934 char **tlist;
1936 if (!list || !*list)
1937 return;
1938 tlist = *list;
1939 for(; *tlist; tlist++) {
1940 if (mem_ctx) {
1941 TALLOC_FREE(*tlist);
1942 } else {
1943 SAFE_FREE(*tlist);
1946 if (mem_ctx) {
1947 TALLOC_FREE(*tlist);
1948 } else {
1949 SAFE_FREE(*list);
1953 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1955 str_list_free_internal(mem_ctx, list);
1958 void str_list_free(char ***list)
1960 str_list_free_internal(NULL, list);
1963 /******************************************************************************
1964 *****************************************************************************/
1966 int str_list_count( const char **list )
1968 int i = 0;
1970 if ( ! list )
1971 return 0;
1973 /* count the number of list members */
1975 for ( i=0; *list; i++, list++ );
1977 return i;
1980 /******************************************************************************
1981 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1982 for the work
1983 *****************************************************************************/
1985 BOOL str_list_sub_basic( char **list, const char *smb_name,
1986 const char *domain_name )
1988 char *s, *tmpstr;
1990 while ( *list ) {
1991 s = *list;
1992 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
1993 if ( !tmpstr ) {
1994 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1995 return False;
1998 SAFE_FREE(*list);
1999 *list = tmpstr;
2001 list++;
2004 return True;
2007 /******************************************************************************
2008 substritute a specific pattern in a string list
2009 *****************************************************************************/
2011 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2013 char *p, *s, *t;
2014 ssize_t ls, lp, li, ld, i, d;
2016 if (!list)
2017 return False;
2018 if (!pattern)
2019 return False;
2020 if (!insert)
2021 return False;
2023 lp = (ssize_t)strlen(pattern);
2024 li = (ssize_t)strlen(insert);
2025 ld = li -lp;
2027 while (*list) {
2028 s = *list;
2029 ls = (ssize_t)strlen(s);
2031 while ((p = strstr_m(s, pattern))) {
2032 t = *list;
2033 d = p -t;
2034 if (ld) {
2035 t = (char *) SMB_MALLOC(ls +ld +1);
2036 if (!t) {
2037 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2038 return False;
2040 memcpy(t, *list, d);
2041 memcpy(t +d +li, p +lp, ls -d -lp +1);
2042 SAFE_FREE(*list);
2043 *list = t;
2044 ls += ld;
2045 s = t +d +li;
2048 for (i = 0; i < li; i++) {
2049 switch (insert[i]) {
2050 case '`':
2051 case '"':
2052 case '\'':
2053 case ';':
2054 case '$':
2055 case '%':
2056 case '\r':
2057 case '\n':
2058 t[d +i] = '_';
2059 break;
2060 default:
2061 t[d +i] = insert[i];
2067 list++;
2070 return True;
2074 #define IPSTR_LIST_SEP ","
2075 #define IPSTR_LIST_CHAR ','
2078 * Add ip string representation to ipstr list. Used also
2079 * as part of @function ipstr_list_make
2081 * @param ipstr_list pointer to string containing ip list;
2082 * MUST BE already allocated and IS reallocated if necessary
2083 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2084 * as a result of reallocation)
2085 * @param ip IP address which is to be added to list
2086 * @return pointer to string appended with new ip and possibly
2087 * reallocated to new length
2090 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2092 char* new_ipstr = NULL;
2094 /* arguments checking */
2095 if (!ipstr_list || !service) return NULL;
2097 /* attempt to convert ip to a string and append colon separator to it */
2098 if (*ipstr_list) {
2099 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2100 inet_ntoa(service->ip), service->port);
2101 SAFE_FREE(*ipstr_list);
2102 } else {
2103 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2105 *ipstr_list = new_ipstr;
2106 return *ipstr_list;
2111 * Allocate and initialise an ipstr list using ip adresses
2112 * passed as arguments.
2114 * @param ipstr_list pointer to string meant to be allocated and set
2115 * @param ip_list array of ip addresses to place in the list
2116 * @param ip_count number of addresses stored in ip_list
2117 * @return pointer to allocated ip string
2120 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2122 int i;
2124 /* arguments checking */
2125 if (!ip_list || !ipstr_list) return 0;
2127 *ipstr_list = NULL;
2129 /* process ip addresses given as arguments */
2130 for (i = 0; i < ip_count; i++)
2131 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2133 return (*ipstr_list);
2138 * Parse given ip string list into array of ip addresses
2139 * (as ip_service structures)
2140 * e.g. 192.168.1.100:389,192.168.1.78, ...
2142 * @param ipstr ip string list to be parsed
2143 * @param ip_list pointer to array of ip addresses which is
2144 * allocated by this function and must be freed by caller
2145 * @return number of successfully parsed addresses
2148 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2150 fstring token_str;
2151 size_t count;
2152 int i;
2154 if (!ipstr_list || !ip_list)
2155 return 0;
2157 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2158 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2159 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2160 return 0;
2163 for ( i=0;
2164 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2165 i++ )
2167 struct in_addr addr;
2168 unsigned port = 0;
2169 char *p = strchr(token_str, ':');
2171 if (p) {
2172 *p = 0;
2173 port = atoi(p+1);
2176 /* convert single token to ip address */
2177 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2178 break;
2180 (*ip_list)[i].ip = addr;
2181 (*ip_list)[i].port = port;
2184 return count;
2189 * Safely free ip string list
2191 * @param ipstr_list ip string list to be freed
2194 void ipstr_list_free(char* ipstr_list)
2196 SAFE_FREE(ipstr_list);
2201 Unescape a URL encoded string, in place.
2204 void rfc1738_unescape(char *buf)
2206 char *p=buf;
2208 while (p && *p && (p=strchr_m(p,'%'))) {
2209 int c1 = p[1];
2210 int c2 = p[2];
2212 if (c1 >= '0' && c1 <= '9')
2213 c1 = c1 - '0';
2214 else if (c1 >= 'A' && c1 <= 'F')
2215 c1 = 10 + c1 - 'A';
2216 else if (c1 >= 'a' && c1 <= 'f')
2217 c1 = 10 + c1 - 'a';
2218 else {p++; continue;}
2220 if (c2 >= '0' && c2 <= '9')
2221 c2 = c2 - '0';
2222 else if (c2 >= 'A' && c2 <= 'F')
2223 c2 = 10 + c2 - 'A';
2224 else if (c2 >= 'a' && c2 <= 'f')
2225 c2 = 10 + c2 - 'a';
2226 else {p++; continue;}
2228 *p = (c1<<4) | c2;
2230 memmove(p+1, p+3, strlen(p+3)+1);
2231 p++;
2235 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2238 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2240 DATA_BLOB base64_decode_data_blob(const char *s)
2242 int bit_offset, byte_offset, idx, i, n;
2243 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2244 unsigned char *d = decoded.data;
2245 char *p;
2247 n=i=0;
2249 while (*s && (p=strchr_m(b64,*s))) {
2250 idx = (int)(p - b64);
2251 byte_offset = (i*6)/8;
2252 bit_offset = (i*6)%8;
2253 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2254 if (bit_offset < 3) {
2255 d[byte_offset] |= (idx << (2-bit_offset));
2256 n = byte_offset+1;
2257 } else {
2258 d[byte_offset] |= (idx >> (bit_offset-2));
2259 d[byte_offset+1] = 0;
2260 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2261 n = byte_offset+2;
2263 s++; i++;
2266 if ((n > 0) && (*s == '=')) {
2267 n -= 1;
2270 /* fix up length */
2271 decoded.length = n;
2272 return decoded;
2276 * Decode a base64 string in-place - wrapper for the above
2278 void base64_decode_inplace(char *s)
2280 DATA_BLOB decoded = base64_decode_data_blob(s);
2282 if ( decoded.length != 0 ) {
2283 memcpy(s, decoded.data, decoded.length);
2285 /* null terminate */
2286 s[decoded.length] = '\0';
2287 } else {
2288 *s = '\0';
2291 data_blob_free(&decoded);
2295 * Encode a base64 string into a malloc()ed string caller to free.
2297 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2299 char * base64_encode_data_blob(DATA_BLOB data)
2301 int bits = 0;
2302 int char_count = 0;
2303 size_t out_cnt, len, output_len;
2304 char *result;
2306 if (!data.length || !data.data)
2307 return NULL;
2309 out_cnt = 0;
2310 len = data.length;
2311 output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
2312 * random but should be enough for
2313 * the = and \0 */
2314 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2316 while (len-- && out_cnt < (data.length * 2) - 5) {
2317 int c = (unsigned char) *(data.data++);
2318 bits += c;
2319 char_count++;
2320 if (char_count == 3) {
2321 result[out_cnt++] = b64[bits >> 18];
2322 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2323 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2324 result[out_cnt++] = b64[bits & 0x3f];
2325 bits = 0;
2326 char_count = 0;
2327 } else {
2328 bits <<= 8;
2331 if (char_count != 0) {
2332 bits <<= 16 - (8 * char_count);
2333 result[out_cnt++] = b64[bits >> 18];
2334 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2335 if (char_count == 1) {
2336 result[out_cnt++] = '=';
2337 result[out_cnt++] = '=';
2338 } else {
2339 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2340 result[out_cnt++] = '=';
2343 result[out_cnt] = '\0'; /* terminate */
2344 return result;
2347 /* read a SMB_BIG_UINT from a string */
2348 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2351 SMB_BIG_UINT val = -1;
2352 const char *p = nptr;
2354 if (!p) {
2355 if (entptr) {
2356 *entptr = p;
2358 return val;
2361 while (*p && isspace(*p))
2362 p++;
2364 #ifdef LARGE_SMB_OFF_T
2365 sscanf(p,"%llu",&val);
2366 #else /* LARGE_SMB_OFF_T */
2367 sscanf(p,"%lu",&val);
2368 #endif /* LARGE_SMB_OFF_T */
2369 if (entptr) {
2370 while (*p && isdigit(*p))
2371 p++;
2372 *entptr = p;
2375 return val;
2378 /* Convert a size specification to a count of bytes. We accept the following
2379 * suffixes:
2380 * bytes if there is no suffix
2381 * kK kibibytes
2382 * mM mebibytes
2383 * gG gibibytes
2384 * tT tibibytes
2385 * pP whatever the ISO name for petabytes is
2387 * Returns 0 if the string can't be converted.
2389 SMB_OFF_T conv_str_size(const char * str)
2391 SMB_OFF_T lval;
2392 char * end;
2394 if (str == NULL || *str == '\0') {
2395 return 0;
2398 #ifdef HAVE_STRTOULL
2399 if (sizeof(SMB_OFF_T) == 8) {
2400 lval = strtoull(str, &end, 10 /* base */);
2401 } else {
2402 lval = strtoul(str, &end, 10 /* base */);
2404 #else
2405 lval = strtoul(str, &end, 10 /* base */);
2406 #endif
2408 if (end == NULL || end == str) {
2409 return 0;
2412 if (*end) {
2413 SMB_OFF_T lval_orig = lval;
2415 if (strwicmp(end, "K") == 0) {
2416 lval *= (SMB_OFF_T)1024;
2417 } else if (strwicmp(end, "M") == 0) {
2418 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2419 } else if (strwicmp(end, "G") == 0) {
2420 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2421 (SMB_OFF_T)1024);
2422 } else if (strwicmp(end, "T") == 0) {
2423 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2424 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2425 } else if (strwicmp(end, "P") == 0) {
2426 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2427 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2428 (SMB_OFF_T)1024);
2429 } else {
2430 return 0;
2433 /* Primitive attempt to detect wrapping on platforms with
2434 * 4-byte SMB_OFF_T. It's better to let the caller handle
2435 * a failure than some random number.
2437 if (lval_orig <= lval) {
2438 return 0;
2442 return lval;
2445 void string_append(char **left, const char *right)
2447 int new_len = strlen(right) + 1;
2449 if (*left == NULL) {
2450 *left = (char *)SMB_MALLOC(new_len);
2451 *left[0] = '\0';
2452 } else {
2453 new_len += strlen(*left);
2454 *left = (char *)SMB_REALLOC(*left, new_len);
2457 if (*left == NULL) {
2458 return;
2461 safe_strcat(*left, right, new_len-1);
2464 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2465 const char *str, const char ***strings,
2466 int *num)
2468 char *dup_str = talloc_strdup(mem_ctx, str);
2470 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2472 if ((*strings == NULL) || (dup_str == NULL)) {
2473 *num = 0;
2474 return False;
2477 (*strings)[*num] = dup_str;
2478 *num += 1;
2479 return True;
2482 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2483 * error checking in between. The indiation that something weird happened is
2484 * string==NULL */
2486 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2487 size_t *bufsize, const char *fmt, ...)
2489 va_list ap;
2490 char *newstr;
2491 int ret;
2492 BOOL increased;
2494 /* len<0 is an internal marker that something failed */
2495 if (*len < 0)
2496 goto error;
2498 if (*string == NULL) {
2499 if (*bufsize == 0)
2500 *bufsize = 128;
2502 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2503 if (*string == NULL)
2504 goto error;
2507 va_start(ap, fmt);
2508 ret = vasprintf(&newstr, fmt, ap);
2509 va_end(ap);
2511 if (ret < 0)
2512 goto error;
2514 increased = False;
2516 while ((*len)+ret >= *bufsize) {
2517 increased = True;
2518 *bufsize *= 2;
2519 if (*bufsize >= (1024*1024*256))
2520 goto error;
2523 if (increased) {
2524 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2525 *bufsize);
2526 if (*string == NULL) {
2527 goto error;
2531 StrnCpy((*string)+(*len), newstr, ret);
2532 (*len) += ret;
2533 free(newstr);
2534 return;
2536 error:
2537 *len = -1;
2538 *string = NULL;
2542 Returns the substring from src between the first occurrence of
2543 the char "front" and the first occurence of the char "back".
2544 Mallocs the return string which must be freed. Not for use
2545 with wide character strings.
2547 char *sstring_sub(const char *src, char front, char back)
2549 char *temp1, *temp2, *temp3;
2550 ptrdiff_t len;
2552 temp1 = strchr(src, front);
2553 if (temp1 == NULL) return NULL;
2554 temp2 = strchr(src, back);
2555 if (temp2 == NULL) return NULL;
2556 len = temp2 - temp1;
2557 if (len <= 0) return NULL;
2558 temp3 = (char*)SMB_MALLOC(len);
2559 if (temp3 == NULL) {
2560 DEBUG(1,("Malloc failure in sstring_sub\n"));
2561 return NULL;
2563 memcpy(temp3, temp1+1, len-1);
2564 temp3[len-1] = '\0';
2565 return temp3;
2568 /********************************************************************
2569 Check a string for any occurrences of a specified list of invalid
2570 characters.
2571 ********************************************************************/
2573 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2575 int i;
2577 for ( i=0; i<max_len && name[i]; i++ ) {
2578 /* fail if strchr_m() finds one of the invalid characters */
2579 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2580 return False;
2584 return True;
2589 return the number of bytes occupied by a buffer in ASCII format
2590 the result includes the null termination
2591 limited by 'n' bytes
2593 size_t ascii_len_n(const char *src, size_t n)
2595 size_t len;
2597 len = strnlen(src, n);
2598 if (len+1 <= n) {
2599 len += 1;
2602 return len;
2606 return the number of bytes occupied by a buffer in CH_UTF16 format
2607 the result includes the null termination
2609 size_t utf16_len(const void *buf)
2611 size_t len;
2613 for (len = 0; SVAL(buf,len); len += 2) ;
2615 return len + 2;
2619 return the number of bytes occupied by a buffer in CH_UTF16 format
2620 the result includes the null termination
2621 limited by 'n' bytes
2623 size_t utf16_len_n(const void *src, size_t n)
2625 size_t len;
2627 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2629 if (len+2 <= n) {
2630 len += 2;
2633 return len;
2636 /*******************************************************************
2637 Add a shell escape character '\' to any character not in a known list
2638 of characters. UNIX charset format.
2639 *******************************************************************/
2641 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2642 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2644 char *escape_shell_string(const char *src)
2646 size_t srclen = strlen(src);
2647 char *ret = SMB_MALLOC((srclen * 2) + 1);
2648 char *dest = ret;
2649 BOOL in_s_quote = False;
2650 BOOL in_d_quote = False;
2651 BOOL next_escaped = False;
2653 if (!ret) {
2654 return NULL;
2657 while (*src) {
2658 size_t c_size;
2659 codepoint_t c = next_codepoint(src, &c_size);
2661 if (c == INVALID_CODEPOINT) {
2662 SAFE_FREE(ret);
2663 return NULL;
2666 if (c_size > 1) {
2667 memcpy(dest, src, c_size);
2668 src += c_size;
2669 dest += c_size;
2670 next_escaped = False;
2671 continue;
2675 * Deal with backslash escaped state.
2676 * This only lasts for one character.
2679 if (next_escaped) {
2680 *dest++ = *src++;
2681 next_escaped = False;
2682 continue;
2686 * Deal with single quote state. The
2687 * only thing we care about is exiting
2688 * this state.
2691 if (in_s_quote) {
2692 if (*src == '\'') {
2693 in_s_quote = False;
2695 *dest++ = *src++;
2696 continue;
2700 * Deal with double quote state. The most
2701 * complex state. We must cope with \, meaning
2702 * possibly escape next char (depending what it
2703 * is), ", meaning exit this state, and possibly
2704 * add an \ escape to any unprotected character
2705 * (listed in INSIDE_DQUOTE_LIST).
2708 if (in_d_quote) {
2709 if (*src == '\\') {
2711 * Next character might be escaped.
2712 * We have to peek. Inside double
2713 * quotes only INSIDE_DQUOTE_LIST
2714 * characters are escaped by a \.
2717 char nextchar;
2719 c = next_codepoint(&src[1], &c_size);
2720 if (c == INVALID_CODEPOINT) {
2721 SAFE_FREE(ret);
2722 return NULL;
2724 if (c_size > 1) {
2726 * Don't escape the next char.
2727 * Just copy the \.
2729 *dest++ = *src++;
2730 continue;
2733 nextchar = src[1];
2735 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2736 next_escaped = True;
2738 *dest++ = *src++;
2739 continue;
2742 if (*src == '\"') {
2743 /* Exit double quote state. */
2744 in_d_quote = False;
2745 *dest++ = *src++;
2746 continue;
2750 * We know the character isn't \ or ",
2751 * so escape it if it's any of the other
2752 * possible unprotected characters.
2755 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2756 *dest++ = '\\';
2758 *dest++ = *src++;
2759 continue;
2763 * From here to the end of the loop we're
2764 * not in the single or double quote state.
2767 if (*src == '\\') {
2768 /* Next character must be escaped. */
2769 next_escaped = True;
2770 *dest++ = *src++;
2771 continue;
2774 if (*src == '\'') {
2775 /* Go into single quote state. */
2776 in_s_quote = True;
2777 *dest++ = *src++;
2778 continue;
2781 if (*src == '\"') {
2782 /* Go into double quote state. */
2783 in_d_quote = True;
2784 *dest++ = *src++;
2785 continue;
2788 /* Check if we need to escape the character. */
2790 if (!strchr(INCLUDE_LIST, (int)*src)) {
2791 *dest++ = '\\';
2793 *dest++ = *src++;
2795 *dest++ = '\0';
2796 return ret;