r4231: commiting changes to 3.0.10
[Samba.git] / source / lib / util_str.c
blobc6b6570f5c436314d7f6962dd14af6261669fe82
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, s);
215 if (size == (size_t)-1) {
216 return strcmp(s, t);
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, t);
222 if (size == (size_t)-1) {
223 SAFE_FREE(buffer_s);
224 return strcmp(s, t);
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 unsigned 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 = (unsigned char *)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(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(char *s,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.
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_sub(char *s,const char *pattern, const char *insert, size_t len)
921 char *p;
922 ssize_t ls,lp,li, i;
924 if (!insert || !pattern || !*pattern || !s)
925 return;
927 ls = (ssize_t)strlen(s);
928 lp = (ssize_t)strlen(pattern);
929 li = (ssize_t)strlen(insert);
931 if (len == 0)
932 len = ls + 1; /* len is number of *bytes* */
934 while (lp <= ls && (p = strstr_m(s,pattern))) {
935 if (ls + (li-lp) >= len) {
936 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
937 (int)(ls + (li-lp) - len),
938 pattern, (int)len));
939 break;
941 if (li != lp) {
942 memmove(p+li,p+lp,strlen(p+lp)+1);
944 for (i=0;i<li;i++) {
945 switch (insert[i]) {
946 case '`':
947 case '"':
948 case '\'':
949 case ';':
950 case '$':
951 case '%':
952 case '\r':
953 case '\n':
954 p[i] = '_';
955 break;
956 default:
957 p[i] = insert[i];
960 s = p + li;
961 ls += (li-lp);
965 void fstring_sub(char *s,const char *pattern,const char *insert)
967 string_sub(s, pattern, insert, sizeof(fstring));
970 void pstring_sub(char *s,const char *pattern,const char *insert)
972 string_sub(s, pattern, insert, sizeof(pstring));
976 Similar to string_sub, but it will accept only allocated strings
977 and may realloc them so pay attention at what you pass on no
978 pointers inside strings, no pstrings or const may be passed
979 as string.
982 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
984 char *p, *in;
985 char *s;
986 ssize_t ls,lp,li,ld, i;
988 if (!insert || !pattern || !*pattern || !string || !*string)
989 return NULL;
991 s = string;
993 in = SMB_STRDUP(insert);
994 if (!in) {
995 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
996 return NULL;
998 ls = (ssize_t)strlen(s);
999 lp = (ssize_t)strlen(pattern);
1000 li = (ssize_t)strlen(insert);
1001 ld = li - lp;
1002 for (i=0;i<li;i++) {
1003 switch (in[i]) {
1004 case '`':
1005 case '"':
1006 case '\'':
1007 case ';':
1008 case '$':
1009 case '%':
1010 case '\r':
1011 case '\n':
1012 in[i] = '_';
1013 default:
1014 /* ok */
1015 break;
1019 while ((p = strstr_m(s,pattern))) {
1020 if (ld > 0) {
1021 int offset = PTR_DIFF(s,string);
1022 char *t = SMB_REALLOC(string, ls + ld + 1);
1023 if (!t) {
1024 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1025 SAFE_FREE(in);
1026 return NULL;
1028 string = t;
1029 p = t + offset + (p - s);
1031 if (li != lp) {
1032 memmove(p+li,p+lp,strlen(p+lp)+1);
1034 memcpy(p, in, li);
1035 s = p + li;
1036 ls += ld;
1038 SAFE_FREE(in);
1039 return string;
1043 Similar to string_sub() but allows for any character to be substituted.
1044 Use with caution!
1045 if len==0 then the string cannot be extended. This is different from the old
1046 use of len==0 which was for no length checks to be done.
1049 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1051 char *p;
1052 ssize_t ls,lp,li;
1054 if (!insert || !pattern || !s)
1055 return;
1057 ls = (ssize_t)strlen(s);
1058 lp = (ssize_t)strlen(pattern);
1059 li = (ssize_t)strlen(insert);
1061 if (!*pattern)
1062 return;
1064 if (len == 0)
1065 len = ls + 1; /* len is number of *bytes* */
1067 while (lp <= ls && (p = strstr_m(s,pattern))) {
1068 if (ls + (li-lp) >= len) {
1069 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1070 (int)(ls + (li-lp) - len),
1071 pattern, (int)len));
1072 break;
1074 if (li != lp) {
1075 memmove(p+li,p+lp,strlen(p+lp)+1);
1077 memcpy(p, insert, li);
1078 s = p + li;
1079 ls += (li-lp);
1084 Similar to all_string_sub but for unicode strings.
1085 Return a new allocated unicode string.
1086 similar to string_sub() but allows for any character to be substituted.
1087 Use with caution!
1090 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1091 const smb_ucs2_t *insert)
1093 smb_ucs2_t *r, *rp;
1094 const smb_ucs2_t *sp;
1095 size_t lr, lp, li, lt;
1097 if (!insert || !pattern || !*pattern || !s)
1098 return NULL;
1100 lt = (size_t)strlen_w(s);
1101 lp = (size_t)strlen_w(pattern);
1102 li = (size_t)strlen_w(insert);
1104 if (li > lp) {
1105 const smb_ucs2_t *st = s;
1106 int ld = li - lp;
1107 while ((sp = strstr_w(st, pattern))) {
1108 st = sp + lp;
1109 lt += ld;
1113 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1114 if (!r) {
1115 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1116 return NULL;
1119 while ((sp = strstr_w(s, pattern))) {
1120 memcpy(rp, s, (sp - s));
1121 rp += ((sp - s) / sizeof(smb_ucs2_t));
1122 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1123 s = sp + lp;
1124 rp += li;
1126 lr = ((rp - r) / sizeof(smb_ucs2_t));
1127 if (lr < lt) {
1128 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1129 rp += (lt - lr);
1131 *rp = 0;
1133 return r;
1136 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1137 const char *insert)
1139 wpstring p, i;
1141 if (!insert || !pattern || !s)
1142 return NULL;
1143 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1144 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1145 return all_string_sub_w(s, p, i);
1148 #if 0
1150 Splits out the front and back at a separator.
1153 static void split_at_last_component(char *path, char *front, char sep, char *back)
1155 char *p = strrchr_m(path, sep);
1157 if (p != NULL)
1158 *p = 0;
1160 if (front != NULL)
1161 pstrcpy(front, path);
1163 if (p != NULL) {
1164 if (back != NULL)
1165 pstrcpy(back, p+1);
1166 *p = '\\';
1167 } else {
1168 if (back != NULL)
1169 back[0] = 0;
1172 #endif
1175 Write an octal as a string.
1178 const char *octal_string(int i)
1180 static char ret[64];
1181 if (i == -1)
1182 return "-1";
1183 slprintf(ret, sizeof(ret)-1, "0%o", i);
1184 return ret;
1189 Truncate a string at a specified length.
1192 char *string_truncate(char *s, unsigned int length)
1194 if (s && strlen(s) > length)
1195 s[length] = 0;
1196 return s;
1200 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1201 We convert via ucs2 for now.
1204 char *strchr_m(const char *src, char c)
1206 wpstring ws;
1207 pstring s2;
1208 smb_ucs2_t *p;
1209 const char *s;
1211 /* characters below 0x3F are guaranteed to not appear in
1212 non-initial position in multi-byte charsets */
1213 if ((c & 0xC0) == 0) {
1214 return strchr(src, c);
1217 /* this is quite a common operation, so we want it to be
1218 fast. We optimise for the ascii case, knowing that all our
1219 supported multi-byte character sets are ascii-compatible
1220 (ie. they match for the first 128 chars) */
1222 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1223 if (*s == c)
1224 return (char *)s;
1227 if (!*s)
1228 return NULL;
1230 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1231 /* With compose characters we must restart from the beginning. JRA. */
1232 s = src;
1233 #endif
1235 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1236 p = strchr_w(ws, UCS2_CHAR(c));
1237 if (!p)
1238 return NULL;
1239 *p = 0;
1240 pull_ucs2_pstring(s2, ws);
1241 return (char *)(s+strlen(s2));
1244 char *strrchr_m(const char *s, char c)
1246 /* characters below 0x3F are guaranteed to not appear in
1247 non-initial position in multi-byte charsets */
1248 if ((c & 0xC0) == 0) {
1249 return strrchr(s, c);
1252 /* this is quite a common operation, so we want it to be
1253 fast. We optimise for the ascii case, knowing that all our
1254 supported multi-byte character sets are ascii-compatible
1255 (ie. they match for the first 128 chars). Also, in Samba
1256 we only search for ascii characters in 'c' and that
1257 in all mb character sets with a compound character
1258 containing c, if 'c' is not a match at position
1259 p, then p[-1] > 0x7f. JRA. */
1262 size_t len = strlen(s);
1263 const char *cp = s;
1264 BOOL got_mb = False;
1266 if (len == 0)
1267 return NULL;
1268 cp += (len - 1);
1269 do {
1270 if (c == *cp) {
1271 /* Could be a match. Part of a multibyte ? */
1272 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1273 /* Yep - go slow :-( */
1274 got_mb = True;
1275 break;
1277 /* No - we have a match ! */
1278 return (char *)cp;
1280 } while (cp-- != s);
1281 if (!got_mb)
1282 return NULL;
1285 /* String contained a non-ascii char. Slow path. */
1287 wpstring ws;
1288 pstring s2;
1289 smb_ucs2_t *p;
1291 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1292 p = strrchr_w(ws, UCS2_CHAR(c));
1293 if (!p)
1294 return NULL;
1295 *p = 0;
1296 pull_ucs2_pstring(s2, ws);
1297 return (char *)(s+strlen(s2));
1301 /***********************************************************************
1302 Return the equivalent of doing strrchr 'n' times - always going
1303 backwards.
1304 ***********************************************************************/
1306 char *strnrchr_m(const char *s, char c, unsigned int n)
1308 wpstring ws;
1309 pstring s2;
1310 smb_ucs2_t *p;
1312 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1313 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1314 if (!p)
1315 return NULL;
1316 *p = 0;
1317 pull_ucs2_pstring(s2, ws);
1318 return (char *)(s+strlen(s2));
1321 /***********************************************************************
1322 strstr_m - We convert via ucs2 for now.
1323 ***********************************************************************/
1325 char *strstr_m(const char *src, const char *findstr)
1327 smb_ucs2_t *p;
1328 smb_ucs2_t *src_w, *find_w;
1329 const char *s;
1330 char *s2;
1331 char *retp;
1333 size_t findstr_len = 0;
1335 /* for correctness */
1336 if (!findstr[0]) {
1337 return src;
1340 /* Samba does single character findstr calls a *lot*. */
1341 if (findstr[1] == '\0')
1342 return strchr_m(src, *findstr);
1344 /* We optimise for the ascii case, knowing that all our
1345 supported multi-byte character sets are ascii-compatible
1346 (ie. they match for the first 128 chars) */
1348 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1349 if (*s == *findstr) {
1350 if (!findstr_len)
1351 findstr_len = strlen(findstr);
1353 if (strncmp(s, findstr, findstr_len) == 0) {
1354 return (char *)s;
1359 if (!*s)
1360 return NULL;
1362 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1363 /* 'make check' fails unless we do this */
1365 /* With compose characters we must restart from the beginning. JRA. */
1366 s = src;
1367 #endif
1369 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1370 DEBUG(0,("strstr_m: src malloc fail\n"));
1371 return NULL;
1374 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1375 SAFE_FREE(src_w);
1376 DEBUG(0,("strstr_m: find malloc fail\n"));
1377 return NULL;
1380 p = strstr_w(src_w, find_w);
1382 if (!p) {
1383 SAFE_FREE(src_w);
1384 SAFE_FREE(find_w);
1385 return NULL;
1388 *p = 0;
1389 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1390 SAFE_FREE(src_w);
1391 SAFE_FREE(find_w);
1392 DEBUG(0,("strstr_m: dest malloc fail\n"));
1393 return NULL;
1395 retp = (char *)(s+strlen(s2));
1396 SAFE_FREE(src_w);
1397 SAFE_FREE(find_w);
1398 SAFE_FREE(s2);
1399 return retp;
1403 Convert a string to lower case.
1406 void strlower_m(char *s)
1408 size_t len;
1409 int errno_save;
1411 /* this is quite a common operation, so we want it to be
1412 fast. We optimise for the ascii case, knowing that all our
1413 supported multi-byte character sets are ascii-compatible
1414 (ie. they match for the first 128 chars) */
1416 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1417 *s = tolower((unsigned char)*s);
1418 s++;
1421 if (!*s)
1422 return;
1424 /* I assume that lowercased string takes the same number of bytes
1425 * as source string even in UTF-8 encoding. (VIV) */
1426 len = strlen(s) + 1;
1427 errno_save = errno;
1428 errno = 0;
1429 unix_strlower(s,len,s,len);
1430 /* Catch mb conversion errors that may not terminate. */
1431 if (errno)
1432 s[len-1] = '\0';
1433 errno = errno_save;
1437 Convert a string to upper case.
1440 void strupper_m(char *s)
1442 size_t len;
1443 int errno_save;
1445 /* this is quite a common operation, so we want it to be
1446 fast. We optimise for the ascii case, knowing that all our
1447 supported multi-byte character sets are ascii-compatible
1448 (ie. they match for the first 128 chars) */
1450 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1451 *s = toupper((unsigned char)*s);
1452 s++;
1455 if (!*s)
1456 return;
1458 /* I assume that lowercased string takes the same number of bytes
1459 * as source string even in multibyte encoding. (VIV) */
1460 len = strlen(s) + 1;
1461 errno_save = errno;
1462 errno = 0;
1463 unix_strupper(s,len,s,len);
1464 /* Catch mb conversion errors that may not terminate. */
1465 if (errno)
1466 s[len-1] = '\0';
1467 errno = errno_save;
1471 Return a RFC2254 binary string representation of a buffer.
1472 Used in LDAP filters.
1473 Caller must free.
1476 char *binary_string(char *buf, int len)
1478 char *s;
1479 int i, j;
1480 const char *hex = "0123456789ABCDEF";
1481 s = SMB_MALLOC(len * 3 + 1);
1482 if (!s)
1483 return NULL;
1484 for (j=i=0;i<len;i++) {
1485 s[j] = '\\';
1486 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1487 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1488 j += 3;
1490 s[j] = 0;
1491 return s;
1495 Just a typesafety wrapper for snprintf into a pstring.
1498 int pstr_sprintf(pstring s, const char *fmt, ...)
1500 va_list ap;
1501 int ret;
1503 va_start(ap, fmt);
1504 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1505 va_end(ap);
1506 return ret;
1511 Just a typesafety wrapper for snprintf into a fstring.
1514 int fstr_sprintf(fstring s, const char *fmt, ...)
1516 va_list ap;
1517 int ret;
1519 va_start(ap, fmt);
1520 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1521 va_end(ap);
1522 return ret;
1526 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1528 Some platforms don't have strndup.
1531 char *strndup(const char *s, size_t n)
1533 char *ret;
1535 n = strnlen(s, n);
1536 ret = SMB_MALLOC(n+1);
1537 if (!ret)
1538 return NULL;
1539 memcpy(ret, s, n);
1540 ret[n] = 0;
1542 return ret;
1544 #endif
1546 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1548 Some platforms don't have strnlen
1551 size_t strnlen(const char *s, size_t n)
1553 int i;
1554 for (i=0; s[i] && i<n; i++)
1555 /* noop */ ;
1556 return i;
1558 #endif
1561 List of Strings manipulation functions
1564 #define S_LIST_ABS 16 /* List Allocation Block Size */
1566 char **str_list_make(const char *string, const char *sep)
1568 char **list, **rlist;
1569 const char *str;
1570 char *s;
1571 int num, lsize;
1572 pstring tok;
1574 if (!string || !*string)
1575 return NULL;
1576 s = SMB_STRDUP(string);
1577 if (!s) {
1578 DEBUG(0,("str_list_make: Unable to allocate memory"));
1579 return NULL;
1581 if (!sep) sep = LIST_SEP;
1583 num = lsize = 0;
1584 list = NULL;
1586 str = s;
1587 while (next_token(&str, tok, sep, sizeof(tok))) {
1588 if (num == lsize) {
1589 lsize += S_LIST_ABS;
1590 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1591 if (!rlist) {
1592 DEBUG(0,("str_list_make: Unable to allocate memory"));
1593 str_list_free(&list);
1594 SAFE_FREE(s);
1595 return NULL;
1596 } else
1597 list = rlist;
1598 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1601 list[num] = SMB_STRDUP(tok);
1602 if (!list[num]) {
1603 DEBUG(0,("str_list_make: Unable to allocate memory"));
1604 str_list_free(&list);
1605 SAFE_FREE(s);
1606 return NULL;
1609 num++;
1612 SAFE_FREE(s);
1613 return list;
1616 BOOL str_list_copy(char ***dest, const char **src)
1618 char **list, **rlist;
1619 int num, lsize;
1621 *dest = NULL;
1622 if (!src)
1623 return False;
1625 num = lsize = 0;
1626 list = NULL;
1628 while (src[num]) {
1629 if (num == lsize) {
1630 lsize += S_LIST_ABS;
1631 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1632 if (!rlist) {
1633 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1634 str_list_free(&list);
1635 return False;
1636 } else
1637 list = rlist;
1638 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1641 list[num] = SMB_STRDUP(src[num]);
1642 if (!list[num]) {
1643 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1644 str_list_free(&list);
1645 return False;
1648 num++;
1651 *dest = list;
1652 return True;
1656 * Return true if all the elements of the list match exactly.
1658 BOOL str_list_compare(char **list1, char **list2)
1660 int num;
1662 if (!list1 || !list2)
1663 return (list1 == list2);
1665 for (num = 0; list1[num]; num++) {
1666 if (!list2[num])
1667 return False;
1668 if (!strcsequal(list1[num], list2[num]))
1669 return False;
1671 if (list2[num])
1672 return False; /* if list2 has more elements than list1 fail */
1674 return True;
1677 void str_list_free(char ***list)
1679 char **tlist;
1681 if (!list || !*list)
1682 return;
1683 tlist = *list;
1684 for(; *tlist; tlist++)
1685 SAFE_FREE(*tlist);
1686 SAFE_FREE(*list);
1689 /******************************************************************************
1690 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1691 for the work
1692 *****************************************************************************/
1694 BOOL str_list_sub_basic( char **list, const char *smb_name )
1696 char *s, *tmpstr;
1698 while ( *list ) {
1699 s = *list;
1700 tmpstr = alloc_sub_basic(smb_name, s);
1701 if ( !tmpstr ) {
1702 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1703 return False;
1706 SAFE_FREE(*list);
1707 *list = tmpstr;
1709 list++;
1712 return True;
1715 /******************************************************************************
1716 substritute a specific pattern in a string list
1717 *****************************************************************************/
1719 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1721 char *p, *s, *t;
1722 ssize_t ls, lp, li, ld, i, d;
1724 if (!list)
1725 return False;
1726 if (!pattern)
1727 return False;
1728 if (!insert)
1729 return False;
1731 lp = (ssize_t)strlen(pattern);
1732 li = (ssize_t)strlen(insert);
1733 ld = li -lp;
1735 while (*list) {
1736 s = *list;
1737 ls = (ssize_t)strlen(s);
1739 while ((p = strstr_m(s, pattern))) {
1740 t = *list;
1741 d = p -t;
1742 if (ld) {
1743 t = (char *) SMB_MALLOC(ls +ld +1);
1744 if (!t) {
1745 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1746 return False;
1748 memcpy(t, *list, d);
1749 memcpy(t +d +li, p +lp, ls -d -lp +1);
1750 SAFE_FREE(*list);
1751 *list = t;
1752 ls += ld;
1753 s = t +d +li;
1756 for (i = 0; i < li; i++) {
1757 switch (insert[i]) {
1758 case '`':
1759 case '"':
1760 case '\'':
1761 case ';':
1762 case '$':
1763 case '%':
1764 case '\r':
1765 case '\n':
1766 t[d +i] = '_';
1767 break;
1768 default:
1769 t[d +i] = insert[i];
1775 list++;
1778 return True;
1782 #define IPSTR_LIST_SEP ","
1783 #define IPSTR_LIST_CHAR ','
1786 * Add ip string representation to ipstr list. Used also
1787 * as part of @function ipstr_list_make
1789 * @param ipstr_list pointer to string containing ip list;
1790 * MUST BE already allocated and IS reallocated if necessary
1791 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1792 * as a result of reallocation)
1793 * @param ip IP address which is to be added to list
1794 * @return pointer to string appended with new ip and possibly
1795 * reallocated to new length
1798 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1800 char* new_ipstr = NULL;
1802 /* arguments checking */
1803 if (!ipstr_list || !service) return NULL;
1805 /* attempt to convert ip to a string and append colon separator to it */
1806 if (*ipstr_list) {
1807 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1808 inet_ntoa(service->ip), service->port);
1809 SAFE_FREE(*ipstr_list);
1810 } else {
1811 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1813 *ipstr_list = new_ipstr;
1814 return *ipstr_list;
1819 * Allocate and initialise an ipstr list using ip adresses
1820 * passed as arguments.
1822 * @param ipstr_list pointer to string meant to be allocated and set
1823 * @param ip_list array of ip addresses to place in the list
1824 * @param ip_count number of addresses stored in ip_list
1825 * @return pointer to allocated ip string
1828 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1830 int i;
1832 /* arguments checking */
1833 if (!ip_list && !ipstr_list) return 0;
1835 *ipstr_list = NULL;
1837 /* process ip addresses given as arguments */
1838 for (i = 0; i < ip_count; i++)
1839 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1841 return (*ipstr_list);
1846 * Parse given ip string list into array of ip addresses
1847 * (as ip_service structures)
1848 * e.g. 192.168.1.100:389,192.168.1.78, ...
1850 * @param ipstr ip string list to be parsed
1851 * @param ip_list pointer to array of ip addresses which is
1852 * allocated by this function and must be freed by caller
1853 * @return number of succesfully parsed addresses
1856 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1858 fstring token_str;
1859 size_t count;
1860 int i;
1862 if (!ipstr_list || !ip_list)
1863 return 0;
1865 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1866 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1867 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1868 return 0;
1871 for ( i=0;
1872 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1873 i++ )
1875 struct in_addr addr;
1876 unsigned port = 0;
1877 char *p = strchr(token_str, ':');
1879 if (p) {
1880 *p = 0;
1881 port = atoi(p+1);
1884 /* convert single token to ip address */
1885 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1886 break;
1888 (*ip_list)[i].ip = addr;
1889 (*ip_list)[i].port = port;
1892 return count;
1897 * Safely free ip string list
1899 * @param ipstr_list ip string list to be freed
1902 void ipstr_list_free(char* ipstr_list)
1904 SAFE_FREE(ipstr_list);
1909 Unescape a URL encoded string, in place.
1912 void rfc1738_unescape(char *buf)
1914 char *p=buf;
1916 while (p && *p && (p=strchr_m(p,'%'))) {
1917 int c1 = p[1];
1918 int c2 = p[2];
1920 if (c1 >= '0' && c1 <= '9')
1921 c1 = c1 - '0';
1922 else if (c1 >= 'A' && c1 <= 'F')
1923 c1 = 10 + c1 - 'A';
1924 else if (c1 >= 'a' && c1 <= 'f')
1925 c1 = 10 + c1 - 'a';
1926 else {p++; continue;}
1928 if (c2 >= '0' && c2 <= '9')
1929 c2 = c2 - '0';
1930 else if (c2 >= 'A' && c2 <= 'F')
1931 c2 = 10 + c2 - 'A';
1932 else if (c2 >= 'a' && c2 <= 'f')
1933 c2 = 10 + c2 - 'a';
1934 else {p++; continue;}
1936 *p = (c1<<4) | c2;
1938 memmove(p+1, p+3, strlen(p+3)+1);
1939 p++;
1943 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1946 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1948 DATA_BLOB base64_decode_data_blob(const char *s)
1950 int bit_offset, byte_offset, idx, i, n;
1951 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1952 unsigned char *d = decoded.data;
1953 char *p;
1955 n=i=0;
1957 while (*s && (p=strchr_m(b64,*s))) {
1958 idx = (int)(p - b64);
1959 byte_offset = (i*6)/8;
1960 bit_offset = (i*6)%8;
1961 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1962 if (bit_offset < 3) {
1963 d[byte_offset] |= (idx << (2-bit_offset));
1964 n = byte_offset+1;
1965 } else {
1966 d[byte_offset] |= (idx >> (bit_offset-2));
1967 d[byte_offset+1] = 0;
1968 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1969 n = byte_offset+2;
1971 s++; i++;
1974 if ((n > 0) && (*s == '=')) {
1975 n -= 1;
1978 /* fix up length */
1979 decoded.length = n;
1980 return decoded;
1984 * Decode a base64 string in-place - wrapper for the above
1986 void base64_decode_inplace(char *s)
1988 DATA_BLOB decoded = base64_decode_data_blob(s);
1990 if ( decoded.length != 0 ) {
1991 memcpy(s, decoded.data, decoded.length);
1993 /* null terminate */
1994 s[decoded.length] = '\0';
1995 } else {
1996 *s = '\0';
1999 data_blob_free(&decoded);
2003 * Encode a base64 string into a malloc()ed string caller to free.
2005 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2007 char * base64_encode_data_blob(DATA_BLOB data)
2009 int bits = 0;
2010 int char_count = 0;
2011 size_t out_cnt = 0;
2012 size_t len = data.length;
2013 size_t output_len = data.length * 2;
2014 char *result = SMB_MALLOC(output_len); /* get us plenty of space */
2016 while (len-- && out_cnt < (data.length * 2) - 5) {
2017 int c = (unsigned char) *(data.data++);
2018 bits += c;
2019 char_count++;
2020 if (char_count == 3) {
2021 result[out_cnt++] = b64[bits >> 18];
2022 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2023 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2024 result[out_cnt++] = b64[bits & 0x3f];
2025 bits = 0;
2026 char_count = 0;
2027 } else {
2028 bits <<= 8;
2031 if (char_count != 0) {
2032 bits <<= 16 - (8 * char_count);
2033 result[out_cnt++] = b64[bits >> 18];
2034 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2035 if (char_count == 1) {
2036 result[out_cnt++] = '=';
2037 result[out_cnt++] = '=';
2038 } else {
2039 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2040 result[out_cnt++] = '=';
2043 result[out_cnt] = '\0'; /* terminate */
2044 return result;
2047 /* read a SMB_BIG_UINT from a string */
2048 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2051 SMB_BIG_UINT val = -1;
2052 const char *p = nptr;
2054 while (p && *p && isspace(*p))
2055 p++;
2056 #ifdef LARGE_SMB_OFF_T
2057 sscanf(p,"%llu",&val);
2058 #else /* LARGE_SMB_OFF_T */
2059 sscanf(p,"%lu",&val);
2060 #endif /* LARGE_SMB_OFF_T */
2061 if (entptr) {
2062 while (p && *p && isdigit(*p))
2063 p++;
2064 *entptr = p;
2067 return val;
2070 void string_append(char **left, const char *right)
2072 int new_len = strlen(right) + 1;
2074 if (*left == NULL) {
2075 *left = SMB_MALLOC(new_len);
2076 *left[0] = '\0';
2077 } else {
2078 new_len += strlen(*left);
2079 *left = SMB_REALLOC(*left, new_len);
2082 if (*left == NULL)
2083 return;
2085 safe_strcat(*left, right, new_len-1);