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 if (maxlength > dest_len) {
487 memcpy(&dest[dest_len], src, maxlength - dest_len);
493 memcpy(&dest[dest_len], src, src_len);
494 dest[dest_len + src_len] = 0;
498 /*******************************************************************
499 Paranoid strcpy into a buffer of given length (includes terminating
500 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
501 and replaces with '_'. Deliberately does *NOT* check for multibyte
502 characters. Don't change it !
503 ********************************************************************/
505 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
510 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
520 if (len >= maxlength)
523 if (!other_safe_chars)
524 other_safe_chars = "";
526 for(i = 0; i < len; i++) {
527 int val = (src[i] & 0xff);
528 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
539 /****************************************************************************
540 Like strncpy but always null terminates. Make sure there is room!
541 The variable n should always be one less than the available size.
542 ****************************************************************************/
544 char *StrnCpy(char *dest,const char *src,size_t n)
553 while (n-- && (*d++ = *src++))
559 /****************************************************************************
560 Like strncpy but copies up to the character marker. always null terminates.
561 returns a pointer to the character marker in the source string (src).
562 ****************************************************************************/
564 char *strncpyn(char *dest, const char *src, size_t n, char c)
569 p = strchr_m(src, c);
571 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
575 str_len = PTR_DIFF(p, src);
576 strncpy(dest, src, MIN(n, str_len));
577 dest[str_len] = '\0';
582 /*************************************************************
583 Routine to get hex characters and turn them into a 16 byte array.
584 the array can be variable length, and any non-hex-numeric
585 characters are skipped. "0xnn" or "0Xnn" is specially catered
588 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
590 **************************************************************/
592 size_t strhex_to_str(char *p, size_t len, const char *strhex)
595 size_t num_chars = 0;
596 unsigned char lonybble, hinybble;
597 const char *hexchars = "0123456789ABCDEF";
598 char *p1 = NULL, *p2 = NULL;
600 for (i = 0; i < len && strhex[i] != 0; i++) {
601 if (strnequal(hexchars, "0x", 2)) {
602 i++; /* skip two chars */
606 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
609 i++; /* next hex digit */
611 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
614 /* get the two nybbles */
615 hinybble = PTR_DIFF(p1, hexchars);
616 lonybble = PTR_DIFF(p2, hexchars);
618 p[num_chars] = (hinybble << 4) | lonybble;
627 /****************************************************************************
628 Check if a string is part of a list.
629 ****************************************************************************/
631 BOOL in_list(char *s,char *list,BOOL casesensitive)
639 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
641 if (strcmp(tok,s) == 0)
644 if (StrCaseCmp(tok,s) == 0)
651 /* this is used to prevent lots of mallocs of size 1 */
652 static char *null_string = NULL;
654 /****************************************************************************
655 Set a string value, allocing the space for the string
656 ****************************************************************************/
658 static BOOL string_init(char **dest,const char *src)
668 if((null_string = (char *)malloc(1)) == NULL) {
669 DEBUG(0,("string_init: malloc fail for null_string.\n"));
676 (*dest) = strdup(src);
677 if ((*dest) == NULL) {
678 DEBUG(0,("Out of memory in string_init\n"));
685 /****************************************************************************
687 ****************************************************************************/
689 void string_free(char **s)
693 if (*s == null_string)
698 /****************************************************************************
699 Set a string value, deallocating any existing space, and allocing the space
701 ****************************************************************************/
703 BOOL string_set(char **dest,const char *src)
706 return(string_init(dest,src));
709 /****************************************************************************
710 Substitute a string for a pattern in another string. Make sure there is
713 This routine looks for pattern in s and replaces it with
714 insert. It may do multiple replacements.
716 Any of " ; ' $ or ` in the insert string are replaced with _
717 if len==0 then the string cannot be extended. This is different from the old
718 use of len==0 which was for no length checks to be done.
719 ****************************************************************************/
721 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
726 if (!insert || !pattern || !*pattern || !s)
729 ls = (ssize_t)strlen(s);
730 lp = (ssize_t)strlen(pattern);
731 li = (ssize_t)strlen(insert);
734 len = ls + 1; /* len is number of *bytes* */
736 while (lp <= ls && (p = strstr(s,pattern))) {
737 if (ls + (li-lp) >= len) {
738 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
739 (int)(ls + (li-lp) - len),
744 memmove(p+li,p+lp,strlen(p+lp)+1);
767 void fstring_sub(char *s,const char *pattern,const char *insert)
769 string_sub(s, pattern, insert, sizeof(fstring));
772 void pstring_sub(char *s,const char *pattern,const char *insert)
774 string_sub(s, pattern, insert, sizeof(pstring));
777 /****************************************************************************
778 Similar to string_sub, but it will accept only allocated strings
779 and may realloc them so pay attention at what you pass on no
780 pointers inside strings, no pstrings or const may be passed
782 ****************************************************************************/
784 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
788 ssize_t ls,lp,li,ld, i;
790 if (!insert || !pattern || !*pattern || !string || !*string)
797 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
800 ls = (ssize_t)strlen(s);
801 lp = (ssize_t)strlen(pattern);
802 li = (ssize_t)strlen(insert);
821 while ((p = strstr(s,pattern))) {
823 char *t = Realloc(string, ls + ld + 1);
825 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
833 memmove(p+li,p+lp,strlen(p+lp)+1);
843 /****************************************************************************
844 Similar to string_sub() but allows for any character to be substituted.
846 if len==0 then the string cannot be extended. This is different from the old
847 use of len==0 which was for no length checks to be done.
848 ****************************************************************************/
850 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
855 if (!insert || !pattern || !s)
858 ls = (ssize_t)strlen(s);
859 lp = (ssize_t)strlen(pattern);
860 li = (ssize_t)strlen(insert);
866 len = ls + 1; /* len is number of *bytes* */
868 while (lp <= ls && (p = strstr(s,pattern))) {
869 if (ls + (li-lp) >= len) {
870 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
871 (int)(ls + (li-lp) - len),
876 memmove(p+li,p+lp,strlen(p+lp)+1);
878 memcpy(p, insert, li);
884 /****************************************************************************
885 Similar to all_string_sub but for unicode strings.
886 Return a new allocated unicode string.
887 similar to string_sub() but allows for any character to be substituted.
889 ****************************************************************************/
891 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
892 const smb_ucs2_t *insert)
895 const smb_ucs2_t *sp;
896 size_t lr, lp, li, lt;
898 if (!insert || !pattern || !*pattern || !s)
901 lt = (size_t)strlen_w(s);
902 lp = (size_t)strlen_w(pattern);
903 li = (size_t)strlen_w(insert);
906 const smb_ucs2_t *st = s;
908 while ((sp = strstr_w(st, pattern))) {
914 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
916 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
920 while ((sp = strstr_w(s, pattern))) {
921 memcpy(rp, s, (sp - s));
922 rp += ((sp - s) / sizeof(smb_ucs2_t));
923 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
927 lr = ((rp - r) / sizeof(smb_ucs2_t));
929 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
937 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
942 if (!insert || !pattern || !s)
944 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
945 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
946 return all_string_sub_w(s, p, i);
949 /****************************************************************************
950 Splits out the front and back at a separator.
951 ****************************************************************************/
953 void split_at_last_component(char *path, char *front, char sep, char *back)
955 char *p = strrchr_m(path, sep);
961 pstrcpy(front, path);
973 /****************************************************************************
974 Write an octal as a string.
975 ****************************************************************************/
977 const char *octal_string(int i)
982 slprintf(ret, sizeof(ret)-1, "0%o", i);
987 /****************************************************************************
988 Truncate a string at a specified length.
989 ****************************************************************************/
991 char *string_truncate(char *s, int length)
993 if (s && strlen(s) > length)
998 /****************************************************************************
999 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1000 We convert via ucs2 for now.
1001 ****************************************************************************/
1003 char *strchr_m(const char *s, char c)
1009 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1010 p = strchr_w(ws, UCS2_CHAR(c));
1014 pull_ucs2_pstring(s2, ws);
1015 return (char *)(s+strlen(s2));
1018 char *strrchr_m(const char *s, char c)
1024 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1025 p = strrchr_w(ws, UCS2_CHAR(c));
1029 pull_ucs2_pstring(s2, ws);
1030 return (char *)(s+strlen(s2));
1033 /*******************************************************************
1034 Convert a string to lower case.
1035 ********************************************************************/
1037 void strlower_m(char *s)
1039 /* this is quite a common operation, so we want it to be
1040 fast. We optimise for the ascii case, knowing that all our
1041 supported multi-byte character sets are ascii-compatible
1042 (ie. they match for the first 128 chars) */
1044 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1045 *s = tolower((unsigned char)*s);
1052 /* I assume that lowercased string takes the same number of bytes
1053 * as source string even in UTF-8 encoding. (VIV) */
1054 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1057 /*******************************************************************
1058 Duplicate convert a string to lower case.
1059 ********************************************************************/
1061 char *strdup_lower(const char *s)
1063 char *t = strdup(s);
1065 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1072 /*******************************************************************
1073 Convert a string to upper case.
1074 ********************************************************************/
1076 void strupper_m(char *s)
1078 /* this is quite a common operation, so we want it to be
1079 fast. We optimise for the ascii case, knowing that all our
1080 supported multi-byte character sets are ascii-compatible
1081 (ie. they match for the first 128 chars) */
1083 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1084 *s = toupper((unsigned char)*s);
1091 /* I assume that lowercased string takes the same number of bytes
1092 * as source string even in multibyte encoding. (VIV) */
1093 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1096 /*******************************************************************
1097 Convert a string to upper case.
1098 ********************************************************************/
1100 char *strdup_upper(const char *s)
1102 char *t = strdup(s);
1104 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1111 /*******************************************************************
1112 Return a RFC2254 binary string representation of a buffer.
1113 Used in LDAP filters.
1115 ********************************************************************/
1117 char *binary_string(char *buf, int len)
1121 const char *hex = "0123456789ABCDEF";
1122 s = malloc(len * 3 + 1);
1125 for (j=i=0;i<len;i++) {
1127 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1128 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1135 /*******************************************************************
1136 Just a typesafety wrapper for snprintf into a pstring.
1137 ********************************************************************/
1139 int pstr_sprintf(pstring s, const char *fmt, ...)
1145 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1150 /*******************************************************************
1151 Just a typesafety wrapper for snprintf into a fstring.
1152 ********************************************************************/
1154 int fstr_sprintf(fstring s, const char *fmt, ...)
1160 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1165 #ifndef HAVE_STRNDUP
1166 /*******************************************************************
1167 Some platforms don't have strndup.
1168 ********************************************************************/
1170 char *strndup(const char *s, size_t n)
1185 #ifndef HAVE_STRNLEN
1186 /*******************************************************************
1187 Some platforms don't have strnlen
1188 ********************************************************************/
1190 size_t strnlen(const char *s, size_t n)
1193 for (i=0; s[i] && i<n; i++)
1199 /***********************************************************
1200 List of Strings manipulation functions
1201 ***********************************************************/
1203 #define S_LIST_ABS 16 /* List Allocation Block Size */
1205 char **str_list_make(const char *string, const char *sep)
1207 char **list, **rlist;
1213 if (!string || !*string)
1217 DEBUG(0,("str_list_make: Unable to allocate memory"));
1220 if (!sep) sep = LIST_SEP;
1226 while (next_token(&str, tok, sep, sizeof(tok))) {
1228 lsize += S_LIST_ABS;
1229 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1231 DEBUG(0,("str_list_make: Unable to allocate memory"));
1232 str_list_free(&list);
1237 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1240 list[num] = strdup(tok);
1242 DEBUG(0,("str_list_make: Unable to allocate memory"));
1243 str_list_free(&list);
1255 BOOL str_list_copy(char ***dest, const char **src)
1257 char **list, **rlist;
1269 lsize += S_LIST_ABS;
1270 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1272 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1273 str_list_free(&list);
1277 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1280 list[num] = strdup(src[num]);
1282 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1283 str_list_free(&list);
1294 /***********************************************************
1295 Return true if all the elements of the list match exactly.
1296 ***********************************************************/
1298 BOOL str_list_compare(char **list1, char **list2)
1302 if (!list1 || !list2)
1303 return (list1 == list2);
1305 for (num = 0; list1[num]; num++) {
1308 if (!strcsequal(list1[num], list2[num]))
1312 return False; /* if list2 has more elements than list1 fail */
1317 void str_list_free(char ***list)
1321 if (!list || !*list)
1324 for(; *tlist; tlist++)
1329 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1332 ssize_t ls, lp, li, ld, i, d;
1341 lp = (ssize_t)strlen(pattern);
1342 li = (ssize_t)strlen(insert);
1347 ls = (ssize_t)strlen(s);
1349 while ((p = strstr(s, pattern))) {
1353 t = (char *) malloc(ls +ld +1);
1355 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1358 memcpy(t, *list, d);
1359 memcpy(t +d +li, p +lp, ls -d -lp +1);
1366 for (i = 0; i < li; i++) {
1367 switch (insert[i]) {
1379 t[d +i] = insert[i];
1391 #define IPSTR_LIST_SEP ","
1394 * Add ip string representation to ipstr list. Used also
1395 * as part of @function ipstr_list_make
1397 * @param ipstr_list pointer to string containing ip list;
1398 * MUST BE already allocated and IS reallocated if necessary
1399 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1400 * as a result of reallocation)
1401 * @param ip IP address which is to be added to list
1402 * @return pointer to string appended with new ip and possibly
1403 * reallocated to new length
1406 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1408 char* new_ipstr = NULL;
1410 /* arguments checking */
1411 if (!ipstr_list || !ip) return NULL;
1413 /* attempt to convert ip to a string and append colon separator to it */
1415 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1416 SAFE_FREE(*ipstr_list);
1418 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1420 *ipstr_list = new_ipstr;
1426 * Allocate and initialise an ipstr list using ip adresses
1427 * passed as arguments.
1429 * @param ipstr_list pointer to string meant to be allocated and set
1430 * @param ip_list array of ip addresses to place in the list
1431 * @param ip_count number of addresses stored in ip_list
1432 * @return pointer to allocated ip string
1435 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1439 /* arguments checking */
1440 if (!ip_list && !ipstr_list) return 0;
1444 /* process ip addresses given as arguments */
1445 for (i = 0; i < ip_count; i++)
1446 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1448 return (*ipstr_list);
1453 * Parse given ip string list into array of ip addresses
1454 * (as in_addr structures)
1456 * @param ipstr ip string list to be parsed
1457 * @param ip_list pointer to array of ip addresses which is
1458 * allocated by this function and must be freed by caller
1459 * @return number of succesfully parsed addresses
1462 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1467 if (!ipstr_list || !ip_list) return 0;
1469 for (*ip_list = NULL, count = 0;
1470 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1473 struct in_addr addr;
1475 /* convert single token to ip address */
1476 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1479 /* prepare place for another in_addr structure */
1480 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1481 if (!*ip_list) return -1;
1483 (*ip_list)[count] = addr;
1491 * Safely free ip string list
1493 * @param ipstr_list ip string list to be freed
1496 void ipstr_list_free(char* ipstr_list)
1498 SAFE_FREE(ipstr_list);
1502 /***********************************************************
1503 Unescape a URL encoded string, in place.
1504 ***********************************************************/
1506 void rfc1738_unescape(char *buf)
1510 while ((p=strchr_m(p,'+')))
1515 while (p && *p && (p=strchr_m(p,'%'))) {
1519 if (c1 >= '0' && c1 <= '9')
1521 else if (c1 >= 'A' && c1 <= 'F')
1523 else if (c1 >= 'a' && c1 <= 'f')
1525 else {p++; continue;}
1527 if (c2 >= '0' && c2 <= '9')
1529 else if (c2 >= 'A' && c2 <= 'F')
1531 else if (c2 >= 'a' && c2 <= 'f')
1533 else {p++; continue;}
1537 memmove(p+1, p+3, strlen(p+3)+1);
1542 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1544 /***************************************************************************
1545 decode a base64 string into a DATA_BLOB - simple and slow algorithm
1546 ***************************************************************************/
1547 DATA_BLOB base64_decode_data_blob(const char *s)
1549 int bit_offset, byte_offset, idx, i, n;
1550 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1551 unsigned char *d = decoded.data;
1556 while (*s && (p=strchr_m(b64,*s))) {
1557 idx = (int)(p - b64);
1558 byte_offset = (i*6)/8;
1559 bit_offset = (i*6)%8;
1560 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1561 if (bit_offset < 3) {
1562 d[byte_offset] |= (idx << (2-bit_offset));
1565 d[byte_offset] |= (idx >> (bit_offset-2));
1566 d[byte_offset+1] = 0;
1567 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1578 /***************************************************************************
1579 decode a base64 string in-place - wrapper for the above
1580 ***************************************************************************/
1581 void base64_decode(char *s)
1583 DATA_BLOB decoded = base64_decode_data_blob(s);
1584 memcpy(s, decoded.data, decoded.length);
1585 data_blob_free(&decoded);
1587 /* null terminate */
1588 s[decoded.length] = '\0';
1591 /***************************************************************************
1592 encode a base64 string into a malloc()ed string caller to free.
1594 From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1595 ***************************************************************************/
1596 char * base64_encode_data_blob(DATA_BLOB data)
1601 size_t len = data.length;
1602 size_t output_len = data.length * 2;
1603 char *result = malloc(output_len); /* get us plenty of space */
1605 while (len-- && out_cnt < (data.length * 2) - 5) {
1606 int c = (unsigned char) *(data.data++);
1609 if (char_count == 3) {
1610 result[out_cnt++] = b64[bits >> 18];
1611 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1612 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1613 result[out_cnt++] = b64[bits & 0x3f];
1620 if (char_count != 0) {
1621 bits <<= 16 - (8 * char_count);
1622 result[out_cnt++] = b64[bits >> 18];
1623 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1624 if (char_count == 1) {
1625 result[out_cnt++] = '=';
1626 result[out_cnt++] = '=';
1628 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1629 result[out_cnt++] = '=';
1632 result[out_cnt] = '\0'; /* terminate */
1637 size_t valgrind_strlen(const char *s)
1640 for(count = 0; *s++; count++)