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.
25 * Get the next token from a string, return False if none found.
26 * Handles double-quotes.
28 * Based on a routine by GJC@VILLAGE.COM.
29 * Extensively modified by Andrew.Tridgell@anu.edu.au
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
;
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!
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
)
97 Convert list of tokens to array; dependent on above routine.
98 Uses last_ptr from above - bit of a hack.
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 *))))
143 Case insensitive string compararison.
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
);
155 Case insensitive string compararison, length limited.
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
);
170 BOOL
strequal(const char *s1
, const char *s2
)
177 return(StrCaseCmp(s1
,s2
)==0);
181 Compare 2 strings up to and including the nth char.
184 BOOL
strnequal(const char *s1
,const char *s2
,size_t n
)
188 if (!s1
|| !s2
|| !n
)
191 return(StrnCaseCmp(s1
,s2
,n
)==0);
195 Compare 2 strings (case sensitive).
198 BOOL
strcsequal(const char *s1
,const char *s2
)
205 return(strcmp(s1
,s2
)==0);
209 Do a case-insensitive, whitespace-ignoring string compare.
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
);
240 Convert a string to upper case, but don't modify it.
243 char *strupper_static(const char *s
)
254 Convert a string to "normal" form.
257 void strnorm(char *s
)
259 extern int case_default
;
260 if (case_default
== CASE_UPPER
)
267 Check if a string is in "normal" case.
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
));
282 NOTE: oldc and newc must be 7 bit characters
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
);
293 Skip past some strings in a buffer.
296 char *skip_string(char *buf
,size_t n
)
299 buf
+= strlen(buf
) + 1;
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.
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
);
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.
322 size_t str_ascii_charnum(const char *s
)
325 push_ascii(tmpbuf2
, s
, sizeof(tmpbuf2
), STR_TERMINATE
);
326 return strlen(tmpbuf2
);
330 Trim the specified elements off the front and back of a string.
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';
368 Does a string have any uppercase chars in it?
371 BOOL
strhasupper(const char *s
)
374 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
375 for(ptr
=tmpbuf
;*ptr
;ptr
++)
382 Does a string have any lowercase chars in it?
385 BOOL
strhaslower(const char *s
)
388 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
389 for(ptr
=tmpbuf
;*ptr
;ptr
++)
396 Find the number of 'c' chars in a string
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
))
411 Return True if a string consists only of one particular character.
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
))
432 Safe string copy into a known length string. maxlength does not
433 include the terminating zero.
436 char *safe_strcpy(char *dest
,const char *src
, size_t maxlength
)
441 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
446 /* We intentionally write out at the extremity of the destination
447 * string. If the destination is too short (e.g. pstrcpy into mallocd
448 * or fstring) then this should cause an error under a memory
450 dest
[maxlength
] = '\0';
460 if (len
> maxlength
) {
461 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
462 (unsigned int)(len
-maxlength
), len
, maxlength
, src
));
466 memmove(dest
, src
, len
);
472 Safe string cat into a string. maxlength does not
473 include the terminating zero.
476 char *safe_strcat(char *dest
, const char *src
, size_t maxlength
)
478 size_t src_len
, dest_len
;
481 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
488 src_len
= strlen(src
);
489 dest_len
= strlen(dest
);
491 if (src_len
+ dest_len
> maxlength
) {
492 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
493 (int)(src_len
+ dest_len
- maxlength
), src
));
494 if (maxlength
> dest_len
) {
495 memcpy(&dest
[dest_len
], src
, maxlength
- dest_len
);
501 memcpy(&dest
[dest_len
], src
, src_len
);
502 dest
[dest_len
+ src_len
] = 0;
507 Paranoid strcpy into a buffer of given length (includes terminating
508 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
509 and replaces with '_'. Deliberately does *NOT* check for multibyte
510 characters. Don't change it !
513 char *alpha_strcpy(char *dest
, const char *src
, const char *other_safe_chars
, size_t maxlength
)
518 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
528 if (len
>= maxlength
)
531 if (!other_safe_chars
)
532 other_safe_chars
= "";
534 for(i
= 0; i
< len
; i
++) {
535 int val
= (src
[i
] & 0xff);
536 if (isupper(val
) || islower(val
) || isdigit(val
) || strchr_m(other_safe_chars
, val
))
548 Like strncpy but always null terminates. Make sure there is room!
549 The variable n should always be one less than the available size.
552 char *StrnCpy(char *dest
,const char *src
,size_t n
)
561 while (n
-- && (*d
++ = *src
++))
568 Like strncpy but copies up to the character marker. always null terminates.
569 returns a pointer to the character marker in the source string (src).
572 char *strncpyn(char *dest
, const char *src
, size_t n
, char c
)
577 p
= strchr_m(src
, c
);
579 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c
));
583 str_len
= PTR_DIFF(p
, src
);
584 strncpy(dest
, src
, MIN(n
, str_len
));
585 dest
[str_len
] = '\0';
591 Routine to get hex characters and turn them into a 16 byte array.
592 the array can be variable length, and any non-hex-numeric
593 characters are skipped. "0xnn" or "0Xnn" is specially catered
596 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
600 size_t strhex_to_str(char *p
, size_t len
, const char *strhex
)
603 size_t num_chars
= 0;
604 unsigned char lonybble
, hinybble
;
605 const char *hexchars
= "0123456789ABCDEF";
606 char *p1
= NULL
, *p2
= NULL
;
608 for (i
= 0; i
< len
&& strhex
[i
] != 0; i
++) {
609 if (strnequal(hexchars
, "0x", 2)) {
610 i
++; /* skip two chars */
614 if (!(p1
= strchr_m(hexchars
, toupper(strhex
[i
]))))
617 i
++; /* next hex digit */
619 if (!(p2
= strchr_m(hexchars
, toupper(strhex
[i
]))))
622 /* get the two nybbles */
623 hinybble
= PTR_DIFF(p1
, hexchars
);
624 lonybble
= PTR_DIFF(p2
, hexchars
);
626 p
[num_chars
] = (hinybble
<< 4) | lonybble
;
636 Check if a string is part of a list.
639 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
647 while (next_token(&p
,tok
,LIST_SEP
,sizeof(tok
))) {
649 if (strcmp(tok
,s
) == 0)
652 if (StrCaseCmp(tok
,s
) == 0)
659 /* this is used to prevent lots of mallocs of size 1 */
660 static char *null_string
= NULL
;
663 Set a string value, allocing the space for the string
666 static BOOL
string_init(char **dest
,const char *src
)
676 if((null_string
= (char *)malloc(1)) == NULL
) {
677 DEBUG(0,("string_init: malloc fail for null_string.\n"));
684 (*dest
) = strdup(src
);
685 if ((*dest
) == NULL
) {
686 DEBUG(0,("Out of memory in string_init\n"));
697 void string_free(char **s
)
701 if (*s
== null_string
)
707 Set a string value, deallocating any existing space, and allocing the space
711 BOOL
string_set(char **dest
,const char *src
)
714 return(string_init(dest
,src
));
718 Substitute a string for a pattern in another string. Make sure there is
721 This routine looks for pattern in s and replaces it with
722 insert. It may do multiple replacements.
724 Any of " ; ' $ or ` in the insert string are replaced with _
725 if len==0 then the string cannot be extended. This is different from the old
726 use of len==0 which was for no length checks to be done.
729 void string_sub(char *s
,const char *pattern
, const char *insert
, size_t len
)
734 if (!insert
|| !pattern
|| !*pattern
|| !s
)
737 ls
= (ssize_t
)strlen(s
);
738 lp
= (ssize_t
)strlen(pattern
);
739 li
= (ssize_t
)strlen(insert
);
742 len
= ls
+ 1; /* len is number of *bytes* */
744 while (lp
<= ls
&& (p
= strstr(s
,pattern
))) {
745 if (ls
+ (li
-lp
) >= len
) {
746 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
747 (int)(ls
+ (li
-lp
) - len
),
752 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
775 void fstring_sub(char *s
,const char *pattern
,const char *insert
)
777 string_sub(s
, pattern
, insert
, sizeof(fstring
));
780 void pstring_sub(char *s
,const char *pattern
,const char *insert
)
782 string_sub(s
, pattern
, insert
, sizeof(pstring
));
786 Similar to string_sub, but it will accept only allocated strings
787 and may realloc them so pay attention at what you pass on no
788 pointers inside strings, no pstrings or const may be passed
792 char *realloc_string_sub(char *string
, const char *pattern
, const char *insert
)
796 ssize_t ls
,lp
,li
,ld
, i
;
798 if (!insert
|| !pattern
|| !*pattern
|| !string
|| !*string
)
805 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
808 ls
= (ssize_t
)strlen(s
);
809 lp
= (ssize_t
)strlen(pattern
);
810 li
= (ssize_t
)strlen(insert
);
829 while ((p
= strstr(s
,pattern
))) {
831 char *t
= Realloc(string
, ls
+ ld
+ 1);
833 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
841 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
852 Similar to string_sub() but allows for any character to be substituted.
854 if len==0 then the string cannot be extended. This is different from the old
855 use of len==0 which was for no length checks to be done.
858 void all_string_sub(char *s
,const char *pattern
,const char *insert
, size_t len
)
863 if (!insert
|| !pattern
|| !s
)
866 ls
= (ssize_t
)strlen(s
);
867 lp
= (ssize_t
)strlen(pattern
);
868 li
= (ssize_t
)strlen(insert
);
874 len
= ls
+ 1; /* len is number of *bytes* */
876 while (lp
<= ls
&& (p
= strstr(s
,pattern
))) {
877 if (ls
+ (li
-lp
) >= len
) {
878 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
879 (int)(ls
+ (li
-lp
) - len
),
884 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
886 memcpy(p
, insert
, li
);
893 Similar to all_string_sub but for unicode strings.
894 Return a new allocated unicode string.
895 similar to string_sub() but allows for any character to be substituted.
899 smb_ucs2_t
*all_string_sub_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*pattern
,
900 const smb_ucs2_t
*insert
)
903 const smb_ucs2_t
*sp
;
904 size_t lr
, lp
, li
, lt
;
906 if (!insert
|| !pattern
|| !*pattern
|| !s
)
909 lt
= (size_t)strlen_w(s
);
910 lp
= (size_t)strlen_w(pattern
);
911 li
= (size_t)strlen_w(insert
);
914 const smb_ucs2_t
*st
= s
;
916 while ((sp
= strstr_w(st
, pattern
))) {
922 r
= rp
= (smb_ucs2_t
*)malloc((lt
+ 1)*(sizeof(smb_ucs2_t
)));
924 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
928 while ((sp
= strstr_w(s
, pattern
))) {
929 memcpy(rp
, s
, (sp
- s
));
930 rp
+= ((sp
- s
) / sizeof(smb_ucs2_t
));
931 memcpy(rp
, insert
, (li
* sizeof(smb_ucs2_t
)));
935 lr
= ((rp
- r
) / sizeof(smb_ucs2_t
));
937 memcpy(rp
, s
, ((lt
- lr
) * sizeof(smb_ucs2_t
)));
945 smb_ucs2_t
*all_string_sub_wa(smb_ucs2_t
*s
, const char *pattern
,
950 if (!insert
|| !pattern
|| !s
)
952 push_ucs2(NULL
, p
, pattern
, sizeof(wpstring
) - 1, STR_TERMINATE
);
953 push_ucs2(NULL
, i
, insert
, sizeof(wpstring
) - 1, STR_TERMINATE
);
954 return all_string_sub_w(s
, p
, i
);
958 Splits out the front and back at a separator.
961 void split_at_last_component(char *path
, char *front
, char sep
, char *back
)
963 char *p
= strrchr_m(path
, sep
);
969 pstrcpy(front
, path
);
982 Write an octal as a string.
985 const char *octal_string(int i
)
990 slprintf(ret
, sizeof(ret
)-1, "0%o", i
);
996 Truncate a string at a specified length.
999 char *string_truncate(char *s
, int length
)
1001 if (s
&& strlen(s
) > length
)
1007 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1008 We convert via ucs2 for now.
1011 char *strchr_m(const char *s
, char c
)
1017 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1018 p
= strchr_w(ws
, UCS2_CHAR(c
));
1022 pull_ucs2_pstring(s2
, ws
);
1023 return (char *)(s
+strlen(s2
));
1026 char *strrchr_m(const char *s
, char c
)
1032 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1033 p
= strrchr_w(ws
, UCS2_CHAR(c
));
1037 pull_ucs2_pstring(s2
, ws
);
1038 return (char *)(s
+strlen(s2
));
1042 Convert a string to lower case.
1045 void strlower_m(char *s
)
1047 /* this is quite a common operation, so we want it to be
1048 fast. We optimise for the ascii case, knowing that all our
1049 supported multi-byte character sets are ascii-compatible
1050 (ie. they match for the first 128 chars) */
1052 while (*s
&& !(((unsigned char)s
[0]) & 0x7F)) {
1053 *s
= tolower((unsigned char)*s
);
1060 /* I assume that lowercased string takes the same number of bytes
1061 * as source string even in UTF-8 encoding. (VIV) */
1062 unix_strlower(s
,strlen(s
)+1,s
,strlen(s
)+1);
1066 Duplicate convert a string to lower case.
1069 char *strdup_lower(const char *s
)
1071 char *t
= strdup(s
);
1073 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1081 Convert a string to upper case.
1084 void strupper_m(char *s
)
1086 /* this is quite a common operation, so we want it to be
1087 fast. We optimise for the ascii case, knowing that all our
1088 supported multi-byte character sets are ascii-compatible
1089 (ie. they match for the first 128 chars) */
1091 while (*s
&& !(((unsigned char)s
[0]) & 0x7F)) {
1092 *s
= toupper((unsigned char)*s
);
1099 /* I assume that lowercased string takes the same number of bytes
1100 * as source string even in multibyte encoding. (VIV) */
1101 unix_strupper(s
,strlen(s
)+1,s
,strlen(s
)+1);
1105 Convert a string to upper case.
1108 char *strdup_upper(const char *s
)
1110 char *t
= strdup(s
);
1112 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1120 Return a RFC2254 binary string representation of a buffer.
1121 Used in LDAP filters.
1125 char *binary_string(char *buf
, int len
)
1129 const char *hex
= "0123456789ABCDEF";
1130 s
= malloc(len
* 3 + 1);
1133 for (j
=i
=0;i
<len
;i
++) {
1135 s
[j
+1] = hex
[((unsigned char)buf
[i
]) >> 4];
1136 s
[j
+2] = hex
[((unsigned char)buf
[i
]) & 0xF];
1144 Just a typesafety wrapper for snprintf into a pstring.
1147 int pstr_sprintf(pstring s
, const char *fmt
, ...)
1153 ret
= vsnprintf(s
, PSTRING_LEN
, fmt
, ap
);
1159 Just a typesafety wrapper for snprintf into a fstring.
1162 int fstr_sprintf(fstring s
, const char *fmt
, ...)
1168 ret
= vsnprintf(s
, FSTRING_LEN
, fmt
, ap
);
1173 #ifndef HAVE_STRNDUP
1175 Some platforms don't have strndup.
1178 char *strndup(const char *s
, size_t n
)
1193 #ifndef HAVE_STRNLEN
1195 Some platforms don't have strnlen
1198 size_t strnlen(const char *s
, size_t n
)
1201 for (i
=0; s
[i
] && i
<n
; i
++)
1208 List of Strings manipulation functions
1211 #define S_LIST_ABS 16 /* List Allocation Block Size */
1213 char **str_list_make(const char *string
, const char *sep
)
1215 char **list
, **rlist
;
1221 if (!string
|| !*string
)
1225 DEBUG(0,("str_list_make: Unable to allocate memory"));
1228 if (!sep
) sep
= LIST_SEP
;
1234 while (next_token(&str
, tok
, sep
, sizeof(tok
))) {
1236 lsize
+= S_LIST_ABS
;
1237 rlist
= (char **)Realloc(list
, ((sizeof(char **)) * (lsize
+1)));
1239 DEBUG(0,("str_list_make: Unable to allocate memory"));
1240 str_list_free(&list
);
1245 memset (&list
[num
], 0, ((sizeof(char**)) * (S_LIST_ABS
+1)));
1248 list
[num
] = strdup(tok
);
1250 DEBUG(0,("str_list_make: Unable to allocate memory"));
1251 str_list_free(&list
);
1263 BOOL
str_list_copy(char ***dest
, const char **src
)
1265 char **list
, **rlist
;
1277 lsize
+= S_LIST_ABS
;
1278 rlist
= (char **)Realloc(list
, ((sizeof(char **)) * (lsize
+1)));
1280 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1281 str_list_free(&list
);
1285 memset (&list
[num
], 0, ((sizeof(char **)) * (S_LIST_ABS
+1)));
1288 list
[num
] = strdup(src
[num
]);
1290 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1291 str_list_free(&list
);
1303 * Return true if all the elements of the list match exactly.
1305 BOOL
str_list_compare(char **list1
, char **list2
)
1309 if (!list1
|| !list2
)
1310 return (list1
== list2
);
1312 for (num
= 0; list1
[num
]; num
++) {
1315 if (!strcsequal(list1
[num
], list2
[num
]))
1319 return False
; /* if list2 has more elements than list1 fail */
1324 void str_list_free(char ***list
)
1328 if (!list
|| !*list
)
1331 for(; *tlist
; tlist
++)
1336 BOOL
str_list_substitute(char **list
, const char *pattern
, const char *insert
)
1339 ssize_t ls
, lp
, li
, ld
, i
, d
;
1348 lp
= (ssize_t
)strlen(pattern
);
1349 li
= (ssize_t
)strlen(insert
);
1354 ls
= (ssize_t
)strlen(s
);
1356 while ((p
= strstr(s
, pattern
))) {
1360 t
= (char *) malloc(ls
+ld
+1);
1362 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1365 memcpy(t
, *list
, d
);
1366 memcpy(t
+d
+li
, p
+lp
, ls
-d
-lp
+1);
1373 for (i
= 0; i
< li
; i
++) {
1374 switch (insert
[i
]) {
1386 t
[d
+i
] = insert
[i
];
1398 #define IPSTR_LIST_SEP ","
1401 * Add ip string representation to ipstr list. Used also
1402 * as part of @function ipstr_list_make
1404 * @param ipstr_list pointer to string containing ip list;
1405 * MUST BE already allocated and IS reallocated if necessary
1406 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1407 * as a result of reallocation)
1408 * @param ip IP address which is to be added to list
1409 * @return pointer to string appended with new ip and possibly
1410 * reallocated to new length
1413 char* ipstr_list_add(char** ipstr_list
, const struct in_addr
*ip
)
1415 char* new_ipstr
= NULL
;
1417 /* arguments checking */
1418 if (!ipstr_list
|| !ip
) return NULL
;
1420 /* attempt to convert ip to a string and append colon separator to it */
1422 asprintf(&new_ipstr
, "%s%s%s", *ipstr_list
, IPSTR_LIST_SEP
,inet_ntoa(*ip
));
1423 SAFE_FREE(*ipstr_list
);
1425 asprintf(&new_ipstr
, "%s", inet_ntoa(*ip
));
1427 *ipstr_list
= new_ipstr
;
1433 * Allocate and initialise an ipstr list using ip adresses
1434 * passed as arguments.
1436 * @param ipstr_list pointer to string meant to be allocated and set
1437 * @param ip_list array of ip addresses to place in the list
1438 * @param ip_count number of addresses stored in ip_list
1439 * @return pointer to allocated ip string
1442 char* ipstr_list_make(char** ipstr_list
, const struct in_addr
* ip_list
, int ip_count
)
1446 /* arguments checking */
1447 if (!ip_list
&& !ipstr_list
) return 0;
1451 /* process ip addresses given as arguments */
1452 for (i
= 0; i
< ip_count
; i
++)
1453 *ipstr_list
= ipstr_list_add(ipstr_list
, &ip_list
[i
]);
1455 return (*ipstr_list
);
1460 * Parse given ip string list into array of ip addresses
1461 * (as in_addr structures)
1463 * @param ipstr ip string list to be parsed
1464 * @param ip_list pointer to array of ip addresses which is
1465 * allocated by this function and must be freed by caller
1466 * @return number of succesfully parsed addresses
1469 int ipstr_list_parse(const char* ipstr_list
, struct in_addr
** ip_list
)
1474 if (!ipstr_list
|| !ip_list
) return 0;
1476 for (*ip_list
= NULL
, count
= 0;
1477 next_token(&ipstr_list
, token_str
, IPSTR_LIST_SEP
, FSTRING_LEN
);
1480 struct in_addr addr
;
1482 /* convert single token to ip address */
1483 if ( (addr
.s_addr
= inet_addr(token_str
)) == INADDR_NONE
)
1486 /* prepare place for another in_addr structure */
1487 *ip_list
= Realloc(*ip_list
, (count
+ 1) * sizeof(struct in_addr
));
1488 if (!*ip_list
) return -1;
1490 (*ip_list
)[count
] = addr
;
1498 * Safely free ip string list
1500 * @param ipstr_list ip string list to be freed
1503 void ipstr_list_free(char* ipstr_list
)
1505 SAFE_FREE(ipstr_list
);
1510 Unescape a URL encoded string, in place.
1513 void rfc1738_unescape(char *buf
)
1517 while ((p
=strchr_m(p
,'+')))
1522 while (p
&& *p
&& (p
=strchr_m(p
,'%'))) {
1526 if (c1
>= '0' && c1
<= '9')
1528 else if (c1
>= 'A' && c1
<= 'F')
1530 else if (c1
>= 'a' && c1
<= 'f')
1532 else {p
++; continue;}
1534 if (c2
>= '0' && c2
<= '9')
1536 else if (c2
>= 'A' && c2
<= 'F')
1538 else if (c2
>= 'a' && c2
<= 'f')
1540 else {p
++; continue;}
1544 memmove(p
+1, p
+3, strlen(p
+3)+1);
1549 static const char *b64
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1552 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1554 DATA_BLOB
base64_decode_data_blob(const char *s
)
1556 int bit_offset
, byte_offset
, idx
, i
, n
;
1557 DATA_BLOB decoded
= data_blob(s
, strlen(s
)+1);
1558 unsigned char *d
= decoded
.data
;
1563 while (*s
&& (p
=strchr_m(b64
,*s
))) {
1564 idx
= (int)(p
- b64
);
1565 byte_offset
= (i
*6)/8;
1566 bit_offset
= (i
*6)%8;
1567 d
[byte_offset
] &= ~((1<<(8-bit_offset
))-1);
1568 if (bit_offset
< 3) {
1569 d
[byte_offset
] |= (idx
<< (2-bit_offset
));
1572 d
[byte_offset
] |= (idx
>> (bit_offset
-2));
1573 d
[byte_offset
+1] = 0;
1574 d
[byte_offset
+1] |= (idx
<< (8-(bit_offset
-2))) & 0xFF;
1586 * Decode a base64 string in-place - wrapper for the above
1588 void base64_decode_inplace(char *s
)
1590 DATA_BLOB decoded
= base64_decode_data_blob(s
);
1591 memcpy(s
, decoded
.data
, decoded
.length
);
1592 data_blob_free(&decoded
);
1594 /* null terminate */
1595 s
[decoded
.length
] = '\0';
1599 * Encode a base64 string into a malloc()ed string caller to free.
1601 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1603 char * base64_encode_data_blob(DATA_BLOB data
)
1608 size_t len
= data
.length
;
1609 size_t output_len
= data
.length
* 2;
1610 char *result
= malloc(output_len
); /* get us plenty of space */
1612 while (len
-- && out_cnt
< (data
.length
* 2) - 5) {
1613 int c
= (unsigned char) *(data
.data
++);
1616 if (char_count
== 3) {
1617 result
[out_cnt
++] = b64
[bits
>> 18];
1618 result
[out_cnt
++] = b64
[(bits
>> 12) & 0x3f];
1619 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
1620 result
[out_cnt
++] = b64
[bits
& 0x3f];
1627 if (char_count
!= 0) {
1628 bits
<<= 16 - (8 * char_count
);
1629 result
[out_cnt
++] = b64
[bits
>> 18];
1630 result
[out_cnt
++] = b64
[(bits
>> 12) & 0x3f];
1631 if (char_count
== 1) {
1632 result
[out_cnt
++] = '=';
1633 result
[out_cnt
++] = '=';
1635 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
1636 result
[out_cnt
++] = '=';
1639 result
[out_cnt
] = '\0'; /* terminate */
1644 size_t valgrind_strlen(const char *s
)
1647 for(count
= 0; *s
++; count
++)