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);
169 * @note The comparison is case-insensitive.
171 BOOL strequal(const char *s1, const char *s2)
178 return(StrCaseCmp(s1,s2)==0);
182 * Compare 2 strings up to and including the nth char.
184 * @note The comparison is case-insensitive.
186 BOOL strnequal(const char *s1,const char *s2,size_t n)
190 if (!s1 || !s2 || !n)
193 return(StrnCaseCmp(s1,s2,n)==0);
197 Compare 2 strings (case sensitive).
200 BOOL strcsequal(const char *s1,const char *s2)
207 return(strcmp(s1,s2)==0);
211 Do a case-insensitive, whitespace-ignoring string compare.
214 int strwicmp(const char *psz1, const char *psz2)
216 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
217 /* appropriate value. */
220 else if (psz1 == NULL)
222 else if (psz2 == NULL)
225 /* sync the strings on first non-whitespace */
227 while (isspace((int)*psz1))
229 while (isspace((int)*psz2))
231 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
237 return (*psz1 - *psz2);
241 Convert a string to upper case, but don't modify it.
244 char *strupper_talloc(TALLOC_CTX *mem_ctx, const char *s)
248 str = talloc_strdup(mem_ctx, s);
257 NOTE: oldc and newc must be 7 bit characters
260 void string_replace(char *s,char oldc,char newc)
262 if (strchr(s, oldc)) {
263 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
264 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
265 pull_ucs2(NULL, s, tmpbuf, strlen(s)+1, sizeof(tmpbuf), STR_TERMINATE);
270 Skip past some strings in a buffer.
273 char *skip_string(char *buf,size_t n)
276 buf += strlen(buf) + 1;
281 Count the number of characters in a string. Normally this will
282 be the same as the number of bytes in a string for single byte strings,
283 but will be different for multibyte.
286 size_t str_charnum(const char *s)
288 uint16 tmpbuf2[sizeof(pstring)];
289 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
290 return strlen_w(tmpbuf2);
294 Count the number of characters in a string. Normally this will
295 be the same as the number of bytes in a string for single byte strings,
296 but will be different for multibyte.
299 size_t str_ascii_charnum(const char *s)
302 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
303 return strlen(tmpbuf2);
307 Trim the specified elements off the front and back of a string.
310 BOOL trim_string(char *s,const char *front,const char *back)
317 /* Ignore null or empty strings. */
318 if (!s || (s[0] == '\0'))
321 front_len = front? strlen(front) : 0;
322 back_len = back? strlen(back) : 0;
327 while (len && strncmp(s, front, front_len)==0) {
328 memcpy(s, s+front_len, (len-front_len)+1);
335 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
336 s[len-back_len]='\0';
345 Does a string have any uppercase chars in it?
348 BOOL strhasupper(const char *s)
351 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
352 for(ptr=tmpbuf;*ptr;ptr++)
359 Does a string have any lowercase chars in it?
362 BOOL strhaslower(const char *s)
365 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
366 for(ptr=tmpbuf;*ptr;ptr++)
373 Find the number of 'c' chars in a string
376 size_t count_chars(const char *s,char c)
380 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
381 for(count=0,ptr=tmpbuf;*ptr;ptr++)
382 if(*ptr==UCS2_CHAR(c))
388 Return True if a string consists only of one particular character.
391 BOOL str_is_all(const char *s,char c)
400 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
401 for(ptr=tmpbuf;*ptr;ptr++)
402 if(*ptr!=UCS2_CHAR(c))
409 Safe string copy into a known length string. maxlength does not
410 include the terminating zero.
413 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
418 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
423 /* We intentionally write out at the extremity of the destination
424 * string. If the destination is too short (e.g. pstrcpy into mallocd
425 * or fstring) then this should cause an error under a memory
427 dest[maxlength] = '\0';
428 if (PTR_DIFF(&len, dest) > 0) { /* check if destination is on the stack, ok if so */
429 log_suspicious_usage("safe_strcpy", src);
440 if (len > maxlength) {
441 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
442 (unsigned int)(len-maxlength), len, maxlength, src));
446 memmove(dest, src, len);
452 Safe string cat into a string. maxlength does not
453 include the terminating zero.
456 char *safe_strcat(char *dest, const char *src, size_t maxlength)
458 size_t src_len, dest_len;
461 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
469 if (PTR_DIFF(&src_len, dest) > 0) { /* check if destination is on the stack, ok if so */
470 log_suspicious_usage("safe_strcat", src);
473 src_len = strlen(src);
474 dest_len = strlen(dest);
476 if (src_len + dest_len > maxlength) {
477 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
478 (int)(src_len + dest_len - maxlength), src));
479 if (maxlength > dest_len) {
480 memcpy(&dest[dest_len], src, maxlength - dest_len);
486 memcpy(&dest[dest_len], src, src_len);
487 dest[dest_len + src_len] = 0;
492 Paranoid strcpy into a buffer of given length (includes terminating
493 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
494 and replaces with '_'. Deliberately does *NOT* check for multibyte
495 characters. Don't change it !
498 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
502 if (maxlength == 0) {
503 /* can't fit any bytes at all! */
508 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
518 if (len >= maxlength)
521 if (!other_safe_chars)
522 other_safe_chars = "";
524 for(i = 0; i < len; i++) {
525 int val = (src[i] & 0xff);
526 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
538 Like strncpy but always null terminates. Make sure there is room!
539 The variable n should always be one less than the available size.
542 char *StrnCpy(char *dest,const char *src,size_t n)
551 while (n-- && (*d++ = *src++))
558 Like strncpy but copies up to the character marker. always null terminates.
559 returns a pointer to the character marker in the source string (src).
562 char *strncpyn(char *dest, const char *src, size_t n, char c)
567 p = strchr_m(src, c);
569 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
573 str_len = PTR_DIFF(p, src);
574 strncpy(dest, src, MIN(n, str_len));
575 dest[str_len] = '\0';
581 Routine to get hex characters and turn them into a 16 byte array.
582 the array can be variable length, and any non-hex-numeric
583 characters are skipped. "0xnn" or "0Xnn" is specially catered
586 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
590 size_t strhex_to_str(char *p, size_t len, const char *strhex)
593 size_t num_chars = 0;
594 unsigned char lonybble, hinybble;
595 const char *hexchars = "0123456789ABCDEF";
596 char *p1 = NULL, *p2 = NULL;
598 for (i = 0; i < len && strhex[i] != 0; i++) {
599 if (strnequal(hexchars, "0x", 2)) {
600 i++; /* skip two chars */
604 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
607 i++; /* next hex digit */
609 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
612 /* get the two nybbles */
613 hinybble = PTR_DIFF(p1, hexchars);
614 lonybble = PTR_DIFF(p2, hexchars);
616 p[num_chars] = (hinybble << 4) | lonybble;
626 Check if a string is part of a list.
629 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
637 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
639 if (strcmp(tok,s) == 0)
642 if (StrCaseCmp(tok,s) == 0)
650 Set a string value, allocing the space for the string
652 static BOOL string_init(char **dest,const char *src)
656 (*dest) = strdup(src);
657 if ((*dest) == NULL) {
658 DEBUG(0,("Out of memory in string_init\n"));
667 void string_free(char **s)
669 if (s) SAFE_FREE(*s);
673 Set a string value, deallocating any existing space, and allocing the space
676 BOOL string_set(char **dest, const char *src)
679 return string_init(dest,src);
683 Substitute a string for a pattern in another string. Make sure there is
686 This routine looks for pattern in s and replaces it with
687 insert. It may do multiple replacements.
689 Any of " ; ' $ or ` in the insert string are replaced with _
690 if len==0 then the string cannot be extended. This is different from the old
691 use of len==0 which was for no length checks to be done.
694 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
699 if (!insert || !pattern || !*pattern || !s)
702 ls = (ssize_t)strlen(s);
703 lp = (ssize_t)strlen(pattern);
704 li = (ssize_t)strlen(insert);
707 len = ls + 1; /* len is number of *bytes* */
709 while (lp <= ls && (p = strstr(s,pattern))) {
710 if (ls + (li-lp) >= len) {
711 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
712 (int)(ls + (li-lp) - len),
717 memmove(p+li,p+lp,strlen(p+lp)+1);
740 void pstring_sub(char *s,const char *pattern,const char *insert)
742 string_sub(s, pattern, insert, sizeof(pstring));
746 Similar to string_sub, but it will accept only allocated strings
747 and may realloc them so pay attention at what you pass on no
748 pointers inside strings, no pstrings or const may be passed
752 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
756 ssize_t ls,lp,li,ld, i;
758 if (!insert || !pattern || !*pattern || !string || !*string)
765 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
768 ls = (ssize_t)strlen(s);
769 lp = (ssize_t)strlen(pattern);
770 li = (ssize_t)strlen(insert);
789 while ((p = strstr(s,pattern))) {
791 char *t = Realloc(string, ls + ld + 1);
793 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
801 memmove(p+li,p+lp,strlen(p+lp)+1);
812 Similar to string_sub() but allows for any character to be substituted.
814 if len==0 then the string cannot be extended. This is different from the old
815 use of len==0 which was for no length checks to be done.
818 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
823 if (!insert || !pattern || !s)
826 ls = (ssize_t)strlen(s);
827 lp = (ssize_t)strlen(pattern);
828 li = (ssize_t)strlen(insert);
834 len = ls + 1; /* len is number of *bytes* */
836 while (lp <= ls && (p = strstr(s,pattern))) {
837 if (ls + (li-lp) >= len) {
838 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
839 (int)(ls + (li-lp) - len),
844 memmove(p+li,p+lp,strlen(p+lp)+1);
846 memcpy(p, insert, li);
853 Splits out the front and back at a separator.
856 void split_at_last_component(char *path, char *front, char sep, char *back)
858 char *p = strrchr_m(path, sep);
864 pstrcpy(front, path);
877 Write an octal as a string.
880 const char *octal_string(int i)
885 slprintf(ret, sizeof(ret)-1, "0%o", i);
891 Truncate a string at a specified length.
894 char *string_truncate(char *s, int length)
896 if (s && strlen(s) > length)
902 Strchr and strrchr_m are very hard to do on general multi-byte strings.
903 We convert via ucs2 for now.
906 char *strchr_m(const char *s, char c)
912 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
913 p = strchr_w(ws, UCS2_CHAR(c));
917 pull_ucs2_pstring(s2, ws);
918 return (char *)(s+strlen(s2));
921 char *strrchr_m(const char *s, char c)
927 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
928 p = strrchr_w(ws, UCS2_CHAR(c));
932 pull_ucs2_pstring(s2, ws);
933 return (char *)(s+strlen(s2));
937 Convert a string to lower case.
940 void strlower_m(char *s)
942 /* this is quite a common operation, so we want it to be
943 fast. We optimise for the ascii case, knowing that all our
944 supported multi-byte character sets are ascii-compatible
945 (ie. they match for the first 128 chars) */
947 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
948 *s = tolower((unsigned char)*s);
955 /* I assume that lowercased string takes the same number of bytes
956 * as source string even in UTF-8 encoding. (VIV) */
957 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
961 Duplicate convert a string to lower case.
964 char *strdup_lower(const char *s)
968 DEBUG(0, ("strdup_lower: Out of memory!\n"));
976 Convert a string to upper case.
979 void strupper_m(char *s)
981 /* this is quite a common operation, so we want it to be
982 fast. We optimise for the ascii case, knowing that all our
983 supported multi-byte character sets are ascii-compatible
984 (ie. they match for the first 128 chars) */
986 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
987 *s = toupper((unsigned char)*s);
994 /* I assume that lowercased string takes the same number of bytes
995 * as source string even in multibyte encoding. (VIV) */
996 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1001 work out the number of multibyte chars in a string
1003 size_t strlen_m(const char *s)
1011 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1020 push_ucs2(NULL,tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
1021 return count + strlen_w(tmpbuf);
1025 Work out the number of multibyte chars in a string, including the NULL
1028 size_t strlen_m_term(const char *s)
1034 return strlen_m(s) + 1;
1038 Convert a string to upper case.
1041 char *strdup_upper(const char *s)
1043 char *t = strdup(s);
1045 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1053 Return a RFC2254 binary string representation of a buffer.
1054 Used in LDAP filters.
1058 char *binary_string(char *buf, int len)
1062 const char *hex = "0123456789ABCDEF";
1063 s = malloc(len * 3 + 1);
1066 for (j=i=0;i<len;i++) {
1068 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1069 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1077 Just a typesafety wrapper for snprintf into a pstring.
1080 int pstr_sprintf(pstring s, const char *fmt, ...)
1086 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1091 #ifndef HAVE_STRNDUP
1093 Some platforms don't have strndup.
1095 char *strndup(const char *s, size_t n)
1110 #ifndef HAVE_STRNLEN
1112 Some platforms don't have strnlen
1114 size_t strnlen(const char *s, size_t n)
1117 for (i=0; s[i] && i<n; i++)
1124 List of Strings manipulation functions
1127 #define S_LIST_ABS 16 /* List Allocation Block Size */
1129 char **str_list_make(const char *string, const char *sep)
1131 char **list, **rlist;
1137 if (!string || !*string)
1141 DEBUG(0,("str_list_make: Unable to allocate memory"));
1144 if (!sep) sep = LIST_SEP;
1150 while (next_token(&str, tok, sep, sizeof(tok))) {
1152 lsize += S_LIST_ABS;
1153 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1155 DEBUG(0,("str_list_make: Unable to allocate memory"));
1156 str_list_free(&list);
1161 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1164 list[num] = strdup(tok);
1166 DEBUG(0,("str_list_make: Unable to allocate memory"));
1167 str_list_free(&list);
1179 BOOL str_list_copy(char ***dest, const char **src)
1181 char **list, **rlist;
1193 lsize += S_LIST_ABS;
1194 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1196 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1197 str_list_free(&list);
1201 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1204 list[num] = strdup(src[num]);
1206 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1207 str_list_free(&list);
1219 * Return true if all the elements of the list match exactly.
1221 BOOL str_list_compare(char **list1, char **list2)
1225 if (!list1 || !list2)
1226 return (list1 == list2);
1228 for (num = 0; list1[num]; num++) {
1231 if (!strcsequal(list1[num], list2[num]))
1235 return False; /* if list2 has more elements than list1 fail */
1240 void str_list_free(char ***list)
1244 if (!list || !*list)
1247 for(; *tlist; tlist++)
1252 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1255 ssize_t ls, lp, li, ld, i, d;
1264 lp = (ssize_t)strlen(pattern);
1265 li = (ssize_t)strlen(insert);
1270 ls = (ssize_t)strlen(s);
1272 while ((p = strstr(s, pattern))) {
1276 t = (char *) malloc(ls +ld +1);
1278 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1281 memcpy(t, *list, d);
1282 memcpy(t +d +li, p +lp, ls -d -lp +1);
1289 for (i = 0; i < li; i++) {
1290 switch (insert[i]) {
1302 t[d +i] = insert[i];
1314 #define IPSTR_LIST_SEP ","
1317 * Add ip string representation to ipstr list. Used also
1318 * as part of @function ipstr_list_make
1320 * @param ipstr_list pointer to string containing ip list;
1321 * MUST BE already allocated and IS reallocated if necessary
1322 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1323 * as a result of reallocation)
1324 * @param ip IP address which is to be added to list
1325 * @return pointer to string appended with new ip and possibly
1326 * reallocated to new length
1329 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1331 char* new_ipstr = NULL;
1333 /* arguments checking */
1334 if (!ipstr_list || !ip) return NULL;
1336 /* attempt to convert ip to a string and append colon separator to it */
1338 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1339 SAFE_FREE(*ipstr_list);
1341 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1343 *ipstr_list = new_ipstr;
1349 * Allocate and initialise an ipstr list using ip adresses
1350 * passed as arguments.
1352 * @param ipstr_list pointer to string meant to be allocated and set
1353 * @param ip_list array of ip addresses to place in the list
1354 * @param ip_count number of addresses stored in ip_list
1355 * @return pointer to allocated ip string
1358 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1362 /* arguments checking */
1363 if (!ip_list && !ipstr_list) return 0;
1367 /* process ip addresses given as arguments */
1368 for (i = 0; i < ip_count; i++)
1369 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1371 return (*ipstr_list);
1376 * Parse given ip string list into array of ip addresses
1377 * (as in_addr structures)
1379 * @param ipstr ip string list to be parsed
1380 * @param ip_list pointer to array of ip addresses which is
1381 * allocated by this function and must be freed by caller
1382 * @return number of succesfully parsed addresses
1385 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1390 if (!ipstr_list || !ip_list) return 0;
1392 for (*ip_list = NULL, count = 0;
1393 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1396 struct in_addr addr;
1398 /* convert single token to ip address */
1399 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1402 /* prepare place for another in_addr structure */
1403 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1404 if (!*ip_list) return -1;
1406 (*ip_list)[count] = addr;
1414 * Safely free ip string list
1416 * @param ipstr_list ip string list to be freed
1419 void ipstr_list_free(char* ipstr_list)
1421 SAFE_FREE(ipstr_list);
1426 Unescape a URL encoded string, in place.
1429 void rfc1738_unescape(char *buf)
1433 while ((p=strchr_m(p,'+')))
1438 while (p && *p && (p=strchr_m(p,'%'))) {
1442 if (c1 >= '0' && c1 <= '9')
1444 else if (c1 >= 'A' && c1 <= 'F')
1446 else if (c1 >= 'a' && c1 <= 'f')
1448 else {p++; continue;}
1450 if (c2 >= '0' && c2 <= '9')
1452 else if (c2 >= 'A' && c2 <= 'F')
1454 else if (c2 >= 'a' && c2 <= 'f')
1456 else {p++; continue;}
1460 memmove(p+1, p+3, strlen(p+3)+1);
1465 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1468 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1470 DATA_BLOB base64_decode_data_blob(const char *s)
1472 int bit_offset, byte_offset, idx, i, n;
1473 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1474 unsigned char *d = decoded.data;
1479 while (*s && (p=strchr_m(b64,*s))) {
1480 idx = (int)(p - b64);
1481 byte_offset = (i*6)/8;
1482 bit_offset = (i*6)%8;
1483 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1484 if (bit_offset < 3) {
1485 d[byte_offset] |= (idx << (2-bit_offset));
1488 d[byte_offset] |= (idx >> (bit_offset-2));
1489 d[byte_offset+1] = 0;
1490 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1502 * Decode a base64 string in-place - wrapper for the above
1504 void base64_decode_inplace(char *s)
1506 DATA_BLOB decoded = base64_decode_data_blob(s);
1507 memcpy(s, decoded.data, decoded.length);
1508 data_blob_free(&decoded);
1510 /* null terminate */
1511 s[decoded.length] = '\0';
1515 * Encode a base64 string into a malloc()ed string caller to free.
1517 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1519 char * base64_encode_data_blob(DATA_BLOB data)
1524 size_t len = data.length;
1525 size_t output_len = data.length * 2;
1526 char *result = malloc(output_len); /* get us plenty of space */
1528 while (len-- && out_cnt < (data.length * 2) - 5) {
1529 int c = (unsigned char) *(data.data++);
1532 if (char_count == 3) {
1533 result[out_cnt++] = b64[bits >> 18];
1534 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1535 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1536 result[out_cnt++] = b64[bits & 0x3f];
1543 if (char_count != 0) {
1544 bits <<= 16 - (8 * char_count);
1545 result[out_cnt++] = b64[bits >> 18];
1546 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1547 if (char_count == 1) {
1548 result[out_cnt++] = '=';
1549 result[out_cnt++] = '=';
1551 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1552 result[out_cnt++] = '=';
1555 result[out_cnt] = '\0'; /* terminate */
1560 size_t valgrind_strlen(const char *s)
1563 for(count = 0; *s++; count++)