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"));
446 dest[maxlength]='\0';
456 if (len > maxlength) {
457 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
458 (unsigned int)(len-maxlength), len, maxlength, src));
462 memmove(dest, src, len);
467 /*******************************************************************
468 Safe string cat into a string. maxlength does not
469 include the terminating zero.
470 ********************************************************************/
472 char *safe_strcat(char *dest, const char *src, size_t maxlength)
474 size_t src_len, dest_len;
477 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
484 src_len = strlen(src);
485 dest_len = strlen(dest);
487 if (src_len + dest_len > maxlength) {
488 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
489 (int)(src_len + dest_len - maxlength), src));
490 if (maxlength > dest_len) {
491 memcpy(&dest[dest_len], src, maxlength - dest_len);
497 memcpy(&dest[dest_len], src, src_len);
498 dest[dest_len + src_len] = 0;
502 /*******************************************************************
503 Paranoid strcpy into a buffer of given length (includes terminating
504 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
505 and replaces with '_'. Deliberately does *NOT* check for multibyte
506 characters. Don't change it !
507 ********************************************************************/
509 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
514 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
524 if (len >= maxlength)
527 if (!other_safe_chars)
528 other_safe_chars = "";
530 for(i = 0; i < len; i++) {
531 int val = (src[i] & 0xff);
532 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
543 /****************************************************************************
544 Like strncpy but always null terminates. Make sure there is room!
545 The variable n should always be one less than the available size.
546 ****************************************************************************/
548 char *StrnCpy(char *dest,const char *src,size_t n)
557 while (n-- && (*d++ = *src++))
563 /****************************************************************************
564 Like strncpy but copies up to the character marker. always null terminates.
565 returns a pointer to the character marker in the source string (src).
566 ****************************************************************************/
568 char *strncpyn(char *dest, const char *src, size_t n, char c)
573 p = strchr_m(src, c);
575 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
579 str_len = PTR_DIFF(p, src);
580 strncpy(dest, src, MIN(n, str_len));
581 dest[str_len] = '\0';
586 /*************************************************************
587 Routine to get hex characters and turn them into a 16 byte array.
588 the array can be variable length, and any non-hex-numeric
589 characters are skipped. "0xnn" or "0Xnn" is specially catered
592 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
594 **************************************************************/
596 size_t strhex_to_str(char *p, size_t len, const char *strhex)
599 size_t num_chars = 0;
600 unsigned char lonybble, hinybble;
601 const char *hexchars = "0123456789ABCDEF";
602 char *p1 = NULL, *p2 = NULL;
604 for (i = 0; i < len && strhex[i] != 0; i++) {
605 if (strnequal(hexchars, "0x", 2)) {
606 i++; /* skip two chars */
610 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
613 i++; /* next hex digit */
615 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
618 /* get the two nybbles */
619 hinybble = PTR_DIFF(p1, hexchars);
620 lonybble = PTR_DIFF(p2, hexchars);
622 p[num_chars] = (hinybble << 4) | lonybble;
631 /****************************************************************************
632 Check if a string is part of a list.
633 ****************************************************************************/
635 BOOL in_list(char *s,char *list,BOOL casesensitive)
643 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
645 if (strcmp(tok,s) == 0)
648 if (StrCaseCmp(tok,s) == 0)
655 /* this is used to prevent lots of mallocs of size 1 */
656 static char *null_string = NULL;
658 /****************************************************************************
659 Set a string value, allocing the space for the string
660 ****************************************************************************/
662 static BOOL string_init(char **dest,const char *src)
672 if((null_string = (char *)malloc(1)) == NULL) {
673 DEBUG(0,("string_init: malloc fail for null_string.\n"));
680 (*dest) = strdup(src);
681 if ((*dest) == NULL) {
682 DEBUG(0,("Out of memory in string_init\n"));
689 /****************************************************************************
691 ****************************************************************************/
693 void string_free(char **s)
697 if (*s == null_string)
702 /****************************************************************************
703 Set a string value, deallocating any existing space, and allocing the space
705 ****************************************************************************/
707 BOOL string_set(char **dest,const char *src)
710 return(string_init(dest,src));
713 /****************************************************************************
714 Substitute a string for a pattern in another string. Make sure there is
717 This routine looks for pattern in s and replaces it with
718 insert. It may do multiple replacements.
720 Any of " ; ' $ or ` in the insert string are replaced with _
721 if len==0 then the string cannot be extended. This is different from the old
722 use of len==0 which was for no length checks to be done.
723 ****************************************************************************/
725 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
730 if (!insert || !pattern || !*pattern || !s)
733 ls = (ssize_t)strlen(s);
734 lp = (ssize_t)strlen(pattern);
735 li = (ssize_t)strlen(insert);
738 len = ls + 1; /* len is number of *bytes* */
740 while (lp <= ls && (p = strstr(s,pattern))) {
741 if (ls + (li-lp) >= len) {
742 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
743 (int)(ls + (li-lp) - len),
748 memmove(p+li,p+lp,strlen(p+lp)+1);
771 void fstring_sub(char *s,const char *pattern,const char *insert)
773 string_sub(s, pattern, insert, sizeof(fstring));
776 void pstring_sub(char *s,const char *pattern,const char *insert)
778 string_sub(s, pattern, insert, sizeof(pstring));
781 /****************************************************************************
782 Similar to string_sub, but it will accept only allocated strings
783 and may realloc them so pay attention at what you pass on no
784 pointers inside strings, no pstrings or const may be passed
786 ****************************************************************************/
788 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
792 ssize_t ls,lp,li,ld, i;
794 if (!insert || !pattern || !*pattern || !string || !*string)
801 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
804 ls = (ssize_t)strlen(s);
805 lp = (ssize_t)strlen(pattern);
806 li = (ssize_t)strlen(insert);
825 while ((p = strstr(s,pattern))) {
827 char *t = Realloc(string, ls + ld + 1);
829 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
837 memmove(p+li,p+lp,strlen(p+lp)+1);
847 /****************************************************************************
848 Similar to string_sub() but allows for any character to be substituted.
850 if len==0 then the string cannot be extended. This is different from the old
851 use of len==0 which was for no length checks to be done.
852 ****************************************************************************/
854 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
859 if (!insert || !pattern || !s)
862 ls = (ssize_t)strlen(s);
863 lp = (ssize_t)strlen(pattern);
864 li = (ssize_t)strlen(insert);
870 len = ls + 1; /* len is number of *bytes* */
872 while (lp <= ls && (p = strstr(s,pattern))) {
873 if (ls + (li-lp) >= len) {
874 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
875 (int)(ls + (li-lp) - len),
880 memmove(p+li,p+lp,strlen(p+lp)+1);
882 memcpy(p, insert, li);
888 /****************************************************************************
889 Similar to all_string_sub but for unicode strings.
890 Return a new allocated unicode string.
891 similar to string_sub() but allows for any character to be substituted.
893 ****************************************************************************/
895 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
896 const smb_ucs2_t *insert)
899 const smb_ucs2_t *sp;
900 size_t lr, lp, li, lt;
902 if (!insert || !pattern || !*pattern || !s)
905 lt = (size_t)strlen_w(s);
906 lp = (size_t)strlen_w(pattern);
907 li = (size_t)strlen_w(insert);
910 const smb_ucs2_t *st = s;
912 while ((sp = strstr_w(st, pattern))) {
918 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
920 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
924 while ((sp = strstr_w(s, pattern))) {
925 memcpy(rp, s, (sp - s));
926 rp += ((sp - s) / sizeof(smb_ucs2_t));
927 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
931 lr = ((rp - r) / sizeof(smb_ucs2_t));
933 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
941 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
946 if (!insert || !pattern || !s)
948 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
949 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
950 return all_string_sub_w(s, p, i);
953 /****************************************************************************
954 Splits out the front and back at a separator.
955 ****************************************************************************/
957 void split_at_last_component(char *path, char *front, char sep, char *back)
959 char *p = strrchr_m(path, sep);
965 pstrcpy(front, path);
977 /****************************************************************************
978 Write an octal as a string.
979 ****************************************************************************/
981 const char *octal_string(int i)
986 slprintf(ret, sizeof(ret)-1, "0%o", i);
991 /****************************************************************************
992 Truncate a string at a specified length.
993 ****************************************************************************/
995 char *string_truncate(char *s, int length)
997 if (s && strlen(s) > length)
1002 /****************************************************************************
1003 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1004 We convert via ucs2 for now.
1005 ****************************************************************************/
1007 char *strchr_m(const char *s, char c)
1013 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1014 p = strchr_w(ws, UCS2_CHAR(c));
1018 pull_ucs2_pstring(s2, ws);
1019 return (char *)(s+strlen(s2));
1022 char *strrchr_m(const char *s, char c)
1028 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1029 p = strrchr_w(ws, UCS2_CHAR(c));
1033 pull_ucs2_pstring(s2, ws);
1034 return (char *)(s+strlen(s2));
1037 /*******************************************************************
1038 Convert a string to lower case.
1039 ********************************************************************/
1041 void strlower_m(char *s)
1043 /* this is quite a common operation, so we want it to be
1044 fast. We optimise for the ascii case, knowing that all our
1045 supported multi-byte character sets are ascii-compatible
1046 (ie. they match for the first 128 chars) */
1048 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1049 *s = tolower((unsigned char)*s);
1056 /* I assume that lowercased string takes the same number of bytes
1057 * as source string even in UTF-8 encoding. (VIV) */
1058 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1061 /*******************************************************************
1062 Duplicate convert a string to lower case.
1063 ********************************************************************/
1065 char *strdup_lower(const char *s)
1067 char *t = strdup(s);
1069 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1076 /*******************************************************************
1077 Convert a string to upper case.
1078 ********************************************************************/
1080 void strupper_m(char *s)
1082 /* this is quite a common operation, so we want it to be
1083 fast. We optimise for the ascii case, knowing that all our
1084 supported multi-byte character sets are ascii-compatible
1085 (ie. they match for the first 128 chars) */
1087 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1088 *s = toupper((unsigned char)*s);
1095 /* I assume that lowercased string takes the same number of bytes
1096 * as source string even in multibyte encoding. (VIV) */
1097 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1100 /*******************************************************************
1101 Convert a string to upper case.
1102 ********************************************************************/
1104 char *strdup_upper(const char *s)
1106 char *t = strdup(s);
1108 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1115 /*******************************************************************
1116 Return a RFC2254 binary string representation of a buffer.
1117 Used in LDAP filters.
1119 ********************************************************************/
1121 char *binary_string(char *buf, int len)
1125 const char *hex = "0123456789ABCDEF";
1126 s = malloc(len * 3 + 1);
1129 for (j=i=0;i<len;i++) {
1131 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1132 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1139 /*******************************************************************
1140 Just a typesafety wrapper for snprintf into a pstring.
1141 ********************************************************************/
1143 int pstr_sprintf(pstring s, const char *fmt, ...)
1149 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1154 /*******************************************************************
1155 Just a typesafety wrapper for snprintf into a fstring.
1156 ********************************************************************/
1158 int fstr_sprintf(fstring s, const char *fmt, ...)
1164 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1169 #ifndef HAVE_STRNDUP
1170 /*******************************************************************
1171 Some platforms don't have strndup.
1172 ********************************************************************/
1174 char *strndup(const char *s, size_t n)
1189 #ifndef HAVE_STRNLEN
1190 /*******************************************************************
1191 Some platforms don't have strnlen
1192 ********************************************************************/
1194 size_t strnlen(const char *s, size_t n)
1197 for (i=0; s[i] && i<n; i++)
1203 /***********************************************************
1204 List of Strings manipulation functions
1205 ***********************************************************/
1207 #define S_LIST_ABS 16 /* List Allocation Block Size */
1209 char **str_list_make(const char *string, const char *sep)
1211 char **list, **rlist;
1217 if (!string || !*string)
1221 DEBUG(0,("str_list_make: Unable to allocate memory"));
1224 if (!sep) sep = LIST_SEP;
1230 while (next_token(&str, tok, sep, sizeof(tok))) {
1232 lsize += S_LIST_ABS;
1233 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1235 DEBUG(0,("str_list_make: Unable to allocate memory"));
1236 str_list_free(&list);
1241 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1244 list[num] = strdup(tok);
1246 DEBUG(0,("str_list_make: Unable to allocate memory"));
1247 str_list_free(&list);
1259 BOOL str_list_copy(char ***dest, const char **src)
1261 char **list, **rlist;
1273 lsize += S_LIST_ABS;
1274 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1276 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1277 str_list_free(&list);
1281 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1284 list[num] = strdup(src[num]);
1286 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1287 str_list_free(&list);
1298 /***********************************************************
1299 Return true if all the elements of the list match exactly.
1300 ***********************************************************/
1302 BOOL str_list_compare(char **list1, char **list2)
1306 if (!list1 || !list2)
1307 return (list1 == list2);
1309 for (num = 0; list1[num]; num++) {
1312 if (!strcsequal(list1[num], list2[num]))
1316 return False; /* if list2 has more elements than list1 fail */
1321 void str_list_free(char ***list)
1325 if (!list || !*list)
1328 for(; *tlist; tlist++)
1333 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1336 ssize_t ls, lp, li, ld, i, d;
1345 lp = (ssize_t)strlen(pattern);
1346 li = (ssize_t)strlen(insert);
1351 ls = (ssize_t)strlen(s);
1353 while ((p = strstr(s, pattern))) {
1357 t = (char *) malloc(ls +ld +1);
1359 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1362 memcpy(t, *list, d);
1363 memcpy(t +d +li, p +lp, ls -d -lp +1);
1370 for (i = 0; i < li; i++) {
1371 switch (insert[i]) {
1383 t[d +i] = insert[i];
1395 #define IPSTR_LIST_SEP ","
1398 * Add ip string representation to ipstr list. Used also
1399 * as part of @function ipstr_list_make
1401 * @param ipstr_list pointer to string containing ip list;
1402 * MUST BE already allocated and IS reallocated if necessary
1403 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1404 * as a result of reallocation)
1405 * @param ip IP address which is to be added to list
1406 * @return pointer to string appended with new ip and possibly
1407 * reallocated to new length
1410 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1412 char* new_ipstr = NULL;
1414 /* arguments checking */
1415 if (!ipstr_list || !ip) return NULL;
1417 /* attempt to convert ip to a string and append colon separator to it */
1419 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1420 SAFE_FREE(*ipstr_list);
1422 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1424 *ipstr_list = new_ipstr;
1430 * Allocate and initialise an ipstr list using ip adresses
1431 * passed as arguments.
1433 * @param ipstr_list pointer to string meant to be allocated and set
1434 * @param ip_list array of ip addresses to place in the list
1435 * @param ip_count number of addresses stored in ip_list
1436 * @return pointer to allocated ip string
1439 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1443 /* arguments checking */
1444 if (!ip_list && !ipstr_list) return 0;
1448 /* process ip addresses given as arguments */
1449 for (i = 0; i < ip_count; i++)
1450 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1452 return (*ipstr_list);
1457 * Parse given ip string list into array of ip addresses
1458 * (as in_addr structures)
1460 * @param ipstr ip string list to be parsed
1461 * @param ip_list pointer to array of ip addresses which is
1462 * allocated by this function and must be freed by caller
1463 * @return number of succesfully parsed addresses
1466 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1471 if (!ipstr_list || !ip_list) return 0;
1473 for (*ip_list = NULL, count = 0;
1474 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1477 struct in_addr addr;
1479 /* convert single token to ip address */
1480 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1483 /* prepare place for another in_addr structure */
1484 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1485 if (!*ip_list) return -1;
1487 (*ip_list)[count] = addr;
1495 * Safely free ip string list
1497 * @param ipstr_list ip string list to be freed
1500 void ipstr_list_free(char* ipstr_list)
1502 SAFE_FREE(ipstr_list);
1506 /***********************************************************
1507 Unescape a URL encoded string, in place.
1508 ***********************************************************/
1510 void rfc1738_unescape(char *buf)
1514 while ((p=strchr_m(p,'+')))
1519 while (p && *p && (p=strchr_m(p,'%'))) {
1523 if (c1 >= '0' && c1 <= '9')
1525 else if (c1 >= 'A' && c1 <= 'F')
1527 else if (c1 >= 'a' && c1 <= 'f')
1529 else {p++; continue;}
1531 if (c2 >= '0' && c2 <= '9')
1533 else if (c2 >= 'A' && c2 <= 'F')
1535 else if (c2 >= 'a' && c2 <= 'f')
1537 else {p++; continue;}
1541 memmove(p+1, p+3, strlen(p+3)+1);
1546 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1548 /***************************************************************************
1549 decode a base64 string into a DATA_BLOB - simple and slow algorithm
1550 ***************************************************************************/
1551 DATA_BLOB base64_decode_data_blob(const char *s)
1553 int bit_offset, byte_offset, idx, i, n;
1554 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1555 unsigned char *d = decoded.data;
1560 while (*s && (p=strchr_m(b64,*s))) {
1561 idx = (int)(p - b64);
1562 byte_offset = (i*6)/8;
1563 bit_offset = (i*6)%8;
1564 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1565 if (bit_offset < 3) {
1566 d[byte_offset] |= (idx << (2-bit_offset));
1569 d[byte_offset] |= (idx >> (bit_offset-2));
1570 d[byte_offset+1] = 0;
1571 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1582 /***************************************************************************
1583 decode a base64 string in-place - wrapper for the above
1584 ***************************************************************************/
1585 void base64_decode(char *s)
1587 DATA_BLOB decoded = base64_decode_data_blob(s);
1588 memcpy(s, decoded.data, decoded.length);
1589 data_blob_free(&decoded);
1591 /* null terminate */
1592 s[decoded.length] = '\0';
1595 /***************************************************************************
1596 encode a base64 string into a malloc()ed string caller to free.
1598 From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1599 ***************************************************************************/
1600 char * base64_encode_data_blob(DATA_BLOB data)
1605 size_t len = data.length;
1606 size_t output_len = data.length * 2;
1607 char *result = malloc(output_len); /* get us plenty of space */
1609 while (len-- && out_cnt < (data.length * 2) - 5) {
1610 int c = (unsigned char) *(data.data++);
1613 if (char_count == 3) {
1614 result[out_cnt++] = b64[bits >> 18];
1615 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1616 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1617 result[out_cnt++] = b64[bits & 0x3f];
1624 if (char_count != 0) {
1625 bits <<= 16 - (8 * char_count);
1626 result[out_cnt++] = b64[bits >> 18];
1627 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1628 if (char_count == 1) {
1629 result[out_cnt++] = '=';
1630 result[out_cnt++] = '=';
1632 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1633 result[out_cnt++] = '=';
1636 result[out_cnt] = '\0'; /* terminate */
1641 size_t valgrind_strlen(const char *s)
1644 for(count = 0; *s++; count++)