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 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
312 return strlen_w(tmpbuf);
315 /*******************************************************************
316 Trim the specified elements off the front and back of a string.
317 ********************************************************************/
319 BOOL trim_string(char *s,const char *front,const char *back)
326 /* Ignore null or empty strings. */
327 if (!s || (s[0] == '\0'))
330 front_len = front? strlen(front) : 0;
331 back_len = back? strlen(back) : 0;
336 while (len && strncmp(s, front, front_len)==0) {
337 memcpy(s, s+front_len, (len-front_len)+1);
344 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
345 s[len-back_len]='\0';
353 /****************************************************************************
354 Does a string have any uppercase chars in it?
355 ****************************************************************************/
357 BOOL strhasupper(const char *s)
360 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
361 for(ptr=tmpbuf;*ptr;ptr++)
367 /****************************************************************************
368 Does a string have any lowercase chars in it?
369 ****************************************************************************/
371 BOOL strhaslower(const char *s)
374 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
375 for(ptr=tmpbuf;*ptr;ptr++)
381 /****************************************************************************
382 Find the number of 'c' chars in a string
383 ****************************************************************************/
385 size_t count_chars(const char *s,char c)
389 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
390 for(count=0,ptr=tmpbuf;*ptr;ptr++)
391 if(*ptr==UCS2_CHAR(c))
396 /*******************************************************************
397 Return True if a string consists only of one particular character.
398 ********************************************************************/
400 BOOL str_is_all(const char *s,char c)
409 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
410 for(ptr=tmpbuf;*ptr;ptr++)
411 if(*ptr!=UCS2_CHAR(c))
417 /*******************************************************************
418 Safe string copy into a known length string. maxlength does not
419 include the terminating zero.
420 ********************************************************************/
422 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
427 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
438 if (len > maxlength) {
439 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
440 (int)(len-maxlength), src));
444 memmove(dest, src, len);
449 /*******************************************************************
450 Safe string cat into a string. maxlength does not
451 include the terminating zero.
452 ********************************************************************/
454 char *safe_strcat(char *dest, const char *src, size_t maxlength)
456 size_t src_len, dest_len;
459 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
466 src_len = strlen(src);
467 dest_len = strlen(dest);
469 if (src_len + dest_len > maxlength) {
470 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
471 (int)(src_len + dest_len - maxlength), src));
472 src_len = maxlength - dest_len;
475 memcpy(&dest[dest_len], src, src_len);
476 dest[dest_len + src_len] = 0;
480 /*******************************************************************
481 Paranoid strcpy into a buffer of given length (includes terminating
482 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
483 and replaces with '_'. Deliberately does *NOT* check for multibyte
484 characters. Don't change it !
485 ********************************************************************/
487 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
492 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
502 if (len >= maxlength)
505 if (!other_safe_chars)
506 other_safe_chars = "";
508 for(i = 0; i < len; i++) {
509 int val = (src[i] & 0xff);
510 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
521 /****************************************************************************
522 Like strncpy but always null terminates. Make sure there is room!
523 The variable n should always be one less than the available size.
524 ****************************************************************************/
526 char *StrnCpy(char *dest,const char *src,size_t n)
535 while (n-- && (*d++ = *src++))
541 /****************************************************************************
542 Like strncpy but copies up to the character marker. always null terminates.
543 returns a pointer to the character marker in the source string (src).
544 ****************************************************************************/
546 char *strncpyn(char *dest, const char *src, size_t n, char c)
551 p = strchr_m(src, c);
553 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
557 str_len = PTR_DIFF(p, src);
558 strncpy(dest, src, MIN(n, str_len));
559 dest[str_len] = '\0';
564 /*************************************************************
565 Routine to get hex characters and turn them into a 16 byte array.
566 the array can be variable length, and any non-hex-numeric
567 characters are skipped. "0xnn" or "0Xnn" is specially catered
570 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
572 **************************************************************/
574 size_t strhex_to_str(char *p, size_t len, const char *strhex)
577 size_t num_chars = 0;
578 unsigned char lonybble, hinybble;
579 const char *hexchars = "0123456789ABCDEF";
580 char *p1 = NULL, *p2 = NULL;
582 for (i = 0; i < len && strhex[i] != 0; i++) {
583 if (strnequal(hexchars, "0x", 2)) {
584 i++; /* skip two chars */
588 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
591 i++; /* next hex digit */
593 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
596 /* get the two nybbles */
597 hinybble = PTR_DIFF(p1, hexchars);
598 lonybble = PTR_DIFF(p2, hexchars);
600 p[num_chars] = (hinybble << 4) | lonybble;
609 /****************************************************************************
610 Check if a string is part of a list.
611 ****************************************************************************/
613 BOOL in_list(char *s,char *list,BOOL casesensitive)
621 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
623 if (strcmp(tok,s) == 0)
626 if (StrCaseCmp(tok,s) == 0)
633 /* this is used to prevent lots of mallocs of size 1 */
634 static char *null_string = NULL;
636 /****************************************************************************
637 Set a string value, allocing the space for the string
638 ****************************************************************************/
640 static BOOL string_init(char **dest,const char *src)
650 if((null_string = (char *)malloc(1)) == NULL) {
651 DEBUG(0,("string_init: malloc fail for null_string.\n"));
658 (*dest) = (char *)malloc(l+1);
659 if ((*dest) == NULL) {
660 DEBUG(0,("Out of memory in string_init\n"));
669 /****************************************************************************
671 ****************************************************************************/
673 void string_free(char **s)
677 if (*s == null_string)
682 /****************************************************************************
683 Set a string value, deallocating any existing space, and allocing the space
685 ****************************************************************************/
687 BOOL string_set(char **dest,const char *src)
690 return(string_init(dest,src));
693 /****************************************************************************
694 Substitute a string for a pattern in another string. Make sure there is
697 This routine looks for pattern in s and replaces it with
698 insert. It may do multiple replacements.
700 Any of " ; ' $ or ` in the insert string are replaced with _
701 if len==0 then the string cannot be extended. This is different from the old
702 use of len==0 which was for no length checks to be done.
703 ****************************************************************************/
705 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
710 if (!insert || !pattern || !*pattern || !s)
713 ls = (ssize_t)strlen(s);
714 lp = (ssize_t)strlen(pattern);
715 li = (ssize_t)strlen(insert);
718 len = ls + 1; /* len is number of *bytes* */
720 while (lp <= ls && (p = strstr(s,pattern))) {
721 if (ls + (li-lp) >= len) {
722 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
723 (int)(ls + (li-lp) - len),
728 memmove(p+li,p+lp,strlen(p+lp)+1);
751 void fstring_sub(char *s,const char *pattern,const char *insert)
753 string_sub(s, pattern, insert, sizeof(fstring));
756 void pstring_sub(char *s,const char *pattern,const char *insert)
758 string_sub(s, pattern, insert, sizeof(pstring));
761 /****************************************************************************
762 Similar to string_sub, but it will accept only allocated strings
763 and may realloc them so pay attention at what you pass on no
764 pointers inside strings, no pstrings or const may be passed
766 ****************************************************************************/
768 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
772 ssize_t ls,lp,li,ld, i;
774 if (!insert || !pattern || !*pattern || !string || !*string)
781 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
784 ls = (ssize_t)strlen(s);
785 lp = (ssize_t)strlen(pattern);
786 li = (ssize_t)strlen(insert);
805 while ((p = strstr(s,pattern))) {
807 char *t = Realloc(string, ls + ld + 1);
809 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
817 memmove(p+li,p+lp,strlen(p+lp)+1);
827 /****************************************************************************
828 Similar to string_sub() but allows for any character to be substituted.
830 if len==0 then the string cannot be extended. This is different from the old
831 use of len==0 which was for no length checks to be done.
832 ****************************************************************************/
834 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
839 if (!insert || !pattern || !s)
842 ls = (ssize_t)strlen(s);
843 lp = (ssize_t)strlen(pattern);
844 li = (ssize_t)strlen(insert);
850 len = ls + 1; /* len is number of *bytes* */
852 while (lp <= ls && (p = strstr(s,pattern))) {
853 if (ls + (li-lp) >= len) {
854 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
855 (int)(ls + (li-lp) - len),
860 memmove(p+li,p+lp,strlen(p+lp)+1);
862 memcpy(p, insert, li);
868 /****************************************************************************
869 Similar to all_string_sub but for unicode strings.
870 Return a new allocated unicode string.
871 similar to string_sub() but allows for any character to be substituted.
873 ****************************************************************************/
875 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
876 const smb_ucs2_t *insert)
879 const smb_ucs2_t *sp;
880 size_t lr, lp, li, lt;
882 if (!insert || !pattern || !*pattern || !s)
885 lt = (size_t)strlen_w(s);
886 lp = (size_t)strlen_w(pattern);
887 li = (size_t)strlen_w(insert);
890 const smb_ucs2_t *st = s;
892 while ((sp = strstr_w(st, pattern))) {
898 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
900 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
904 while ((sp = strstr_w(s, pattern))) {
905 memcpy(rp, s, (sp - s));
906 rp += ((sp - s) / sizeof(smb_ucs2_t));
907 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
911 lr = ((rp - r) / sizeof(smb_ucs2_t));
913 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
921 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
926 if (!insert || !pattern || !s)
928 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
929 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
930 return all_string_sub_w(s, p, i);
933 /****************************************************************************
934 Splits out the front and back at a separator.
935 ****************************************************************************/
937 void split_at_last_component(char *path, char *front, char sep, char *back)
939 char *p = strrchr_m(path, sep);
945 pstrcpy(front, path);
957 /****************************************************************************
958 Write an octal as a string.
959 ****************************************************************************/
961 const char *octal_string(int i)
966 slprintf(ret, sizeof(ret)-1, "0%o", i);
971 /****************************************************************************
972 Truncate a string at a specified length.
973 ****************************************************************************/
975 char *string_truncate(char *s, int length)
977 if (s && strlen(s) > length)
982 /****************************************************************************
983 Strchr and strrchr_m are very hard to do on general multi-byte strings.
984 We convert via ucs2 for now.
985 ****************************************************************************/
987 char *strchr_m(const char *s, char c)
993 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
994 p = strchr_w(ws, UCS2_CHAR(c));
998 pull_ucs2_pstring(s2, ws);
999 return (char *)(s+strlen(s2));
1002 char *strrchr_m(const char *s, char c)
1008 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1009 p = strrchr_w(ws, UCS2_CHAR(c));
1013 pull_ucs2_pstring(s2, ws);
1014 return (char *)(s+strlen(s2));
1017 /*******************************************************************
1018 Convert a string to lower case.
1019 ********************************************************************/
1021 void strlower_m(char *s)
1023 /* this is quite a common operation, so we want it to be
1024 fast. We optimise for the ascii case, knowing that all our
1025 supported multi-byte character sets are ascii-compatible
1026 (ie. they match for the first 128 chars) */
1028 while (*s && !(((unsigned char)s[0]) & 0x7F))
1029 *s++ = tolower((unsigned char)*s);
1034 /* I assume that lowercased string takes the same number of bytes
1035 * as source string even in UTF-8 encoding. (VIV) */
1036 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1039 /*******************************************************************
1040 Duplicate convert a string to lower case.
1041 ********************************************************************/
1043 char *strdup_lower(const char *s)
1045 char *t = strdup(s);
1047 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1054 /*******************************************************************
1055 Convert a string to upper case.
1056 ********************************************************************/
1058 void strupper_m(char *s)
1060 /* this is quite a common operation, so we want it to be
1061 fast. We optimise for the ascii case, knowing that all our
1062 supported multi-byte character sets are ascii-compatible
1063 (ie. they match for the first 128 chars) */
1065 while (*s && !(((unsigned char)s[0]) & 0x7F))
1066 *s++ = toupper((unsigned char)*s);
1071 /* I assume that lowercased string takes the same number of bytes
1072 * as source string even in multibyte encoding. (VIV) */
1073 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1076 /*******************************************************************
1077 Convert a string to upper case.
1078 ********************************************************************/
1080 char *strdup_upper(const char *s)
1082 char *t = strdup(s);
1084 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1091 /*******************************************************************
1092 Return a RFC2254 binary string representation of a buffer.
1093 Used in LDAP filters.
1095 ********************************************************************/
1097 char *binary_string(char *buf, int len)
1101 const char *hex = "0123456789ABCDEF";
1102 s = malloc(len * 3 + 1);
1105 for (j=i=0;i<len;i++) {
1107 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1108 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1115 /*******************************************************************
1116 Just a typesafety wrapper for snprintf into a pstring.
1117 ********************************************************************/
1119 int pstr_sprintf(pstring s, const char *fmt, ...)
1125 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1130 /*******************************************************************
1131 Just a typesafety wrapper for snprintf into a fstring.
1132 ********************************************************************/
1134 int fstr_sprintf(fstring s, const char *fmt, ...)
1140 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1145 #ifndef HAVE_STRNDUP
1146 /*******************************************************************
1147 Some platforms don't have strndup.
1148 ********************************************************************/
1150 char *strndup(const char *s, size_t n)
1165 #ifndef HAVE_STRNLEN
1166 /*******************************************************************
1167 Some platforms don't have strnlen
1168 ********************************************************************/
1170 size_t strnlen(const char *s, size_t n)
1173 for (i=0; s[i] && i<n; i++)
1179 /***********************************************************
1180 List of Strings manipulation functions
1181 ***********************************************************/
1183 #define S_LIST_ABS 16 /* List Allocation Block Size */
1185 char **str_list_make(const char *string, const char *sep)
1187 char **list, **rlist;
1193 if (!string || !*string)
1197 DEBUG(0,("str_list_make: Unable to allocate memory"));
1200 if (!sep) sep = LIST_SEP;
1206 while (next_token(&str, tok, sep, sizeof(tok))) {
1208 lsize += S_LIST_ABS;
1209 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1211 DEBUG(0,("str_list_make: Unable to allocate memory"));
1212 str_list_free(&list);
1217 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1220 list[num] = strdup(tok);
1222 DEBUG(0,("str_list_make: Unable to allocate memory"));
1223 str_list_free(&list);
1235 BOOL str_list_copy(char ***dest, const char **src)
1237 char **list, **rlist;
1249 lsize += S_LIST_ABS;
1250 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1252 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1253 str_list_free(&list);
1257 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1260 list[num] = strdup(src[num]);
1262 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1263 str_list_free(&list);
1274 /***********************************************************
1275 Return true if all the elements of the list match exactly.
1276 ***********************************************************/
1278 BOOL str_list_compare(char **list1, char **list2)
1282 if (!list1 || !list2)
1283 return (list1 == list2);
1285 for (num = 0; list1[num]; num++) {
1288 if (!strcsequal(list1[num], list2[num]))
1292 return False; /* if list2 has more elements than list1 fail */
1297 void str_list_free(char ***list)
1301 if (!list || !*list)
1304 for(; *tlist; tlist++)
1309 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1312 ssize_t ls, lp, li, ld, i, d;
1321 lp = (ssize_t)strlen(pattern);
1322 li = (ssize_t)strlen(insert);
1327 ls = (ssize_t)strlen(s);
1329 while ((p = strstr(s, pattern))) {
1333 t = (char *) malloc(ls +ld +1);
1335 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1338 memcpy(t, *list, d);
1339 memcpy(t +d +li, p +lp, ls -d -lp +1);
1346 for (i = 0; i < li; i++) {
1347 switch (insert[i]) {
1359 t[d +i] = insert[i];
1371 #define IPSTR_LIST_SEP ","
1374 * Add ip string representation to ipstr list. Used also
1375 * as part of @function ipstr_list_make
1377 * @param ipstr_list pointer to string containing ip list;
1378 * MUST BE already allocated and IS reallocated if necessary
1379 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1380 * as a result of reallocation)
1381 * @param ip IP address which is to be added to list
1382 * @return pointer to string appended with new ip and possibly
1383 * reallocated to new length
1386 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1388 char* new_ipstr = NULL;
1390 /* arguments checking */
1391 if (!ipstr_list || !ip) return NULL;
1393 /* attempt to convert ip to a string and append colon separator to it */
1395 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1396 SAFE_FREE(*ipstr_list);
1398 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1400 *ipstr_list = new_ipstr;
1406 * Allocate and initialise an ipstr list using ip adresses
1407 * passed as arguments.
1409 * @param ipstr_list pointer to string meant to be allocated and set
1410 * @param ip_list array of ip addresses to place in the list
1411 * @param ip_count number of addresses stored in ip_list
1412 * @return pointer to allocated ip string
1415 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1419 /* arguments checking */
1420 if (!ip_list && !ipstr_list) return 0;
1424 /* process ip addresses given as arguments */
1425 for (i = 0; i < ip_count; i++)
1426 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1428 return (*ipstr_list);
1433 * Parse given ip string list into array of ip addresses
1434 * (as in_addr structures)
1436 * @param ipstr ip string list to be parsed
1437 * @param ip_list pointer to array of ip addresses which is
1438 * allocated by this function and must be freed by caller
1439 * @return number of succesfully parsed addresses
1442 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1447 if (!ipstr_list || !ip_list) return 0;
1449 for (*ip_list = NULL, count = 0;
1450 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1453 struct in_addr addr;
1455 /* convert single token to ip address */
1456 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1459 /* prepare place for another in_addr structure */
1460 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1461 if (!*ip_list) return -1;
1463 (*ip_list)[count] = addr;
1471 * Safely free ip string list
1473 * @param ipstr_list ip string list to be freed
1476 void ipstr_list_free(char* ipstr_list)
1478 SAFE_FREE(ipstr_list);
1482 /***********************************************************
1483 Unescape a URL encoded string, in place.
1484 ***********************************************************/
1486 void rfc1738_unescape(char *buf)
1490 while ((p=strchr_m(p,'+')))
1495 while (p && *p && (p=strchr_m(p,'%'))) {
1499 if (c1 >= '0' && c1 <= '9')
1501 else if (c1 >= 'A' && c1 <= 'F')
1503 else if (c1 >= 'a' && c1 <= 'f')
1505 else {p++; continue;}
1507 if (c2 >= '0' && c2 <= '9')
1509 else if (c2 >= 'A' && c2 <= 'F')
1511 else if (c2 >= 'a' && c2 <= 'f')
1513 else {p++; continue;}
1517 memmove(p+1, p+3, strlen(p+3)+1);
1523 size_t valgrind_strlen(const char *s)
1526 for(count = 0; *s++; count++)