2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-2001
5 Copyright (C) Simo Sorce 2001-2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /****************************************************************************
25 Get the next token from a string, return False if none found.
26 Handles double-quotes.
27 Based on a routine by GJC@VILLAGE.COM.
28 Extensively modified by Andrew.Tridgell@anu.edu.au
29 ****************************************************************************/
31 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
42 /* default to simple separators */
46 /* find the first non sep char */
47 while (*s && strchr_m(sep,*s))
54 /* copy over the token */
55 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
64 *ptr = (*s) ? s+1 : s;
70 /****************************************************************************
71 This is like next_token but is not re-entrant and "remembers" the first
72 parameter so you can pass NULL. This is useful for user interface code
73 but beware the fact that it is not re-entrant!
74 ****************************************************************************/
76 static char *last_ptr=NULL;
78 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
82 ptr = (const char **)&last_ptr;
84 ret = next_token(ptr, buff, sep, bufsize);
89 static uint16 tmpbuf[sizeof(pstring)];
91 void set_first_token(char *ptr)
96 /****************************************************************************
97 Convert list of tokens to array; dependent on above routine.
98 Uses last_ptr from above - bit of a hack.
99 ****************************************************************************/
101 char **toktocliplist(int *ctok, const char *sep)
110 while(*s && strchr_m(sep,*s))
119 while(*s && (!strchr_m(sep,*s)))
121 while(*s && strchr_m(sep,*s))
128 if (!(ret=iret=malloc(ictok*sizeof(char *))))
142 /*******************************************************************
143 Case insensitive string compararison.
144 ********************************************************************/
146 int StrCaseCmp(const char *s, const char *t)
149 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
150 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
151 return strcmp(buf1,buf2);
154 /*******************************************************************
155 Case insensitive string compararison, length limited.
156 ********************************************************************/
158 int StrnCaseCmp(const char *s, const char *t, size_t n)
161 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
162 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
163 return strncmp(buf1,buf2,n);
166 /*******************************************************************
168 ********************************************************************/
170 BOOL strequal(const char *s1, const char *s2)
177 return(StrCaseCmp(s1,s2)==0);
180 /*******************************************************************
181 Compare 2 strings up to and including the nth char.
182 ******************************************************************/
184 BOOL strnequal(const char *s1,const char *s2,size_t n)
188 if (!s1 || !s2 || !n)
191 return(StrnCaseCmp(s1,s2,n)==0);
194 /*******************************************************************
195 Compare 2 strings (case sensitive).
196 ********************************************************************/
198 BOOL strcsequal(const char *s1,const char *s2)
205 return(strcmp(s1,s2)==0);
208 /***************************************************************************
209 Do a case-insensitive, whitespace-ignoring string compare.
210 ***************************************************************************/
212 int strwicmp(const char *psz1, const char *psz2)
214 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
215 /* appropriate value. */
218 else if (psz1 == NULL)
220 else if (psz2 == NULL)
223 /* sync the strings on first non-whitespace */
225 while (isspace((int)*psz1))
227 while (isspace((int)*psz2))
229 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
235 return (*psz1 - *psz2);
239 /*******************************************************************
240 Convert a string to upper case, but don't modify it.
241 ********************************************************************/
243 char *strupper_static(const char *s)
253 /*******************************************************************
254 Convert a string to "normal" form.
255 ********************************************************************/
257 void strnorm(char *s)
259 extern int case_default;
260 if (case_default == CASE_UPPER)
266 /*******************************************************************
267 Check if a string is in "normal" case.
268 ********************************************************************/
270 BOOL strisnormal(const char *s)
272 extern int case_default;
273 if (case_default == CASE_UPPER)
274 return(!strhaslower(s));
276 return(!strhasupper(s));
280 /****************************************************************************
282 NOTE: oldc and newc must be 7 bit characters
283 ****************************************************************************/
285 void string_replace(char *s,char oldc,char newc)
287 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
288 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
289 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
292 /*******************************************************************
293 Skip past some strings in a buffer.
294 ********************************************************************/
296 char *skip_string(char *buf,size_t n)
299 buf += strlen(buf) + 1;
303 /*******************************************************************
304 Count the number of characters in a string. Normally this will
305 be the same as the number of bytes in a string for single byte strings,
306 but will be different for multibyte.
307 ********************************************************************/
309 size_t str_charnum(const char *s)
311 uint16 tmpbuf2[sizeof(pstring)];
312 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
313 return strlen_w(tmpbuf2);
316 /*******************************************************************
317 Count the number of characters in a string. Normally this will
318 be the same as the number of bytes in a string for single byte strings,
319 but will be different for multibyte.
320 ********************************************************************/
322 size_t str_ascii_charnum(const char *s)
325 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
326 return strlen(tmpbuf2);
329 /*******************************************************************
330 Trim the specified elements off the front and back of a string.
331 ********************************************************************/
333 BOOL trim_string(char *s,const char *front,const char *back)
340 /* Ignore null or empty strings. */
341 if (!s || (s[0] == '\0'))
344 front_len = front? strlen(front) : 0;
345 back_len = back? strlen(back) : 0;
350 while (len && strncmp(s, front, front_len)==0) {
351 memcpy(s, s+front_len, (len-front_len)+1);
358 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
359 s[len-back_len]='\0';
367 /****************************************************************************
368 Does a string have any uppercase chars in it?
369 ****************************************************************************/
371 BOOL strhasupper(const char *s)
374 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
375 for(ptr=tmpbuf;*ptr;ptr++)
381 /****************************************************************************
382 Does a string have any lowercase chars in it?
383 ****************************************************************************/
385 BOOL strhaslower(const char *s)
388 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
389 for(ptr=tmpbuf;*ptr;ptr++)
395 /****************************************************************************
396 Find the number of 'c' chars in a string
397 ****************************************************************************/
399 size_t count_chars(const char *s,char c)
403 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
404 for(count=0,ptr=tmpbuf;*ptr;ptr++)
405 if(*ptr==UCS2_CHAR(c))
410 /*******************************************************************
411 Return True if a string consists only of one particular character.
412 ********************************************************************/
414 BOOL str_is_all(const char *s,char c)
423 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
424 for(ptr=tmpbuf;*ptr;ptr++)
425 if(*ptr!=UCS2_CHAR(c))
431 /*******************************************************************
432 Safe string copy into a known length string. maxlength does not
433 include the terminating zero.
434 ********************************************************************/
436 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
441 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
452 if (len > maxlength) {
453 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
454 (int)(len-maxlength), src));
458 memmove(dest, src, len);
463 /*******************************************************************
464 Safe string cat into a string. maxlength does not
465 include the terminating zero.
466 ********************************************************************/
468 char *safe_strcat(char *dest, const char *src, size_t maxlength)
470 size_t src_len, dest_len;
473 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
480 src_len = strlen(src);
481 dest_len = strlen(dest);
483 if (src_len + dest_len > maxlength) {
484 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
485 (int)(src_len + dest_len - maxlength), src));
486 src_len = maxlength - dest_len;
489 memcpy(&dest[dest_len], src, src_len);
490 dest[dest_len + src_len] = 0;
494 /*******************************************************************
495 Paranoid strcpy into a buffer of given length (includes terminating
496 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
497 and replaces with '_'. Deliberately does *NOT* check for multibyte
498 characters. Don't change it !
499 ********************************************************************/
501 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
506 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
516 if (len >= maxlength)
519 if (!other_safe_chars)
520 other_safe_chars = "";
522 for(i = 0; i < len; i++) {
523 int val = (src[i] & 0xff);
524 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
535 /****************************************************************************
536 Like strncpy but always null terminates. Make sure there is room!
537 The variable n should always be one less than the available size.
538 ****************************************************************************/
540 char *StrnCpy(char *dest,const char *src,size_t n)
549 while (n-- && (*d++ = *src++))
555 /****************************************************************************
556 Like strncpy but copies up to the character marker. always null terminates.
557 returns a pointer to the character marker in the source string (src).
558 ****************************************************************************/
560 char *strncpyn(char *dest, const char *src, size_t n, char c)
565 p = strchr_m(src, c);
567 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
571 str_len = PTR_DIFF(p, src);
572 strncpy(dest, src, MIN(n, str_len));
573 dest[str_len] = '\0';
578 /*************************************************************
579 Routine to get hex characters and turn them into a 16 byte array.
580 the array can be variable length, and any non-hex-numeric
581 characters are skipped. "0xnn" or "0Xnn" is specially catered
584 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
586 **************************************************************/
588 size_t strhex_to_str(char *p, size_t len, const char *strhex)
591 size_t num_chars = 0;
592 unsigned char lonybble, hinybble;
593 const char *hexchars = "0123456789ABCDEF";
594 char *p1 = NULL, *p2 = NULL;
596 for (i = 0; i < len && strhex[i] != 0; i++) {
597 if (strnequal(hexchars, "0x", 2)) {
598 i++; /* skip two chars */
602 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
605 i++; /* next hex digit */
607 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
610 /* get the two nybbles */
611 hinybble = PTR_DIFF(p1, hexchars);
612 lonybble = PTR_DIFF(p2, hexchars);
614 p[num_chars] = (hinybble << 4) | lonybble;
623 /****************************************************************************
624 Check if a string is part of a list.
625 ****************************************************************************/
627 BOOL in_list(char *s,char *list,BOOL casesensitive)
635 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
637 if (strcmp(tok,s) == 0)
640 if (StrCaseCmp(tok,s) == 0)
647 /* this is used to prevent lots of mallocs of size 1 */
648 static char *null_string = NULL;
650 /****************************************************************************
651 Set a string value, allocing the space for the string
652 ****************************************************************************/
654 static BOOL string_init(char **dest,const char *src)
664 if((null_string = (char *)malloc(1)) == NULL) {
665 DEBUG(0,("string_init: malloc fail for null_string.\n"));
672 (*dest) = strdup(src);
673 if ((*dest) == NULL) {
674 DEBUG(0,("Out of memory in string_init\n"));
681 /****************************************************************************
683 ****************************************************************************/
685 void string_free(char **s)
689 if (*s == null_string)
694 /****************************************************************************
695 Set a string value, deallocating any existing space, and allocing the space
697 ****************************************************************************/
699 BOOL string_set(char **dest,const char *src)
702 return(string_init(dest,src));
705 /****************************************************************************
706 Substitute a string for a pattern in another string. Make sure there is
709 This routine looks for pattern in s and replaces it with
710 insert. It may do multiple replacements.
712 Any of " ; ' $ or ` in the insert string are replaced with _
713 if len==0 then the string cannot be extended. This is different from the old
714 use of len==0 which was for no length checks to be done.
715 ****************************************************************************/
717 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
722 if (!insert || !pattern || !*pattern || !s)
725 ls = (ssize_t)strlen(s);
726 lp = (ssize_t)strlen(pattern);
727 li = (ssize_t)strlen(insert);
730 len = ls + 1; /* len is number of *bytes* */
732 while (lp <= ls && (p = strstr(s,pattern))) {
733 if (ls + (li-lp) >= len) {
734 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
735 (int)(ls + (li-lp) - len),
740 memmove(p+li,p+lp,strlen(p+lp)+1);
763 void fstring_sub(char *s,const char *pattern,const char *insert)
765 string_sub(s, pattern, insert, sizeof(fstring));
768 void pstring_sub(char *s,const char *pattern,const char *insert)
770 string_sub(s, pattern, insert, sizeof(pstring));
773 /****************************************************************************
774 Similar to string_sub, but it will accept only allocated strings
775 and may realloc them so pay attention at what you pass on no
776 pointers inside strings, no pstrings or const may be passed
778 ****************************************************************************/
780 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
784 ssize_t ls,lp,li,ld, i;
786 if (!insert || !pattern || !*pattern || !string || !*string)
793 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
796 ls = (ssize_t)strlen(s);
797 lp = (ssize_t)strlen(pattern);
798 li = (ssize_t)strlen(insert);
817 while ((p = strstr(s,pattern))) {
819 char *t = Realloc(string, ls + ld + 1);
821 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
829 memmove(p+li,p+lp,strlen(p+lp)+1);
839 /****************************************************************************
840 Similar to string_sub() but allows for any character to be substituted.
842 if len==0 then the string cannot be extended. This is different from the old
843 use of len==0 which was for no length checks to be done.
844 ****************************************************************************/
846 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
851 if (!insert || !pattern || !s)
854 ls = (ssize_t)strlen(s);
855 lp = (ssize_t)strlen(pattern);
856 li = (ssize_t)strlen(insert);
862 len = ls + 1; /* len is number of *bytes* */
864 while (lp <= ls && (p = strstr(s,pattern))) {
865 if (ls + (li-lp) >= len) {
866 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
867 (int)(ls + (li-lp) - len),
872 memmove(p+li,p+lp,strlen(p+lp)+1);
874 memcpy(p, insert, li);
880 /****************************************************************************
881 Similar to all_string_sub but for unicode strings.
882 Return a new allocated unicode string.
883 similar to string_sub() but allows for any character to be substituted.
885 ****************************************************************************/
887 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
888 const smb_ucs2_t *insert)
891 const smb_ucs2_t *sp;
892 size_t lr, lp, li, lt;
894 if (!insert || !pattern || !*pattern || !s)
897 lt = (size_t)strlen_w(s);
898 lp = (size_t)strlen_w(pattern);
899 li = (size_t)strlen_w(insert);
902 const smb_ucs2_t *st = s;
904 while ((sp = strstr_w(st, pattern))) {
910 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
912 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
916 while ((sp = strstr_w(s, pattern))) {
917 memcpy(rp, s, (sp - s));
918 rp += ((sp - s) / sizeof(smb_ucs2_t));
919 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
923 lr = ((rp - r) / sizeof(smb_ucs2_t));
925 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
933 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
938 if (!insert || !pattern || !s)
940 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
941 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
942 return all_string_sub_w(s, p, i);
945 /****************************************************************************
946 Splits out the front and back at a separator.
947 ****************************************************************************/
949 void split_at_last_component(char *path, char *front, char sep, char *back)
951 char *p = strrchr_m(path, sep);
957 pstrcpy(front, path);
969 /****************************************************************************
970 Write an octal as a string.
971 ****************************************************************************/
973 const char *octal_string(int i)
978 slprintf(ret, sizeof(ret)-1, "0%o", i);
983 /****************************************************************************
984 Truncate a string at a specified length.
985 ****************************************************************************/
987 char *string_truncate(char *s, int length)
989 if (s && strlen(s) > length)
994 /****************************************************************************
995 Strchr and strrchr_m are very hard to do on general multi-byte strings.
996 We convert via ucs2 for now.
997 ****************************************************************************/
999 char *strchr_m(const char *s, char c)
1005 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1006 p = strchr_w(ws, UCS2_CHAR(c));
1010 pull_ucs2_pstring(s2, ws);
1011 return (char *)(s+strlen(s2));
1014 char *strrchr_m(const char *s, char c)
1020 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1021 p = strrchr_w(ws, UCS2_CHAR(c));
1025 pull_ucs2_pstring(s2, ws);
1026 return (char *)(s+strlen(s2));
1029 /*******************************************************************
1030 Convert a string to lower case.
1031 ********************************************************************/
1033 void strlower_m(char *s)
1035 /* this is quite a common operation, so we want it to be
1036 fast. We optimise for the ascii case, knowing that all our
1037 supported multi-byte character sets are ascii-compatible
1038 (ie. they match for the first 128 chars) */
1040 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1041 *s = tolower((unsigned char)*s);
1048 /* I assume that lowercased string takes the same number of bytes
1049 * as source string even in UTF-8 encoding. (VIV) */
1050 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1053 /*******************************************************************
1054 Duplicate convert a string to lower case.
1055 ********************************************************************/
1057 char *strdup_lower(const char *s)
1059 char *t = strdup(s);
1061 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1068 /*******************************************************************
1069 Convert a string to upper case.
1070 ********************************************************************/
1072 void strupper_m(char *s)
1074 /* this is quite a common operation, so we want it to be
1075 fast. We optimise for the ascii case, knowing that all our
1076 supported multi-byte character sets are ascii-compatible
1077 (ie. they match for the first 128 chars) */
1079 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1080 *s = toupper((unsigned char)*s);
1087 /* I assume that lowercased string takes the same number of bytes
1088 * as source string even in multibyte encoding. (VIV) */
1089 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1092 /*******************************************************************
1093 Convert a string to upper case.
1094 ********************************************************************/
1096 char *strdup_upper(const char *s)
1098 char *t = strdup(s);
1100 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1107 /*******************************************************************
1108 Return a RFC2254 binary string representation of a buffer.
1109 Used in LDAP filters.
1111 ********************************************************************/
1113 char *binary_string(char *buf, int len)
1117 const char *hex = "0123456789ABCDEF";
1118 s = malloc(len * 3 + 1);
1121 for (j=i=0;i<len;i++) {
1123 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1124 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1131 /*******************************************************************
1132 Just a typesafety wrapper for snprintf into a pstring.
1133 ********************************************************************/
1135 int pstr_sprintf(pstring s, const char *fmt, ...)
1141 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1146 /*******************************************************************
1147 Just a typesafety wrapper for snprintf into a fstring.
1148 ********************************************************************/
1150 int fstr_sprintf(fstring s, const char *fmt, ...)
1156 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1161 #ifndef HAVE_STRNDUP
1162 /*******************************************************************
1163 Some platforms don't have strndup.
1164 ********************************************************************/
1166 char *strndup(const char *s, size_t n)
1181 #ifndef HAVE_STRNLEN
1182 /*******************************************************************
1183 Some platforms don't have strnlen
1184 ********************************************************************/
1186 size_t strnlen(const char *s, size_t n)
1189 for (i=0; s[i] && i<n; i++)
1195 /***********************************************************
1196 List of Strings manipulation functions
1197 ***********************************************************/
1199 #define S_LIST_ABS 16 /* List Allocation Block Size */
1201 char **str_list_make(const char *string, const char *sep)
1203 char **list, **rlist;
1209 if (!string || !*string)
1213 DEBUG(0,("str_list_make: Unable to allocate memory"));
1216 if (!sep) sep = LIST_SEP;
1222 while (next_token(&str, tok, sep, sizeof(tok))) {
1224 lsize += S_LIST_ABS;
1225 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1227 DEBUG(0,("str_list_make: Unable to allocate memory"));
1228 str_list_free(&list);
1233 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1236 list[num] = strdup(tok);
1238 DEBUG(0,("str_list_make: Unable to allocate memory"));
1239 str_list_free(&list);
1251 BOOL str_list_copy(char ***dest, const char **src)
1253 char **list, **rlist;
1265 lsize += S_LIST_ABS;
1266 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1268 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1269 str_list_free(&list);
1273 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1276 list[num] = strdup(src[num]);
1278 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1279 str_list_free(&list);
1290 /***********************************************************
1291 Return true if all the elements of the list match exactly.
1292 ***********************************************************/
1294 BOOL str_list_compare(char **list1, char **list2)
1298 if (!list1 || !list2)
1299 return (list1 == list2);
1301 for (num = 0; list1[num]; num++) {
1304 if (!strcsequal(list1[num], list2[num]))
1308 return False; /* if list2 has more elements than list1 fail */
1313 void str_list_free(char ***list)
1317 if (!list || !*list)
1320 for(; *tlist; tlist++)
1325 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1328 ssize_t ls, lp, li, ld, i, d;
1337 lp = (ssize_t)strlen(pattern);
1338 li = (ssize_t)strlen(insert);
1343 ls = (ssize_t)strlen(s);
1345 while ((p = strstr(s, pattern))) {
1349 t = (char *) malloc(ls +ld +1);
1351 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1354 memcpy(t, *list, d);
1355 memcpy(t +d +li, p +lp, ls -d -lp +1);
1362 for (i = 0; i < li; i++) {
1363 switch (insert[i]) {
1375 t[d +i] = insert[i];
1387 #define IPSTR_LIST_SEP ","
1390 * Add ip string representation to ipstr list. Used also
1391 * as part of @function ipstr_list_make
1393 * @param ipstr_list pointer to string containing ip list;
1394 * MUST BE already allocated and IS reallocated if necessary
1395 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1396 * as a result of reallocation)
1397 * @param ip IP address which is to be added to list
1398 * @return pointer to string appended with new ip and possibly
1399 * reallocated to new length
1402 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1404 char* new_ipstr = NULL;
1406 /* arguments checking */
1407 if (!ipstr_list || !ip) return NULL;
1409 /* attempt to convert ip to a string and append colon separator to it */
1411 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1412 SAFE_FREE(*ipstr_list);
1414 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1416 *ipstr_list = new_ipstr;
1422 * Allocate and initialise an ipstr list using ip adresses
1423 * passed as arguments.
1425 * @param ipstr_list pointer to string meant to be allocated and set
1426 * @param ip_list array of ip addresses to place in the list
1427 * @param ip_count number of addresses stored in ip_list
1428 * @return pointer to allocated ip string
1431 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1435 /* arguments checking */
1436 if (!ip_list && !ipstr_list) return 0;
1440 /* process ip addresses given as arguments */
1441 for (i = 0; i < ip_count; i++)
1442 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1444 return (*ipstr_list);
1449 * Parse given ip string list into array of ip addresses
1450 * (as in_addr structures)
1452 * @param ipstr ip string list to be parsed
1453 * @param ip_list pointer to array of ip addresses which is
1454 * allocated by this function and must be freed by caller
1455 * @return number of succesfully parsed addresses
1458 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1463 if (!ipstr_list || !ip_list) return 0;
1465 for (*ip_list = NULL, count = 0;
1466 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1469 struct in_addr addr;
1471 /* convert single token to ip address */
1472 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1475 /* prepare place for another in_addr structure */
1476 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1477 if (!*ip_list) return -1;
1479 (*ip_list)[count] = addr;
1487 * Safely free ip string list
1489 * @param ipstr_list ip string list to be freed
1492 void ipstr_list_free(char* ipstr_list)
1494 SAFE_FREE(ipstr_list);
1498 /***********************************************************
1499 Unescape a URL encoded string, in place.
1500 ***********************************************************/
1502 void rfc1738_unescape(char *buf)
1506 while ((p=strchr_m(p,'+')))
1511 while (p && *p && (p=strchr_m(p,'%'))) {
1515 if (c1 >= '0' && c1 <= '9')
1517 else if (c1 >= 'A' && c1 <= 'F')
1519 else if (c1 >= 'a' && c1 <= 'f')
1521 else {p++; continue;}
1523 if (c2 >= '0' && c2 <= '9')
1525 else if (c2 >= 'A' && c2 <= 'F')
1527 else if (c2 >= 'a' && c2 <= 'f')
1529 else {p++; continue;}
1533 memmove(p+1, p+3, strlen(p+3)+1);
1538 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1540 /***************************************************************************
1541 decode a base64 string into a DATA_BLOB - simple and slow algorithm
1542 ***************************************************************************/
1543 DATA_BLOB base64_decode_data_blob(const char *s)
1545 int bit_offset, byte_offset, idx, i, n;
1546 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1547 unsigned char *d = decoded.data;
1552 while (*s && (p=strchr_m(b64,*s))) {
1553 idx = (int)(p - b64);
1554 byte_offset = (i*6)/8;
1555 bit_offset = (i*6)%8;
1556 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1557 if (bit_offset < 3) {
1558 d[byte_offset] |= (idx << (2-bit_offset));
1561 d[byte_offset] |= (idx >> (bit_offset-2));
1562 d[byte_offset+1] = 0;
1563 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1574 /***************************************************************************
1575 decode a base64 string in-place - wrapper for the above
1576 ***************************************************************************/
1577 void base64_decode(char *s)
1579 DATA_BLOB decoded = base64_decode_data_blob(s);
1580 memcpy(s, decoded.data, decoded.length);
1581 data_blob_free(&decoded);
1583 /* null terminate */
1584 s[decoded.length] = '\0';
1587 /***************************************************************************
1588 encode a base64 string into a malloc()ed string caller to free.
1590 From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1591 ***************************************************************************/
1592 char * base64_encode_data_blob(DATA_BLOB data)
1597 size_t len = data.length;
1598 size_t output_len = data.length * 2;
1599 char *result = malloc(output_len); /* get us plenty of space */
1601 while (len-- && out_cnt < (data.length * 2) - 5) {
1602 int c = (unsigned char) *(data.data++);
1605 if (char_count == 3) {
1606 result[out_cnt++] = b64[bits >> 18];
1607 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1608 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1609 result[out_cnt++] = b64[bits & 0x3f];
1616 if (char_count != 0) {
1617 bits <<= 16 - (8 * char_count);
1618 result[out_cnt++] = b64[bits >> 18];
1619 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1620 if (char_count == 1) {
1621 result[out_cnt++] = '=';
1622 result[out_cnt++] = '=';
1624 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1625 result[out_cnt++] = '=';
1628 result[out_cnt] = '\0'; /* terminate */
1633 size_t valgrind_strlen(const char *s)
1636 for(count = 0; *s++; count++)