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 const char *global_clobber_region_function;
26 unsigned int global_clobber_region_line;
30 * Get the next token from a string, return False if none found.
31 * Handles double-quotes.
33 * Based on a routine by GJC@VILLAGE.COM.
34 * Extensively modified by Andrew.Tridgell@anu.edu.au
36 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
47 /* default to simple separators */
51 /* find the first non sep char */
52 while (*s && strchr_m(sep,*s))
59 /* copy over the token */
60 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
69 *ptr = (*s) ? s+1 : s;
76 This is like next_token but is not re-entrant and "remembers" the first
77 parameter so you can pass NULL. This is useful for user interface code
78 but beware the fact that it is not re-entrant!
81 static const char *last_ptr=NULL;
83 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
87 ptr = (const char **)&last_ptr;
89 ret = next_token(ptr, buff, sep, bufsize);
94 static uint16 tmpbuf[sizeof(pstring)];
96 void set_first_token(char *ptr)
102 Convert list of tokens to array; dependent on above routine.
103 Uses last_ptr from above - bit of a hack.
106 char **toktocliplist(int *ctok, const char *sep)
115 while(*s && strchr_m(sep,*s))
124 while(*s && (!strchr_m(sep,*s)))
126 while(*s && strchr_m(sep,*s))
133 if (!(ret=iret=malloc(ictok*sizeof(char *))))
148 Case insensitive string compararison.
151 int StrCaseCmp(const char *s, const char *t)
154 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
155 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
156 return strcmp(buf1,buf2);
160 Case insensitive string compararison, length limited.
163 int StrnCaseCmp(const char *s, const char *t, size_t n)
166 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
167 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
168 return strncmp(buf1,buf2,n);
174 * @note The comparison is case-insensitive.
176 BOOL strequal(const char *s1, const char *s2)
183 return(StrCaseCmp(s1,s2)==0);
187 * Compare 2 strings up to and including the nth char.
189 * @note The comparison is case-insensitive.
191 BOOL strnequal(const char *s1,const char *s2,size_t n)
195 if (!s1 || !s2 || !n)
198 return(StrnCaseCmp(s1,s2,n)==0);
202 Compare 2 strings (case sensitive).
205 BOOL strcsequal(const char *s1,const char *s2)
212 return(strcmp(s1,s2)==0);
216 Do a case-insensitive, whitespace-ignoring string compare.
219 int strwicmp(const char *psz1, const char *psz2)
221 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
222 /* appropriate value. */
225 else if (psz1 == NULL)
227 else if (psz2 == NULL)
230 /* sync the strings on first non-whitespace */
232 while (isspace((int)*psz1))
234 while (isspace((int)*psz2))
236 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
242 return (*psz1 - *psz2);
247 Convert a string to upper case, but don't modify it.
250 char *strupper_static(const char *s)
261 Convert a string to "normal" form.
264 void strnorm(char *s)
266 extern int case_default;
267 if (case_default == CASE_UPPER)
274 Check if a string is in "normal" case.
277 BOOL strisnormal(const char *s)
279 extern int case_default;
280 if (case_default == CASE_UPPER)
281 return(!strhaslower(s));
283 return(!strhasupper(s));
289 NOTE: oldc and newc must be 7 bit characters
292 void string_replace(char *s,char oldc,char newc)
294 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
295 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
296 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
300 Skip past some strings in a buffer.
303 char *skip_string(char *buf,size_t n)
306 buf += strlen(buf) + 1;
311 Count the number of characters in a string. Normally this will
312 be the same as the number of bytes in a string for single byte strings,
313 but will be different for multibyte.
316 size_t str_charnum(const char *s)
318 uint16 tmpbuf2[sizeof(pstring)];
319 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
320 return strlen_w(tmpbuf2);
324 Count the number of characters in a string. Normally this will
325 be the same as the number of bytes in a string for single byte strings,
326 but will be different for multibyte.
329 size_t str_ascii_charnum(const char *s)
332 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
333 return strlen(tmpbuf2);
337 Trim the specified elements off the front and back of a string.
340 BOOL trim_string(char *s,const char *front,const char *back)
347 /* Ignore null or empty strings. */
348 if (!s || (s[0] == '\0'))
351 front_len = front? strlen(front) : 0;
352 back_len = back? strlen(back) : 0;
357 while (len && strncmp(s, front, front_len)==0) {
358 memcpy(s, s+front_len, (len-front_len)+1);
365 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
366 s[len-back_len]='\0';
375 Does a string have any uppercase chars in it?
378 BOOL strhasupper(const char *s)
381 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
382 for(ptr=tmpbuf;*ptr;ptr++)
389 Does a string have any lowercase chars in it?
392 BOOL strhaslower(const char *s)
395 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
396 for(ptr=tmpbuf;*ptr;ptr++)
403 Find the number of 'c' chars in a string
406 size_t count_chars(const char *s,char c)
410 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
411 for(count=0,ptr=tmpbuf;*ptr;ptr++)
412 if(*ptr==UCS2_CHAR(c))
418 * In developer builds, clobber a region of memory.
420 * If we think a string buffer is longer than it really is, this ought
421 * to make the failure obvious, by segfaulting (if in the heap) or by
422 * killing the return address (on the stack), or by trapping under a
425 * This is meant to catch possible string overflows, even if the
426 * actual string copied is not big enough to cause an overflow.
428 * In addition, under Valgrind the buffer is marked as uninitialized.
430 void clobber_region(const char *fn, unsigned int line, char *dest, size_t len)
433 global_clobber_region_function = fn;
434 global_clobber_region_line = line;
436 /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */
437 memset(dest, 0xF1, len);
439 /* Even though we just wrote to this, from the application's
440 * point of view it is not initialized.
442 * (This is not redundant with the clobbering above. The
443 * marking might not actually take effect if we're not running
444 * under valgrind.) */
445 VALGRIND_MAKE_WRITABLE(dest, len);
446 #endif /* VALGRIND */
447 #endif /* DEVELOPER */
452 Safe string copy into a known length string. maxlength does not
453 include the terminating zero.
456 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
461 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
465 clobber_region(fn,line,dest, maxlength+1);
474 if (len > maxlength) {
475 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
476 (unsigned int)(len-maxlength), len, maxlength, src));
480 memmove(dest, src, len);
486 Safe string cat into a string. maxlength does not
487 include the terminating zero.
489 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
491 size_t src_len, dest_len;
494 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
501 src_len = strlen(src);
502 dest_len = strlen(dest);
504 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
506 if (src_len + dest_len > maxlength) {
507 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
508 (int)(src_len + dest_len - maxlength), src));
509 if (maxlength > dest_len) {
510 memcpy(&dest[dest_len], src, maxlength - dest_len);
516 memcpy(&dest[dest_len], src, src_len);
517 dest[dest_len + src_len] = 0;
522 Paranoid strcpy into a buffer of given length (includes terminating
523 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
524 and replaces with '_'. Deliberately does *NOT* check for multibyte
525 characters. Don't change it !
527 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
531 clobber_region(fn, line, dest, maxlength);
534 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
544 if (len >= maxlength)
547 if (!other_safe_chars)
548 other_safe_chars = "";
550 for(i = 0; i < len; i++) {
551 int val = (src[i] & 0xff);
552 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
564 Like strncpy but always null terminates. Make sure there is room!
565 The variable n should always be one less than the available size.
567 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
571 clobber_region(fn, line, dest, n+1);
580 while (n-- && (*d++ = *src++))
588 Like strncpy but copies up to the character marker. always null terminates.
589 returns a pointer to the character marker in the source string (src).
592 static char *strncpyn(char *dest, const char *src, size_t n, char c)
597 clobber_region(dest, n+1);
599 p = strchr_m(src, c);
601 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
605 str_len = PTR_DIFF(p, src);
606 strncpy(dest, src, MIN(n, str_len));
607 dest[str_len] = '\0';
614 Routine to get hex characters and turn them into a 16 byte array.
615 the array can be variable length, and any non-hex-numeric
616 characters are skipped. "0xnn" or "0Xnn" is specially catered
619 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
623 size_t strhex_to_str(char *p, size_t len, const char *strhex)
626 size_t num_chars = 0;
627 unsigned char lonybble, hinybble;
628 const char *hexchars = "0123456789ABCDEF";
629 char *p1 = NULL, *p2 = NULL;
631 for (i = 0; i < len && strhex[i] != 0; i++) {
632 if (strnequal(hexchars, "0x", 2)) {
633 i++; /* skip two chars */
637 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
640 i++; /* next hex digit */
642 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
645 /* get the two nybbles */
646 hinybble = PTR_DIFF(p1, hexchars);
647 lonybble = PTR_DIFF(p2, hexchars);
649 p[num_chars] = (hinybble << 4) | lonybble;
659 Check if a string is part of a list.
662 BOOL in_list(char *s,char *list,BOOL casesensitive)
670 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
672 if (strcmp(tok,s) == 0)
675 if (StrCaseCmp(tok,s) == 0)
682 /* this is used to prevent lots of mallocs of size 1 */
683 static char *null_string = NULL;
686 Set a string value, allocing the space for the string
689 static BOOL string_init(char **dest,const char *src)
699 if((null_string = (char *)malloc(1)) == NULL) {
700 DEBUG(0,("string_init: malloc fail for null_string.\n"));
707 (*dest) = strdup(src);
708 if ((*dest) == NULL) {
709 DEBUG(0,("Out of memory in string_init\n"));
720 void string_free(char **s)
724 if (*s == null_string)
730 Set a string value, deallocating any existing space, and allocing the space
734 BOOL string_set(char **dest,const char *src)
737 return(string_init(dest,src));
741 Substitute a string for a pattern in another string. Make sure there is
744 This routine looks for pattern in s and replaces it with
745 insert. It may do multiple replacements.
747 Any of " ; ' $ or ` in the insert string are replaced with _
748 if len==0 then the string cannot be extended. This is different from the old
749 use of len==0 which was for no length checks to be done.
752 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
757 if (!insert || !pattern || !*pattern || !s)
760 ls = (ssize_t)strlen(s);
761 lp = (ssize_t)strlen(pattern);
762 li = (ssize_t)strlen(insert);
765 len = ls + 1; /* len is number of *bytes* */
767 while (lp <= ls && (p = strstr(s,pattern))) {
768 if (ls + (li-lp) >= len) {
769 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
770 (int)(ls + (li-lp) - len),
775 memmove(p+li,p+lp,strlen(p+lp)+1);
798 void fstring_sub(char *s,const char *pattern,const char *insert)
800 string_sub(s, pattern, insert, sizeof(fstring));
803 void pstring_sub(char *s,const char *pattern,const char *insert)
805 string_sub(s, pattern, insert, sizeof(pstring));
809 Similar to string_sub, but it will accept only allocated strings
810 and may realloc them so pay attention at what you pass on no
811 pointers inside strings, no pstrings or const may be passed
815 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
819 ssize_t ls,lp,li,ld, i;
821 if (!insert || !pattern || !*pattern || !string || !*string)
828 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
831 ls = (ssize_t)strlen(s);
832 lp = (ssize_t)strlen(pattern);
833 li = (ssize_t)strlen(insert);
852 while ((p = strstr(s,pattern))) {
854 char *t = Realloc(string, ls + ld + 1);
856 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
864 memmove(p+li,p+lp,strlen(p+lp)+1);
875 Similar to string_sub() but allows for any character to be substituted.
877 if len==0 then the string cannot be extended. This is different from the old
878 use of len==0 which was for no length checks to be done.
881 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
886 if (!insert || !pattern || !s)
889 ls = (ssize_t)strlen(s);
890 lp = (ssize_t)strlen(pattern);
891 li = (ssize_t)strlen(insert);
897 len = ls + 1; /* len is number of *bytes* */
899 while (lp <= ls && (p = strstr(s,pattern))) {
900 if (ls + (li-lp) >= len) {
901 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
902 (int)(ls + (li-lp) - len),
907 memmove(p+li,p+lp,strlen(p+lp)+1);
909 memcpy(p, insert, li);
916 Similar to all_string_sub but for unicode strings.
917 Return a new allocated unicode string.
918 similar to string_sub() but allows for any character to be substituted.
922 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
923 const smb_ucs2_t *insert)
926 const smb_ucs2_t *sp;
927 size_t lr, lp, li, lt;
929 if (!insert || !pattern || !*pattern || !s)
932 lt = (size_t)strlen_w(s);
933 lp = (size_t)strlen_w(pattern);
934 li = (size_t)strlen_w(insert);
937 const smb_ucs2_t *st = s;
939 while ((sp = strstr_w(st, pattern))) {
945 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
947 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
951 while ((sp = strstr_w(s, pattern))) {
952 memcpy(rp, s, (sp - s));
953 rp += ((sp - s) / sizeof(smb_ucs2_t));
954 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
958 lr = ((rp - r) / sizeof(smb_ucs2_t));
960 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
968 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
973 if (!insert || !pattern || !s)
975 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
976 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
977 return all_string_sub_w(s, p, i);
982 Splits out the front and back at a separator.
985 static void split_at_last_component(char *path, char *front, char sep, char *back)
987 char *p = strrchr_m(path, sep);
993 pstrcpy(front, path);
1007 Write an octal as a string.
1010 const char *octal_string(int i)
1012 static char ret[64];
1015 slprintf(ret, sizeof(ret)-1, "0%o", i);
1021 Truncate a string at a specified length.
1024 char *string_truncate(char *s, unsigned int length)
1026 if (s && strlen(s) > length)
1032 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1033 We convert via ucs2 for now.
1036 char *strchr_m(const char *s, char c)
1042 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1043 p = strchr_w(ws, UCS2_CHAR(c));
1047 pull_ucs2_pstring(s2, ws);
1048 return (char *)(s+strlen(s2));
1051 char *strrchr_m(const char *s, char c)
1057 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1058 p = strrchr_w(ws, UCS2_CHAR(c));
1062 pull_ucs2_pstring(s2, ws);
1063 return (char *)(s+strlen(s2));
1067 Convert a string to lower case.
1070 void strlower_m(char *s)
1072 /* this is quite a common operation, so we want it to be
1073 fast. We optimise for the ascii case, knowing that all our
1074 supported multi-byte character sets are ascii-compatible
1075 (ie. they match for the first 128 chars) */
1077 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1078 *s = tolower((unsigned char)*s);
1085 /* I assume that lowercased string takes the same number of bytes
1086 * as source string even in UTF-8 encoding. (VIV) */
1087 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1091 Duplicate convert a string to lower case.
1094 char *strdup_lower(const char *s)
1096 char *t = strdup(s);
1098 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1106 Convert a string to upper case.
1109 void strupper_m(char *s)
1111 /* this is quite a common operation, so we want it to be
1112 fast. We optimise for the ascii case, knowing that all our
1113 supported multi-byte character sets are ascii-compatible
1114 (ie. they match for the first 128 chars) */
1116 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1117 *s = toupper((unsigned char)*s);
1124 /* I assume that lowercased string takes the same number of bytes
1125 * as source string even in multibyte encoding. (VIV) */
1126 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1130 Convert a string to upper case.
1133 char *strdup_upper(const char *s)
1135 char *t = strdup(s);
1137 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1145 Return a RFC2254 binary string representation of a buffer.
1146 Used in LDAP filters.
1150 char *binary_string(char *buf, int len)
1154 const char *hex = "0123456789ABCDEF";
1155 s = malloc(len * 3 + 1);
1158 for (j=i=0;i<len;i++) {
1160 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1161 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1169 Just a typesafety wrapper for snprintf into a pstring.
1172 int pstr_sprintf(pstring s, const char *fmt, ...)
1178 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1185 Just a typesafety wrapper for snprintf into a fstring.
1188 static int fstr_sprintf(fstring s, const char *fmt, ...)
1194 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1200 #ifndef HAVE_STRNDUP
1202 Some platforms don't have strndup.
1205 char *strndup(const char *s, size_t n)
1220 #ifndef HAVE_STRNLEN
1222 Some platforms don't have strnlen
1225 size_t strnlen(const char *s, size_t n)
1228 for (i=0; s[i] && i<n; i++)
1235 List of Strings manipulation functions
1238 #define S_LIST_ABS 16 /* List Allocation Block Size */
1240 char **str_list_make(const char *string, const char *sep)
1242 char **list, **rlist;
1248 if (!string || !*string)
1252 DEBUG(0,("str_list_make: Unable to allocate memory"));
1255 if (!sep) sep = LIST_SEP;
1261 while (next_token(&str, tok, sep, sizeof(tok))) {
1263 lsize += S_LIST_ABS;
1264 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1266 DEBUG(0,("str_list_make: Unable to allocate memory"));
1267 str_list_free(&list);
1272 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1275 list[num] = strdup(tok);
1277 DEBUG(0,("str_list_make: Unable to allocate memory"));
1278 str_list_free(&list);
1290 BOOL str_list_copy(char ***dest, const char **src)
1292 char **list, **rlist;
1304 lsize += S_LIST_ABS;
1305 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1307 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1308 str_list_free(&list);
1312 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1315 list[num] = strdup(src[num]);
1317 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1318 str_list_free(&list);
1330 * Return true if all the elements of the list match exactly.
1332 BOOL str_list_compare(char **list1, char **list2)
1336 if (!list1 || !list2)
1337 return (list1 == list2);
1339 for (num = 0; list1[num]; num++) {
1342 if (!strcsequal(list1[num], list2[num]))
1346 return False; /* if list2 has more elements than list1 fail */
1351 void str_list_free(char ***list)
1355 if (!list || !*list)
1358 for(; *tlist; tlist++)
1363 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1366 ssize_t ls, lp, li, ld, i, d;
1375 lp = (ssize_t)strlen(pattern);
1376 li = (ssize_t)strlen(insert);
1381 ls = (ssize_t)strlen(s);
1383 while ((p = strstr(s, pattern))) {
1387 t = (char *) malloc(ls +ld +1);
1389 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1392 memcpy(t, *list, d);
1393 memcpy(t +d +li, p +lp, ls -d -lp +1);
1400 for (i = 0; i < li; i++) {
1401 switch (insert[i]) {
1413 t[d +i] = insert[i];
1425 #define IPSTR_LIST_SEP ","
1428 * Add ip string representation to ipstr list. Used also
1429 * as part of @function ipstr_list_make
1431 * @param ipstr_list pointer to string containing ip list;
1432 * MUST BE already allocated and IS reallocated if necessary
1433 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1434 * as a result of reallocation)
1435 * @param ip IP address which is to be added to list
1436 * @return pointer to string appended with new ip and possibly
1437 * reallocated to new length
1440 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1442 char* new_ipstr = NULL;
1444 /* arguments checking */
1445 if (!ipstr_list || !ip) return NULL;
1447 /* attempt to convert ip to a string and append colon separator to it */
1449 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1450 SAFE_FREE(*ipstr_list);
1452 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1454 *ipstr_list = new_ipstr;
1460 * Allocate and initialise an ipstr list using ip adresses
1461 * passed as arguments.
1463 * @param ipstr_list pointer to string meant to be allocated and set
1464 * @param ip_list array of ip addresses to place in the list
1465 * @param ip_count number of addresses stored in ip_list
1466 * @return pointer to allocated ip string
1469 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1473 /* arguments checking */
1474 if (!ip_list && !ipstr_list) return 0;
1478 /* process ip addresses given as arguments */
1479 for (i = 0; i < ip_count; i++)
1480 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1482 return (*ipstr_list);
1487 * Parse given ip string list into array of ip addresses
1488 * (as in_addr structures)
1490 * @param ipstr ip string list to be parsed
1491 * @param ip_list pointer to array of ip addresses which is
1492 * allocated by this function and must be freed by caller
1493 * @return number of succesfully parsed addresses
1496 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1501 if (!ipstr_list || !ip_list) return 0;
1503 for (*ip_list = NULL, count = 0;
1504 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1507 struct in_addr addr;
1509 /* convert single token to ip address */
1510 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1513 /* prepare place for another in_addr structure */
1514 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1515 if (!*ip_list) return -1;
1517 (*ip_list)[count] = addr;
1525 * Safely free ip string list
1527 * @param ipstr_list ip string list to be freed
1530 void ipstr_list_free(char* ipstr_list)
1532 SAFE_FREE(ipstr_list);
1537 Unescape a URL encoded string, in place.
1540 void rfc1738_unescape(char *buf)
1544 while ((p=strchr_m(p,'+')))
1549 while (p && *p && (p=strchr_m(p,'%'))) {
1553 if (c1 >= '0' && c1 <= '9')
1555 else if (c1 >= 'A' && c1 <= 'F')
1557 else if (c1 >= 'a' && c1 <= 'f')
1559 else {p++; continue;}
1561 if (c2 >= '0' && c2 <= '9')
1563 else if (c2 >= 'A' && c2 <= 'F')
1565 else if (c2 >= 'a' && c2 <= 'f')
1567 else {p++; continue;}
1571 memmove(p+1, p+3, strlen(p+3)+1);
1576 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1579 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1581 DATA_BLOB base64_decode_data_blob(const char *s)
1583 int bit_offset, byte_offset, idx, i, n;
1584 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1585 unsigned char *d = decoded.data;
1590 while (*s && (p=strchr_m(b64,*s))) {
1591 idx = (int)(p - b64);
1592 byte_offset = (i*6)/8;
1593 bit_offset = (i*6)%8;
1594 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1595 if (bit_offset < 3) {
1596 d[byte_offset] |= (idx << (2-bit_offset));
1599 d[byte_offset] |= (idx >> (bit_offset-2));
1600 d[byte_offset+1] = 0;
1601 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1613 * Decode a base64 string in-place - wrapper for the above
1615 void base64_decode_inplace(char *s)
1617 DATA_BLOB decoded = base64_decode_data_blob(s);
1618 memcpy(s, decoded.data, decoded.length);
1619 data_blob_free(&decoded);
1621 /* null terminate */
1622 s[decoded.length] = '\0';
1626 * Encode a base64 string into a malloc()ed string caller to free.
1628 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1630 char * base64_encode_data_blob(DATA_BLOB data)
1635 size_t len = data.length;
1636 size_t output_len = data.length * 2;
1637 char *result = malloc(output_len); /* get us plenty of space */
1639 while (len-- && out_cnt < (data.length * 2) - 5) {
1640 int c = (unsigned char) *(data.data++);
1643 if (char_count == 3) {
1644 result[out_cnt++] = b64[bits >> 18];
1645 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1646 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1647 result[out_cnt++] = b64[bits & 0x3f];
1654 if (char_count != 0) {
1655 bits <<= 16 - (8 * char_count);
1656 result[out_cnt++] = b64[bits >> 18];
1657 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1658 if (char_count == 1) {
1659 result[out_cnt++] = '=';
1660 result[out_cnt++] = '=';
1662 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1663 result[out_cnt++] = '=';
1666 result[out_cnt] = '\0'; /* terminate */