r11704: methods->alternate_name is not used anymore -- remove it
[Samba/nascimento.git] / source3 / lib / util_str.c
blob9b14dcfaf0faf8b50abe0f93f43da747ab501b5c
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(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)
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 case '%':
959 case '\r':
960 case '\n':
961 if ( remove_unsafe_characters ) {
962 p[i] = '_';
963 /* yes this break should be here since we want to
964 fall throw if not replacing unsafe chars */
965 break;
967 default:
968 p[i] = insert[i];
971 s = p + li;
972 ls += (li-lp);
974 if (replace_once)
975 break;
979 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
981 string_sub2( s, pattern, insert, len, True, True );
984 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
986 string_sub2( s, pattern, insert, len, True, False );
989 void fstring_sub(char *s,const char *pattern,const char *insert)
991 string_sub(s, pattern, insert, sizeof(fstring));
994 void pstring_sub(char *s,const char *pattern,const char *insert)
996 string_sub(s, pattern, insert, sizeof(pstring));
1000 Similar to string_sub, but it will accept only allocated strings
1001 and may realloc them so pay attention at what you pass on no
1002 pointers inside strings, no pstrings or const may be passed
1003 as string.
1006 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
1008 char *p, *in;
1009 char *s;
1010 ssize_t ls,lp,li,ld, i;
1012 if (!insert || !pattern || !*pattern || !string || !*string)
1013 return NULL;
1015 s = string;
1017 in = SMB_STRDUP(insert);
1018 if (!in) {
1019 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1020 return NULL;
1022 ls = (ssize_t)strlen(s);
1023 lp = (ssize_t)strlen(pattern);
1024 li = (ssize_t)strlen(insert);
1025 ld = li - lp;
1026 for (i=0;i<li;i++) {
1027 switch (in[i]) {
1028 case '`':
1029 case '"':
1030 case '\'':
1031 case ';':
1032 case '$':
1033 case '%':
1034 case '\r':
1035 case '\n':
1036 in[i] = '_';
1037 default:
1038 /* ok */
1039 break;
1043 while ((p = strstr_m(s,pattern))) {
1044 if (ld > 0) {
1045 int offset = PTR_DIFF(s,string);
1046 char *t = SMB_REALLOC(string, ls + ld + 1);
1047 if (!t) {
1048 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1049 SAFE_FREE(in);
1050 return NULL;
1052 string = t;
1053 p = t + offset + (p - s);
1055 if (li != lp) {
1056 memmove(p+li,p+lp,strlen(p+lp)+1);
1058 memcpy(p, in, li);
1059 s = p + li;
1060 ls += ld;
1062 SAFE_FREE(in);
1063 return string;
1067 Similar to string_sub() but allows for any character to be substituted.
1068 Use with caution!
1069 if len==0 then the string cannot be extended. This is different from the old
1070 use of len==0 which was for no length checks to be done.
1073 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1075 char *p;
1076 ssize_t ls,lp,li;
1078 if (!insert || !pattern || !s)
1079 return;
1081 ls = (ssize_t)strlen(s);
1082 lp = (ssize_t)strlen(pattern);
1083 li = (ssize_t)strlen(insert);
1085 if (!*pattern)
1086 return;
1088 if (len == 0)
1089 len = ls + 1; /* len is number of *bytes* */
1091 while (lp <= ls && (p = strstr_m(s,pattern))) {
1092 if (ls + (li-lp) >= len) {
1093 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1094 (int)(ls + (li-lp) - len),
1095 pattern, (int)len));
1096 break;
1098 if (li != lp) {
1099 memmove(p+li,p+lp,strlen(p+lp)+1);
1101 memcpy(p, insert, li);
1102 s = p + li;
1103 ls += (li-lp);
1108 Similar to all_string_sub but for unicode strings.
1109 Return a new allocated unicode string.
1110 similar to string_sub() but allows for any character to be substituted.
1111 Use with caution!
1114 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1115 const smb_ucs2_t *insert)
1117 smb_ucs2_t *r, *rp;
1118 const smb_ucs2_t *sp;
1119 size_t lr, lp, li, lt;
1121 if (!insert || !pattern || !*pattern || !s)
1122 return NULL;
1124 lt = (size_t)strlen_w(s);
1125 lp = (size_t)strlen_w(pattern);
1126 li = (size_t)strlen_w(insert);
1128 if (li > lp) {
1129 const smb_ucs2_t *st = s;
1130 int ld = li - lp;
1131 while ((sp = strstr_w(st, pattern))) {
1132 st = sp + lp;
1133 lt += ld;
1137 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1138 if (!r) {
1139 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1140 return NULL;
1143 while ((sp = strstr_w(s, pattern))) {
1144 memcpy(rp, s, (sp - s));
1145 rp += ((sp - s) / sizeof(smb_ucs2_t));
1146 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1147 s = sp + lp;
1148 rp += li;
1150 lr = ((rp - r) / sizeof(smb_ucs2_t));
1151 if (lr < lt) {
1152 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1153 rp += (lt - lr);
1155 *rp = 0;
1157 return r;
1160 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1161 const char *insert)
1163 wpstring p, i;
1165 if (!insert || !pattern || !s)
1166 return NULL;
1167 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1168 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1169 return all_string_sub_w(s, p, i);
1172 #if 0
1174 Splits out the front and back at a separator.
1177 static void split_at_last_component(char *path, char *front, char sep, char *back)
1179 char *p = strrchr_m(path, sep);
1181 if (p != NULL)
1182 *p = 0;
1184 if (front != NULL)
1185 pstrcpy(front, path);
1187 if (p != NULL) {
1188 if (back != NULL)
1189 pstrcpy(back, p+1);
1190 *p = '\\';
1191 } else {
1192 if (back != NULL)
1193 back[0] = 0;
1196 #endif
1199 Write an octal as a string.
1202 const char *octal_string(int i)
1204 static char ret[64];
1205 if (i == -1)
1206 return "-1";
1207 slprintf(ret, sizeof(ret)-1, "0%o", i);
1208 return ret;
1213 Truncate a string at a specified length.
1216 char *string_truncate(char *s, unsigned int length)
1218 if (s && strlen(s) > length)
1219 s[length] = 0;
1220 return s;
1224 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1225 We convert via ucs2 for now.
1228 char *strchr_m(const char *src, char c)
1230 wpstring ws;
1231 pstring s2;
1232 smb_ucs2_t *p;
1233 const char *s;
1235 /* characters below 0x3F are guaranteed to not appear in
1236 non-initial position in multi-byte charsets */
1237 if ((c & 0xC0) == 0) {
1238 return strchr(src, c);
1241 /* this is quite a common operation, so we want it to be
1242 fast. We optimise for the ascii case, knowing that all our
1243 supported multi-byte character sets are ascii-compatible
1244 (ie. they match for the first 128 chars) */
1246 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1247 if (*s == c)
1248 return (char *)s;
1251 if (!*s)
1252 return NULL;
1254 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1255 /* With compose characters we must restart from the beginning. JRA. */
1256 s = src;
1257 #endif
1259 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1260 p = strchr_w(ws, UCS2_CHAR(c));
1261 if (!p)
1262 return NULL;
1263 *p = 0;
1264 pull_ucs2_pstring(s2, ws);
1265 return (char *)(s+strlen(s2));
1268 char *strrchr_m(const char *s, char c)
1270 /* characters below 0x3F are guaranteed to not appear in
1271 non-initial position in multi-byte charsets */
1272 if ((c & 0xC0) == 0) {
1273 return strrchr(s, c);
1276 /* this is quite a common operation, so we want it to be
1277 fast. We optimise for the ascii case, knowing that all our
1278 supported multi-byte character sets are ascii-compatible
1279 (ie. they match for the first 128 chars). Also, in Samba
1280 we only search for ascii characters in 'c' and that
1281 in all mb character sets with a compound character
1282 containing c, if 'c' is not a match at position
1283 p, then p[-1] > 0x7f. JRA. */
1286 size_t len = strlen(s);
1287 const char *cp = s;
1288 BOOL got_mb = False;
1290 if (len == 0)
1291 return NULL;
1292 cp += (len - 1);
1293 do {
1294 if (c == *cp) {
1295 /* Could be a match. Part of a multibyte ? */
1296 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1297 /* Yep - go slow :-( */
1298 got_mb = True;
1299 break;
1301 /* No - we have a match ! */
1302 return (char *)cp;
1304 } while (cp-- != s);
1305 if (!got_mb)
1306 return NULL;
1309 /* String contained a non-ascii char. Slow path. */
1311 wpstring ws;
1312 pstring s2;
1313 smb_ucs2_t *p;
1315 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1316 p = strrchr_w(ws, UCS2_CHAR(c));
1317 if (!p)
1318 return NULL;
1319 *p = 0;
1320 pull_ucs2_pstring(s2, ws);
1321 return (char *)(s+strlen(s2));
1325 /***********************************************************************
1326 Return the equivalent of doing strrchr 'n' times - always going
1327 backwards.
1328 ***********************************************************************/
1330 char *strnrchr_m(const char *s, char c, unsigned int n)
1332 wpstring ws;
1333 pstring s2;
1334 smb_ucs2_t *p;
1336 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1337 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1338 if (!p)
1339 return NULL;
1340 *p = 0;
1341 pull_ucs2_pstring(s2, ws);
1342 return (char *)(s+strlen(s2));
1345 /***********************************************************************
1346 strstr_m - We convert via ucs2 for now.
1347 ***********************************************************************/
1349 char *strstr_m(const char *src, const char *findstr)
1351 smb_ucs2_t *p;
1352 smb_ucs2_t *src_w, *find_w;
1353 const char *s;
1354 char *s2;
1355 char *retp;
1357 size_t findstr_len = 0;
1359 /* for correctness */
1360 if (!findstr[0]) {
1361 return (char*)src;
1364 /* Samba does single character findstr calls a *lot*. */
1365 if (findstr[1] == '\0')
1366 return strchr_m(src, *findstr);
1368 /* We optimise for the ascii case, knowing that all our
1369 supported multi-byte character sets are ascii-compatible
1370 (ie. they match for the first 128 chars) */
1372 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1373 if (*s == *findstr) {
1374 if (!findstr_len)
1375 findstr_len = strlen(findstr);
1377 if (strncmp(s, findstr, findstr_len) == 0) {
1378 return (char *)s;
1383 if (!*s)
1384 return NULL;
1386 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1387 /* 'make check' fails unless we do this */
1389 /* With compose characters we must restart from the beginning. JRA. */
1390 s = src;
1391 #endif
1393 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1394 DEBUG(0,("strstr_m: src malloc fail\n"));
1395 return NULL;
1398 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1399 SAFE_FREE(src_w);
1400 DEBUG(0,("strstr_m: find malloc fail\n"));
1401 return NULL;
1404 p = strstr_w(src_w, find_w);
1406 if (!p) {
1407 SAFE_FREE(src_w);
1408 SAFE_FREE(find_w);
1409 return NULL;
1412 *p = 0;
1413 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1414 SAFE_FREE(src_w);
1415 SAFE_FREE(find_w);
1416 DEBUG(0,("strstr_m: dest malloc fail\n"));
1417 return NULL;
1419 retp = (char *)(s+strlen(s2));
1420 SAFE_FREE(src_w);
1421 SAFE_FREE(find_w);
1422 SAFE_FREE(s2);
1423 return retp;
1427 Convert a string to lower case.
1430 void strlower_m(char *s)
1432 size_t len;
1433 int errno_save;
1435 /* this is quite a common operation, so we want it to be
1436 fast. We optimise for the ascii case, knowing that all our
1437 supported multi-byte character sets are ascii-compatible
1438 (ie. they match for the first 128 chars) */
1440 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1441 *s = tolower((unsigned char)*s);
1442 s++;
1445 if (!*s)
1446 return;
1448 /* I assume that lowercased string takes the same number of bytes
1449 * as source string even in UTF-8 encoding. (VIV) */
1450 len = strlen(s) + 1;
1451 errno_save = errno;
1452 errno = 0;
1453 unix_strlower(s,len,s,len);
1454 /* Catch mb conversion errors that may not terminate. */
1455 if (errno)
1456 s[len-1] = '\0';
1457 errno = errno_save;
1461 Convert a string to upper case.
1464 void strupper_m(char *s)
1466 size_t len;
1467 int errno_save;
1469 /* this is quite a common operation, so we want it to be
1470 fast. We optimise for the ascii case, knowing that all our
1471 supported multi-byte character sets are ascii-compatible
1472 (ie. they match for the first 128 chars) */
1474 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1475 *s = toupper((unsigned char)*s);
1476 s++;
1479 if (!*s)
1480 return;
1482 /* I assume that lowercased string takes the same number of bytes
1483 * as source string even in multibyte encoding. (VIV) */
1484 len = strlen(s) + 1;
1485 errno_save = errno;
1486 errno = 0;
1487 unix_strupper(s,len,s,len);
1488 /* Catch mb conversion errors that may not terminate. */
1489 if (errno)
1490 s[len-1] = '\0';
1491 errno = errno_save;
1495 Return a RFC2254 binary string representation of a buffer.
1496 Used in LDAP filters.
1497 Caller must free.
1500 char *binary_string(char *buf, int len)
1502 char *s;
1503 int i, j;
1504 const char *hex = "0123456789ABCDEF";
1505 s = SMB_MALLOC(len * 3 + 1);
1506 if (!s)
1507 return NULL;
1508 for (j=i=0;i<len;i++) {
1509 s[j] = '\\';
1510 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1511 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1512 j += 3;
1514 s[j] = 0;
1515 return s;
1519 Just a typesafety wrapper for snprintf into a pstring.
1522 int pstr_sprintf(pstring s, const char *fmt, ...)
1524 va_list ap;
1525 int ret;
1527 va_start(ap, fmt);
1528 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1529 va_end(ap);
1530 return ret;
1535 Just a typesafety wrapper for snprintf into a fstring.
1538 int fstr_sprintf(fstring s, const char *fmt, ...)
1540 va_list ap;
1541 int ret;
1543 va_start(ap, fmt);
1544 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1545 va_end(ap);
1546 return ret;
1550 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1552 Some platforms don't have strndup.
1554 #if defined(PARANOID_MALLOC_CHECKER)
1555 #undef strndup
1556 #endif
1558 char *strndup(const char *s, size_t n)
1560 char *ret;
1562 n = strnlen(s, n);
1563 ret = SMB_MALLOC(n+1);
1564 if (!ret)
1565 return NULL;
1566 memcpy(ret, s, n);
1567 ret[n] = 0;
1569 return ret;
1572 #if defined(PARANOID_MALLOC_CHECKER)
1573 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1574 #endif
1576 #endif
1578 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1580 Some platforms don't have strnlen
1583 size_t strnlen(const char *s, size_t n)
1585 size_t i;
1586 for (i=0; i<n && s[i] != '\0'; i++)
1587 /* noop */ ;
1588 return i;
1590 #endif
1593 List of Strings manipulation functions
1596 #define S_LIST_ABS 16 /* List Allocation Block Size */
1598 char **str_list_make(const char *string, const char *sep)
1600 char **list, **rlist;
1601 const char *str;
1602 char *s;
1603 int num, lsize;
1604 pstring tok;
1606 if (!string || !*string)
1607 return NULL;
1608 s = SMB_STRDUP(string);
1609 if (!s) {
1610 DEBUG(0,("str_list_make: Unable to allocate memory"));
1611 return NULL;
1613 if (!sep) sep = LIST_SEP;
1615 num = lsize = 0;
1616 list = NULL;
1618 str = s;
1619 while (next_token(&str, tok, sep, sizeof(tok))) {
1620 if (num == lsize) {
1621 lsize += S_LIST_ABS;
1622 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1623 if (!rlist) {
1624 DEBUG(0,("str_list_make: Unable to allocate memory"));
1625 str_list_free(&list);
1626 SAFE_FREE(s);
1627 return NULL;
1628 } else
1629 list = rlist;
1630 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1633 list[num] = SMB_STRDUP(tok);
1634 if (!list[num]) {
1635 DEBUG(0,("str_list_make: Unable to allocate memory"));
1636 str_list_free(&list);
1637 SAFE_FREE(s);
1638 return NULL;
1641 num++;
1644 SAFE_FREE(s);
1645 return list;
1648 BOOL str_list_copy(char ***dest, const char **src)
1650 char **list, **rlist;
1651 int num, lsize;
1653 *dest = NULL;
1654 if (!src)
1655 return False;
1657 num = lsize = 0;
1658 list = NULL;
1660 while (src[num]) {
1661 if (num == lsize) {
1662 lsize += S_LIST_ABS;
1663 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1664 if (!rlist) {
1665 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1666 str_list_free(&list);
1667 return False;
1668 } else
1669 list = rlist;
1670 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1673 list[num] = SMB_STRDUP(src[num]);
1674 if (!list[num]) {
1675 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1676 str_list_free(&list);
1677 return False;
1680 num++;
1683 *dest = list;
1684 return True;
1688 * Return true if all the elements of the list match exactly.
1690 BOOL str_list_compare(char **list1, char **list2)
1692 int num;
1694 if (!list1 || !list2)
1695 return (list1 == list2);
1697 for (num = 0; list1[num]; num++) {
1698 if (!list2[num])
1699 return False;
1700 if (!strcsequal(list1[num], list2[num]))
1701 return False;
1703 if (list2[num])
1704 return False; /* if list2 has more elements than list1 fail */
1706 return True;
1709 void str_list_free(char ***list)
1711 char **tlist;
1713 if (!list || !*list)
1714 return;
1715 tlist = *list;
1716 for(; *tlist; tlist++)
1717 SAFE_FREE(*tlist);
1718 SAFE_FREE(*list);
1721 /******************************************************************************
1722 *****************************************************************************/
1724 int str_list_count( const char **list )
1726 int i = 0;
1728 /* count the number of list members */
1730 for ( i=0; *list; i++, list++ );
1732 return i;
1735 /******************************************************************************
1736 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1737 for the work
1738 *****************************************************************************/
1740 BOOL str_list_sub_basic( char **list, const char *smb_name )
1742 char *s, *tmpstr;
1744 while ( *list ) {
1745 s = *list;
1746 tmpstr = alloc_sub_basic(smb_name, s);
1747 if ( !tmpstr ) {
1748 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1749 return False;
1752 SAFE_FREE(*list);
1753 *list = tmpstr;
1755 list++;
1758 return True;
1761 /******************************************************************************
1762 substritute a specific pattern in a string list
1763 *****************************************************************************/
1765 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1767 char *p, *s, *t;
1768 ssize_t ls, lp, li, ld, i, d;
1770 if (!list)
1771 return False;
1772 if (!pattern)
1773 return False;
1774 if (!insert)
1775 return False;
1777 lp = (ssize_t)strlen(pattern);
1778 li = (ssize_t)strlen(insert);
1779 ld = li -lp;
1781 while (*list) {
1782 s = *list;
1783 ls = (ssize_t)strlen(s);
1785 while ((p = strstr_m(s, pattern))) {
1786 t = *list;
1787 d = p -t;
1788 if (ld) {
1789 t = (char *) SMB_MALLOC(ls +ld +1);
1790 if (!t) {
1791 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1792 return False;
1794 memcpy(t, *list, d);
1795 memcpy(t +d +li, p +lp, ls -d -lp +1);
1796 SAFE_FREE(*list);
1797 *list = t;
1798 ls += ld;
1799 s = t +d +li;
1802 for (i = 0; i < li; i++) {
1803 switch (insert[i]) {
1804 case '`':
1805 case '"':
1806 case '\'':
1807 case ';':
1808 case '$':
1809 case '%':
1810 case '\r':
1811 case '\n':
1812 t[d +i] = '_';
1813 break;
1814 default:
1815 t[d +i] = insert[i];
1821 list++;
1824 return True;
1828 #define IPSTR_LIST_SEP ","
1829 #define IPSTR_LIST_CHAR ','
1832 * Add ip string representation to ipstr list. Used also
1833 * as part of @function ipstr_list_make
1835 * @param ipstr_list pointer to string containing ip list;
1836 * MUST BE already allocated and IS reallocated if necessary
1837 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1838 * as a result of reallocation)
1839 * @param ip IP address which is to be added to list
1840 * @return pointer to string appended with new ip and possibly
1841 * reallocated to new length
1844 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1846 char* new_ipstr = NULL;
1848 /* arguments checking */
1849 if (!ipstr_list || !service) return NULL;
1851 /* attempt to convert ip to a string and append colon separator to it */
1852 if (*ipstr_list) {
1853 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1854 inet_ntoa(service->ip), service->port);
1855 SAFE_FREE(*ipstr_list);
1856 } else {
1857 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1859 *ipstr_list = new_ipstr;
1860 return *ipstr_list;
1865 * Allocate and initialise an ipstr list using ip adresses
1866 * passed as arguments.
1868 * @param ipstr_list pointer to string meant to be allocated and set
1869 * @param ip_list array of ip addresses to place in the list
1870 * @param ip_count number of addresses stored in ip_list
1871 * @return pointer to allocated ip string
1874 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1876 int i;
1878 /* arguments checking */
1879 if (!ip_list && !ipstr_list) return 0;
1881 *ipstr_list = NULL;
1883 /* process ip addresses given as arguments */
1884 for (i = 0; i < ip_count; i++)
1885 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1887 return (*ipstr_list);
1892 * Parse given ip string list into array of ip addresses
1893 * (as ip_service structures)
1894 * e.g. 192.168.1.100:389,192.168.1.78, ...
1896 * @param ipstr ip string list to be parsed
1897 * @param ip_list pointer to array of ip addresses which is
1898 * allocated by this function and must be freed by caller
1899 * @return number of succesfully parsed addresses
1902 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1904 fstring token_str;
1905 size_t count;
1906 int i;
1908 if (!ipstr_list || !ip_list)
1909 return 0;
1911 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1912 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1913 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1914 return 0;
1917 for ( i=0;
1918 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1919 i++ )
1921 struct in_addr addr;
1922 unsigned port = 0;
1923 char *p = strchr(token_str, ':');
1925 if (p) {
1926 *p = 0;
1927 port = atoi(p+1);
1930 /* convert single token to ip address */
1931 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1932 break;
1934 (*ip_list)[i].ip = addr;
1935 (*ip_list)[i].port = port;
1938 return count;
1943 * Safely free ip string list
1945 * @param ipstr_list ip string list to be freed
1948 void ipstr_list_free(char* ipstr_list)
1950 SAFE_FREE(ipstr_list);
1955 Unescape a URL encoded string, in place.
1958 void rfc1738_unescape(char *buf)
1960 char *p=buf;
1962 while (p && *p && (p=strchr_m(p,'%'))) {
1963 int c1 = p[1];
1964 int c2 = p[2];
1966 if (c1 >= '0' && c1 <= '9')
1967 c1 = c1 - '0';
1968 else if (c1 >= 'A' && c1 <= 'F')
1969 c1 = 10 + c1 - 'A';
1970 else if (c1 >= 'a' && c1 <= 'f')
1971 c1 = 10 + c1 - 'a';
1972 else {p++; continue;}
1974 if (c2 >= '0' && c2 <= '9')
1975 c2 = c2 - '0';
1976 else if (c2 >= 'A' && c2 <= 'F')
1977 c2 = 10 + c2 - 'A';
1978 else if (c2 >= 'a' && c2 <= 'f')
1979 c2 = 10 + c2 - 'a';
1980 else {p++; continue;}
1982 *p = (c1<<4) | c2;
1984 memmove(p+1, p+3, strlen(p+3)+1);
1985 p++;
1989 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1992 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1994 DATA_BLOB base64_decode_data_blob(const char *s)
1996 int bit_offset, byte_offset, idx, i, n;
1997 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1998 unsigned char *d = decoded.data;
1999 char *p;
2001 n=i=0;
2003 while (*s && (p=strchr_m(b64,*s))) {
2004 idx = (int)(p - b64);
2005 byte_offset = (i*6)/8;
2006 bit_offset = (i*6)%8;
2007 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2008 if (bit_offset < 3) {
2009 d[byte_offset] |= (idx << (2-bit_offset));
2010 n = byte_offset+1;
2011 } else {
2012 d[byte_offset] |= (idx >> (bit_offset-2));
2013 d[byte_offset+1] = 0;
2014 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2015 n = byte_offset+2;
2017 s++; i++;
2020 if ((n > 0) && (*s == '=')) {
2021 n -= 1;
2024 /* fix up length */
2025 decoded.length = n;
2026 return decoded;
2030 * Decode a base64 string in-place - wrapper for the above
2032 void base64_decode_inplace(char *s)
2034 DATA_BLOB decoded = base64_decode_data_blob(s);
2036 if ( decoded.length != 0 ) {
2037 memcpy(s, decoded.data, decoded.length);
2039 /* null terminate */
2040 s[decoded.length] = '\0';
2041 } else {
2042 *s = '\0';
2045 data_blob_free(&decoded);
2049 * Encode a base64 string into a malloc()ed string caller to free.
2051 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2053 char * base64_encode_data_blob(DATA_BLOB data)
2055 int bits = 0;
2056 int char_count = 0;
2057 size_t out_cnt, len, output_len;
2058 char *result;
2060 if (!data.length || !data.data)
2061 return NULL;
2063 out_cnt = 0;
2064 len = data.length;
2065 output_len = data.length * 2;
2066 result = SMB_MALLOC(output_len); /* get us plenty of space */
2068 while (len-- && out_cnt < (data.length * 2) - 5) {
2069 int c = (unsigned char) *(data.data++);
2070 bits += c;
2071 char_count++;
2072 if (char_count == 3) {
2073 result[out_cnt++] = b64[bits >> 18];
2074 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2075 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2076 result[out_cnt++] = b64[bits & 0x3f];
2077 bits = 0;
2078 char_count = 0;
2079 } else {
2080 bits <<= 8;
2083 if (char_count != 0) {
2084 bits <<= 16 - (8 * char_count);
2085 result[out_cnt++] = b64[bits >> 18];
2086 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2087 if (char_count == 1) {
2088 result[out_cnt++] = '=';
2089 result[out_cnt++] = '=';
2090 } else {
2091 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2092 result[out_cnt++] = '=';
2095 result[out_cnt] = '\0'; /* terminate */
2096 return result;
2099 /* read a SMB_BIG_UINT from a string */
2100 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2103 SMB_BIG_UINT val = -1;
2104 const char *p = nptr;
2106 while (p && *p && isspace(*p))
2107 p++;
2108 #ifdef LARGE_SMB_OFF_T
2109 sscanf(p,"%llu",&val);
2110 #else /* LARGE_SMB_OFF_T */
2111 sscanf(p,"%lu",&val);
2112 #endif /* LARGE_SMB_OFF_T */
2113 if (entptr) {
2114 while (p && *p && isdigit(*p))
2115 p++;
2116 *entptr = p;
2119 return val;
2122 void string_append(char **left, const char *right)
2124 int new_len = strlen(right) + 1;
2126 if (*left == NULL) {
2127 *left = SMB_MALLOC(new_len);
2128 *left[0] = '\0';
2129 } else {
2130 new_len += strlen(*left);
2131 *left = SMB_REALLOC(*left, new_len);
2134 if (*left == NULL)
2135 return;
2137 safe_strcat(*left, right, new_len-1);
2140 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2141 const char *str, const char ***strings,
2142 int *num)
2144 char *dup_str = talloc_strdup(mem_ctx, str);
2146 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2148 if ((*strings == NULL) || (dup_str == NULL))
2149 return False;
2151 (*strings)[*num] = dup_str;
2152 *num += 1;
2153 return True;
2156 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2157 * error checking in between. The indiation that something weird happened is
2158 * string==NULL */
2160 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2161 size_t *bufsize, const char *fmt, ...)
2163 va_list ap;
2164 char *newstr;
2165 int ret;
2166 BOOL increased;
2168 /* len<0 is an internal marker that something failed */
2169 if (*len < 0)
2170 goto error;
2172 if (*string == NULL) {
2173 if (*bufsize == 0)
2174 *bufsize = 128;
2176 if (mem_ctx != NULL)
2177 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2178 else
2179 *string = SMB_MALLOC_ARRAY(char, *bufsize);
2181 if (*string == NULL)
2182 goto error;
2185 va_start(ap, fmt);
2186 ret = vasprintf(&newstr, fmt, ap);
2187 va_end(ap);
2189 if (ret < 0)
2190 goto error;
2192 increased = False;
2194 while ((*len)+ret >= *bufsize) {
2195 increased = True;
2196 *bufsize *= 2;
2197 if (*bufsize >= (1024*1024*256))
2198 goto error;
2201 if (increased) {
2202 if (mem_ctx != NULL)
2203 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2204 *bufsize);
2205 else
2206 *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2208 if (*string == NULL)
2209 goto error;
2212 StrnCpy((*string)+(*len), newstr, ret);
2213 (*len) += ret;
2214 free(newstr);
2215 return;
2217 error:
2218 *len = -1;
2219 *string = NULL;
2223 Returns the substring from src between the first occurrence of
2224 the char "front" and the first occurence of the char "back".
2225 Mallocs the return string which must be freed. Not for use
2226 with wide character strings.
2228 char *sstring_sub(const char *src, char front, char back)
2230 char *temp1, *temp2, *temp3;
2231 ptrdiff_t len;
2233 temp1 = strchr(src, front);
2234 if (temp1 == NULL) return NULL;
2235 temp2 = strchr(src, back);
2236 if (temp2 == NULL) return NULL;
2237 len = temp2 - temp1;
2238 if (len <= 0) return NULL;
2239 temp3 = (char*)SMB_MALLOC(len);
2240 if (temp3 == NULL) {
2241 DEBUG(1,("Malloc failure in sstring_sub\n"));
2242 return NULL;
2244 memcpy(temp3, temp1+1, len-1);
2245 temp3[len-1] = '\0';
2246 return temp3;