r104: Fix ntlm_auth by adding the new strhex_to_data_blob() call.
[Samba/gebeck_regimport.git] / source3 / lib / util_str.c
blobe4b07a4b731d04a662d596f2af9cfd00fa45d2b2
1 /*
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.
24 #include "includes.h"
26 /**
27 * @file
28 * @brief String utilities.
29 **/
31 /**
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
37 **/
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
40 char *s;
41 char *pbuf;
42 BOOL quoted;
43 size_t len=1;
45 if (!ptr)
46 return(False);
48 s = (char *)*ptr;
50 /* default to simple separators */
51 if (!sep)
52 sep = " \t\n\r";
54 /* find the first non sep char */
55 while (*s && strchr_m(sep,*s))
56 s++;
58 /* nothing left? */
59 if (! *s)
60 return(False);
62 /* copy over the token */
63 pbuf = buff;
64 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65 if (*s == '\"' || *s == '\'') {
66 quoted = !quoted;
67 } else {
68 len++;
69 *pbuf++ = *s;
73 *ptr = (*s) ? s+1 : s;
74 *pbuf = 0;
76 return(True);
79 /**
80 This is like next_token but is not re-entrant and "remembers" the first
81 parameter so you can pass NULL. This is useful for user interface code
82 but beware the fact that it is not re-entrant!
83 **/
85 static const char *last_ptr=NULL;
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
89 BOOL ret;
90 if (!ptr)
91 ptr = &last_ptr;
93 ret = next_token(ptr, buff, sep, bufsize);
94 last_ptr = *ptr;
95 return ret;
98 static uint16 tmpbuf[sizeof(pstring)];
100 void set_first_token(char *ptr)
102 last_ptr = ptr;
106 Convert list of tokens to array; dependent on above routine.
107 Uses last_ptr from above - bit of a hack.
110 char **toktocliplist(int *ctok, const char *sep)
112 char *s=(char *)last_ptr;
113 int ictok=0;
114 char **ret, **iret;
116 if (!sep)
117 sep = " \t\n\r";
119 while(*s && strchr_m(sep,*s))
120 s++;
122 /* nothing left? */
123 if (!*s)
124 return(NULL);
126 do {
127 ictok++;
128 while(*s && (!strchr_m(sep,*s)))
129 s++;
130 while(*s && strchr_m(sep,*s))
131 *s++=0;
132 } while(*s);
134 *ctok=ictok;
135 s=(char *)last_ptr;
137 if (!(ret=iret=malloc(ictok*sizeof(char *))))
138 return NULL;
140 while(ictok--) {
141 *iret++=s;
142 while(*s++)
144 while(!*s)
145 s++;
148 return ret;
152 * Case insensitive string compararison.
154 * iconv does not directly give us a way to compare strings in
155 * arbitrary unix character sets -- all we can is convert and then
156 * compare. This is expensive.
158 * As an optimization, we do a first pass that considers only the
159 * prefix of the strings that is entirely 7-bit. Within this, we
160 * check whether they have the same value.
162 * Hopefully this will often give the answer without needing to copy.
163 * In particular it should speed comparisons to literal ascii strings
164 * or comparisons of strings that are "obviously" different.
166 * If we find a non-ascii character we fall back to converting via
167 * iconv.
169 * This should never be slower than convering the whole thing, and
170 * often faster.
172 * A different optimization would be to compare for bitwise equality
173 * in the binary encoding. (It would be possible thought hairy to do
174 * both simultaneously.) But in that case if they turn out to be
175 * different, we'd need to restart the whole thing.
177 * Even better is to implement strcasecmp for each encoding and use a
178 * function pointer.
180 int StrCaseCmp(const char *s, const char *t)
183 const char * ps, * pt;
184 size_t size;
185 smb_ucs2_t *buffer_s, *buffer_t;
186 int ret;
188 for (ps = s, pt = t; ; ps++, pt++) {
189 char us, ut;
191 if (!*ps && !*pt)
192 return 0; /* both ended */
193 else if (!*ps)
194 return -1; /* s is a prefix */
195 else if (!*pt)
196 return +1; /* t is a prefix */
197 else if ((*ps & 0x80) || (*pt & 0x80))
198 /* not ascii anymore, do it the hard way from here on in */
199 break;
201 us = toupper(*ps);
202 ut = toupper(*pt);
203 if (us == ut)
204 continue;
205 else if (us < ut)
206 return -1;
207 else if (us > ut)
208 return +1;
211 size = push_ucs2_allocate(&buffer_s, s);
212 if (size == (size_t)-1) {
213 return strcmp(s, t);
214 /* Not quite the right answer, but finding the right one
215 under this failure case is expensive, and it's pretty close */
218 size = push_ucs2_allocate(&buffer_t, t);
219 if (size == (size_t)-1) {
220 SAFE_FREE(buffer_s);
221 return strcmp(s, t);
222 /* Not quite the right answer, but finding the right one
223 under this failure case is expensive, and it's pretty close */
226 ret = strcasecmp_w(buffer_s, buffer_t);
227 SAFE_FREE(buffer_s);
228 SAFE_FREE(buffer_t);
229 return ret;
234 Case insensitive string compararison, length limited.
236 int StrnCaseCmp(const char *s, const char *t, size_t n)
238 pstring buf1, buf2;
239 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
240 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
241 return strncmp(buf1,buf2,n);
245 * Compare 2 strings.
247 * @note The comparison is case-insensitive.
249 BOOL strequal(const char *s1, const char *s2)
251 if (s1 == s2)
252 return(True);
253 if (!s1 || !s2)
254 return(False);
256 return(StrCaseCmp(s1,s2)==0);
260 * Compare 2 strings up to and including the nth char.
262 * @note The comparison is case-insensitive.
264 BOOL strnequal(const char *s1,const char *s2,size_t n)
266 if (s1 == s2)
267 return(True);
268 if (!s1 || !s2 || !n)
269 return(False);
271 return(StrnCaseCmp(s1,s2,n)==0);
275 Compare 2 strings (case sensitive).
278 BOOL strcsequal(const char *s1,const char *s2)
280 if (s1 == s2)
281 return(True);
282 if (!s1 || !s2)
283 return(False);
285 return(strcmp(s1,s2)==0);
289 Do a case-insensitive, whitespace-ignoring string compare.
292 int strwicmp(const char *psz1, const char *psz2)
294 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
295 /* appropriate value. */
296 if (psz1 == psz2)
297 return (0);
298 else if (psz1 == NULL)
299 return (-1);
300 else if (psz2 == NULL)
301 return (1);
303 /* sync the strings on first non-whitespace */
304 while (1) {
305 while (isspace((int)*psz1))
306 psz1++;
307 while (isspace((int)*psz2))
308 psz2++;
309 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
310 || *psz2 == '\0')
311 break;
312 psz1++;
313 psz2++;
315 return (*psz1 - *psz2);
320 Convert a string to upper case, but don't modify it.
323 char *strupper_static(const char *s)
325 static pstring str;
327 pstrcpy(str, s);
328 strupper_m(str);
330 return str;
334 Convert a string to "normal" form.
337 void strnorm(char *s)
339 extern int case_default;
340 if (case_default == CASE_UPPER)
341 strupper_m(s);
342 else
343 strlower_m(s);
347 Check if a string is in "normal" case.
350 BOOL strisnormal(const char *s)
352 extern int case_default;
353 if (case_default == CASE_UPPER)
354 return(!strhaslower(s));
356 return(!strhasupper(s));
361 String replace.
362 NOTE: oldc and newc must be 7 bit characters
365 void string_replace(pstring s,char oldc,char newc)
367 unsigned char *p;
369 /* this is quite a common operation, so we want it to be
370 fast. We optimise for the ascii case, knowing that all our
371 supported multi-byte character sets are ascii-compatible
372 (ie. they match for the first 128 chars) */
374 for (p = (unsigned char *)s; *p; p++) {
375 if (*p & 0x80) /* mb string - slow path. */
376 break;
377 if (*p == oldc)
378 *p = newc;
381 if (!*p)
382 return;
384 /* Slow (mb) path. */
385 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
386 /* With compose characters we must restart from the beginning. JRA. */
387 p = s;
388 #endif
389 push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
390 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
391 pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
395 Skip past some strings in a buffer.
398 char *skip_string(char *buf,size_t n)
400 while (n--)
401 buf += strlen(buf) + 1;
402 return(buf);
406 Count the number of characters in a string. Normally this will
407 be the same as the number of bytes in a string for single byte strings,
408 but will be different for multibyte.
411 size_t str_charnum(const char *s)
413 uint16 tmpbuf2[sizeof(pstring)];
414 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
415 return strlen_w(tmpbuf2);
419 Count the number of characters in a string. Normally this will
420 be the same as the number of bytes in a string for single byte strings,
421 but will be different for multibyte.
424 size_t str_ascii_charnum(const char *s)
426 pstring tmpbuf2;
427 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
428 return strlen(tmpbuf2);
431 BOOL trim_char(char *s,char cfront,char cback)
433 BOOL ret = False;
434 char *ep;
435 char *fp = s;
437 /* Ignore null or empty strings. */
438 if (!s || (s[0] == '\0'))
439 return False;
441 if (cfront) {
442 while (*fp && *fp == cfront)
443 fp++;
444 if (!*fp) {
445 /* We ate the string. */
446 s[0] = '\0';
447 return True;
449 if (fp != s)
450 ret = True;
453 ep = fp + strlen(fp) - 1;
454 if (cback) {
455 /* Attempt ascii only. Bail for mb strings. */
456 while ((ep >= fp) && (*ep == cback)) {
457 ret = True;
458 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
459 /* Could be mb... bail back to tim_string. */
460 char fs[2], bs[2];
461 if (cfront) {
462 fs[0] = cfront;
463 fs[1] = '\0';
465 bs[0] = cback;
466 bs[1] = '\0';
467 return trim_string(s, cfront ? fs : NULL, bs);
468 } else {
469 ep--;
472 if (ep < fp) {
473 /* We ate the string. */
474 s[0] = '\0';
475 return True;
479 ep[1] = '\0';
480 memmove(s, fp, ep-fp+2);
481 return ret;
485 Trim the specified elements off the front and back of a string.
488 BOOL trim_string(char *s,const char *front,const char *back)
490 BOOL ret = False;
491 size_t front_len;
492 size_t back_len;
493 size_t len;
495 /* Ignore null or empty strings. */
496 if (!s || (s[0] == '\0'))
497 return False;
499 front_len = front? strlen(front) : 0;
500 back_len = back? strlen(back) : 0;
502 len = strlen(s);
504 if (front_len) {
505 while (len && strncmp(s, front, front_len)==0) {
506 /* Must use memmove here as src & dest can
507 * easily overlap. Found by valgrind. JRA. */
508 memmove(s, s+front_len, (len-front_len)+1);
509 len -= front_len;
510 ret=True;
514 if (back_len) {
515 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
516 s[len-back_len]='\0';
517 len -= back_len;
518 ret=True;
521 return ret;
525 Does a string have any uppercase chars in it?
528 BOOL strhasupper(const char *s)
530 smb_ucs2_t *ptr;
531 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
532 for(ptr=tmpbuf;*ptr;ptr++)
533 if(isupper_w(*ptr))
534 return True;
535 return(False);
539 Does a string have any lowercase chars in it?
542 BOOL strhaslower(const char *s)
544 smb_ucs2_t *ptr;
545 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
546 for(ptr=tmpbuf;*ptr;ptr++)
547 if(islower_w(*ptr))
548 return True;
549 return(False);
553 Find the number of 'c' chars in a string
556 size_t count_chars(const char *s,char c)
558 smb_ucs2_t *ptr;
559 int count;
560 smb_ucs2_t *alloc_tmpbuf = NULL;
562 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
563 return 0;
566 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
567 if(*ptr==UCS2_CHAR(c))
568 count++;
570 SAFE_FREE(alloc_tmpbuf);
571 return(count);
575 Safe string copy into a known length string. maxlength does not
576 include the terminating zero.
579 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
581 size_t len;
583 if (!dest) {
584 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
585 return NULL;
588 #ifdef DEVELOPER
589 clobber_region(fn,line,dest, maxlength+1);
590 #endif
592 if (!src) {
593 *dest = 0;
594 return dest;
597 len = strnlen(src, maxlength+1);
599 if (len > maxlength) {
600 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
601 (unsigned long)(len-maxlength), (unsigned long)len,
602 (unsigned long)maxlength, src));
603 len = maxlength;
606 memmove(dest, src, len);
607 dest[len] = 0;
608 return dest;
612 Safe string cat into a string. maxlength does not
613 include the terminating zero.
615 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
617 size_t src_len, dest_len;
619 if (!dest) {
620 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
621 return NULL;
624 if (!src)
625 return dest;
627 src_len = strnlen(src, maxlength + 1);
628 dest_len = strnlen(dest, maxlength + 1);
630 #ifdef DEVELOPER
631 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
632 #endif
634 if (src_len + dest_len > maxlength) {
635 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
636 (int)(src_len + dest_len - maxlength), src));
637 if (maxlength > dest_len) {
638 memcpy(&dest[dest_len], src, maxlength - dest_len);
640 dest[maxlength] = 0;
641 return NULL;
644 memcpy(&dest[dest_len], src, src_len);
645 dest[dest_len + src_len] = 0;
646 return dest;
650 Paranoid strcpy into a buffer of given length (includes terminating
651 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
652 and replaces with '_'. Deliberately does *NOT* check for multibyte
653 characters. Don't change it !
655 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
657 size_t len, i;
659 #ifdef DEVELOPER
660 clobber_region(fn, line, dest, maxlength);
661 #endif
663 if (!dest) {
664 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
665 return NULL;
668 if (!src) {
669 *dest = 0;
670 return dest;
673 len = strlen(src);
674 if (len >= maxlength)
675 len = maxlength - 1;
677 if (!other_safe_chars)
678 other_safe_chars = "";
680 for(i = 0; i < len; i++) {
681 int val = (src[i] & 0xff);
682 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
683 dest[i] = src[i];
684 else
685 dest[i] = '_';
688 dest[i] = '\0';
690 return dest;
694 Like strncpy but always null terminates. Make sure there is room!
695 The variable n should always be one less than the available size.
697 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
699 char *d = dest;
701 #ifdef DEVELOPER
702 clobber_region(fn, line, dest, n+1);
703 #endif
705 if (!dest) {
706 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
707 return(NULL);
710 if (!src) {
711 *dest = 0;
712 return(dest);
715 while (n-- && (*d = *src)) {
716 d++;
717 src++;
720 *d = 0;
721 return(dest);
724 #if 0
726 Like strncpy but copies up to the character marker. always null terminates.
727 returns a pointer to the character marker in the source string (src).
730 static char *strncpyn(char *dest, const char *src, size_t n, char c)
732 char *p;
733 size_t str_len;
735 #ifdef DEVELOPER
736 clobber_region(dest, n+1);
737 #endif
738 p = strchr_m(src, c);
739 if (p == NULL) {
740 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
741 return NULL;
744 str_len = PTR_DIFF(p, src);
745 strncpy(dest, src, MIN(n, str_len));
746 dest[str_len] = '\0';
748 return p;
750 #endif
753 Routine to get hex characters and turn them into a 16 byte array.
754 the array can be variable length, and any non-hex-numeric
755 characters are skipped. "0xnn" or "0Xnn" is specially catered
756 for.
758 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
762 size_t strhex_to_str(char *p, size_t len, const char *strhex)
764 size_t i;
765 size_t num_chars = 0;
766 unsigned char lonybble, hinybble;
767 const char *hexchars = "0123456789ABCDEF";
768 char *p1 = NULL, *p2 = NULL;
770 for (i = 0; i < len && strhex[i] != 0; i++) {
771 if (strnequal(hexchars, "0x", 2)) {
772 i++; /* skip two chars */
773 continue;
776 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
777 break;
779 i++; /* next hex digit */
781 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
782 break;
784 /* get the two nybbles */
785 hinybble = PTR_DIFF(p1, hexchars);
786 lonybble = PTR_DIFF(p2, hexchars);
788 p[num_chars] = (hinybble << 4) | lonybble;
789 num_chars++;
791 p1 = NULL;
792 p2 = NULL;
794 return num_chars;
797 DATA_BLOB strhex_to_data_blob(const char *strhex)
799 DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
801 ret_blob.length = strhex_to_str(ret_blob.data,
802 strlen(strhex),
803 strhex);
805 return ret_blob;
809 * Routine to print a buffer as HEX digits, into an allocated string.
812 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
814 int i;
815 char *hex_buffer;
817 *out_hex_buffer = smb_xmalloc((len*2)+1);
818 hex_buffer = *out_hex_buffer;
820 for (i = 0; i < len; i++)
821 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
825 Check if a string is part of a list.
828 BOOL in_list(char *s,char *list,BOOL casesensitive)
830 pstring tok;
831 const char *p=list;
833 if (!list)
834 return(False);
836 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
837 if (casesensitive) {
838 if (strcmp(tok,s) == 0)
839 return(True);
840 } else {
841 if (StrCaseCmp(tok,s) == 0)
842 return(True);
845 return(False);
848 /* this is used to prevent lots of mallocs of size 1 */
849 static char *null_string = NULL;
852 Set a string value, allocing the space for the string
855 static BOOL string_init(char **dest,const char *src)
857 size_t l;
858 if (!src)
859 src = "";
861 l = strlen(src);
863 if (l == 0) {
864 if (!null_string) {
865 if((null_string = (char *)malloc(1)) == NULL) {
866 DEBUG(0,("string_init: malloc fail for null_string.\n"));
867 return False;
869 *null_string = 0;
871 *dest = null_string;
872 } else {
873 (*dest) = strdup(src);
874 if ((*dest) == NULL) {
875 DEBUG(0,("Out of memory in string_init\n"));
876 return False;
879 return(True);
883 Free a string value.
886 void string_free(char **s)
888 if (!s || !(*s))
889 return;
890 if (*s == null_string)
891 *s = NULL;
892 SAFE_FREE(*s);
896 Set a string value, deallocating any existing space, and allocing the space
897 for the string
900 BOOL string_set(char **dest,const char *src)
902 string_free(dest);
903 return(string_init(dest,src));
907 Substitute a string for a pattern in another string. Make sure there is
908 enough room!
910 This routine looks for pattern in s and replaces it with
911 insert. It may do multiple replacements.
913 Any of " ; ' $ or ` in the insert string are replaced with _
914 if len==0 then the string cannot be extended. This is different from the old
915 use of len==0 which was for no length checks to be done.
918 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
920 char *p;
921 ssize_t ls,lp,li, i;
923 if (!insert || !pattern || !*pattern || !s)
924 return;
926 ls = (ssize_t)strlen(s);
927 lp = (ssize_t)strlen(pattern);
928 li = (ssize_t)strlen(insert);
930 if (len == 0)
931 len = ls + 1; /* len is number of *bytes* */
933 while (lp <= ls && (p = strstr_m(s,pattern))) {
934 if (ls + (li-lp) >= len) {
935 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
936 (int)(ls + (li-lp) - len),
937 pattern, (int)len));
938 break;
940 if (li != lp) {
941 memmove(p+li,p+lp,strlen(p+lp)+1);
943 for (i=0;i<li;i++) {
944 switch (insert[i]) {
945 case '`':
946 case '"':
947 case '\'':
948 case ';':
949 case '$':
950 case '%':
951 case '\r':
952 case '\n':
953 p[i] = '_';
954 break;
955 default:
956 p[i] = insert[i];
959 s = p + li;
960 ls += (li-lp);
964 void fstring_sub(char *s,const char *pattern,const char *insert)
966 string_sub(s, pattern, insert, sizeof(fstring));
969 void pstring_sub(char *s,const char *pattern,const char *insert)
971 string_sub(s, pattern, insert, sizeof(pstring));
975 Similar to string_sub, but it will accept only allocated strings
976 and may realloc them so pay attention at what you pass on no
977 pointers inside strings, no pstrings or const may be passed
978 as string.
981 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
983 char *p, *in;
984 char *s;
985 ssize_t ls,lp,li,ld, i;
987 if (!insert || !pattern || !*pattern || !string || !*string)
988 return NULL;
990 s = string;
992 in = strdup(insert);
993 if (!in) {
994 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
995 return NULL;
997 ls = (ssize_t)strlen(s);
998 lp = (ssize_t)strlen(pattern);
999 li = (ssize_t)strlen(insert);
1000 ld = li - lp;
1001 for (i=0;i<li;i++) {
1002 switch (in[i]) {
1003 case '`':
1004 case '"':
1005 case '\'':
1006 case ';':
1007 case '$':
1008 case '%':
1009 case '\r':
1010 case '\n':
1011 in[i] = '_';
1012 default:
1013 /* ok */
1014 break;
1018 while ((p = strstr_m(s,pattern))) {
1019 if (ld > 0) {
1020 int offset = PTR_DIFF(s,string);
1021 char *t = Realloc(string, ls + ld + 1);
1022 if (!t) {
1023 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1024 SAFE_FREE(in);
1025 return NULL;
1027 string = t;
1028 p = t + offset + (p - s);
1030 if (li != lp) {
1031 memmove(p+li,p+lp,strlen(p+lp)+1);
1033 memcpy(p, in, li);
1034 s = p + li;
1035 ls += ld;
1037 SAFE_FREE(in);
1038 return string;
1042 Similar to string_sub() but allows for any character to be substituted.
1043 Use with caution!
1044 if len==0 then the string cannot be extended. This is different from the old
1045 use of len==0 which was for no length checks to be done.
1048 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1050 char *p;
1051 ssize_t ls,lp,li;
1053 if (!insert || !pattern || !s)
1054 return;
1056 ls = (ssize_t)strlen(s);
1057 lp = (ssize_t)strlen(pattern);
1058 li = (ssize_t)strlen(insert);
1060 if (!*pattern)
1061 return;
1063 if (len == 0)
1064 len = ls + 1; /* len is number of *bytes* */
1066 while (lp <= ls && (p = strstr_m(s,pattern))) {
1067 if (ls + (li-lp) >= len) {
1068 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1069 (int)(ls + (li-lp) - len),
1070 pattern, (int)len));
1071 break;
1073 if (li != lp) {
1074 memmove(p+li,p+lp,strlen(p+lp)+1);
1076 memcpy(p, insert, li);
1077 s = p + li;
1078 ls += (li-lp);
1083 Similar to all_string_sub but for unicode strings.
1084 Return a new allocated unicode string.
1085 similar to string_sub() but allows for any character to be substituted.
1086 Use with caution!
1089 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1090 const smb_ucs2_t *insert)
1092 smb_ucs2_t *r, *rp;
1093 const smb_ucs2_t *sp;
1094 size_t lr, lp, li, lt;
1096 if (!insert || !pattern || !*pattern || !s)
1097 return NULL;
1099 lt = (size_t)strlen_w(s);
1100 lp = (size_t)strlen_w(pattern);
1101 li = (size_t)strlen_w(insert);
1103 if (li > lp) {
1104 const smb_ucs2_t *st = s;
1105 int ld = li - lp;
1106 while ((sp = strstr_w(st, pattern))) {
1107 st = sp + lp;
1108 lt += ld;
1112 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1113 if (!r) {
1114 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1115 return NULL;
1118 while ((sp = strstr_w(s, pattern))) {
1119 memcpy(rp, s, (sp - s));
1120 rp += ((sp - s) / sizeof(smb_ucs2_t));
1121 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1122 s = sp + lp;
1123 rp += li;
1125 lr = ((rp - r) / sizeof(smb_ucs2_t));
1126 if (lr < lt) {
1127 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1128 rp += (lt - lr);
1130 *rp = 0;
1132 return r;
1135 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1136 const char *insert)
1138 wpstring p, i;
1140 if (!insert || !pattern || !s)
1141 return NULL;
1142 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1143 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1144 return all_string_sub_w(s, p, i);
1147 #if 0
1149 Splits out the front and back at a separator.
1152 static void split_at_last_component(char *path, char *front, char sep, char *back)
1154 char *p = strrchr_m(path, sep);
1156 if (p != NULL)
1157 *p = 0;
1159 if (front != NULL)
1160 pstrcpy(front, path);
1162 if (p != NULL) {
1163 if (back != NULL)
1164 pstrcpy(back, p+1);
1165 *p = '\\';
1166 } else {
1167 if (back != NULL)
1168 back[0] = 0;
1171 #endif
1174 Write an octal as a string.
1177 const char *octal_string(int i)
1179 static char ret[64];
1180 if (i == -1)
1181 return "-1";
1182 slprintf(ret, sizeof(ret)-1, "0%o", i);
1183 return ret;
1188 Truncate a string at a specified length.
1191 char *string_truncate(char *s, unsigned int length)
1193 if (s && strlen(s) > length)
1194 s[length] = 0;
1195 return s;
1199 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1200 We convert via ucs2 for now.
1203 char *strchr_m(const char *src, char c)
1205 wpstring ws;
1206 pstring s2;
1207 smb_ucs2_t *p;
1208 const char *s;
1210 /* this is quite a common operation, so we want it to be
1211 fast. We optimise for the ascii case, knowing that all our
1212 supported multi-byte character sets are ascii-compatible
1213 (ie. they match for the first 128 chars) */
1215 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1216 if (*s == c)
1217 return (char *)s;
1220 if (!*s)
1221 return NULL;
1223 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1224 /* With compose characters we must restart from the beginning. JRA. */
1225 s = src;
1226 #endif
1228 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1229 p = strchr_w(ws, UCS2_CHAR(c));
1230 if (!p)
1231 return NULL;
1232 *p = 0;
1233 pull_ucs2_pstring(s2, ws);
1234 return (char *)(s+strlen(s2));
1237 char *strrchr_m(const char *s, char c)
1239 /* this is quite a common operation, so we want it to be
1240 fast. We optimise for the ascii case, knowing that all our
1241 supported multi-byte character sets are ascii-compatible
1242 (ie. they match for the first 128 chars). Also, in Samba
1243 we only search for ascii characters in 'c' and that
1244 in all mb character sets with a compound character
1245 containing c, if 'c' is not a match at position
1246 p, then p[-1] > 0x7f. JRA. */
1249 size_t len = strlen(s);
1250 const char *cp = s;
1251 BOOL got_mb = False;
1253 if (len == 0)
1254 return NULL;
1255 cp += (len - 1);
1256 do {
1257 if (c == *cp) {
1258 /* Could be a match. Part of a multibyte ? */
1259 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1260 /* Yep - go slow :-( */
1261 got_mb = True;
1262 break;
1264 /* No - we have a match ! */
1265 return (char *)cp;
1267 } while (cp-- != s);
1268 if (!got_mb)
1269 return NULL;
1272 /* String contained a non-ascii char. Slow path. */
1274 wpstring ws;
1275 pstring s2;
1276 smb_ucs2_t *p;
1278 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1279 p = strrchr_w(ws, UCS2_CHAR(c));
1280 if (!p)
1281 return NULL;
1282 *p = 0;
1283 pull_ucs2_pstring(s2, ws);
1284 return (char *)(s+strlen(s2));
1288 /***********************************************************************
1289 Return the equivalent of doing strrchr 'n' times - always going
1290 backwards.
1291 ***********************************************************************/
1293 char *strnrchr_m(const char *s, char c, unsigned int n)
1295 wpstring ws;
1296 pstring s2;
1297 smb_ucs2_t *p;
1299 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1300 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1301 if (!p)
1302 return NULL;
1303 *p = 0;
1304 pull_ucs2_pstring(s2, ws);
1305 return (char *)(s+strlen(s2));
1308 /***********************************************************************
1309 strstr_m - We convert via ucs2 for now.
1310 ***********************************************************************/
1312 char *strstr_m(const char *src, const char *findstr)
1314 smb_ucs2_t *p;
1315 smb_ucs2_t *src_w, *find_w;
1316 const char *s;
1317 char *s2;
1318 char *retp;
1320 size_t findstr_len = 0;
1322 /* for correctness */
1323 if (!findstr[0]) {
1324 return src;
1327 /* Samba does single character findstr calls a *lot*. */
1328 if (findstr[1] == '\0')
1329 return strchr_m(src, *findstr);
1331 /* We optimise for the ascii case, knowing that all our
1332 supported multi-byte character sets are ascii-compatible
1333 (ie. they match for the first 128 chars) */
1335 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1336 if (*s == *findstr) {
1337 if (!findstr_len)
1338 findstr_len = strlen(findstr);
1340 if (strncmp(s, findstr, findstr_len) == 0) {
1341 return (char *)s;
1346 if (!*s)
1347 return NULL;
1349 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1350 /* 'make check' fails unless we do this */
1352 /* With compose characters we must restart from the beginning. JRA. */
1353 s = src;
1354 #endif
1356 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1357 DEBUG(0,("strstr_m: src malloc fail\n"));
1358 return NULL;
1361 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1362 SAFE_FREE(src_w);
1363 DEBUG(0,("strstr_m: find malloc fail\n"));
1364 return NULL;
1367 p = strstr_w(src_w, find_w);
1369 if (!p) {
1370 SAFE_FREE(src_w);
1371 SAFE_FREE(find_w);
1372 return NULL;
1375 *p = 0;
1376 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1377 SAFE_FREE(src_w);
1378 SAFE_FREE(find_w);
1379 DEBUG(0,("strstr_m: dest malloc fail\n"));
1380 return NULL;
1382 retp = (char *)(s+strlen(s2));
1383 SAFE_FREE(src_w);
1384 SAFE_FREE(find_w);
1385 SAFE_FREE(s2);
1386 return retp;
1390 Convert a string to lower case.
1393 void strlower_m(char *s)
1395 size_t len;
1397 /* this is quite a common operation, so we want it to be
1398 fast. We optimise for the ascii case, knowing that all our
1399 supported multi-byte character sets are ascii-compatible
1400 (ie. they match for the first 128 chars) */
1402 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1403 *s = tolower((unsigned char)*s);
1404 s++;
1407 if (!*s)
1408 return;
1410 /* I assume that lowercased string takes the same number of bytes
1411 * as source string even in UTF-8 encoding. (VIV) */
1412 len = strlen(s) + 1;
1413 errno = 0;
1414 unix_strlower(s,len,s,len);
1415 /* Catch mb conversion errors that may not terminate. */
1416 if (errno)
1417 s[len-1] = '\0';
1421 Convert a string to upper case.
1424 void strupper_m(char *s)
1426 size_t len;
1428 /* this is quite a common operation, so we want it to be
1429 fast. We optimise for the ascii case, knowing that all our
1430 supported multi-byte character sets are ascii-compatible
1431 (ie. they match for the first 128 chars) */
1433 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1434 *s = toupper((unsigned char)*s);
1435 s++;
1438 if (!*s)
1439 return;
1441 /* I assume that lowercased string takes the same number of bytes
1442 * as source string even in multibyte encoding. (VIV) */
1443 len = strlen(s) + 1;
1444 errno = 0;
1445 unix_strupper(s,len,s,len);
1446 /* Catch mb conversion errors that may not terminate. */
1447 if (errno)
1448 s[len-1] = '\0';
1452 Return a RFC2254 binary string representation of a buffer.
1453 Used in LDAP filters.
1454 Caller must free.
1457 char *binary_string(char *buf, int len)
1459 char *s;
1460 int i, j;
1461 const char *hex = "0123456789ABCDEF";
1462 s = malloc(len * 3 + 1);
1463 if (!s)
1464 return NULL;
1465 for (j=i=0;i<len;i++) {
1466 s[j] = '\\';
1467 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1468 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1469 j += 3;
1471 s[j] = 0;
1472 return s;
1476 Just a typesafety wrapper for snprintf into a pstring.
1479 int pstr_sprintf(pstring s, const char *fmt, ...)
1481 va_list ap;
1482 int ret;
1484 va_start(ap, fmt);
1485 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1486 va_end(ap);
1487 return ret;
1492 Just a typesafety wrapper for snprintf into a fstring.
1495 int fstr_sprintf(fstring s, const char *fmt, ...)
1497 va_list ap;
1498 int ret;
1500 va_start(ap, fmt);
1501 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1502 va_end(ap);
1503 return ret;
1507 #ifndef HAVE_STRNDUP
1509 Some platforms don't have strndup.
1512 char *strndup(const char *s, size_t n)
1514 char *ret;
1516 n = strnlen(s, n);
1517 ret = malloc(n+1);
1518 if (!ret)
1519 return NULL;
1520 memcpy(ret, s, n);
1521 ret[n] = 0;
1523 return ret;
1525 #endif
1527 #ifndef HAVE_STRNLEN
1529 Some platforms don't have strnlen
1532 size_t strnlen(const char *s, size_t n)
1534 int i;
1535 for (i=0; s[i] && i<n; i++)
1536 /* noop */ ;
1537 return i;
1539 #endif
1542 List of Strings manipulation functions
1545 #define S_LIST_ABS 16 /* List Allocation Block Size */
1547 char **str_list_make(const char *string, const char *sep)
1549 char **list, **rlist;
1550 const char *str;
1551 char *s;
1552 int num, lsize;
1553 pstring tok;
1555 if (!string || !*string)
1556 return NULL;
1557 s = strdup(string);
1558 if (!s) {
1559 DEBUG(0,("str_list_make: Unable to allocate memory"));
1560 return NULL;
1562 if (!sep) sep = LIST_SEP;
1564 num = lsize = 0;
1565 list = NULL;
1567 str = s;
1568 while (next_token(&str, tok, sep, sizeof(tok))) {
1569 if (num == lsize) {
1570 lsize += S_LIST_ABS;
1571 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1572 if (!rlist) {
1573 DEBUG(0,("str_list_make: Unable to allocate memory"));
1574 str_list_free(&list);
1575 SAFE_FREE(s);
1576 return NULL;
1577 } else
1578 list = rlist;
1579 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1582 list[num] = strdup(tok);
1583 if (!list[num]) {
1584 DEBUG(0,("str_list_make: Unable to allocate memory"));
1585 str_list_free(&list);
1586 SAFE_FREE(s);
1587 return NULL;
1590 num++;
1593 SAFE_FREE(s);
1594 return list;
1597 BOOL str_list_copy(char ***dest, const char **src)
1599 char **list, **rlist;
1600 int num, lsize;
1602 *dest = NULL;
1603 if (!src)
1604 return False;
1606 num = lsize = 0;
1607 list = NULL;
1609 while (src[num]) {
1610 if (num == lsize) {
1611 lsize += S_LIST_ABS;
1612 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1613 if (!rlist) {
1614 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1615 str_list_free(&list);
1616 return False;
1617 } else
1618 list = rlist;
1619 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1622 list[num] = strdup(src[num]);
1623 if (!list[num]) {
1624 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1625 str_list_free(&list);
1626 return False;
1629 num++;
1632 *dest = list;
1633 return True;
1637 * Return true if all the elements of the list match exactly.
1639 BOOL str_list_compare(char **list1, char **list2)
1641 int num;
1643 if (!list1 || !list2)
1644 return (list1 == list2);
1646 for (num = 0; list1[num]; num++) {
1647 if (!list2[num])
1648 return False;
1649 if (!strcsequal(list1[num], list2[num]))
1650 return False;
1652 if (list2[num])
1653 return False; /* if list2 has more elements than list1 fail */
1655 return True;
1658 void str_list_free(char ***list)
1660 char **tlist;
1662 if (!list || !*list)
1663 return;
1664 tlist = *list;
1665 for(; *tlist; tlist++)
1666 SAFE_FREE(*tlist);
1667 SAFE_FREE(*list);
1670 /******************************************************************************
1671 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1672 for the work
1673 *****************************************************************************/
1675 BOOL str_list_sub_basic( char **list, const char *smb_name )
1677 char *s, *tmpstr;
1679 while ( *list ) {
1680 s = *list;
1681 tmpstr = alloc_sub_basic(smb_name, s);
1682 if ( !tmpstr ) {
1683 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1684 return False;
1687 *list = tmpstr;
1689 list++;
1692 return True;
1695 /******************************************************************************
1696 substritute a specific pattern in a string list
1697 *****************************************************************************/
1699 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1701 char *p, *s, *t;
1702 ssize_t ls, lp, li, ld, i, d;
1704 if (!list)
1705 return False;
1706 if (!pattern)
1707 return False;
1708 if (!insert)
1709 return False;
1711 lp = (ssize_t)strlen(pattern);
1712 li = (ssize_t)strlen(insert);
1713 ld = li -lp;
1715 while (*list) {
1716 s = *list;
1717 ls = (ssize_t)strlen(s);
1719 while ((p = strstr_m(s, pattern))) {
1720 t = *list;
1721 d = p -t;
1722 if (ld) {
1723 t = (char *) malloc(ls +ld +1);
1724 if (!t) {
1725 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1726 return False;
1728 memcpy(t, *list, d);
1729 memcpy(t +d +li, p +lp, ls -d -lp +1);
1730 SAFE_FREE(*list);
1731 *list = t;
1732 ls += ld;
1733 s = t +d +li;
1736 for (i = 0; i < li; i++) {
1737 switch (insert[i]) {
1738 case '`':
1739 case '"':
1740 case '\'':
1741 case ';':
1742 case '$':
1743 case '%':
1744 case '\r':
1745 case '\n':
1746 t[d +i] = '_';
1747 break;
1748 default:
1749 t[d +i] = insert[i];
1755 list++;
1758 return True;
1762 #define IPSTR_LIST_SEP ","
1763 #define IPSTR_LIST_CHAR ','
1766 * Add ip string representation to ipstr list. Used also
1767 * as part of @function ipstr_list_make
1769 * @param ipstr_list pointer to string containing ip list;
1770 * MUST BE already allocated and IS reallocated if necessary
1771 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1772 * as a result of reallocation)
1773 * @param ip IP address which is to be added to list
1774 * @return pointer to string appended with new ip and possibly
1775 * reallocated to new length
1778 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1780 char* new_ipstr = NULL;
1782 /* arguments checking */
1783 if (!ipstr_list || !service) return NULL;
1785 /* attempt to convert ip to a string and append colon separator to it */
1786 if (*ipstr_list) {
1787 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1788 inet_ntoa(service->ip), service->port);
1789 SAFE_FREE(*ipstr_list);
1790 } else {
1791 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1793 *ipstr_list = new_ipstr;
1794 return *ipstr_list;
1799 * Allocate and initialise an ipstr list using ip adresses
1800 * passed as arguments.
1802 * @param ipstr_list pointer to string meant to be allocated and set
1803 * @param ip_list array of ip addresses to place in the list
1804 * @param ip_count number of addresses stored in ip_list
1805 * @return pointer to allocated ip string
1808 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1810 int i;
1812 /* arguments checking */
1813 if (!ip_list && !ipstr_list) return 0;
1815 *ipstr_list = NULL;
1817 /* process ip addresses given as arguments */
1818 for (i = 0; i < ip_count; i++)
1819 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1821 return (*ipstr_list);
1826 * Parse given ip string list into array of ip addresses
1827 * (as ip_service structures)
1828 * e.g. 192.168.1.100:389,192.168.1.78, ...
1830 * @param ipstr ip string list to be parsed
1831 * @param ip_list pointer to array of ip addresses which is
1832 * allocated by this function and must be freed by caller
1833 * @return number of succesfully parsed addresses
1836 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1838 fstring token_str;
1839 size_t count;
1840 int i;
1842 if (!ipstr_list || !ip_list)
1843 return 0;
1845 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1846 if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1847 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1848 return 0;
1851 for ( i=0;
1852 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1853 i++ )
1855 struct in_addr addr;
1856 unsigned port = 0;
1857 char *p = strchr(token_str, ':');
1859 if (p) {
1860 *p = 0;
1861 port = atoi(p+1);
1864 /* convert single token to ip address */
1865 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1866 break;
1868 (*ip_list)[i].ip = addr;
1869 (*ip_list)[i].port = port;
1872 return count;
1877 * Safely free ip string list
1879 * @param ipstr_list ip string list to be freed
1882 void ipstr_list_free(char* ipstr_list)
1884 SAFE_FREE(ipstr_list);
1889 Unescape a URL encoded string, in place.
1892 void rfc1738_unescape(char *buf)
1894 char *p=buf;
1896 while (p && *p && (p=strchr_m(p,'%'))) {
1897 int c1 = p[1];
1898 int c2 = p[2];
1900 if (c1 >= '0' && c1 <= '9')
1901 c1 = c1 - '0';
1902 else if (c1 >= 'A' && c1 <= 'F')
1903 c1 = 10 + c1 - 'A';
1904 else if (c1 >= 'a' && c1 <= 'f')
1905 c1 = 10 + c1 - 'a';
1906 else {p++; continue;}
1908 if (c2 >= '0' && c2 <= '9')
1909 c2 = c2 - '0';
1910 else if (c2 >= 'A' && c2 <= 'F')
1911 c2 = 10 + c2 - 'A';
1912 else if (c2 >= 'a' && c2 <= 'f')
1913 c2 = 10 + c2 - 'a';
1914 else {p++; continue;}
1916 *p = (c1<<4) | c2;
1918 memmove(p+1, p+3, strlen(p+3)+1);
1919 p++;
1923 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1926 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1928 DATA_BLOB base64_decode_data_blob(const char *s)
1930 int bit_offset, byte_offset, idx, i, n;
1931 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1932 unsigned char *d = decoded.data;
1933 char *p;
1935 n=i=0;
1937 while (*s && (p=strchr_m(b64,*s))) {
1938 idx = (int)(p - b64);
1939 byte_offset = (i*6)/8;
1940 bit_offset = (i*6)%8;
1941 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1942 if (bit_offset < 3) {
1943 d[byte_offset] |= (idx << (2-bit_offset));
1944 n = byte_offset+1;
1945 } else {
1946 d[byte_offset] |= (idx >> (bit_offset-2));
1947 d[byte_offset+1] = 0;
1948 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1949 n = byte_offset+2;
1951 s++; i++;
1954 if (*s == '=') n -= 1;
1956 /* fix up length */
1957 decoded.length = n;
1958 return decoded;
1962 * Decode a base64 string in-place - wrapper for the above
1964 void base64_decode_inplace(char *s)
1966 DATA_BLOB decoded = base64_decode_data_blob(s);
1967 memcpy(s, decoded.data, decoded.length);
1968 /* null terminate */
1969 s[decoded.length] = '\0';
1971 data_blob_free(&decoded);
1975 * Encode a base64 string into a malloc()ed string caller to free.
1977 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1979 char * base64_encode_data_blob(DATA_BLOB data)
1981 int bits = 0;
1982 int char_count = 0;
1983 size_t out_cnt = 0;
1984 size_t len = data.length;
1985 size_t output_len = data.length * 2;
1986 char *result = malloc(output_len); /* get us plenty of space */
1988 while (len-- && out_cnt < (data.length * 2) - 5) {
1989 int c = (unsigned char) *(data.data++);
1990 bits += c;
1991 char_count++;
1992 if (char_count == 3) {
1993 result[out_cnt++] = b64[bits >> 18];
1994 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1995 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1996 result[out_cnt++] = b64[bits & 0x3f];
1997 bits = 0;
1998 char_count = 0;
1999 } else {
2000 bits <<= 8;
2003 if (char_count != 0) {
2004 bits <<= 16 - (8 * char_count);
2005 result[out_cnt++] = b64[bits >> 18];
2006 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2007 if (char_count == 1) {
2008 result[out_cnt++] = '=';
2009 result[out_cnt++] = '=';
2010 } else {
2011 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2012 result[out_cnt++] = '=';
2015 result[out_cnt] = '\0'; /* terminate */
2016 return result;
2019 /* read a SMB_BIG_UINT from a string */
2020 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2023 SMB_BIG_UINT val = -1;
2024 const char *p = nptr;
2026 while (p && *p && isspace(*p))
2027 p++;
2028 #ifdef LARGE_SMB_OFF_T
2029 sscanf(p,"%llu",&val);
2030 #else /* LARGE_SMB_OFF_T */
2031 sscanf(p,"%lu",&val);
2032 #endif /* LARGE_SMB_OFF_T */
2033 if (entptr) {
2034 while (p && *p && isdigit(*p))
2035 p++;
2036 *entptr = p;
2039 return val;