r10400: commit merge patch from jra
[Samba.git] / source / lib / util_str.c
blob567e70d8c21bd4fa0b205a3b22e8099298ae901a
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(*ps);
205 ut = toupper(*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(*psz1) != toupper(*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(val) || islower(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(strhex[i]))))
778 break;
780 i++; /* next hex digit */
782 if (!(p2 = strchr_m(hexchars, toupper(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(const char *strhex)
800 DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
802 ret_blob.length = strhex_to_str((char*)ret_blob.data,
803 strlen(strhex),
804 strhex);
806 return ret_blob;
810 * Routine to print a buffer as HEX digits, into an allocated string.
813 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
815 int i;
816 char *hex_buffer;
818 *out_hex_buffer = SMB_XMALLOC_ARRAY(char, (len*2)+1);
819 hex_buffer = *out_hex_buffer;
821 for (i = 0; i < len; i++)
822 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
826 Check if a string is part of a list.
829 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
831 pstring tok;
832 const char *p=list;
834 if (!list)
835 return(False);
837 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
838 if (casesensitive) {
839 if (strcmp(tok,s) == 0)
840 return(True);
841 } else {
842 if (StrCaseCmp(tok,s) == 0)
843 return(True);
846 return(False);
849 /* this is used to prevent lots of mallocs of size 1 */
850 static char *null_string = NULL;
853 Set a string value, allocing the space for the string
856 static BOOL string_init(char **dest,const char *src)
858 size_t l;
859 if (!src)
860 src = "";
862 l = strlen(src);
864 if (l == 0) {
865 if (!null_string) {
866 if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
867 DEBUG(0,("string_init: malloc fail for null_string.\n"));
868 return False;
870 *null_string = 0;
872 *dest = 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)
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 case '%':
953 case '\r':
954 case '\n':
955 if ( remove_unsafe_characters ) {
956 p[i] = '_';
957 /* yes this break should be here since we want to
958 fall throw if not replacing unsafe chars */
959 break;
961 default:
962 p[i] = insert[i];
965 s = p + li;
966 ls += (li-lp);
968 if (replace_once)
969 break;
973 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
975 string_sub2( s, pattern, insert, len, True, True );
978 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
980 string_sub2( s, pattern, insert, len, True, False );
983 void fstring_sub(char *s,const char *pattern,const char *insert)
985 string_sub(s, pattern, insert, sizeof(fstring));
988 void pstring_sub(char *s,const char *pattern,const char *insert)
990 string_sub(s, pattern, insert, sizeof(pstring));
994 Similar to string_sub, but it will accept only allocated strings
995 and may realloc them so pay attention at what you pass on no
996 pointers inside strings, no pstrings or const may be passed
997 as string.
1000 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
1002 char *p, *in;
1003 char *s;
1004 ssize_t ls,lp,li,ld, i;
1006 if (!insert || !pattern || !*pattern || !string || !*string)
1007 return NULL;
1009 s = string;
1011 in = SMB_STRDUP(insert);
1012 if (!in) {
1013 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1014 return NULL;
1016 ls = (ssize_t)strlen(s);
1017 lp = (ssize_t)strlen(pattern);
1018 li = (ssize_t)strlen(insert);
1019 ld = li - lp;
1020 for (i=0;i<li;i++) {
1021 switch (in[i]) {
1022 case '`':
1023 case '"':
1024 case '\'':
1025 case ';':
1026 case '$':
1027 case '%':
1028 case '\r':
1029 case '\n':
1030 in[i] = '_';
1031 default:
1032 /* ok */
1033 break;
1037 while ((p = strstr_m(s,pattern))) {
1038 if (ld > 0) {
1039 int offset = PTR_DIFF(s,string);
1040 char *t = SMB_REALLOC(string, ls + ld + 1);
1041 if (!t) {
1042 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1043 SAFE_FREE(in);
1044 return NULL;
1046 string = t;
1047 p = t + offset + (p - s);
1049 if (li != lp) {
1050 memmove(p+li,p+lp,strlen(p+lp)+1);
1052 memcpy(p, in, li);
1053 s = p + li;
1054 ls += ld;
1056 SAFE_FREE(in);
1057 return string;
1061 Similar to string_sub() but allows for any character to be substituted.
1062 Use with caution!
1063 if len==0 then the string cannot be extended. This is different from the old
1064 use of len==0 which was for no length checks to be done.
1067 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1069 char *p;
1070 ssize_t ls,lp,li;
1072 if (!insert || !pattern || !s)
1073 return;
1075 ls = (ssize_t)strlen(s);
1076 lp = (ssize_t)strlen(pattern);
1077 li = (ssize_t)strlen(insert);
1079 if (!*pattern)
1080 return;
1082 if (len == 0)
1083 len = ls + 1; /* len is number of *bytes* */
1085 while (lp <= ls && (p = strstr_m(s,pattern))) {
1086 if (ls + (li-lp) >= len) {
1087 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1088 (int)(ls + (li-lp) - len),
1089 pattern, (int)len));
1090 break;
1092 if (li != lp) {
1093 memmove(p+li,p+lp,strlen(p+lp)+1);
1095 memcpy(p, insert, li);
1096 s = p + li;
1097 ls += (li-lp);
1102 Similar to all_string_sub but for unicode strings.
1103 Return a new allocated unicode string.
1104 similar to string_sub() but allows for any character to be substituted.
1105 Use with caution!
1108 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1109 const smb_ucs2_t *insert)
1111 smb_ucs2_t *r, *rp;
1112 const smb_ucs2_t *sp;
1113 size_t lr, lp, li, lt;
1115 if (!insert || !pattern || !*pattern || !s)
1116 return NULL;
1118 lt = (size_t)strlen_w(s);
1119 lp = (size_t)strlen_w(pattern);
1120 li = (size_t)strlen_w(insert);
1122 if (li > lp) {
1123 const smb_ucs2_t *st = s;
1124 int ld = li - lp;
1125 while ((sp = strstr_w(st, pattern))) {
1126 st = sp + lp;
1127 lt += ld;
1131 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1132 if (!r) {
1133 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1134 return NULL;
1137 while ((sp = strstr_w(s, pattern))) {
1138 memcpy(rp, s, (sp - s));
1139 rp += ((sp - s) / sizeof(smb_ucs2_t));
1140 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1141 s = sp + lp;
1142 rp += li;
1144 lr = ((rp - r) / sizeof(smb_ucs2_t));
1145 if (lr < lt) {
1146 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1147 rp += (lt - lr);
1149 *rp = 0;
1151 return r;
1154 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1155 const char *insert)
1157 wpstring p, i;
1159 if (!insert || !pattern || !s)
1160 return NULL;
1161 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1162 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1163 return all_string_sub_w(s, p, i);
1166 #if 0
1168 Splits out the front and back at a separator.
1171 static void split_at_last_component(char *path, char *front, char sep, char *back)
1173 char *p = strrchr_m(path, sep);
1175 if (p != NULL)
1176 *p = 0;
1178 if (front != NULL)
1179 pstrcpy(front, path);
1181 if (p != NULL) {
1182 if (back != NULL)
1183 pstrcpy(back, p+1);
1184 *p = '\\';
1185 } else {
1186 if (back != NULL)
1187 back[0] = 0;
1190 #endif
1193 Write an octal as a string.
1196 const char *octal_string(int i)
1198 static char ret[64];
1199 if (i == -1)
1200 return "-1";
1201 slprintf(ret, sizeof(ret)-1, "0%o", i);
1202 return ret;
1207 Truncate a string at a specified length.
1210 char *string_truncate(char *s, unsigned int length)
1212 if (s && strlen(s) > length)
1213 s[length] = 0;
1214 return s;
1218 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1219 We convert via ucs2 for now.
1222 char *strchr_m(const char *src, char c)
1224 wpstring ws;
1225 pstring s2;
1226 smb_ucs2_t *p;
1227 const char *s;
1229 /* characters below 0x3F are guaranteed to not appear in
1230 non-initial position in multi-byte charsets */
1231 if ((c & 0xC0) == 0) {
1232 return strchr(src, c);
1235 /* this is quite a common operation, so we want it to be
1236 fast. We optimise for the ascii case, knowing that all our
1237 supported multi-byte character sets are ascii-compatible
1238 (ie. they match for the first 128 chars) */
1240 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1241 if (*s == c)
1242 return (char *)s;
1245 if (!*s)
1246 return NULL;
1248 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1249 /* With compose characters we must restart from the beginning. JRA. */
1250 s = src;
1251 #endif
1253 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1254 p = strchr_w(ws, UCS2_CHAR(c));
1255 if (!p)
1256 return NULL;
1257 *p = 0;
1258 pull_ucs2_pstring(s2, ws);
1259 return (char *)(s+strlen(s2));
1262 char *strrchr_m(const char *s, char c)
1264 /* characters below 0x3F are guaranteed to not appear in
1265 non-initial position in multi-byte charsets */
1266 if ((c & 0xC0) == 0) {
1267 return strrchr(s, c);
1270 /* this is quite a common operation, so we want it to be
1271 fast. We optimise for the ascii case, knowing that all our
1272 supported multi-byte character sets are ascii-compatible
1273 (ie. they match for the first 128 chars). Also, in Samba
1274 we only search for ascii characters in 'c' and that
1275 in all mb character sets with a compound character
1276 containing c, if 'c' is not a match at position
1277 p, then p[-1] > 0x7f. JRA. */
1280 size_t len = strlen(s);
1281 const char *cp = s;
1282 BOOL got_mb = False;
1284 if (len == 0)
1285 return NULL;
1286 cp += (len - 1);
1287 do {
1288 if (c == *cp) {
1289 /* Could be a match. Part of a multibyte ? */
1290 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1291 /* Yep - go slow :-( */
1292 got_mb = True;
1293 break;
1295 /* No - we have a match ! */
1296 return (char *)cp;
1298 } while (cp-- != s);
1299 if (!got_mb)
1300 return NULL;
1303 /* String contained a non-ascii char. Slow path. */
1305 wpstring ws;
1306 pstring s2;
1307 smb_ucs2_t *p;
1309 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1310 p = strrchr_w(ws, UCS2_CHAR(c));
1311 if (!p)
1312 return NULL;
1313 *p = 0;
1314 pull_ucs2_pstring(s2, ws);
1315 return (char *)(s+strlen(s2));
1319 /***********************************************************************
1320 Return the equivalent of doing strrchr 'n' times - always going
1321 backwards.
1322 ***********************************************************************/
1324 char *strnrchr_m(const char *s, char c, unsigned int n)
1326 wpstring ws;
1327 pstring s2;
1328 smb_ucs2_t *p;
1330 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1331 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1332 if (!p)
1333 return NULL;
1334 *p = 0;
1335 pull_ucs2_pstring(s2, ws);
1336 return (char *)(s+strlen(s2));
1339 /***********************************************************************
1340 strstr_m - We convert via ucs2 for now.
1341 ***********************************************************************/
1343 char *strstr_m(const char *src, const char *findstr)
1345 smb_ucs2_t *p;
1346 smb_ucs2_t *src_w, *find_w;
1347 const char *s;
1348 char *s2;
1349 char *retp;
1351 size_t findstr_len = 0;
1353 /* for correctness */
1354 if (!findstr[0]) {
1355 return (char*)src;
1358 /* Samba does single character findstr calls a *lot*. */
1359 if (findstr[1] == '\0')
1360 return strchr_m(src, *findstr);
1362 /* We optimise for the ascii case, knowing that all our
1363 supported multi-byte character sets are ascii-compatible
1364 (ie. they match for the first 128 chars) */
1366 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1367 if (*s == *findstr) {
1368 if (!findstr_len)
1369 findstr_len = strlen(findstr);
1371 if (strncmp(s, findstr, findstr_len) == 0) {
1372 return (char *)s;
1377 if (!*s)
1378 return NULL;
1380 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1381 /* 'make check' fails unless we do this */
1383 /* With compose characters we must restart from the beginning. JRA. */
1384 s = src;
1385 #endif
1387 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1388 DEBUG(0,("strstr_m: src malloc fail\n"));
1389 return NULL;
1392 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1393 SAFE_FREE(src_w);
1394 DEBUG(0,("strstr_m: find malloc fail\n"));
1395 return NULL;
1398 p = strstr_w(src_w, find_w);
1400 if (!p) {
1401 SAFE_FREE(src_w);
1402 SAFE_FREE(find_w);
1403 return NULL;
1406 *p = 0;
1407 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1408 SAFE_FREE(src_w);
1409 SAFE_FREE(find_w);
1410 DEBUG(0,("strstr_m: dest malloc fail\n"));
1411 return NULL;
1413 retp = (char *)(s+strlen(s2));
1414 SAFE_FREE(src_w);
1415 SAFE_FREE(find_w);
1416 SAFE_FREE(s2);
1417 return retp;
1421 Convert a string to lower case.
1424 void strlower_m(char *s)
1426 size_t len;
1427 int errno_save;
1429 /* this is quite a common operation, so we want it to be
1430 fast. We optimise for the ascii case, knowing that all our
1431 supported multi-byte character sets are ascii-compatible
1432 (ie. they match for the first 128 chars) */
1434 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1435 *s = tolower((unsigned char)*s);
1436 s++;
1439 if (!*s)
1440 return;
1442 /* I assume that lowercased string takes the same number of bytes
1443 * as source string even in UTF-8 encoding. (VIV) */
1444 len = strlen(s) + 1;
1445 errno_save = errno;
1446 errno = 0;
1447 unix_strlower(s,len,s,len);
1448 /* Catch mb conversion errors that may not terminate. */
1449 if (errno)
1450 s[len-1] = '\0';
1451 errno = errno_save;
1455 Convert a string to upper case.
1458 void strupper_m(char *s)
1460 size_t len;
1461 int errno_save;
1463 /* this is quite a common operation, so we want it to be
1464 fast. We optimise for the ascii case, knowing that all our
1465 supported multi-byte character sets are ascii-compatible
1466 (ie. they match for the first 128 chars) */
1468 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1469 *s = toupper((unsigned char)*s);
1470 s++;
1473 if (!*s)
1474 return;
1476 /* I assume that lowercased string takes the same number of bytes
1477 * as source string even in multibyte encoding. (VIV) */
1478 len = strlen(s) + 1;
1479 errno_save = errno;
1480 errno = 0;
1481 unix_strupper(s,len,s,len);
1482 /* Catch mb conversion errors that may not terminate. */
1483 if (errno)
1484 s[len-1] = '\0';
1485 errno = errno_save;
1489 Return a RFC2254 binary string representation of a buffer.
1490 Used in LDAP filters.
1491 Caller must free.
1494 char *binary_string(char *buf, int len)
1496 char *s;
1497 int i, j;
1498 const char *hex = "0123456789ABCDEF";
1499 s = SMB_MALLOC(len * 3 + 1);
1500 if (!s)
1501 return NULL;
1502 for (j=i=0;i<len;i++) {
1503 s[j] = '\\';
1504 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1505 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1506 j += 3;
1508 s[j] = 0;
1509 return s;
1513 Just a typesafety wrapper for snprintf into a pstring.
1516 int pstr_sprintf(pstring s, const char *fmt, ...)
1518 va_list ap;
1519 int ret;
1521 va_start(ap, fmt);
1522 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1523 va_end(ap);
1524 return ret;
1529 Just a typesafety wrapper for snprintf into a fstring.
1532 int fstr_sprintf(fstring s, const char *fmt, ...)
1534 va_list ap;
1535 int ret;
1537 va_start(ap, fmt);
1538 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1539 va_end(ap);
1540 return ret;
1544 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1546 Some platforms don't have strndup.
1548 #if defined(PARANOID_MALLOC_CHECKER)
1549 #undef strndup
1550 #endif
1552 char *strndup(const char *s, size_t n)
1554 char *ret;
1556 n = strnlen(s, n);
1557 ret = SMB_MALLOC(n+1);
1558 if (!ret)
1559 return NULL;
1560 memcpy(ret, s, n);
1561 ret[n] = 0;
1563 return ret;
1566 #if defined(PARANOID_MALLOC_CHECKER)
1567 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1568 #endif
1570 #endif
1572 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1574 Some platforms don't have strnlen
1577 size_t strnlen(const char *s, size_t n)
1579 size_t i;
1580 for (i=0; i<n && s[i] != '\0'; i++)
1581 /* noop */ ;
1582 return i;
1584 #endif
1587 List of Strings manipulation functions
1590 #define S_LIST_ABS 16 /* List Allocation Block Size */
1592 char **str_list_make(const char *string, const char *sep)
1594 char **list, **rlist;
1595 const char *str;
1596 char *s;
1597 int num, lsize;
1598 pstring tok;
1600 if (!string || !*string)
1601 return NULL;
1602 s = SMB_STRDUP(string);
1603 if (!s) {
1604 DEBUG(0,("str_list_make: Unable to allocate memory"));
1605 return NULL;
1607 if (!sep) sep = LIST_SEP;
1609 num = lsize = 0;
1610 list = NULL;
1612 str = s;
1613 while (next_token(&str, tok, sep, sizeof(tok))) {
1614 if (num == lsize) {
1615 lsize += S_LIST_ABS;
1616 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1617 if (!rlist) {
1618 DEBUG(0,("str_list_make: Unable to allocate memory"));
1619 str_list_free(&list);
1620 SAFE_FREE(s);
1621 return NULL;
1622 } else
1623 list = rlist;
1624 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1627 list[num] = SMB_STRDUP(tok);
1628 if (!list[num]) {
1629 DEBUG(0,("str_list_make: Unable to allocate memory"));
1630 str_list_free(&list);
1631 SAFE_FREE(s);
1632 return NULL;
1635 num++;
1638 SAFE_FREE(s);
1639 return list;
1642 BOOL str_list_copy(char ***dest, const char **src)
1644 char **list, **rlist;
1645 int num, lsize;
1647 *dest = NULL;
1648 if (!src)
1649 return False;
1651 num = lsize = 0;
1652 list = NULL;
1654 while (src[num]) {
1655 if (num == lsize) {
1656 lsize += S_LIST_ABS;
1657 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1658 if (!rlist) {
1659 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1660 str_list_free(&list);
1661 return False;
1662 } else
1663 list = rlist;
1664 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1667 list[num] = SMB_STRDUP(src[num]);
1668 if (!list[num]) {
1669 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1670 str_list_free(&list);
1671 return False;
1674 num++;
1677 *dest = list;
1678 return True;
1682 * Return true if all the elements of the list match exactly.
1684 BOOL str_list_compare(char **list1, char **list2)
1686 int num;
1688 if (!list1 || !list2)
1689 return (list1 == list2);
1691 for (num = 0; list1[num]; num++) {
1692 if (!list2[num])
1693 return False;
1694 if (!strcsequal(list1[num], list2[num]))
1695 return False;
1697 if (list2[num])
1698 return False; /* if list2 has more elements than list1 fail */
1700 return True;
1703 void str_list_free(char ***list)
1705 char **tlist;
1707 if (!list || !*list)
1708 return;
1709 tlist = *list;
1710 for(; *tlist; tlist++)
1711 SAFE_FREE(*tlist);
1712 SAFE_FREE(*list);
1715 /******************************************************************************
1716 *****************************************************************************/
1718 int str_list_count( const char **list )
1720 int i = 0;
1722 /* count the number of list members */
1724 for ( i=0; *list; i++, list++ );
1726 return i;
1729 /******************************************************************************
1730 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1731 for the work
1732 *****************************************************************************/
1734 BOOL str_list_sub_basic( char **list, const char *smb_name )
1736 char *s, *tmpstr;
1738 while ( *list ) {
1739 s = *list;
1740 tmpstr = alloc_sub_basic(smb_name, s);
1741 if ( !tmpstr ) {
1742 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1743 return False;
1746 SAFE_FREE(*list);
1747 *list = tmpstr;
1749 list++;
1752 return True;
1755 /******************************************************************************
1756 substritute a specific pattern in a string list
1757 *****************************************************************************/
1759 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1761 char *p, *s, *t;
1762 ssize_t ls, lp, li, ld, i, d;
1764 if (!list)
1765 return False;
1766 if (!pattern)
1767 return False;
1768 if (!insert)
1769 return False;
1771 lp = (ssize_t)strlen(pattern);
1772 li = (ssize_t)strlen(insert);
1773 ld = li -lp;
1775 while (*list) {
1776 s = *list;
1777 ls = (ssize_t)strlen(s);
1779 while ((p = strstr_m(s, pattern))) {
1780 t = *list;
1781 d = p -t;
1782 if (ld) {
1783 t = (char *) SMB_MALLOC(ls +ld +1);
1784 if (!t) {
1785 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1786 return False;
1788 memcpy(t, *list, d);
1789 memcpy(t +d +li, p +lp, ls -d -lp +1);
1790 SAFE_FREE(*list);
1791 *list = t;
1792 ls += ld;
1793 s = t +d +li;
1796 for (i = 0; i < li; i++) {
1797 switch (insert[i]) {
1798 case '`':
1799 case '"':
1800 case '\'':
1801 case ';':
1802 case '$':
1803 case '%':
1804 case '\r':
1805 case '\n':
1806 t[d +i] = '_';
1807 break;
1808 default:
1809 t[d +i] = insert[i];
1815 list++;
1818 return True;
1822 #define IPSTR_LIST_SEP ","
1823 #define IPSTR_LIST_CHAR ','
1826 * Add ip string representation to ipstr list. Used also
1827 * as part of @function ipstr_list_make
1829 * @param ipstr_list pointer to string containing ip list;
1830 * MUST BE already allocated and IS reallocated if necessary
1831 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1832 * as a result of reallocation)
1833 * @param ip IP address which is to be added to list
1834 * @return pointer to string appended with new ip and possibly
1835 * reallocated to new length
1838 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1840 char* new_ipstr = NULL;
1842 /* arguments checking */
1843 if (!ipstr_list || !service) return NULL;
1845 /* attempt to convert ip to a string and append colon separator to it */
1846 if (*ipstr_list) {
1847 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1848 inet_ntoa(service->ip), service->port);
1849 SAFE_FREE(*ipstr_list);
1850 } else {
1851 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1853 *ipstr_list = new_ipstr;
1854 return *ipstr_list;
1859 * Allocate and initialise an ipstr list using ip adresses
1860 * passed as arguments.
1862 * @param ipstr_list pointer to string meant to be allocated and set
1863 * @param ip_list array of ip addresses to place in the list
1864 * @param ip_count number of addresses stored in ip_list
1865 * @return pointer to allocated ip string
1868 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1870 int i;
1872 /* arguments checking */
1873 if (!ip_list && !ipstr_list) return 0;
1875 *ipstr_list = NULL;
1877 /* process ip addresses given as arguments */
1878 for (i = 0; i < ip_count; i++)
1879 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1881 return (*ipstr_list);
1886 * Parse given ip string list into array of ip addresses
1887 * (as ip_service structures)
1888 * e.g. 192.168.1.100:389,192.168.1.78, ...
1890 * @param ipstr ip string list to be parsed
1891 * @param ip_list pointer to array of ip addresses which is
1892 * allocated by this function and must be freed by caller
1893 * @return number of succesfully parsed addresses
1896 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1898 fstring token_str;
1899 size_t count;
1900 int i;
1902 if (!ipstr_list || !ip_list)
1903 return 0;
1905 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1906 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1907 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1908 return 0;
1911 for ( i=0;
1912 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1913 i++ )
1915 struct in_addr addr;
1916 unsigned port = 0;
1917 char *p = strchr(token_str, ':');
1919 if (p) {
1920 *p = 0;
1921 port = atoi(p+1);
1924 /* convert single token to ip address */
1925 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1926 break;
1928 (*ip_list)[i].ip = addr;
1929 (*ip_list)[i].port = port;
1932 return count;
1937 * Safely free ip string list
1939 * @param ipstr_list ip string list to be freed
1942 void ipstr_list_free(char* ipstr_list)
1944 SAFE_FREE(ipstr_list);
1949 Unescape a URL encoded string, in place.
1952 void rfc1738_unescape(char *buf)
1954 char *p=buf;
1956 while (p && *p && (p=strchr_m(p,'%'))) {
1957 int c1 = p[1];
1958 int c2 = p[2];
1960 if (c1 >= '0' && c1 <= '9')
1961 c1 = c1 - '0';
1962 else if (c1 >= 'A' && c1 <= 'F')
1963 c1 = 10 + c1 - 'A';
1964 else if (c1 >= 'a' && c1 <= 'f')
1965 c1 = 10 + c1 - 'a';
1966 else {p++; continue;}
1968 if (c2 >= '0' && c2 <= '9')
1969 c2 = c2 - '0';
1970 else if (c2 >= 'A' && c2 <= 'F')
1971 c2 = 10 + c2 - 'A';
1972 else if (c2 >= 'a' && c2 <= 'f')
1973 c2 = 10 + c2 - 'a';
1974 else {p++; continue;}
1976 *p = (c1<<4) | c2;
1978 memmove(p+1, p+3, strlen(p+3)+1);
1979 p++;
1983 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1986 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1988 DATA_BLOB base64_decode_data_blob(const char *s)
1990 int bit_offset, byte_offset, idx, i, n;
1991 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1992 unsigned char *d = decoded.data;
1993 char *p;
1995 n=i=0;
1997 while (*s && (p=strchr_m(b64,*s))) {
1998 idx = (int)(p - b64);
1999 byte_offset = (i*6)/8;
2000 bit_offset = (i*6)%8;
2001 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2002 if (bit_offset < 3) {
2003 d[byte_offset] |= (idx << (2-bit_offset));
2004 n = byte_offset+1;
2005 } else {
2006 d[byte_offset] |= (idx >> (bit_offset-2));
2007 d[byte_offset+1] = 0;
2008 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2009 n = byte_offset+2;
2011 s++; i++;
2014 if ((n > 0) && (*s == '=')) {
2015 n -= 1;
2018 /* fix up length */
2019 decoded.length = n;
2020 return decoded;
2024 * Decode a base64 string in-place - wrapper for the above
2026 void base64_decode_inplace(char *s)
2028 DATA_BLOB decoded = base64_decode_data_blob(s);
2030 if ( decoded.length != 0 ) {
2031 memcpy(s, decoded.data, decoded.length);
2033 /* null terminate */
2034 s[decoded.length] = '\0';
2035 } else {
2036 *s = '\0';
2039 data_blob_free(&decoded);
2043 * Encode a base64 string into a malloc()ed string caller to free.
2045 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2047 char * base64_encode_data_blob(DATA_BLOB data)
2049 int bits = 0;
2050 int char_count = 0;
2051 size_t out_cnt, len, output_len;
2052 char *result;
2054 if (!data.length || !data.data)
2055 return NULL;
2057 out_cnt = 0;
2058 len = data.length;
2059 output_len = data.length * 2;
2060 result = SMB_MALLOC(output_len); /* get us plenty of space */
2062 while (len-- && out_cnt < (data.length * 2) - 5) {
2063 int c = (unsigned char) *(data.data++);
2064 bits += c;
2065 char_count++;
2066 if (char_count == 3) {
2067 result[out_cnt++] = b64[bits >> 18];
2068 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2069 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2070 result[out_cnt++] = b64[bits & 0x3f];
2071 bits = 0;
2072 char_count = 0;
2073 } else {
2074 bits <<= 8;
2077 if (char_count != 0) {
2078 bits <<= 16 - (8 * char_count);
2079 result[out_cnt++] = b64[bits >> 18];
2080 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2081 if (char_count == 1) {
2082 result[out_cnt++] = '=';
2083 result[out_cnt++] = '=';
2084 } else {
2085 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2086 result[out_cnt++] = '=';
2089 result[out_cnt] = '\0'; /* terminate */
2090 return result;
2093 /* read a SMB_BIG_UINT from a string */
2094 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2097 SMB_BIG_UINT val = -1;
2098 const char *p = nptr;
2100 while (p && *p && isspace(*p))
2101 p++;
2102 #ifdef LARGE_SMB_OFF_T
2103 sscanf(p,"%llu",&val);
2104 #else /* LARGE_SMB_OFF_T */
2105 sscanf(p,"%lu",&val);
2106 #endif /* LARGE_SMB_OFF_T */
2107 if (entptr) {
2108 while (p && *p && isdigit(*p))
2109 p++;
2110 *entptr = p;
2113 return val;
2116 void string_append(char **left, const char *right)
2118 int new_len = strlen(right) + 1;
2120 if (*left == NULL) {
2121 *left = SMB_MALLOC(new_len);
2122 *left[0] = '\0';
2123 } else {
2124 new_len += strlen(*left);
2125 *left = SMB_REALLOC(*left, new_len);
2128 if (*left == NULL)
2129 return;
2131 safe_strcat(*left, right, new_len-1);
2134 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2135 const char *str, const char ***strings,
2136 int *num)
2138 char *dup_str = talloc_strdup(mem_ctx, str);
2140 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2142 if ((*strings == NULL) || (dup_str == NULL))
2143 return False;
2145 (*strings)[*num] = dup_str;
2146 *num += 1;
2147 return True;
2150 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2151 * error checking in between. The indiation that something weird happened is
2152 * string==NULL */
2154 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2155 size_t *bufsize, const char *fmt, ...)
2157 va_list ap;
2158 char *newstr;
2159 int ret;
2160 BOOL increased;
2162 /* len<0 is an internal marker that something failed */
2163 if (*len < 0)
2164 goto error;
2166 if (*string == NULL) {
2167 if (*bufsize == 0)
2168 *bufsize = 128;
2170 if (mem_ctx != NULL)
2171 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2172 else
2173 *string = SMB_MALLOC_ARRAY(char, *bufsize);
2175 if (*string == NULL)
2176 goto error;
2179 va_start(ap, fmt);
2180 ret = vasprintf(&newstr, fmt, ap);
2181 va_end(ap);
2183 if (ret < 0)
2184 goto error;
2186 increased = False;
2188 while ((*len)+ret >= *bufsize) {
2189 increased = True;
2190 *bufsize *= 2;
2191 if (*bufsize >= (1024*1024*256))
2192 goto error;
2195 if (increased) {
2196 if (mem_ctx != NULL)
2197 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2198 *bufsize);
2199 else
2200 *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2202 if (*string == NULL)
2203 goto error;
2206 StrnCpy((*string)+(*len), newstr, ret);
2207 (*len) += ret;
2208 free(newstr);
2209 return;
2211 error:
2212 *len = -1;
2213 *string = NULL;
2217 Returns the substring from src between the first occurrence of
2218 the char "front" and the first occurence of the char "back".
2219 Mallocs the return string which must be freed. Not for use
2220 with wide character strings.
2222 char *sstring_sub(const char *src, char front, char back)
2224 char *temp1, *temp2, *temp3;
2225 ptrdiff_t len;
2227 temp1 = strchr(src, front);
2228 if (temp1 == NULL) return NULL;
2229 temp2 = strchr(src, back);
2230 if (temp2 == NULL) return NULL;
2231 len = temp2 - temp1;
2232 if (len <= 0) return NULL;
2233 temp3 = (char*)SMB_MALLOC(len);
2234 if (temp3 == NULL) {
2235 DEBUG(1,("Malloc failure in sstring_sub\n"));
2236 return NULL;
2238 memcpy(temp3, temp1+1, len-1);
2239 temp3[len-1] = '\0';
2240 return temp3;