r13676: have to return a value from a non-void function
[Samba.git] / source / lib / util_str.c
blobe799556cd1ebb6ad87208561b429f38979331b7b
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 char *null_string = NULL;
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;
865 if (!src)
866 src = "";
868 l = strlen(src);
870 if (l == 0) {
871 if (!null_string) {
872 if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
873 DEBUG(0,("string_init: malloc fail for null_string.\n"));
874 return False;
876 *null_string = 0;
878 *dest = null_string;
879 } else {
880 (*dest) = SMB_STRDUP(src);
881 if ((*dest) == NULL) {
882 DEBUG(0,("Out of memory in string_init\n"));
883 return False;
886 return(True);
890 Free a string value.
893 void string_free(char **s)
895 if (!s || !(*s))
896 return;
897 if (*s == null_string)
898 *s = NULL;
899 SAFE_FREE(*s);
903 Set a string value, deallocating any existing space, and allocing the space
904 for the string
907 BOOL string_set(char **dest,const char *src)
909 string_free(dest);
910 return(string_init(dest,src));
914 Substitute a string for a pattern in another string. Make sure there is
915 enough room!
917 This routine looks for pattern in s and replaces it with
918 insert. It may do multiple replacements or just one.
920 Any of " ; ' $ or ` in the insert string are replaced with _
921 if len==0 then the string cannot be extended. This is different from the old
922 use of len==0 which was for no length checks to be done.
925 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
926 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
928 char *p;
929 ssize_t ls,lp,li, i;
931 if (!insert || !pattern || !*pattern || !s)
932 return;
934 ls = (ssize_t)strlen(s);
935 lp = (ssize_t)strlen(pattern);
936 li = (ssize_t)strlen(insert);
938 if (len == 0)
939 len = ls + 1; /* len is number of *bytes* */
941 while (lp <= ls && (p = strstr_m(s,pattern))) {
942 if (ls + (li-lp) >= len) {
943 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
944 (int)(ls + (li-lp) - len),
945 pattern, (int)len));
946 break;
948 if (li != lp) {
949 memmove(p+li,p+lp,strlen(p+lp)+1);
951 for (i=0;i<li;i++) {
952 switch (insert[i]) {
953 case '`':
954 case '"':
955 case '\'':
956 case ';':
957 case '$':
958 /* allow a trailing $ (as in machine accounts) */
959 if (allow_trailing_dollar && (i == li - 1 )) {
960 p[i] = insert[i];
961 break;
963 case '%':
964 case '\r':
965 case '\n':
966 if ( remove_unsafe_characters ) {
967 p[i] = '_';
968 /* yes this break should be here since we want to
969 fall throw if not replacing unsafe chars */
970 break;
972 default:
973 p[i] = insert[i];
976 s = p + li;
977 ls += (li-lp);
979 if (replace_once)
980 break;
984 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
986 string_sub2( s, pattern, insert, len, True, True, False );
989 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
991 string_sub2( s, pattern, insert, len, True, False, False );
994 void fstring_sub(char *s,const char *pattern,const char *insert)
996 string_sub(s, pattern, insert, sizeof(fstring));
999 void pstring_sub(char *s,const char *pattern,const char *insert)
1001 string_sub(s, pattern, insert, sizeof(pstring));
1005 Similar to string_sub, but it will accept only allocated strings
1006 and may realloc them so pay attention at what you pass on no
1007 pointers inside strings, no pstrings or const may be passed
1008 as string.
1011 char *realloc_string_sub(char *string, const char *pattern,
1012 const char *insert)
1014 char *p, *in;
1015 char *s;
1016 ssize_t ls,lp,li,ld, i;
1018 if (!insert || !pattern || !*pattern || !string || !*string)
1019 return NULL;
1021 s = string;
1023 in = SMB_STRDUP(insert);
1024 if (!in) {
1025 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1026 return NULL;
1028 ls = (ssize_t)strlen(s);
1029 lp = (ssize_t)strlen(pattern);
1030 li = (ssize_t)strlen(insert);
1031 ld = li - lp;
1032 for (i=0;i<li;i++) {
1033 switch (in[i]) {
1034 case '`':
1035 case '"':
1036 case '\'':
1037 case ';':
1038 case '$':
1039 case '%':
1040 case '\r':
1041 case '\n':
1042 in[i] = '_';
1043 default:
1044 /* ok */
1045 break;
1049 while ((p = strstr_m(s,pattern))) {
1050 if (ld > 0) {
1051 int offset = PTR_DIFF(s,string);
1052 char *t = SMB_REALLOC(string, ls + ld + 1);
1053 if (!t) {
1054 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1055 SAFE_FREE(in);
1056 return NULL;
1058 string = t;
1059 p = t + offset + (p - s);
1061 if (li != lp) {
1062 memmove(p+li,p+lp,strlen(p+lp)+1);
1064 memcpy(p, in, li);
1065 s = p + li;
1066 ls += ld;
1068 SAFE_FREE(in);
1069 return string;
1072 /* Same as string_sub, but returns a talloc'ed string */
1074 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1075 const char *pattern, const char *insert)
1077 char *p, *in;
1078 char *s;
1079 char *string;
1080 ssize_t ls,lp,li,ld, i;
1082 if (!insert || !pattern || !*pattern || !src || !*src)
1083 return NULL;
1085 string = talloc_strdup(mem_ctx, src);
1086 if (string == NULL) {
1087 DEBUG(0, ("talloc_strdup failed\n"));
1088 return NULL;
1091 s = string;
1093 in = SMB_STRDUP(insert);
1094 if (!in) {
1095 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1096 return NULL;
1098 ls = (ssize_t)strlen(s);
1099 lp = (ssize_t)strlen(pattern);
1100 li = (ssize_t)strlen(insert);
1101 ld = li - lp;
1102 for (i=0;i<li;i++) {
1103 switch (in[i]) {
1104 case '`':
1105 case '"':
1106 case '\'':
1107 case ';':
1108 case '$':
1109 case '%':
1110 case '\r':
1111 case '\n':
1112 in[i] = '_';
1113 default:
1114 /* ok */
1115 break;
1119 while ((p = strstr_m(s,pattern))) {
1120 if (ld > 0) {
1121 int offset = PTR_DIFF(s,string);
1122 char *t = TALLOC_REALLOC(mem_ctx, string, ls + ld + 1);
1123 if (!t) {
1124 DEBUG(0, ("talloc_string_sub: out of "
1125 "memory!\n"));
1126 SAFE_FREE(in);
1127 return NULL;
1129 string = t;
1130 p = t + offset + (p - s);
1132 if (li != lp) {
1133 memmove(p+li,p+lp,strlen(p+lp)+1);
1135 memcpy(p, in, li);
1136 s = p + li;
1137 ls += ld;
1139 SAFE_FREE(in);
1140 return string;
1144 Similar to string_sub() but allows for any character to be substituted.
1145 Use with caution!
1146 if len==0 then the string cannot be extended. This is different from the old
1147 use of len==0 which was for no length checks to be done.
1150 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1152 char *p;
1153 ssize_t ls,lp,li;
1155 if (!insert || !pattern || !s)
1156 return;
1158 ls = (ssize_t)strlen(s);
1159 lp = (ssize_t)strlen(pattern);
1160 li = (ssize_t)strlen(insert);
1162 if (!*pattern)
1163 return;
1165 if (len == 0)
1166 len = ls + 1; /* len is number of *bytes* */
1168 while (lp <= ls && (p = strstr_m(s,pattern))) {
1169 if (ls + (li-lp) >= len) {
1170 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1171 (int)(ls + (li-lp) - len),
1172 pattern, (int)len));
1173 break;
1175 if (li != lp) {
1176 memmove(p+li,p+lp,strlen(p+lp)+1);
1178 memcpy(p, insert, li);
1179 s = p + li;
1180 ls += (li-lp);
1185 Similar to all_string_sub but for unicode strings.
1186 Return a new allocated unicode string.
1187 similar to string_sub() but allows for any character to be substituted.
1188 Use with caution!
1191 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1192 const smb_ucs2_t *insert)
1194 smb_ucs2_t *r, *rp;
1195 const smb_ucs2_t *sp;
1196 size_t lr, lp, li, lt;
1198 if (!insert || !pattern || !*pattern || !s)
1199 return NULL;
1201 lt = (size_t)strlen_w(s);
1202 lp = (size_t)strlen_w(pattern);
1203 li = (size_t)strlen_w(insert);
1205 if (li > lp) {
1206 const smb_ucs2_t *st = s;
1207 int ld = li - lp;
1208 while ((sp = strstr_w(st, pattern))) {
1209 st = sp + lp;
1210 lt += ld;
1214 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1215 if (!r) {
1216 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1217 return NULL;
1220 while ((sp = strstr_w(s, pattern))) {
1221 memcpy(rp, s, (sp - s));
1222 rp += ((sp - s) / sizeof(smb_ucs2_t));
1223 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1224 s = sp + lp;
1225 rp += li;
1227 lr = ((rp - r) / sizeof(smb_ucs2_t));
1228 if (lr < lt) {
1229 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1230 rp += (lt - lr);
1232 *rp = 0;
1234 return r;
1237 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1238 const char *insert)
1240 wpstring p, i;
1242 if (!insert || !pattern || !s)
1243 return NULL;
1244 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1245 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1246 return all_string_sub_w(s, p, i);
1249 #if 0
1251 Splits out the front and back at a separator.
1254 static void split_at_last_component(char *path, char *front, char sep, char *back)
1256 char *p = strrchr_m(path, sep);
1258 if (p != NULL)
1259 *p = 0;
1261 if (front != NULL)
1262 pstrcpy(front, path);
1264 if (p != NULL) {
1265 if (back != NULL)
1266 pstrcpy(back, p+1);
1267 *p = '\\';
1268 } else {
1269 if (back != NULL)
1270 back[0] = 0;
1273 #endif
1276 Write an octal as a string.
1279 const char *octal_string(int i)
1281 static char ret[64];
1282 if (i == -1)
1283 return "-1";
1284 slprintf(ret, sizeof(ret)-1, "0%o", i);
1285 return ret;
1290 Truncate a string at a specified length.
1293 char *string_truncate(char *s, unsigned int length)
1295 if (s && strlen(s) > length)
1296 s[length] = 0;
1297 return s;
1301 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1302 We convert via ucs2 for now.
1305 char *strchr_m(const char *src, char c)
1307 wpstring ws;
1308 pstring s2;
1309 smb_ucs2_t *p;
1310 const char *s;
1312 /* characters below 0x3F are guaranteed to not appear in
1313 non-initial position in multi-byte charsets */
1314 if ((c & 0xC0) == 0) {
1315 return strchr(src, c);
1318 /* this is quite a common operation, so we want it to be
1319 fast. We optimise for the ascii case, knowing that all our
1320 supported multi-byte character sets are ascii-compatible
1321 (ie. they match for the first 128 chars) */
1323 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1324 if (*s == c)
1325 return (char *)s;
1328 if (!*s)
1329 return NULL;
1331 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1332 /* With compose characters we must restart from the beginning. JRA. */
1333 s = src;
1334 #endif
1336 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1337 p = strchr_w(ws, UCS2_CHAR(c));
1338 if (!p)
1339 return NULL;
1340 *p = 0;
1341 pull_ucs2_pstring(s2, ws);
1342 return (char *)(s+strlen(s2));
1345 char *strrchr_m(const char *s, char c)
1347 /* characters below 0x3F are guaranteed to not appear in
1348 non-initial position in multi-byte charsets */
1349 if ((c & 0xC0) == 0) {
1350 return strrchr(s, c);
1353 /* this is quite a common operation, so we want it to be
1354 fast. We optimise for the ascii case, knowing that all our
1355 supported multi-byte character sets are ascii-compatible
1356 (ie. they match for the first 128 chars). Also, in Samba
1357 we only search for ascii characters in 'c' and that
1358 in all mb character sets with a compound character
1359 containing c, if 'c' is not a match at position
1360 p, then p[-1] > 0x7f. JRA. */
1363 size_t len = strlen(s);
1364 const char *cp = s;
1365 BOOL got_mb = False;
1367 if (len == 0)
1368 return NULL;
1369 cp += (len - 1);
1370 do {
1371 if (c == *cp) {
1372 /* Could be a match. Part of a multibyte ? */
1373 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1374 /* Yep - go slow :-( */
1375 got_mb = True;
1376 break;
1378 /* No - we have a match ! */
1379 return (char *)cp;
1381 } while (cp-- != s);
1382 if (!got_mb)
1383 return NULL;
1386 /* String contained a non-ascii char. Slow path. */
1388 wpstring ws;
1389 pstring s2;
1390 smb_ucs2_t *p;
1392 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1393 p = strrchr_w(ws, UCS2_CHAR(c));
1394 if (!p)
1395 return NULL;
1396 *p = 0;
1397 pull_ucs2_pstring(s2, ws);
1398 return (char *)(s+strlen(s2));
1402 /***********************************************************************
1403 Return the equivalent of doing strrchr 'n' times - always going
1404 backwards.
1405 ***********************************************************************/
1407 char *strnrchr_m(const char *s, char c, unsigned int n)
1409 wpstring ws;
1410 pstring s2;
1411 smb_ucs2_t *p;
1413 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1414 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1415 if (!p)
1416 return NULL;
1417 *p = 0;
1418 pull_ucs2_pstring(s2, ws);
1419 return (char *)(s+strlen(s2));
1422 /***********************************************************************
1423 strstr_m - We convert via ucs2 for now.
1424 ***********************************************************************/
1426 char *strstr_m(const char *src, const char *findstr)
1428 smb_ucs2_t *p;
1429 smb_ucs2_t *src_w, *find_w;
1430 const char *s;
1431 char *s2;
1432 char *retp;
1434 size_t findstr_len = 0;
1436 /* for correctness */
1437 if (!findstr[0]) {
1438 return (char*)src;
1441 /* Samba does single character findstr calls a *lot*. */
1442 if (findstr[1] == '\0')
1443 return strchr_m(src, *findstr);
1445 /* We optimise for the ascii case, knowing that all our
1446 supported multi-byte character sets are ascii-compatible
1447 (ie. they match for the first 128 chars) */
1449 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1450 if (*s == *findstr) {
1451 if (!findstr_len)
1452 findstr_len = strlen(findstr);
1454 if (strncmp(s, findstr, findstr_len) == 0) {
1455 return (char *)s;
1460 if (!*s)
1461 return NULL;
1463 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1464 /* 'make check' fails unless we do this */
1466 /* With compose characters we must restart from the beginning. JRA. */
1467 s = src;
1468 #endif
1470 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1471 DEBUG(0,("strstr_m: src malloc fail\n"));
1472 return NULL;
1475 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1476 SAFE_FREE(src_w);
1477 DEBUG(0,("strstr_m: find malloc fail\n"));
1478 return NULL;
1481 p = strstr_w(src_w, find_w);
1483 if (!p) {
1484 SAFE_FREE(src_w);
1485 SAFE_FREE(find_w);
1486 return NULL;
1489 *p = 0;
1490 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1491 SAFE_FREE(src_w);
1492 SAFE_FREE(find_w);
1493 DEBUG(0,("strstr_m: dest malloc fail\n"));
1494 return NULL;
1496 retp = (char *)(s+strlen(s2));
1497 SAFE_FREE(src_w);
1498 SAFE_FREE(find_w);
1499 SAFE_FREE(s2);
1500 return retp;
1504 Convert a string to lower case.
1507 void strlower_m(char *s)
1509 size_t len;
1510 int errno_save;
1512 /* this is quite a common operation, so we want it to be
1513 fast. We optimise for the ascii case, knowing that all our
1514 supported multi-byte character sets are ascii-compatible
1515 (ie. they match for the first 128 chars) */
1517 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1518 *s = tolower_ascii((unsigned char)*s);
1519 s++;
1522 if (!*s)
1523 return;
1525 /* I assume that lowercased string takes the same number of bytes
1526 * as source string even in UTF-8 encoding. (VIV) */
1527 len = strlen(s) + 1;
1528 errno_save = errno;
1529 errno = 0;
1530 unix_strlower(s,len,s,len);
1531 /* Catch mb conversion errors that may not terminate. */
1532 if (errno)
1533 s[len-1] = '\0';
1534 errno = errno_save;
1538 Convert a string to upper case.
1541 void strupper_m(char *s)
1543 size_t len;
1544 int errno_save;
1546 /* this is quite a common operation, so we want it to be
1547 fast. We optimise for the ascii case, knowing that all our
1548 supported multi-byte character sets are ascii-compatible
1549 (ie. they match for the first 128 chars) */
1551 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1552 *s = toupper_ascii((unsigned char)*s);
1553 s++;
1556 if (!*s)
1557 return;
1559 /* I assume that lowercased string takes the same number of bytes
1560 * as source string even in multibyte encoding. (VIV) */
1561 len = strlen(s) + 1;
1562 errno_save = errno;
1563 errno = 0;
1564 unix_strupper(s,len,s,len);
1565 /* Catch mb conversion errors that may not terminate. */
1566 if (errno)
1567 s[len-1] = '\0';
1568 errno = errno_save;
1572 Return a RFC2254 binary string representation of a buffer.
1573 Used in LDAP filters.
1574 Caller must free.
1577 char *binary_string(char *buf, int len)
1579 char *s;
1580 int i, j;
1581 const char *hex = "0123456789ABCDEF";
1582 s = SMB_MALLOC(len * 3 + 1);
1583 if (!s)
1584 return NULL;
1585 for (j=i=0;i<len;i++) {
1586 s[j] = '\\';
1587 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1588 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1589 j += 3;
1591 s[j] = 0;
1592 return s;
1596 Just a typesafety wrapper for snprintf into a pstring.
1599 int pstr_sprintf(pstring s, const char *fmt, ...)
1601 va_list ap;
1602 int ret;
1604 va_start(ap, fmt);
1605 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1606 va_end(ap);
1607 return ret;
1612 Just a typesafety wrapper for snprintf into a fstring.
1615 int fstr_sprintf(fstring s, const char *fmt, ...)
1617 va_list ap;
1618 int ret;
1620 va_start(ap, fmt);
1621 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1622 va_end(ap);
1623 return ret;
1627 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1629 Some platforms don't have strndup.
1631 #if defined(PARANOID_MALLOC_CHECKER)
1632 #undef strndup
1633 #endif
1635 char *strndup(const char *s, size_t n)
1637 char *ret;
1639 n = strnlen(s, n);
1640 ret = SMB_MALLOC(n+1);
1641 if (!ret)
1642 return NULL;
1643 memcpy(ret, s, n);
1644 ret[n] = 0;
1646 return ret;
1649 #if defined(PARANOID_MALLOC_CHECKER)
1650 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1651 #endif
1653 #endif
1655 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1657 Some platforms don't have strnlen
1660 size_t strnlen(const char *s, size_t n)
1662 size_t i;
1663 for (i=0; i<n && s[i] != '\0'; i++)
1664 /* noop */ ;
1665 return i;
1667 #endif
1670 List of Strings manipulation functions
1673 #define S_LIST_ABS 16 /* List Allocation Block Size */
1675 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1677 char **list, **rlist;
1678 const char *str;
1679 char *s;
1680 int num, lsize;
1681 pstring tok;
1683 if (!string || !*string)
1684 return NULL;
1685 if (mem_ctx) {
1686 s = talloc_strdup(mem_ctx, string);
1687 } else {
1688 s = SMB_STRDUP(string);
1690 if (!s) {
1691 DEBUG(0,("str_list_make: Unable to allocate memory"));
1692 return NULL;
1694 if (!sep) sep = LIST_SEP;
1696 num = lsize = 0;
1697 list = NULL;
1699 str = s;
1700 while (next_token(&str, tok, sep, sizeof(tok))) {
1701 if (num == lsize) {
1702 lsize += S_LIST_ABS;
1703 if (mem_ctx) {
1704 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1705 } else {
1706 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1708 if (!rlist) {
1709 DEBUG(0,("str_list_make: Unable to allocate memory"));
1710 str_list_free(&list);
1711 if (mem_ctx) {
1712 TALLOC_FREE(s);
1713 } else {
1714 SAFE_FREE(s);
1716 return NULL;
1717 } else
1718 list = rlist;
1719 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1722 if (mem_ctx) {
1723 list[num] = talloc_strdup(mem_ctx, tok);
1724 } else {
1725 list[num] = SMB_STRDUP(tok);
1728 if (!list[num]) {
1729 DEBUG(0,("str_list_make: Unable to allocate memory"));
1730 str_list_free(&list);
1731 if (mem_ctx) {
1732 TALLOC_FREE(s);
1733 } else {
1734 SAFE_FREE(s);
1736 return NULL;
1739 num++;
1742 if (mem_ctx) {
1743 TALLOC_FREE(s);
1744 } else {
1745 SAFE_FREE(s);
1748 return list;
1751 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1753 return str_list_make_internal(mem_ctx, string, sep);
1756 char **str_list_make(const char *string, const char *sep)
1758 return str_list_make_internal(NULL, string, sep);
1761 BOOL str_list_copy(char ***dest, const char **src)
1763 char **list, **rlist;
1764 int num, lsize;
1766 *dest = NULL;
1767 if (!src)
1768 return False;
1770 num = lsize = 0;
1771 list = NULL;
1773 while (src[num]) {
1774 if (num == lsize) {
1775 lsize += S_LIST_ABS;
1776 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1777 if (!rlist) {
1778 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1779 str_list_free(&list);
1780 return False;
1781 } else
1782 list = rlist;
1783 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1786 list[num] = SMB_STRDUP(src[num]);
1787 if (!list[num]) {
1788 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1789 str_list_free(&list);
1790 return False;
1793 num++;
1796 *dest = list;
1797 return True;
1801 * Return true if all the elements of the list match exactly.
1803 BOOL str_list_compare(char **list1, char **list2)
1805 int num;
1807 if (!list1 || !list2)
1808 return (list1 == list2);
1810 for (num = 0; list1[num]; num++) {
1811 if (!list2[num])
1812 return False;
1813 if (!strcsequal(list1[num], list2[num]))
1814 return False;
1816 if (list2[num])
1817 return False; /* if list2 has more elements than list1 fail */
1819 return True;
1822 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1824 char **tlist;
1826 if (!list || !*list)
1827 return;
1828 tlist = *list;
1829 for(; *tlist; tlist++) {
1830 if (mem_ctx) {
1831 TALLOC_FREE(*tlist);
1832 } else {
1833 SAFE_FREE(*tlist);
1836 if (mem_ctx) {
1837 TALLOC_FREE(*tlist);
1838 } else {
1839 SAFE_FREE(*list);
1843 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1845 str_list_free_internal(mem_ctx, list);
1848 void str_list_free(char ***list)
1850 str_list_free_internal(NULL, list);
1853 /******************************************************************************
1854 *****************************************************************************/
1856 int str_list_count( const char **list )
1858 int i = 0;
1860 if ( ! list )
1861 return 0;
1863 /* count the number of list members */
1865 for ( i=0; *list; i++, list++ );
1867 return i;
1870 /******************************************************************************
1871 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1872 for the work
1873 *****************************************************************************/
1875 BOOL str_list_sub_basic( char **list, const char *smb_name )
1877 char *s, *tmpstr;
1879 while ( *list ) {
1880 s = *list;
1881 tmpstr = alloc_sub_basic(smb_name, s);
1882 if ( !tmpstr ) {
1883 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1884 return False;
1887 SAFE_FREE(*list);
1888 *list = tmpstr;
1890 list++;
1893 return True;
1896 /******************************************************************************
1897 substritute a specific pattern in a string list
1898 *****************************************************************************/
1900 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1902 char *p, *s, *t;
1903 ssize_t ls, lp, li, ld, i, d;
1905 if (!list)
1906 return False;
1907 if (!pattern)
1908 return False;
1909 if (!insert)
1910 return False;
1912 lp = (ssize_t)strlen(pattern);
1913 li = (ssize_t)strlen(insert);
1914 ld = li -lp;
1916 while (*list) {
1917 s = *list;
1918 ls = (ssize_t)strlen(s);
1920 while ((p = strstr_m(s, pattern))) {
1921 t = *list;
1922 d = p -t;
1923 if (ld) {
1924 t = (char *) SMB_MALLOC(ls +ld +1);
1925 if (!t) {
1926 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1927 return False;
1929 memcpy(t, *list, d);
1930 memcpy(t +d +li, p +lp, ls -d -lp +1);
1931 SAFE_FREE(*list);
1932 *list = t;
1933 ls += ld;
1934 s = t +d +li;
1937 for (i = 0; i < li; i++) {
1938 switch (insert[i]) {
1939 case '`':
1940 case '"':
1941 case '\'':
1942 case ';':
1943 case '$':
1944 case '%':
1945 case '\r':
1946 case '\n':
1947 t[d +i] = '_';
1948 break;
1949 default:
1950 t[d +i] = insert[i];
1956 list++;
1959 return True;
1963 #define IPSTR_LIST_SEP ","
1964 #define IPSTR_LIST_CHAR ','
1967 * Add ip string representation to ipstr list. Used also
1968 * as part of @function ipstr_list_make
1970 * @param ipstr_list pointer to string containing ip list;
1971 * MUST BE already allocated and IS reallocated if necessary
1972 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1973 * as a result of reallocation)
1974 * @param ip IP address which is to be added to list
1975 * @return pointer to string appended with new ip and possibly
1976 * reallocated to new length
1979 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1981 char* new_ipstr = NULL;
1983 /* arguments checking */
1984 if (!ipstr_list || !service) return NULL;
1986 /* attempt to convert ip to a string and append colon separator to it */
1987 if (*ipstr_list) {
1988 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1989 inet_ntoa(service->ip), service->port);
1990 SAFE_FREE(*ipstr_list);
1991 } else {
1992 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1994 *ipstr_list = new_ipstr;
1995 return *ipstr_list;
2000 * Allocate and initialise an ipstr list using ip adresses
2001 * passed as arguments.
2003 * @param ipstr_list pointer to string meant to be allocated and set
2004 * @param ip_list array of ip addresses to place in the list
2005 * @param ip_count number of addresses stored in ip_list
2006 * @return pointer to allocated ip string
2009 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2011 int i;
2013 /* arguments checking */
2014 if (!ip_list && !ipstr_list) return 0;
2016 *ipstr_list = NULL;
2018 /* process ip addresses given as arguments */
2019 for (i = 0; i < ip_count; i++)
2020 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2022 return (*ipstr_list);
2027 * Parse given ip string list into array of ip addresses
2028 * (as ip_service structures)
2029 * e.g. 192.168.1.100:389,192.168.1.78, ...
2031 * @param ipstr ip string list to be parsed
2032 * @param ip_list pointer to array of ip addresses which is
2033 * allocated by this function and must be freed by caller
2034 * @return number of succesfully parsed addresses
2037 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2039 fstring token_str;
2040 size_t count;
2041 int i;
2043 if (!ipstr_list || !ip_list)
2044 return 0;
2046 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2047 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2048 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2049 return 0;
2052 for ( i=0;
2053 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2054 i++ )
2056 struct in_addr addr;
2057 unsigned port = 0;
2058 char *p = strchr(token_str, ':');
2060 if (p) {
2061 *p = 0;
2062 port = atoi(p+1);
2065 /* convert single token to ip address */
2066 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2067 break;
2069 (*ip_list)[i].ip = addr;
2070 (*ip_list)[i].port = port;
2073 return count;
2078 * Safely free ip string list
2080 * @param ipstr_list ip string list to be freed
2083 void ipstr_list_free(char* ipstr_list)
2085 SAFE_FREE(ipstr_list);
2090 Unescape a URL encoded string, in place.
2093 void rfc1738_unescape(char *buf)
2095 char *p=buf;
2097 while (p && *p && (p=strchr_m(p,'%'))) {
2098 int c1 = p[1];
2099 int c2 = p[2];
2101 if (c1 >= '0' && c1 <= '9')
2102 c1 = c1 - '0';
2103 else if (c1 >= 'A' && c1 <= 'F')
2104 c1 = 10 + c1 - 'A';
2105 else if (c1 >= 'a' && c1 <= 'f')
2106 c1 = 10 + c1 - 'a';
2107 else {p++; continue;}
2109 if (c2 >= '0' && c2 <= '9')
2110 c2 = c2 - '0';
2111 else if (c2 >= 'A' && c2 <= 'F')
2112 c2 = 10 + c2 - 'A';
2113 else if (c2 >= 'a' && c2 <= 'f')
2114 c2 = 10 + c2 - 'a';
2115 else {p++; continue;}
2117 *p = (c1<<4) | c2;
2119 memmove(p+1, p+3, strlen(p+3)+1);
2120 p++;
2124 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2127 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2129 DATA_BLOB base64_decode_data_blob(const char *s)
2131 int bit_offset, byte_offset, idx, i, n;
2132 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2133 unsigned char *d = decoded.data;
2134 char *p;
2136 n=i=0;
2138 while (*s && (p=strchr_m(b64,*s))) {
2139 idx = (int)(p - b64);
2140 byte_offset = (i*6)/8;
2141 bit_offset = (i*6)%8;
2142 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2143 if (bit_offset < 3) {
2144 d[byte_offset] |= (idx << (2-bit_offset));
2145 n = byte_offset+1;
2146 } else {
2147 d[byte_offset] |= (idx >> (bit_offset-2));
2148 d[byte_offset+1] = 0;
2149 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2150 n = byte_offset+2;
2152 s++; i++;
2155 if ((n > 0) && (*s == '=')) {
2156 n -= 1;
2159 /* fix up length */
2160 decoded.length = n;
2161 return decoded;
2165 * Decode a base64 string in-place - wrapper for the above
2167 void base64_decode_inplace(char *s)
2169 DATA_BLOB decoded = base64_decode_data_blob(s);
2171 if ( decoded.length != 0 ) {
2172 memcpy(s, decoded.data, decoded.length);
2174 /* null terminate */
2175 s[decoded.length] = '\0';
2176 } else {
2177 *s = '\0';
2180 data_blob_free(&decoded);
2184 * Encode a base64 string into a malloc()ed string caller to free.
2186 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2188 char * base64_encode_data_blob(DATA_BLOB data)
2190 int bits = 0;
2191 int char_count = 0;
2192 size_t out_cnt, len, output_len;
2193 char *result;
2195 if (!data.length || !data.data)
2196 return NULL;
2198 out_cnt = 0;
2199 len = data.length;
2200 output_len = data.length * 2;
2201 result = SMB_MALLOC(output_len); /* get us plenty of space */
2203 while (len-- && out_cnt < (data.length * 2) - 5) {
2204 int c = (unsigned char) *(data.data++);
2205 bits += c;
2206 char_count++;
2207 if (char_count == 3) {
2208 result[out_cnt++] = b64[bits >> 18];
2209 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2210 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2211 result[out_cnt++] = b64[bits & 0x3f];
2212 bits = 0;
2213 char_count = 0;
2214 } else {
2215 bits <<= 8;
2218 if (char_count != 0) {
2219 bits <<= 16 - (8 * char_count);
2220 result[out_cnt++] = b64[bits >> 18];
2221 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2222 if (char_count == 1) {
2223 result[out_cnt++] = '=';
2224 result[out_cnt++] = '=';
2225 } else {
2226 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2227 result[out_cnt++] = '=';
2230 result[out_cnt] = '\0'; /* terminate */
2231 return result;
2234 /* read a SMB_BIG_UINT from a string */
2235 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2238 SMB_BIG_UINT val = -1;
2239 const char *p = nptr;
2241 while (p && *p && isspace(*p))
2242 p++;
2243 #ifdef LARGE_SMB_OFF_T
2244 sscanf(p,"%llu",&val);
2245 #else /* LARGE_SMB_OFF_T */
2246 sscanf(p,"%lu",&val);
2247 #endif /* LARGE_SMB_OFF_T */
2248 if (entptr) {
2249 while (p && *p && isdigit(*p))
2250 p++;
2251 *entptr = p;
2254 return val;
2257 void string_append(char **left, const char *right)
2259 int new_len = strlen(right) + 1;
2261 if (*left == NULL) {
2262 *left = SMB_MALLOC(new_len);
2263 *left[0] = '\0';
2264 } else {
2265 new_len += strlen(*left);
2266 *left = SMB_REALLOC(*left, new_len);
2269 if (*left == NULL)
2270 return;
2272 safe_strcat(*left, right, new_len-1);
2275 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2276 const char *str, const char ***strings,
2277 int *num)
2279 char *dup_str = talloc_strdup(mem_ctx, str);
2281 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2283 if ((*strings == NULL) || (dup_str == NULL))
2284 return False;
2286 (*strings)[*num] = dup_str;
2287 *num += 1;
2288 return True;
2291 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2292 * error checking in between. The indiation that something weird happened is
2293 * string==NULL */
2295 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2296 size_t *bufsize, const char *fmt, ...)
2298 va_list ap;
2299 char *newstr;
2300 int ret;
2301 BOOL increased;
2303 /* len<0 is an internal marker that something failed */
2304 if (*len < 0)
2305 goto error;
2307 if (*string == NULL) {
2308 if (*bufsize == 0)
2309 *bufsize = 128;
2311 if (mem_ctx != NULL)
2312 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2313 else
2314 *string = SMB_MALLOC_ARRAY(char, *bufsize);
2316 if (*string == NULL)
2317 goto error;
2320 va_start(ap, fmt);
2321 ret = vasprintf(&newstr, fmt, ap);
2322 va_end(ap);
2324 if (ret < 0)
2325 goto error;
2327 increased = False;
2329 while ((*len)+ret >= *bufsize) {
2330 increased = True;
2331 *bufsize *= 2;
2332 if (*bufsize >= (1024*1024*256))
2333 goto error;
2336 if (increased) {
2337 if (mem_ctx != NULL)
2338 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2339 *bufsize);
2340 else
2341 *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2343 if (*string == NULL)
2344 goto error;
2347 StrnCpy((*string)+(*len), newstr, ret);
2348 (*len) += ret;
2349 free(newstr);
2350 return;
2352 error:
2353 *len = -1;
2354 *string = NULL;
2358 Returns the substring from src between the first occurrence of
2359 the char "front" and the first occurence of the char "back".
2360 Mallocs the return string which must be freed. Not for use
2361 with wide character strings.
2363 char *sstring_sub(const char *src, char front, char back)
2365 char *temp1, *temp2, *temp3;
2366 ptrdiff_t len;
2368 temp1 = strchr(src, front);
2369 if (temp1 == NULL) return NULL;
2370 temp2 = strchr(src, back);
2371 if (temp2 == NULL) return NULL;
2372 len = temp2 - temp1;
2373 if (len <= 0) return NULL;
2374 temp3 = (char*)SMB_MALLOC(len);
2375 if (temp3 == NULL) {
2376 DEBUG(1,("Malloc failure in sstring_sub\n"));
2377 return NULL;
2379 memcpy(temp3, temp1+1, len-1);
2380 temp3[len-1] = '\0';
2381 return temp3;
2384 /********************************************************************
2385 Check a string for any occurrences of a specified list of invalid
2386 characters.
2387 ********************************************************************/
2389 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2391 int i;
2393 for ( i=0; i<max_len && name[i]; i++ ) {
2394 /* fail if strchr_m() finds one of the invalid characters */
2395 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2396 return False;
2400 return True;