2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) Simo Sorce 2001-2002
7 Copyright (C) Martin Pool 2003
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * @brief String utilities.
32 * Get the next token from a string, return False if none found.
33 * Handles double-quotes.
35 * Based on a routine by GJC@VILLAGE.COM.
36 * Extensively modified by Andrew.Tridgell@anu.edu.au
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
49 /* default to simple separators */
53 /* find the first non sep char */
54 while (*s && strchr_m(sep,*s))
61 /* copy over the token */
62 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
71 *ptr = (*s) ? s+1 : s;
78 This is like next_token but is not re-entrant and "remembers" the first
79 parameter so you can pass NULL. This is useful for user interface code
80 but beware the fact that it is not re-entrant!
83 static const char *last_ptr=NULL;
85 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
89 ptr = (const char **)&last_ptr;
91 ret = next_token(ptr, buff, sep, bufsize);
96 static uint16 tmpbuf[sizeof(pstring)];
98 void set_first_token(char *ptr)
104 Convert list of tokens to array; dependent on above routine.
105 Uses last_ptr from above - bit of a hack.
108 char **toktocliplist(int *ctok, const char *sep)
117 while(*s && strchr_m(sep,*s))
126 while(*s && (!strchr_m(sep,*s)))
128 while(*s && strchr_m(sep,*s))
135 if (!(ret=iret=malloc(ictok*sizeof(char *))))
150 * Case insensitive string compararison.
152 * iconv does not directly give us a way to compare strings in
153 * arbitrary unix character sets -- all we can is convert and then
154 * compare. This is expensive.
156 * As an optimization, we do a first pass that considers only the
157 * prefix of the strings that is entirely 7-bit. Within this, we
158 * check whether they have the same value.
160 * Hopefully this will often give the answer without needing to copy.
161 * In particular it should speed comparisons to literal ascii strings
162 * or comparisons of strings that are "obviously" different.
164 * If we find a non-ascii character we fall back to converting via
167 * This should never be slower than convering the whole thing, and
170 * A different optimization would be to compare for bitwise equality
171 * in the binary encoding. (It would be possible thought hairy to do
172 * both simultaneously.) But in that case if they turn out to be
173 * different, we'd need to restart the whole thing.
175 * Even better is to implement strcasecmp for each encoding and use a
178 int StrCaseCmp(const char *s, const char *t)
181 const char * ps, * pt;
184 for (ps = s, pt = t; ; ps++, pt++) {
188 return 0; /* both ended */
190 return -1; /* s is a prefix */
192 return +1; /* t is a prefix */
193 else if ((*ps & 0x80) || (*pt & 0x80))
194 /* not ascii anymore, do it the hard way from here on in */
207 /* TODO: Don't do this with a fixed-length buffer. This could
208 * still be much more efficient. */
209 /* TODO: Hardcode a char-by-char comparison for UTF-8, which
210 * can be much faster. */
211 /* TODO: Test case for this! */
213 unix_strupper(ps, strlen(ps)+1, buf1, sizeof(buf1));
214 unix_strupper(pt, strlen(pt)+1, buf2, sizeof(buf2));
216 return strcmp(buf1, buf2);
221 Case insensitive string compararison, length limited.
223 int StrnCaseCmp(const char *s, const char *t, size_t n)
226 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
227 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
228 return strncmp(buf1,buf2,n);
234 * @note The comparison is case-insensitive.
236 BOOL strequal(const char *s1, const char *s2)
243 return(StrCaseCmp(s1,s2)==0);
247 * Compare 2 strings up to and including the nth char.
249 * @note The comparison is case-insensitive.
251 BOOL strnequal(const char *s1,const char *s2,size_t n)
255 if (!s1 || !s2 || !n)
258 return(StrnCaseCmp(s1,s2,n)==0);
262 Compare 2 strings (case sensitive).
265 BOOL strcsequal(const char *s1,const char *s2)
272 return(strcmp(s1,s2)==0);
276 Do a case-insensitive, whitespace-ignoring string compare.
279 int strwicmp(const char *psz1, const char *psz2)
281 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
282 /* appropriate value. */
285 else if (psz1 == NULL)
287 else if (psz2 == NULL)
290 /* sync the strings on first non-whitespace */
292 while (isspace((int)*psz1))
294 while (isspace((int)*psz2))
296 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
302 return (*psz1 - *psz2);
307 Convert a string to upper case, but don't modify it.
310 char *strupper_static(const char *s)
321 Convert a string to "normal" form.
324 void strnorm(char *s)
326 extern int case_default;
327 if (case_default == CASE_UPPER)
334 Check if a string is in "normal" case.
337 BOOL strisnormal(const char *s)
339 extern int case_default;
340 if (case_default == CASE_UPPER)
341 return(!strhaslower(s));
343 return(!strhasupper(s));
349 NOTE: oldc and newc must be 7 bit characters
352 void string_replace(char *s,char oldc,char newc)
354 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
355 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
356 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
360 Skip past some strings in a buffer.
363 char *skip_string(char *buf,size_t n)
366 buf += strlen(buf) + 1;
371 Count the number of characters in a string. Normally this will
372 be the same as the number of bytes in a string for single byte strings,
373 but will be different for multibyte.
376 size_t str_charnum(const char *s)
378 uint16 tmpbuf2[sizeof(pstring)];
379 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
380 return strlen_w(tmpbuf2);
384 Count the number of characters in a string. Normally this will
385 be the same as the number of bytes in a string for single byte strings,
386 but will be different for multibyte.
389 size_t str_ascii_charnum(const char *s)
392 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
393 return strlen(tmpbuf2);
397 Trim the specified elements off the front and back of a string.
400 BOOL trim_string(char *s,const char *front,const char *back)
407 /* Ignore null or empty strings. */
408 if (!s || (s[0] == '\0'))
411 front_len = front? strlen(front) : 0;
412 back_len = back? strlen(back) : 0;
417 while (len && strncmp(s, front, front_len)==0) {
418 memcpy(s, s+front_len, (len-front_len)+1);
425 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
426 s[len-back_len]='\0';
435 Does a string have any uppercase chars in it?
438 BOOL strhasupper(const char *s)
441 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
442 for(ptr=tmpbuf;*ptr;ptr++)
449 Does a string have any lowercase chars in it?
452 BOOL strhaslower(const char *s)
455 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
456 for(ptr=tmpbuf;*ptr;ptr++)
463 Find the number of 'c' chars in a string
466 size_t count_chars(const char *s,char c)
470 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
471 for(count=0,ptr=tmpbuf;*ptr;ptr++)
472 if(*ptr==UCS2_CHAR(c))
478 Safe string copy into a known length string. maxlength does not
479 include the terminating zero.
482 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
487 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
491 clobber_region(fn,line,dest, maxlength+1);
498 len = strnlen(src, maxlength+1);
500 if (len > maxlength) {
501 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
502 (unsigned int)(len-maxlength), len, maxlength, src));
506 memmove(dest, src, len);
512 Safe string cat into a string. maxlength does not
513 include the terminating zero.
515 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
517 size_t src_len, dest_len;
520 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
527 src_len = strnlen(src, maxlength + 1);
528 dest_len = strnlen(dest, maxlength + 1);
530 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
532 if (src_len + dest_len > maxlength) {
533 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
534 (int)(src_len + dest_len - maxlength), src));
535 if (maxlength > dest_len) {
536 memcpy(&dest[dest_len], src, maxlength - dest_len);
542 memcpy(&dest[dest_len], src, src_len);
543 dest[dest_len + src_len] = 0;
548 Paranoid strcpy into a buffer of given length (includes terminating
549 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
550 and replaces with '_'. Deliberately does *NOT* check for multibyte
551 characters. Don't change it !
553 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
557 clobber_region(fn, line, dest, maxlength);
560 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
570 if (len >= maxlength)
573 if (!other_safe_chars)
574 other_safe_chars = "";
576 for(i = 0; i < len; i++) {
577 int val = (src[i] & 0xff);
578 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
590 Like strncpy but always null terminates. Make sure there is room!
591 The variable n should always be one less than the available size.
593 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
597 clobber_region(fn, line, dest, n+1);
606 while (n-- && (*d++ = *src++))
614 Like strncpy but copies up to the character marker. always null terminates.
615 returns a pointer to the character marker in the source string (src).
618 static char *strncpyn(char *dest, const char *src, size_t n, char c)
623 clobber_region(dest, n+1);
625 p = strchr_m(src, c);
627 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
631 str_len = PTR_DIFF(p, src);
632 strncpy(dest, src, MIN(n, str_len));
633 dest[str_len] = '\0';
640 Routine to get hex characters and turn them into a 16 byte array.
641 the array can be variable length, and any non-hex-numeric
642 characters are skipped. "0xnn" or "0Xnn" is specially catered
645 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
649 size_t strhex_to_str(char *p, size_t len, const char *strhex)
652 size_t num_chars = 0;
653 unsigned char lonybble, hinybble;
654 const char *hexchars = "0123456789ABCDEF";
655 char *p1 = NULL, *p2 = NULL;
657 for (i = 0; i < len && strhex[i] != 0; i++) {
658 if (strnequal(hexchars, "0x", 2)) {
659 i++; /* skip two chars */
663 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
666 i++; /* next hex digit */
668 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
671 /* get the two nybbles */
672 hinybble = PTR_DIFF(p1, hexchars);
673 lonybble = PTR_DIFF(p2, hexchars);
675 p[num_chars] = (hinybble << 4) | lonybble;
685 Check if a string is part of a list.
688 BOOL in_list(char *s,char *list,BOOL casesensitive)
696 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
698 if (strcmp(tok,s) == 0)
701 if (StrCaseCmp(tok,s) == 0)
708 /* this is used to prevent lots of mallocs of size 1 */
709 static char *null_string = NULL;
712 Set a string value, allocing the space for the string
715 static BOOL string_init(char **dest,const char *src)
725 if((null_string = (char *)malloc(1)) == NULL) {
726 DEBUG(0,("string_init: malloc fail for null_string.\n"));
733 (*dest) = strdup(src);
734 if ((*dest) == NULL) {
735 DEBUG(0,("Out of memory in string_init\n"));
746 void string_free(char **s)
750 if (*s == null_string)
756 Set a string value, deallocating any existing space, and allocing the space
760 BOOL string_set(char **dest,const char *src)
763 return(string_init(dest,src));
767 Substitute a string for a pattern in another string. Make sure there is
770 This routine looks for pattern in s and replaces it with
771 insert. It may do multiple replacements.
773 Any of " ; ' $ or ` in the insert string are replaced with _
774 if len==0 then the string cannot be extended. This is different from the old
775 use of len==0 which was for no length checks to be done.
778 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
783 if (!insert || !pattern || !*pattern || !s)
786 ls = (ssize_t)strlen(s);
787 lp = (ssize_t)strlen(pattern);
788 li = (ssize_t)strlen(insert);
791 len = ls + 1; /* len is number of *bytes* */
793 while (lp <= ls && (p = strstr(s,pattern))) {
794 if (ls + (li-lp) >= len) {
795 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
796 (int)(ls + (li-lp) - len),
801 memmove(p+li,p+lp,strlen(p+lp)+1);
824 void fstring_sub(char *s,const char *pattern,const char *insert)
826 string_sub(s, pattern, insert, sizeof(fstring));
829 void pstring_sub(char *s,const char *pattern,const char *insert)
831 string_sub(s, pattern, insert, sizeof(pstring));
835 Similar to string_sub, but it will accept only allocated strings
836 and may realloc them so pay attention at what you pass on no
837 pointers inside strings, no pstrings or const may be passed
841 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
845 ssize_t ls,lp,li,ld, i;
847 if (!insert || !pattern || !*pattern || !string || !*string)
854 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
857 ls = (ssize_t)strlen(s);
858 lp = (ssize_t)strlen(pattern);
859 li = (ssize_t)strlen(insert);
878 while ((p = strstr(s,pattern))) {
880 char *t = Realloc(string, ls + ld + 1);
882 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
890 memmove(p+li,p+lp,strlen(p+lp)+1);
901 Similar to string_sub() but allows for any character to be substituted.
903 if len==0 then the string cannot be extended. This is different from the old
904 use of len==0 which was for no length checks to be done.
907 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
912 if (!insert || !pattern || !s)
915 ls = (ssize_t)strlen(s);
916 lp = (ssize_t)strlen(pattern);
917 li = (ssize_t)strlen(insert);
923 len = ls + 1; /* len is number of *bytes* */
925 while (lp <= ls && (p = strstr(s,pattern))) {
926 if (ls + (li-lp) >= len) {
927 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
928 (int)(ls + (li-lp) - len),
933 memmove(p+li,p+lp,strlen(p+lp)+1);
935 memcpy(p, insert, li);
942 Similar to all_string_sub but for unicode strings.
943 Return a new allocated unicode string.
944 similar to string_sub() but allows for any character to be substituted.
948 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
949 const smb_ucs2_t *insert)
952 const smb_ucs2_t *sp;
953 size_t lr, lp, li, lt;
955 if (!insert || !pattern || !*pattern || !s)
958 lt = (size_t)strlen_w(s);
959 lp = (size_t)strlen_w(pattern);
960 li = (size_t)strlen_w(insert);
963 const smb_ucs2_t *st = s;
965 while ((sp = strstr_w(st, pattern))) {
971 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
973 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
977 while ((sp = strstr_w(s, pattern))) {
978 memcpy(rp, s, (sp - s));
979 rp += ((sp - s) / sizeof(smb_ucs2_t));
980 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
984 lr = ((rp - r) / sizeof(smb_ucs2_t));
986 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
994 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
999 if (!insert || !pattern || !s)
1001 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1002 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1003 return all_string_sub_w(s, p, i);
1008 Splits out the front and back at a separator.
1011 static void split_at_last_component(char *path, char *front, char sep, char *back)
1013 char *p = strrchr_m(path, sep);
1019 pstrcpy(front, path);
1033 Write an octal as a string.
1036 const char *octal_string(int i)
1038 static char ret[64];
1041 slprintf(ret, sizeof(ret)-1, "0%o", i);
1047 Truncate a string at a specified length.
1050 char *string_truncate(char *s, unsigned int length)
1052 if (s && strlen(s) > length)
1058 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1059 We convert via ucs2 for now.
1062 char *strchr_m(const char *s, char c)
1068 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1069 p = strchr_w(ws, UCS2_CHAR(c));
1073 pull_ucs2_pstring(s2, ws);
1074 return (char *)(s+strlen(s2));
1077 char *strrchr_m(const char *s, char c)
1083 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1084 p = strrchr_w(ws, UCS2_CHAR(c));
1088 pull_ucs2_pstring(s2, ws);
1089 return (char *)(s+strlen(s2));
1093 Convert a string to lower case.
1096 void strlower_m(char *s)
1098 /* this is quite a common operation, so we want it to be
1099 fast. We optimise for the ascii case, knowing that all our
1100 supported multi-byte character sets are ascii-compatible
1101 (ie. they match for the first 128 chars) */
1103 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1104 *s = tolower((unsigned char)*s);
1111 /* I assume that lowercased string takes the same number of bytes
1112 * as source string even in UTF-8 encoding. (VIV) */
1113 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1117 Duplicate convert a string to lower case.
1120 char *strdup_lower(const char *s)
1122 char *t = strdup(s);
1124 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1132 Convert a string to upper case.
1135 void strupper_m(char *s)
1137 /* this is quite a common operation, so we want it to be
1138 fast. We optimise for the ascii case, knowing that all our
1139 supported multi-byte character sets are ascii-compatible
1140 (ie. they match for the first 128 chars) */
1142 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1143 *s = toupper((unsigned char)*s);
1150 /* I assume that lowercased string takes the same number of bytes
1151 * as source string even in multibyte encoding. (VIV) */
1152 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1156 Convert a string to upper case.
1159 char *strdup_upper(const char *s)
1161 char *t = strdup(s);
1163 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1171 Return a RFC2254 binary string representation of a buffer.
1172 Used in LDAP filters.
1176 char *binary_string(char *buf, int len)
1180 const char *hex = "0123456789ABCDEF";
1181 s = malloc(len * 3 + 1);
1184 for (j=i=0;i<len;i++) {
1186 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1187 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1195 Just a typesafety wrapper for snprintf into a pstring.
1198 int pstr_sprintf(pstring s, const char *fmt, ...)
1204 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1211 Just a typesafety wrapper for snprintf into a fstring.
1214 static int fstr_sprintf(fstring s, const char *fmt, ...)
1220 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1226 #ifndef HAVE_STRNDUP
1228 Some platforms don't have strndup.
1231 char *strndup(const char *s, size_t n)
1246 #ifndef HAVE_STRNLEN
1248 Some platforms don't have strnlen
1251 size_t strnlen(const char *s, size_t n)
1254 for (i=0; s[i] && i<n; i++)
1261 List of Strings manipulation functions
1264 #define S_LIST_ABS 16 /* List Allocation Block Size */
1266 char **str_list_make(const char *string, const char *sep)
1268 char **list, **rlist;
1274 if (!string || !*string)
1278 DEBUG(0,("str_list_make: Unable to allocate memory"));
1281 if (!sep) sep = LIST_SEP;
1287 while (next_token(&str, tok, sep, sizeof(tok))) {
1289 lsize += S_LIST_ABS;
1290 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1292 DEBUG(0,("str_list_make: Unable to allocate memory"));
1293 str_list_free(&list);
1298 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1301 list[num] = strdup(tok);
1303 DEBUG(0,("str_list_make: Unable to allocate memory"));
1304 str_list_free(&list);
1316 BOOL str_list_copy(char ***dest, const char **src)
1318 char **list, **rlist;
1330 lsize += S_LIST_ABS;
1331 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1333 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1334 str_list_free(&list);
1338 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1341 list[num] = strdup(src[num]);
1343 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1344 str_list_free(&list);
1356 * Return true if all the elements of the list match exactly.
1358 BOOL str_list_compare(char **list1, char **list2)
1362 if (!list1 || !list2)
1363 return (list1 == list2);
1365 for (num = 0; list1[num]; num++) {
1368 if (!strcsequal(list1[num], list2[num]))
1372 return False; /* if list2 has more elements than list1 fail */
1377 void str_list_free(char ***list)
1381 if (!list || !*list)
1384 for(; *tlist; tlist++)
1389 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1392 ssize_t ls, lp, li, ld, i, d;
1401 lp = (ssize_t)strlen(pattern);
1402 li = (ssize_t)strlen(insert);
1407 ls = (ssize_t)strlen(s);
1409 while ((p = strstr(s, pattern))) {
1413 t = (char *) malloc(ls +ld +1);
1415 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1418 memcpy(t, *list, d);
1419 memcpy(t +d +li, p +lp, ls -d -lp +1);
1426 for (i = 0; i < li; i++) {
1427 switch (insert[i]) {
1439 t[d +i] = insert[i];
1451 #define IPSTR_LIST_SEP ","
1454 * Add ip string representation to ipstr list. Used also
1455 * as part of @function ipstr_list_make
1457 * @param ipstr_list pointer to string containing ip list;
1458 * MUST BE already allocated and IS reallocated if necessary
1459 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1460 * as a result of reallocation)
1461 * @param ip IP address which is to be added to list
1462 * @return pointer to string appended with new ip and possibly
1463 * reallocated to new length
1466 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1468 char* new_ipstr = NULL;
1470 /* arguments checking */
1471 if (!ipstr_list || !ip) return NULL;
1473 /* attempt to convert ip to a string and append colon separator to it */
1475 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1476 SAFE_FREE(*ipstr_list);
1478 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1480 *ipstr_list = new_ipstr;
1486 * Allocate and initialise an ipstr list using ip adresses
1487 * passed as arguments.
1489 * @param ipstr_list pointer to string meant to be allocated and set
1490 * @param ip_list array of ip addresses to place in the list
1491 * @param ip_count number of addresses stored in ip_list
1492 * @return pointer to allocated ip string
1495 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1499 /* arguments checking */
1500 if (!ip_list && !ipstr_list) return 0;
1504 /* process ip addresses given as arguments */
1505 for (i = 0; i < ip_count; i++)
1506 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1508 return (*ipstr_list);
1513 * Parse given ip string list into array of ip addresses
1514 * (as in_addr structures)
1516 * @param ipstr ip string list to be parsed
1517 * @param ip_list pointer to array of ip addresses which is
1518 * allocated by this function and must be freed by caller
1519 * @return number of succesfully parsed addresses
1522 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1527 if (!ipstr_list || !ip_list) return 0;
1529 for (*ip_list = NULL, count = 0;
1530 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1533 struct in_addr addr;
1535 /* convert single token to ip address */
1536 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1539 /* prepare place for another in_addr structure */
1540 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1541 if (!*ip_list) return -1;
1543 (*ip_list)[count] = addr;
1551 * Safely free ip string list
1553 * @param ipstr_list ip string list to be freed
1556 void ipstr_list_free(char* ipstr_list)
1558 SAFE_FREE(ipstr_list);
1563 Unescape a URL encoded string, in place.
1566 void rfc1738_unescape(char *buf)
1570 while ((p=strchr_m(p,'+')))
1575 while (p && *p && (p=strchr_m(p,'%'))) {
1579 if (c1 >= '0' && c1 <= '9')
1581 else if (c1 >= 'A' && c1 <= 'F')
1583 else if (c1 >= 'a' && c1 <= 'f')
1585 else {p++; continue;}
1587 if (c2 >= '0' && c2 <= '9')
1589 else if (c2 >= 'A' && c2 <= 'F')
1591 else if (c2 >= 'a' && c2 <= 'f')
1593 else {p++; continue;}
1597 memmove(p+1, p+3, strlen(p+3)+1);
1602 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1605 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1607 DATA_BLOB base64_decode_data_blob(const char *s)
1609 int bit_offset, byte_offset, idx, i, n;
1610 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1611 unsigned char *d = decoded.data;
1616 while (*s && (p=strchr_m(b64,*s))) {
1617 idx = (int)(p - b64);
1618 byte_offset = (i*6)/8;
1619 bit_offset = (i*6)%8;
1620 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1621 if (bit_offset < 3) {
1622 d[byte_offset] |= (idx << (2-bit_offset));
1625 d[byte_offset] |= (idx >> (bit_offset-2));
1626 d[byte_offset+1] = 0;
1627 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1639 * Decode a base64 string in-place - wrapper for the above
1641 void base64_decode_inplace(char *s)
1643 DATA_BLOB decoded = base64_decode_data_blob(s);
1644 memcpy(s, decoded.data, decoded.length);
1645 data_blob_free(&decoded);
1647 /* null terminate */
1648 s[decoded.length] = '\0';
1652 * Encode a base64 string into a malloc()ed string caller to free.
1654 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1656 char * base64_encode_data_blob(DATA_BLOB data)
1661 size_t len = data.length;
1662 size_t output_len = data.length * 2;
1663 char *result = malloc(output_len); /* get us plenty of space */
1665 while (len-- && out_cnt < (data.length * 2) - 5) {
1666 int c = (unsigned char) *(data.data++);
1669 if (char_count == 3) {
1670 result[out_cnt++] = b64[bits >> 18];
1671 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1672 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1673 result[out_cnt++] = b64[bits & 0x3f];
1680 if (char_count != 0) {
1681 bits <<= 16 - (8 * char_count);
1682 result[out_cnt++] = b64[bits >> 18];
1683 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1684 if (char_count == 1) {
1685 result[out_cnt++] = '=';
1686 result[out_cnt++] = '=';
1688 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1689 result[out_cnt++] = '=';
1692 result[out_cnt] = '\0'; /* terminate */