r17914: snpritnf() fixes & NULL deref fixes
[Samba.git] / source / lib / util_str.c
blobc106c4433aaefb9098a5718b50de4215328e3511
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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 /**
27 * @file
28 * @brief String utilities.
29 **/
31 /**
32 * Get the next token from a string, return False if none found.
33 * Handles double-quotes.
35 * Based on a routine by GJC@VILLAGE.COM.
36 * Extensively modified by Andrew.Tridgell@anu.edu.au
37 **/
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
40 char *s;
41 char *pbuf;
42 BOOL quoted;
43 size_t len=1;
45 if (!ptr)
46 return(False);
48 s = (char *)*ptr;
50 /* default to simple separators */
51 if (!sep)
52 sep = " \t\n\r";
54 /* find the first non sep char */
55 while (*s && strchr_m(sep,*s))
56 s++;
58 /* nothing left? */
59 if (! *s)
60 return(False);
62 /* copy over the token */
63 pbuf = buff;
64 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65 if ( *s == '\"' ) {
66 quoted = !quoted;
67 } else {
68 len++;
69 *pbuf++ = *s;
73 *ptr = (*s) ? s+1 : s;
74 *pbuf = 0;
76 return(True);
79 /**
80 This is like next_token but is not re-entrant and "remembers" the first
81 parameter so you can pass NULL. This is useful for user interface code
82 but beware the fact that it is not re-entrant!
83 **/
85 static const char *last_ptr=NULL;
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
89 BOOL ret;
90 if (!ptr)
91 ptr = &last_ptr;
93 ret = next_token(ptr, buff, sep, bufsize);
94 last_ptr = *ptr;
95 return ret;
98 static uint16 tmpbuf[sizeof(pstring)];
100 void set_first_token(char *ptr)
102 last_ptr = ptr;
106 Convert list of tokens to array; dependent on above routine.
107 Uses last_ptr from above - bit of a hack.
110 char **toktocliplist(int *ctok, const char *sep)
112 char *s=(char *)last_ptr;
113 int ictok=0;
114 char **ret, **iret;
116 if (!sep)
117 sep = " \t\n\r";
119 while(*s && strchr_m(sep,*s))
120 s++;
122 /* nothing left? */
123 if (!*s)
124 return(NULL);
126 do {
127 ictok++;
128 while(*s && (!strchr_m(sep,*s)))
129 s++;
130 while(*s && strchr_m(sep,*s))
131 *s++=0;
132 } while(*s);
134 *ctok=ictok;
135 s=(char *)last_ptr;
137 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
138 return NULL;
140 while(ictok--) {
141 *iret++=s;
142 if (ictok > 0) {
143 while(*s++)
145 while(!*s)
146 s++;
150 ret[*ctok] = NULL;
151 return ret;
155 * Case insensitive string compararison.
157 * iconv does not directly give us a way to compare strings in
158 * arbitrary unix character sets -- all we can is convert and then
159 * compare. This is expensive.
161 * As an optimization, we do a first pass that considers only the
162 * prefix of the strings that is entirely 7-bit. Within this, we
163 * check whether they have the same value.
165 * Hopefully this will often give the answer without needing to copy.
166 * In particular it should speed comparisons to literal ascii strings
167 * or comparisons of strings that are "obviously" different.
169 * If we find a non-ascii character we fall back to converting via
170 * iconv.
172 * This should never be slower than convering the whole thing, and
173 * often faster.
175 * A different optimization would be to compare for bitwise equality
176 * in the binary encoding. (It would be possible thought hairy to do
177 * both simultaneously.) But in that case if they turn out to be
178 * different, we'd need to restart the whole thing.
180 * Even better is to implement strcasecmp for each encoding and use a
181 * function pointer.
183 int StrCaseCmp(const char *s, const char *t)
186 const char *ps, *pt;
187 size_t size;
188 smb_ucs2_t *buffer_s, *buffer_t;
189 int ret;
191 for (ps = s, pt = t; ; ps++, pt++) {
192 char us, ut;
194 if (!*ps && !*pt)
195 return 0; /* both ended */
196 else if (!*ps)
197 return -1; /* s is a prefix */
198 else if (!*pt)
199 return +1; /* t is a prefix */
200 else if ((*ps & 0x80) || (*pt & 0x80))
201 /* not ascii anymore, do it the hard way from here on in */
202 break;
204 us = toupper_ascii(*ps);
205 ut = toupper_ascii(*pt);
206 if (us == ut)
207 continue;
208 else if (us < ut)
209 return -1;
210 else if (us > ut)
211 return +1;
214 size = push_ucs2_allocate(&buffer_s, ps);
215 if (size == (size_t)-1) {
216 return strcmp(ps, pt);
217 /* Not quite the right answer, but finding the right one
218 under this failure case is expensive, and it's pretty close */
221 size = push_ucs2_allocate(&buffer_t, pt);
222 if (size == (size_t)-1) {
223 SAFE_FREE(buffer_s);
224 return strcmp(ps, pt);
225 /* Not quite the right answer, but finding the right one
226 under this failure case is expensive, and it's pretty close */
229 ret = strcasecmp_w(buffer_s, buffer_t);
230 SAFE_FREE(buffer_s);
231 SAFE_FREE(buffer_t);
232 return ret;
237 Case insensitive string compararison, length limited.
239 int StrnCaseCmp(const char *s, const char *t, size_t n)
241 pstring buf1, buf2;
242 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
243 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
244 return strncmp(buf1,buf2,n);
248 * Compare 2 strings.
250 * @note The comparison is case-insensitive.
252 BOOL strequal(const char *s1, const char *s2)
254 if (s1 == s2)
255 return(True);
256 if (!s1 || !s2)
257 return(False);
259 return(StrCaseCmp(s1,s2)==0);
263 * Compare 2 strings up to and including the nth char.
265 * @note The comparison is case-insensitive.
267 BOOL strnequal(const char *s1,const char *s2,size_t n)
269 if (s1 == s2)
270 return(True);
271 if (!s1 || !s2 || !n)
272 return(False);
274 return(StrnCaseCmp(s1,s2,n)==0);
278 Compare 2 strings (case sensitive).
281 BOOL strcsequal(const char *s1,const char *s2)
283 if (s1 == s2)
284 return(True);
285 if (!s1 || !s2)
286 return(False);
288 return(strcmp(s1,s2)==0);
292 Do a case-insensitive, whitespace-ignoring string compare.
295 int strwicmp(const char *psz1, const char *psz2)
297 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
298 /* appropriate value. */
299 if (psz1 == psz2)
300 return (0);
301 else if (psz1 == NULL)
302 return (-1);
303 else if (psz2 == NULL)
304 return (1);
306 /* sync the strings on first non-whitespace */
307 while (1) {
308 while (isspace((int)*psz1))
309 psz1++;
310 while (isspace((int)*psz2))
311 psz2++;
312 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
313 || *psz2 == '\0')
314 break;
315 psz1++;
316 psz2++;
318 return (*psz1 - *psz2);
323 Convert a string to upper case, but don't modify it.
326 char *strupper_static(const char *s)
328 static pstring str;
330 pstrcpy(str, s);
331 strupper_m(str);
333 return str;
337 Convert a string to "normal" form.
340 void strnorm(char *s, int case_default)
342 if (case_default == CASE_UPPER)
343 strupper_m(s);
344 else
345 strlower_m(s);
349 Check if a string is in "normal" case.
352 BOOL strisnormal(const char *s, int case_default)
354 if (case_default == CASE_UPPER)
355 return(!strhaslower(s));
357 return(!strhasupper(s));
362 String replace.
363 NOTE: oldc and newc must be 7 bit characters
366 void string_replace( pstring s, char oldc, char newc )
368 char *p;
370 /* this is quite a common operation, so we want it to be
371 fast. We optimise for the ascii case, knowing that all our
372 supported multi-byte character sets are ascii-compatible
373 (ie. they match for the first 128 chars) */
375 for (p = s; *p; p++) {
376 if (*p & 0x80) /* mb string - slow path. */
377 break;
378 if (*p == oldc)
379 *p = newc;
382 if (!*p)
383 return;
385 /* Slow (mb) path. */
386 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
387 /* With compose characters we must restart from the beginning. JRA. */
388 p = s;
389 #endif
390 push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
391 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
392 pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
396 Skip past some strings in a buffer.
399 char *skip_string(char *buf,size_t n)
401 while (n--)
402 buf += strlen(buf) + 1;
403 return(buf);
407 Count the number of characters in a string. Normally this will
408 be the same as the number of bytes in a string for single byte strings,
409 but will be different for multibyte.
412 size_t str_charnum(const char *s)
414 uint16 tmpbuf2[sizeof(pstring)];
415 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
416 return strlen_w(tmpbuf2);
420 Count the number of characters in a string. Normally this will
421 be the same as the number of bytes in a string for single byte strings,
422 but will be different for multibyte.
425 size_t str_ascii_charnum(const char *s)
427 pstring tmpbuf2;
428 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
429 return strlen(tmpbuf2);
432 BOOL trim_char(char *s,char cfront,char cback)
434 BOOL ret = False;
435 char *ep;
436 char *fp = s;
438 /* Ignore null or empty strings. */
439 if (!s || (s[0] == '\0'))
440 return False;
442 if (cfront) {
443 while (*fp && *fp == cfront)
444 fp++;
445 if (!*fp) {
446 /* We ate the string. */
447 s[0] = '\0';
448 return True;
450 if (fp != s)
451 ret = True;
454 ep = fp + strlen(fp) - 1;
455 if (cback) {
456 /* Attempt ascii only. Bail for mb strings. */
457 while ((ep >= fp) && (*ep == cback)) {
458 ret = True;
459 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
460 /* Could be mb... bail back to tim_string. */
461 char fs[2], bs[2];
462 if (cfront) {
463 fs[0] = cfront;
464 fs[1] = '\0';
466 bs[0] = cback;
467 bs[1] = '\0';
468 return trim_string(s, cfront ? fs : NULL, bs);
469 } else {
470 ep--;
473 if (ep < fp) {
474 /* We ate the string. */
475 s[0] = '\0';
476 return True;
480 ep[1] = '\0';
481 memmove(s, fp, ep-fp+2);
482 return ret;
486 Trim the specified elements off the front and back of a string.
489 BOOL trim_string(char *s,const char *front,const char *back)
491 BOOL ret = False;
492 size_t front_len;
493 size_t back_len;
494 size_t len;
496 /* Ignore null or empty strings. */
497 if (!s || (s[0] == '\0'))
498 return False;
500 front_len = front? strlen(front) : 0;
501 back_len = back? strlen(back) : 0;
503 len = strlen(s);
505 if (front_len) {
506 while (len && strncmp(s, front, front_len)==0) {
507 /* Must use memmove here as src & dest can
508 * easily overlap. Found by valgrind. JRA. */
509 memmove(s, s+front_len, (len-front_len)+1);
510 len -= front_len;
511 ret=True;
515 if (back_len) {
516 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
517 s[len-back_len]='\0';
518 len -= back_len;
519 ret=True;
522 return ret;
526 Does a string have any uppercase chars in it?
529 BOOL strhasupper(const char *s)
531 smb_ucs2_t *ptr;
532 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
533 for(ptr=tmpbuf;*ptr;ptr++)
534 if(isupper_w(*ptr))
535 return True;
536 return(False);
540 Does a string have any lowercase chars in it?
543 BOOL strhaslower(const char *s)
545 smb_ucs2_t *ptr;
546 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
547 for(ptr=tmpbuf;*ptr;ptr++)
548 if(islower_w(*ptr))
549 return True;
550 return(False);
554 Find the number of 'c' chars in a string
557 size_t count_chars(const char *s,char c)
559 smb_ucs2_t *ptr;
560 int count;
561 smb_ucs2_t *alloc_tmpbuf = NULL;
563 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
564 return 0;
567 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
568 if(*ptr==UCS2_CHAR(c))
569 count++;
571 SAFE_FREE(alloc_tmpbuf);
572 return(count);
576 Safe string copy into a known length string. maxlength does not
577 include the terminating zero.
580 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
582 size_t len;
584 if (!dest) {
585 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
586 return NULL;
589 #ifdef DEVELOPER
590 clobber_region(fn,line,dest, maxlength+1);
591 #endif
593 if (!src) {
594 *dest = 0;
595 return dest;
598 len = strnlen(src, maxlength+1);
600 if (len > maxlength) {
601 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
602 (unsigned long)(len-maxlength), (unsigned long)len,
603 (unsigned long)maxlength, src));
604 len = maxlength;
607 memmove(dest, src, len);
608 dest[len] = 0;
609 return dest;
613 Safe string cat into a string. maxlength does not
614 include the terminating zero.
616 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
618 size_t src_len, dest_len;
620 if (!dest) {
621 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
622 return NULL;
625 if (!src)
626 return dest;
628 src_len = strnlen(src, maxlength + 1);
629 dest_len = strnlen(dest, maxlength + 1);
631 #ifdef DEVELOPER
632 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
633 #endif
635 if (src_len + dest_len > maxlength) {
636 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
637 (int)(src_len + dest_len - maxlength), src));
638 if (maxlength > dest_len) {
639 memcpy(&dest[dest_len], src, maxlength - dest_len);
641 dest[maxlength] = 0;
642 return NULL;
645 memcpy(&dest[dest_len], src, src_len);
646 dest[dest_len + src_len] = 0;
647 return dest;
651 Paranoid strcpy into a buffer of given length (includes terminating
652 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
653 and replaces with '_'. Deliberately does *NOT* check for multibyte
654 characters. Don't change it !
656 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
658 size_t len, i;
660 #ifdef DEVELOPER
661 clobber_region(fn, line, dest, maxlength);
662 #endif
664 if (!dest) {
665 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
666 return NULL;
669 if (!src) {
670 *dest = 0;
671 return dest;
674 len = strlen(src);
675 if (len >= maxlength)
676 len = maxlength - 1;
678 if (!other_safe_chars)
679 other_safe_chars = "";
681 for(i = 0; i < len; i++) {
682 int val = (src[i] & 0xff);
683 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
684 dest[i] = src[i];
685 else
686 dest[i] = '_';
689 dest[i] = '\0';
691 return dest;
695 Like strncpy but always null terminates. Make sure there is room!
696 The variable n should always be one less than the available size.
698 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
700 char *d = dest;
702 #ifdef DEVELOPER
703 clobber_region(fn, line, dest, n+1);
704 #endif
706 if (!dest) {
707 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
708 return(NULL);
711 if (!src) {
712 *dest = 0;
713 return(dest);
716 while (n-- && (*d = *src)) {
717 d++;
718 src++;
721 *d = 0;
722 return(dest);
725 #if 0
727 Like strncpy but copies up to the character marker. always null terminates.
728 returns a pointer to the character marker in the source string (src).
731 static char *strncpyn(char *dest, const char *src, size_t n, char c)
733 char *p;
734 size_t str_len;
736 #ifdef DEVELOPER
737 clobber_region(dest, n+1);
738 #endif
739 p = strchr_m(src, c);
740 if (p == NULL) {
741 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
742 return NULL;
745 str_len = PTR_DIFF(p, src);
746 strncpy(dest, src, MIN(n, str_len));
747 dest[str_len] = '\0';
749 return p;
751 #endif
754 Routine to get hex characters and turn them into a 16 byte array.
755 the array can be variable length, and any non-hex-numeric
756 characters are skipped. "0xnn" or "0Xnn" is specially catered
757 for.
759 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
763 size_t strhex_to_str(char *p, size_t len, const char *strhex)
765 size_t i;
766 size_t num_chars = 0;
767 unsigned char lonybble, hinybble;
768 const char *hexchars = "0123456789ABCDEF";
769 char *p1 = NULL, *p2 = NULL;
771 for (i = 0; i < len && strhex[i] != 0; i++) {
772 if (strnequal(hexchars, "0x", 2)) {
773 i++; /* skip two chars */
774 continue;
777 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
778 break;
780 i++; /* next hex digit */
782 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
783 break;
785 /* get the two nybbles */
786 hinybble = PTR_DIFF(p1, hexchars);
787 lonybble = PTR_DIFF(p2, hexchars);
789 p[num_chars] = (hinybble << 4) | lonybble;
790 num_chars++;
792 p1 = NULL;
793 p2 = NULL;
795 return num_chars;
798 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
800 DATA_BLOB ret_blob;
802 if (mem_ctx != NULL)
803 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
804 else
805 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
807 ret_blob.length = strhex_to_str((char*)ret_blob.data,
808 strlen(strhex),
809 strhex);
811 return ret_blob;
815 * Routine to print a buffer as HEX digits, into an allocated string.
818 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
820 int i;
821 char *hex_buffer;
823 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
825 for (i = 0; i < len; i++)
826 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
828 return hex_buffer;
832 Check if a string is part of a list.
835 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
837 pstring tok;
838 const char *p=list;
840 if (!list)
841 return(False);
843 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
844 if (casesensitive) {
845 if (strcmp(tok,s) == 0)
846 return(True);
847 } else {
848 if (StrCaseCmp(tok,s) == 0)
849 return(True);
852 return(False);
855 /* this is used to prevent lots of mallocs of size 1 */
856 static const char *null_string = "";
859 Set a string value, allocing the space for the string
862 static BOOL string_init(char **dest,const char *src)
864 size_t l;
866 if (!src)
867 src = "";
869 l = strlen(src);
871 if (l == 0) {
872 *dest = CONST_DISCARD(char*, null_string);
873 } else {
874 (*dest) = SMB_STRDUP(src);
875 if ((*dest) == NULL) {
876 DEBUG(0,("Out of memory in string_init\n"));
877 return False;
880 return(True);
884 Free a string value.
887 void string_free(char **s)
889 if (!s || !(*s))
890 return;
891 if (*s == null_string)
892 *s = NULL;
893 SAFE_FREE(*s);
897 Set a string value, deallocating any existing space, and allocing the space
898 for the string
901 BOOL string_set(char **dest,const char *src)
903 string_free(dest);
904 return(string_init(dest,src));
908 Substitute a string for a pattern in another string. Make sure there is
909 enough room!
911 This routine looks for pattern in s and replaces it with
912 insert. It may do multiple replacements or just one.
914 Any of " ; ' $ or ` in the insert string are replaced with _
915 if len==0 then the string cannot be extended. This is different from the old
916 use of len==0 which was for no length checks to be done.
919 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
920 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
922 char *p;
923 ssize_t ls,lp,li, i;
925 if (!insert || !pattern || !*pattern || !s)
926 return;
928 ls = (ssize_t)strlen(s);
929 lp = (ssize_t)strlen(pattern);
930 li = (ssize_t)strlen(insert);
932 if (len == 0)
933 len = ls + 1; /* len is number of *bytes* */
935 while (lp <= ls && (p = strstr_m(s,pattern))) {
936 if (ls + (li-lp) >= len) {
937 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
938 (int)(ls + (li-lp) - len),
939 pattern, (int)len));
940 break;
942 if (li != lp) {
943 memmove(p+li,p+lp,strlen(p+lp)+1);
945 for (i=0;i<li;i++) {
946 switch (insert[i]) {
947 case '`':
948 case '"':
949 case '\'':
950 case ';':
951 case '$':
952 /* allow a trailing $ (as in machine accounts) */
953 if (allow_trailing_dollar && (i == li - 1 )) {
954 p[i] = insert[i];
955 break;
957 case '%':
958 case '\r':
959 case '\n':
960 if ( remove_unsafe_characters ) {
961 p[i] = '_';
962 /* yes this break should be here since we want to
963 fall throw if not replacing unsafe chars */
964 break;
966 default:
967 p[i] = insert[i];
970 s = p + li;
971 ls += (li-lp);
973 if (replace_once)
974 break;
978 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
980 string_sub2( s, pattern, insert, len, True, True, False );
983 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
985 string_sub2( s, pattern, insert, len, True, False, False );
988 void fstring_sub(char *s,const char *pattern,const char *insert)
990 string_sub(s, pattern, insert, sizeof(fstring));
993 void pstring_sub(char *s,const char *pattern,const char *insert)
995 string_sub(s, pattern, insert, sizeof(pstring));
999 Similar to string_sub, but it will accept only allocated strings
1000 and may realloc them so pay attention at what you pass on no
1001 pointers inside strings, no pstrings or const may be passed
1002 as string.
1005 char *realloc_string_sub(char *string, const char *pattern,
1006 const char *insert)
1008 char *p, *in;
1009 char *s;
1010 ssize_t ls,lp,li,ld, i;
1012 if (!insert || !pattern || !*pattern || !string || !*string)
1013 return NULL;
1015 s = string;
1017 in = SMB_STRDUP(insert);
1018 if (!in) {
1019 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1020 return NULL;
1022 ls = (ssize_t)strlen(s);
1023 lp = (ssize_t)strlen(pattern);
1024 li = (ssize_t)strlen(insert);
1025 ld = li - lp;
1026 for (i=0;i<li;i++) {
1027 switch (in[i]) {
1028 case '`':
1029 case '"':
1030 case '\'':
1031 case ';':
1032 case '$':
1033 case '%':
1034 case '\r':
1035 case '\n':
1036 in[i] = '_';
1037 default:
1038 /* ok */
1039 break;
1043 while ((p = strstr_m(s,pattern))) {
1044 if (ld > 0) {
1045 int offset = PTR_DIFF(s,string);
1046 string = SMB_REALLOC(string, ls + ld + 1);
1047 if (!string) {
1048 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1049 SAFE_FREE(in);
1050 return NULL;
1052 p = string + offset + (p - s);
1054 if (li != lp) {
1055 memmove(p+li,p+lp,strlen(p+lp)+1);
1057 memcpy(p, in, li);
1058 s = p + li;
1059 ls += ld;
1061 SAFE_FREE(in);
1062 return string;
1065 /* Same as string_sub, but returns a talloc'ed string */
1067 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1068 const char *pattern, const char *insert)
1070 char *p, *in;
1071 char *s;
1072 char *string;
1073 ssize_t ls,lp,li,ld, i;
1075 if (!insert || !pattern || !*pattern || !src || !*src)
1076 return NULL;
1078 string = talloc_strdup(mem_ctx, src);
1079 if (string == NULL) {
1080 DEBUG(0, ("talloc_strdup failed\n"));
1081 return NULL;
1084 s = string;
1086 in = SMB_STRDUP(insert);
1087 if (!in) {
1088 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1089 return NULL;
1091 ls = (ssize_t)strlen(s);
1092 lp = (ssize_t)strlen(pattern);
1093 li = (ssize_t)strlen(insert);
1094 ld = li - lp;
1095 for (i=0;i<li;i++) {
1096 switch (in[i]) {
1097 case '`':
1098 case '"':
1099 case '\'':
1100 case ';':
1101 case '$':
1102 case '%':
1103 case '\r':
1104 case '\n':
1105 in[i] = '_';
1106 default:
1107 /* ok */
1108 break;
1112 while ((p = strstr_m(s,pattern))) {
1113 if (ld > 0) {
1114 int offset = PTR_DIFF(s,string);
1115 string = TALLOC_REALLOC(mem_ctx, string, ls + ld + 1);
1116 if (!string) {
1117 DEBUG(0, ("talloc_string_sub: out of "
1118 "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;
1136 Similar to string_sub() but allows for any character to be substituted.
1137 Use with caution!
1138 if len==0 then the string cannot be extended. This is different from the old
1139 use of len==0 which was for no length checks to be done.
1142 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1144 char *p;
1145 ssize_t ls,lp,li;
1147 if (!insert || !pattern || !s)
1148 return;
1150 ls = (ssize_t)strlen(s);
1151 lp = (ssize_t)strlen(pattern);
1152 li = (ssize_t)strlen(insert);
1154 if (!*pattern)
1155 return;
1157 if (len == 0)
1158 len = ls + 1; /* len is number of *bytes* */
1160 while (lp <= ls && (p = strstr_m(s,pattern))) {
1161 if (ls + (li-lp) >= len) {
1162 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1163 (int)(ls + (li-lp) - len),
1164 pattern, (int)len));
1165 break;
1167 if (li != lp) {
1168 memmove(p+li,p+lp,strlen(p+lp)+1);
1170 memcpy(p, insert, li);
1171 s = p + li;
1172 ls += (li-lp);
1177 Similar to all_string_sub but for unicode strings.
1178 Return a new allocated unicode string.
1179 similar to string_sub() but allows for any character to be substituted.
1180 Use with caution!
1183 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1184 const smb_ucs2_t *insert)
1186 smb_ucs2_t *r, *rp;
1187 const smb_ucs2_t *sp;
1188 size_t lr, lp, li, lt;
1190 if (!insert || !pattern || !*pattern || !s)
1191 return NULL;
1193 lt = (size_t)strlen_w(s);
1194 lp = (size_t)strlen_w(pattern);
1195 li = (size_t)strlen_w(insert);
1197 if (li > lp) {
1198 const smb_ucs2_t *st = s;
1199 int ld = li - lp;
1200 while ((sp = strstr_w(st, pattern))) {
1201 st = sp + lp;
1202 lt += ld;
1206 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1207 if (!r) {
1208 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1209 return NULL;
1212 while ((sp = strstr_w(s, pattern))) {
1213 memcpy(rp, s, (sp - s));
1214 rp += ((sp - s) / sizeof(smb_ucs2_t));
1215 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1216 s = sp + lp;
1217 rp += li;
1219 lr = ((rp - r) / sizeof(smb_ucs2_t));
1220 if (lr < lt) {
1221 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1222 rp += (lt - lr);
1224 *rp = 0;
1226 return r;
1229 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1230 const char *insert)
1232 wpstring p, i;
1234 if (!insert || !pattern || !s)
1235 return NULL;
1236 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1237 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1238 return all_string_sub_w(s, p, i);
1241 #if 0
1243 Splits out the front and back at a separator.
1246 static void split_at_last_component(char *path, char *front, char sep, char *back)
1248 char *p = strrchr_m(path, sep);
1250 if (p != NULL)
1251 *p = 0;
1253 if (front != NULL)
1254 pstrcpy(front, path);
1256 if (p != NULL) {
1257 if (back != NULL)
1258 pstrcpy(back, p+1);
1259 *p = '\\';
1260 } else {
1261 if (back != NULL)
1262 back[0] = 0;
1265 #endif
1268 Write an octal as a string.
1271 const char *octal_string(int i)
1273 static char ret[64];
1274 if (i == -1)
1275 return "-1";
1276 slprintf(ret, sizeof(ret)-1, "0%o", i);
1277 return ret;
1282 Truncate a string at a specified length.
1285 char *string_truncate(char *s, unsigned int length)
1287 if (s && strlen(s) > length)
1288 s[length] = 0;
1289 return s;
1293 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1294 We convert via ucs2 for now.
1297 char *strchr_m(const char *src, char c)
1299 wpstring ws;
1300 pstring s2;
1301 smb_ucs2_t *p;
1302 const char *s;
1304 /* characters below 0x3F are guaranteed to not appear in
1305 non-initial position in multi-byte charsets */
1306 if ((c & 0xC0) == 0) {
1307 return strchr(src, c);
1310 /* this is quite a common operation, so we want it to be
1311 fast. We optimise for the ascii case, knowing that all our
1312 supported multi-byte character sets are ascii-compatible
1313 (ie. they match for the first 128 chars) */
1315 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1316 if (*s == c)
1317 return (char *)s;
1320 if (!*s)
1321 return NULL;
1323 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1324 /* With compose characters we must restart from the beginning. JRA. */
1325 s = src;
1326 #endif
1328 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1329 p = strchr_w(ws, UCS2_CHAR(c));
1330 if (!p)
1331 return NULL;
1332 *p = 0;
1333 pull_ucs2_pstring(s2, ws);
1334 return (char *)(s+strlen(s2));
1337 char *strrchr_m(const char *s, char c)
1339 /* characters below 0x3F are guaranteed to not appear in
1340 non-initial position in multi-byte charsets */
1341 if ((c & 0xC0) == 0) {
1342 return strrchr(s, c);
1345 /* this is quite a common operation, so we want it to be
1346 fast. We optimise for the ascii case, knowing that all our
1347 supported multi-byte character sets are ascii-compatible
1348 (ie. they match for the first 128 chars). Also, in Samba
1349 we only search for ascii characters in 'c' and that
1350 in all mb character sets with a compound character
1351 containing c, if 'c' is not a match at position
1352 p, then p[-1] > 0x7f. JRA. */
1355 size_t len = strlen(s);
1356 const char *cp = s;
1357 BOOL got_mb = False;
1359 if (len == 0)
1360 return NULL;
1361 cp += (len - 1);
1362 do {
1363 if (c == *cp) {
1364 /* Could be a match. Part of a multibyte ? */
1365 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1366 /* Yep - go slow :-( */
1367 got_mb = True;
1368 break;
1370 /* No - we have a match ! */
1371 return (char *)cp;
1373 } while (cp-- != s);
1374 if (!got_mb)
1375 return NULL;
1378 /* String contained a non-ascii char. Slow path. */
1380 wpstring ws;
1381 pstring s2;
1382 smb_ucs2_t *p;
1384 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1385 p = strrchr_w(ws, UCS2_CHAR(c));
1386 if (!p)
1387 return NULL;
1388 *p = 0;
1389 pull_ucs2_pstring(s2, ws);
1390 return (char *)(s+strlen(s2));
1394 /***********************************************************************
1395 Return the equivalent of doing strrchr 'n' times - always going
1396 backwards.
1397 ***********************************************************************/
1399 char *strnrchr_m(const char *s, char c, unsigned int n)
1401 wpstring ws;
1402 pstring s2;
1403 smb_ucs2_t *p;
1405 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1406 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1407 if (!p)
1408 return NULL;
1409 *p = 0;
1410 pull_ucs2_pstring(s2, ws);
1411 return (char *)(s+strlen(s2));
1414 /***********************************************************************
1415 strstr_m - We convert via ucs2 for now.
1416 ***********************************************************************/
1418 char *strstr_m(const char *src, const char *findstr)
1420 smb_ucs2_t *p;
1421 smb_ucs2_t *src_w, *find_w;
1422 const char *s;
1423 char *s2;
1424 char *retp;
1426 size_t findstr_len = 0;
1428 /* for correctness */
1429 if (!findstr[0]) {
1430 return (char*)src;
1433 /* Samba does single character findstr calls a *lot*. */
1434 if (findstr[1] == '\0')
1435 return strchr_m(src, *findstr);
1437 /* We optimise for the ascii case, knowing that all our
1438 supported multi-byte character sets are ascii-compatible
1439 (ie. they match for the first 128 chars) */
1441 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1442 if (*s == *findstr) {
1443 if (!findstr_len)
1444 findstr_len = strlen(findstr);
1446 if (strncmp(s, findstr, findstr_len) == 0) {
1447 return (char *)s;
1452 if (!*s)
1453 return NULL;
1455 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1456 /* 'make check' fails unless we do this */
1458 /* With compose characters we must restart from the beginning. JRA. */
1459 s = src;
1460 #endif
1462 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1463 DEBUG(0,("strstr_m: src malloc fail\n"));
1464 return NULL;
1467 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1468 SAFE_FREE(src_w);
1469 DEBUG(0,("strstr_m: find malloc fail\n"));
1470 return NULL;
1473 p = strstr_w(src_w, find_w);
1475 if (!p) {
1476 SAFE_FREE(src_w);
1477 SAFE_FREE(find_w);
1478 return NULL;
1481 *p = 0;
1482 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1483 SAFE_FREE(src_w);
1484 SAFE_FREE(find_w);
1485 DEBUG(0,("strstr_m: dest malloc fail\n"));
1486 return NULL;
1488 retp = (char *)(s+strlen(s2));
1489 SAFE_FREE(src_w);
1490 SAFE_FREE(find_w);
1491 SAFE_FREE(s2);
1492 return retp;
1496 Convert a string to lower case.
1499 void strlower_m(char *s)
1501 size_t len;
1502 int errno_save;
1504 /* this is quite a common operation, so we want it to be
1505 fast. We optimise for the ascii case, knowing that all our
1506 supported multi-byte character sets are ascii-compatible
1507 (ie. they match for the first 128 chars) */
1509 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1510 *s = tolower_ascii((unsigned char)*s);
1511 s++;
1514 if (!*s)
1515 return;
1517 /* I assume that lowercased string takes the same number of bytes
1518 * as source string even in UTF-8 encoding. (VIV) */
1519 len = strlen(s) + 1;
1520 errno_save = errno;
1521 errno = 0;
1522 unix_strlower(s,len,s,len);
1523 /* Catch mb conversion errors that may not terminate. */
1524 if (errno)
1525 s[len-1] = '\0';
1526 errno = errno_save;
1530 Convert a string to upper case.
1533 void strupper_m(char *s)
1535 size_t len;
1536 int errno_save;
1538 /* this is quite a common operation, so we want it to be
1539 fast. We optimise for the ascii case, knowing that all our
1540 supported multi-byte character sets are ascii-compatible
1541 (ie. they match for the first 128 chars) */
1543 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1544 *s = toupper_ascii((unsigned char)*s);
1545 s++;
1548 if (!*s)
1549 return;
1551 /* I assume that lowercased string takes the same number of bytes
1552 * as source string even in multibyte encoding. (VIV) */
1553 len = strlen(s) + 1;
1554 errno_save = errno;
1555 errno = 0;
1556 unix_strupper(s,len,s,len);
1557 /* Catch mb conversion errors that may not terminate. */
1558 if (errno)
1559 s[len-1] = '\0';
1560 errno = errno_save;
1564 Return a RFC2254 binary string representation of a buffer.
1565 Used in LDAP filters.
1566 Caller must free.
1569 char *binary_string_rfc2254(char *buf, int len)
1571 char *s;
1572 int i, j;
1573 const char *hex = "0123456789ABCDEF";
1574 s = SMB_MALLOC(len * 3 + 1);
1575 if (!s)
1576 return NULL;
1577 for (j=i=0;i<len;i++) {
1578 s[j] = '\\';
1579 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1580 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1581 j += 3;
1583 s[j] = 0;
1584 return s;
1587 char *binary_string(char *buf, int len)
1589 char *s;
1590 int i, j;
1591 const char *hex = "0123456789ABCDEF";
1592 s = SMB_MALLOC(len * 2 + 1);
1593 if (!s)
1594 return NULL;
1595 for (j=i=0;i<len;i++) {
1596 s[j] = hex[((unsigned char)buf[i]) >> 4];
1597 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1598 j += 2;
1600 s[j] = 0;
1601 return s;
1604 Just a typesafety wrapper for snprintf into a pstring.
1607 int pstr_sprintf(pstring s, const char *fmt, ...)
1609 va_list ap;
1610 int ret;
1612 va_start(ap, fmt);
1613 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1614 va_end(ap);
1615 return ret;
1620 Just a typesafety wrapper for snprintf into a fstring.
1623 int fstr_sprintf(fstring s, const char *fmt, ...)
1625 va_list ap;
1626 int ret;
1628 va_start(ap, fmt);
1629 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1630 va_end(ap);
1631 return ret;
1635 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1637 Some platforms don't have strndup.
1639 #if defined(PARANOID_MALLOC_CHECKER)
1640 #undef strndup
1641 #endif
1643 char *strndup(const char *s, size_t n)
1645 char *ret;
1647 n = strnlen(s, n);
1648 ret = SMB_MALLOC(n+1);
1649 if (!ret)
1650 return NULL;
1651 memcpy(ret, s, n);
1652 ret[n] = 0;
1654 return ret;
1657 #if defined(PARANOID_MALLOC_CHECKER)
1658 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1659 #endif
1661 #endif
1663 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1665 Some platforms don't have strnlen
1668 size_t strnlen(const char *s, size_t n)
1670 size_t i;
1671 for (i=0; i<n && s[i] != '\0'; i++)
1672 /* noop */ ;
1673 return i;
1675 #endif
1678 List of Strings manipulation functions
1681 #define S_LIST_ABS 16 /* List Allocation Block Size */
1683 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1685 char **list, **rlist;
1686 const char *str;
1687 char *s;
1688 int num, lsize;
1689 pstring tok;
1691 if (!string || !*string)
1692 return NULL;
1693 if (mem_ctx) {
1694 s = talloc_strdup(mem_ctx, string);
1695 } else {
1696 s = SMB_STRDUP(string);
1698 if (!s) {
1699 DEBUG(0,("str_list_make: Unable to allocate memory"));
1700 return NULL;
1702 if (!sep) sep = LIST_SEP;
1704 num = lsize = 0;
1705 list = NULL;
1707 str = s;
1708 while (next_token(&str, tok, sep, sizeof(tok))) {
1709 if (num == lsize) {
1710 lsize += S_LIST_ABS;
1711 if (mem_ctx) {
1712 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1713 } else {
1714 /* We need to keep the old list on error so we can free the elements
1715 if the realloc fails. */
1716 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1718 if (!rlist) {
1719 DEBUG(0,("str_list_make: Unable to allocate memory"));
1720 str_list_free(&list);
1721 if (mem_ctx) {
1722 TALLOC_FREE(s);
1723 } else {
1724 SAFE_FREE(s);
1726 return NULL;
1727 } else {
1728 list = rlist;
1730 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1733 if (mem_ctx) {
1734 list[num] = talloc_strdup(mem_ctx, tok);
1735 } else {
1736 list[num] = SMB_STRDUP(tok);
1739 if (!list[num]) {
1740 DEBUG(0,("str_list_make: Unable to allocate memory"));
1741 str_list_free(&list);
1742 if (mem_ctx) {
1743 TALLOC_FREE(s);
1744 } else {
1745 SAFE_FREE(s);
1747 return NULL;
1750 num++;
1753 if (mem_ctx) {
1754 TALLOC_FREE(s);
1755 } else {
1756 SAFE_FREE(s);
1759 return list;
1762 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1764 return str_list_make_internal(mem_ctx, string, sep);
1767 char **str_list_make(const char *string, const char *sep)
1769 return str_list_make_internal(NULL, string, sep);
1772 BOOL str_list_copy(char ***dest, const char **src)
1774 char **list, **rlist;
1775 int num, lsize;
1777 *dest = NULL;
1778 if (!src)
1779 return False;
1781 num = lsize = 0;
1782 list = NULL;
1784 while (src[num]) {
1785 if (num == lsize) {
1786 lsize += S_LIST_ABS;
1787 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1788 if (!rlist) {
1789 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1790 str_list_free(&list);
1791 return False;
1792 } else {
1793 list = rlist;
1795 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1798 list[num] = SMB_STRDUP(src[num]);
1799 if (!list[num]) {
1800 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1801 str_list_free(&list);
1802 return False;
1805 num++;
1808 *dest = list;
1809 return True;
1813 * Return true if all the elements of the list match exactly.
1815 BOOL str_list_compare(char **list1, char **list2)
1817 int num;
1819 if (!list1 || !list2)
1820 return (list1 == list2);
1822 for (num = 0; list1[num]; num++) {
1823 if (!list2[num])
1824 return False;
1825 if (!strcsequal(list1[num], list2[num]))
1826 return False;
1828 if (list2[num])
1829 return False; /* if list2 has more elements than list1 fail */
1831 return True;
1834 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1836 char **tlist;
1838 if (!list || !*list)
1839 return;
1840 tlist = *list;
1841 for(; *tlist; tlist++) {
1842 if (mem_ctx) {
1843 TALLOC_FREE(*tlist);
1844 } else {
1845 SAFE_FREE(*tlist);
1848 if (mem_ctx) {
1849 TALLOC_FREE(*tlist);
1850 } else {
1851 SAFE_FREE(*list);
1855 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1857 str_list_free_internal(mem_ctx, list);
1860 void str_list_free(char ***list)
1862 str_list_free_internal(NULL, list);
1865 /******************************************************************************
1866 *****************************************************************************/
1868 int str_list_count( const char **list )
1870 int i = 0;
1872 if ( ! list )
1873 return 0;
1875 /* count the number of list members */
1877 for ( i=0; *list; i++, list++ );
1879 return i;
1882 /******************************************************************************
1883 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1884 for the work
1885 *****************************************************************************/
1887 BOOL str_list_sub_basic( char **list, const char *smb_name )
1889 char *s, *tmpstr;
1891 while ( *list ) {
1892 s = *list;
1893 tmpstr = alloc_sub_basic(smb_name, s);
1894 if ( !tmpstr ) {
1895 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1896 return False;
1899 SAFE_FREE(*list);
1900 *list = tmpstr;
1902 list++;
1905 return True;
1908 /******************************************************************************
1909 substritute a specific pattern in a string list
1910 *****************************************************************************/
1912 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1914 char *p, *s, *t;
1915 ssize_t ls, lp, li, ld, i, d;
1917 if (!list)
1918 return False;
1919 if (!pattern)
1920 return False;
1921 if (!insert)
1922 return False;
1924 lp = (ssize_t)strlen(pattern);
1925 li = (ssize_t)strlen(insert);
1926 ld = li -lp;
1928 while (*list) {
1929 s = *list;
1930 ls = (ssize_t)strlen(s);
1932 while ((p = strstr_m(s, pattern))) {
1933 t = *list;
1934 d = p -t;
1935 if (ld) {
1936 t = (char *) SMB_MALLOC(ls +ld +1);
1937 if (!t) {
1938 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1939 return False;
1941 memcpy(t, *list, d);
1942 memcpy(t +d +li, p +lp, ls -d -lp +1);
1943 SAFE_FREE(*list);
1944 *list = t;
1945 ls += ld;
1946 s = t +d +li;
1949 for (i = 0; i < li; i++) {
1950 switch (insert[i]) {
1951 case '`':
1952 case '"':
1953 case '\'':
1954 case ';':
1955 case '$':
1956 case '%':
1957 case '\r':
1958 case '\n':
1959 t[d +i] = '_';
1960 break;
1961 default:
1962 t[d +i] = insert[i];
1968 list++;
1971 return True;
1975 #define IPSTR_LIST_SEP ","
1976 #define IPSTR_LIST_CHAR ','
1979 * Add ip string representation to ipstr list. Used also
1980 * as part of @function ipstr_list_make
1982 * @param ipstr_list pointer to string containing ip list;
1983 * MUST BE already allocated and IS reallocated if necessary
1984 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1985 * as a result of reallocation)
1986 * @param ip IP address which is to be added to list
1987 * @return pointer to string appended with new ip and possibly
1988 * reallocated to new length
1991 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1993 char* new_ipstr = NULL;
1995 /* arguments checking */
1996 if (!ipstr_list || !service) return NULL;
1998 /* attempt to convert ip to a string and append colon separator to it */
1999 if (*ipstr_list) {
2000 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2001 inet_ntoa(service->ip), service->port);
2002 SAFE_FREE(*ipstr_list);
2003 } else {
2004 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2006 *ipstr_list = new_ipstr;
2007 return *ipstr_list;
2012 * Allocate and initialise an ipstr list using ip adresses
2013 * passed as arguments.
2015 * @param ipstr_list pointer to string meant to be allocated and set
2016 * @param ip_list array of ip addresses to place in the list
2017 * @param ip_count number of addresses stored in ip_list
2018 * @return pointer to allocated ip string
2021 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2023 int i;
2025 /* arguments checking */
2026 if (!ip_list || !ipstr_list) return 0;
2028 *ipstr_list = NULL;
2030 /* process ip addresses given as arguments */
2031 for (i = 0; i < ip_count; i++)
2032 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2034 return (*ipstr_list);
2039 * Parse given ip string list into array of ip addresses
2040 * (as ip_service structures)
2041 * e.g. 192.168.1.100:389,192.168.1.78, ...
2043 * @param ipstr ip string list to be parsed
2044 * @param ip_list pointer to array of ip addresses which is
2045 * allocated by this function and must be freed by caller
2046 * @return number of succesfully parsed addresses
2049 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2051 fstring token_str;
2052 size_t count;
2053 int i;
2055 if (!ipstr_list || !ip_list)
2056 return 0;
2058 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2059 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2060 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2061 return 0;
2064 for ( i=0;
2065 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2066 i++ )
2068 struct in_addr addr;
2069 unsigned port = 0;
2070 char *p = strchr(token_str, ':');
2072 if (p) {
2073 *p = 0;
2074 port = atoi(p+1);
2077 /* convert single token to ip address */
2078 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2079 break;
2081 (*ip_list)[i].ip = addr;
2082 (*ip_list)[i].port = port;
2085 return count;
2090 * Safely free ip string list
2092 * @param ipstr_list ip string list to be freed
2095 void ipstr_list_free(char* ipstr_list)
2097 SAFE_FREE(ipstr_list);
2102 Unescape a URL encoded string, in place.
2105 void rfc1738_unescape(char *buf)
2107 char *p=buf;
2109 while (p && *p && (p=strchr_m(p,'%'))) {
2110 int c1 = p[1];
2111 int c2 = p[2];
2113 if (c1 >= '0' && c1 <= '9')
2114 c1 = c1 - '0';
2115 else if (c1 >= 'A' && c1 <= 'F')
2116 c1 = 10 + c1 - 'A';
2117 else if (c1 >= 'a' && c1 <= 'f')
2118 c1 = 10 + c1 - 'a';
2119 else {p++; continue;}
2121 if (c2 >= '0' && c2 <= '9')
2122 c2 = c2 - '0';
2123 else if (c2 >= 'A' && c2 <= 'F')
2124 c2 = 10 + c2 - 'A';
2125 else if (c2 >= 'a' && c2 <= 'f')
2126 c2 = 10 + c2 - 'a';
2127 else {p++; continue;}
2129 *p = (c1<<4) | c2;
2131 memmove(p+1, p+3, strlen(p+3)+1);
2132 p++;
2136 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2139 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2141 DATA_BLOB base64_decode_data_blob(const char *s)
2143 int bit_offset, byte_offset, idx, i, n;
2144 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2145 unsigned char *d = decoded.data;
2146 char *p;
2148 n=i=0;
2150 while (*s && (p=strchr_m(b64,*s))) {
2151 idx = (int)(p - b64);
2152 byte_offset = (i*6)/8;
2153 bit_offset = (i*6)%8;
2154 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2155 if (bit_offset < 3) {
2156 d[byte_offset] |= (idx << (2-bit_offset));
2157 n = byte_offset+1;
2158 } else {
2159 d[byte_offset] |= (idx >> (bit_offset-2));
2160 d[byte_offset+1] = 0;
2161 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2162 n = byte_offset+2;
2164 s++; i++;
2167 if ((n > 0) && (*s == '=')) {
2168 n -= 1;
2171 /* fix up length */
2172 decoded.length = n;
2173 return decoded;
2177 * Decode a base64 string in-place - wrapper for the above
2179 void base64_decode_inplace(char *s)
2181 DATA_BLOB decoded = base64_decode_data_blob(s);
2183 if ( decoded.length != 0 ) {
2184 memcpy(s, decoded.data, decoded.length);
2186 /* null terminate */
2187 s[decoded.length] = '\0';
2188 } else {
2189 *s = '\0';
2192 data_blob_free(&decoded);
2196 * Encode a base64 string into a malloc()ed string caller to free.
2198 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2200 char * base64_encode_data_blob(DATA_BLOB data)
2202 int bits = 0;
2203 int char_count = 0;
2204 size_t out_cnt, len, output_len;
2205 char *result;
2207 if (!data.length || !data.data)
2208 return NULL;
2210 out_cnt = 0;
2211 len = data.length;
2212 output_len = data.length * 2;
2213 result = SMB_MALLOC(output_len); /* get us plenty of space */
2215 while (len-- && out_cnt < (data.length * 2) - 5) {
2216 int c = (unsigned char) *(data.data++);
2217 bits += c;
2218 char_count++;
2219 if (char_count == 3) {
2220 result[out_cnt++] = b64[bits >> 18];
2221 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2222 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2223 result[out_cnt++] = b64[bits & 0x3f];
2224 bits = 0;
2225 char_count = 0;
2226 } else {
2227 bits <<= 8;
2230 if (char_count != 0) {
2231 bits <<= 16 - (8 * char_count);
2232 result[out_cnt++] = b64[bits >> 18];
2233 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2234 if (char_count == 1) {
2235 result[out_cnt++] = '=';
2236 result[out_cnt++] = '=';
2237 } else {
2238 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2239 result[out_cnt++] = '=';
2242 result[out_cnt] = '\0'; /* terminate */
2243 return result;
2246 /* read a SMB_BIG_UINT from a string */
2247 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2250 SMB_BIG_UINT val = -1;
2251 const char *p = nptr;
2253 if (!p) {
2254 if (entptr) {
2255 *entptr = p;
2257 return val;
2260 while (*p && isspace(*p))
2261 p++;
2263 #ifdef LARGE_SMB_OFF_T
2264 sscanf(p,"%llu",&val);
2265 #else /* LARGE_SMB_OFF_T */
2266 sscanf(p,"%lu",&val);
2267 #endif /* LARGE_SMB_OFF_T */
2268 if (entptr) {
2269 while (*p && isdigit(*p))
2270 p++;
2271 *entptr = p;
2274 return val;
2277 void string_append(char **left, const char *right)
2279 int new_len = strlen(right) + 1;
2281 if (*left == NULL) {
2282 *left = SMB_MALLOC(new_len);
2283 *left[0] = '\0';
2284 } else {
2285 new_len += strlen(*left);
2286 *left = SMB_REALLOC(*left, new_len);
2289 if (*left == NULL) {
2290 return;
2293 safe_strcat(*left, right, new_len-1);
2296 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2297 const char *str, const char ***strings,
2298 int *num)
2300 char *dup_str = talloc_strdup(mem_ctx, str);
2302 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2304 if ((*strings == NULL) || (dup_str == NULL))
2305 return False;
2307 (*strings)[*num] = dup_str;
2308 *num += 1;
2309 return True;
2312 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2313 * error checking in between. The indiation that something weird happened is
2314 * string==NULL */
2316 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2317 size_t *bufsize, const char *fmt, ...)
2319 va_list ap;
2320 char *newstr;
2321 int ret;
2322 BOOL increased;
2324 /* len<0 is an internal marker that something failed */
2325 if (*len < 0)
2326 goto error;
2328 if (*string == NULL) {
2329 if (*bufsize == 0)
2330 *bufsize = 128;
2332 if (mem_ctx != NULL)
2333 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2334 else
2335 *string = SMB_MALLOC_ARRAY(char, *bufsize);
2337 if (*string == NULL)
2338 goto error;
2341 va_start(ap, fmt);
2342 ret = vasprintf(&newstr, fmt, ap);
2343 va_end(ap);
2345 if (ret < 0)
2346 goto error;
2348 increased = False;
2350 while ((*len)+ret >= *bufsize) {
2351 increased = True;
2352 *bufsize *= 2;
2353 if (*bufsize >= (1024*1024*256))
2354 goto error;
2357 if (increased) {
2358 if (mem_ctx != NULL) {
2359 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2360 *bufsize);
2361 } else {
2362 *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2365 if (*string == NULL) {
2366 goto error;
2370 StrnCpy((*string)+(*len), newstr, ret);
2371 (*len) += ret;
2372 free(newstr);
2373 return;
2375 error:
2376 *len = -1;
2377 if (mem_ctx == NULL) {
2378 SAFE_FREE(*string);
2380 *string = NULL;
2384 Returns the substring from src between the first occurrence of
2385 the char "front" and the first occurence of the char "back".
2386 Mallocs the return string which must be freed. Not for use
2387 with wide character strings.
2389 char *sstring_sub(const char *src, char front, char back)
2391 char *temp1, *temp2, *temp3;
2392 ptrdiff_t len;
2394 temp1 = strchr(src, front);
2395 if (temp1 == NULL) return NULL;
2396 temp2 = strchr(src, back);
2397 if (temp2 == NULL) return NULL;
2398 len = temp2 - temp1;
2399 if (len <= 0) return NULL;
2400 temp3 = (char*)SMB_MALLOC(len);
2401 if (temp3 == NULL) {
2402 DEBUG(1,("Malloc failure in sstring_sub\n"));
2403 return NULL;
2405 memcpy(temp3, temp1+1, len-1);
2406 temp3[len-1] = '\0';
2407 return temp3;
2410 /********************************************************************
2411 Check a string for any occurrences of a specified list of invalid
2412 characters.
2413 ********************************************************************/
2415 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2417 int i;
2419 for ( i=0; i<max_len && name[i]; i++ ) {
2420 /* fail if strchr_m() finds one of the invalid characters */
2421 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2422 return False;
2426 return True;