JRA's recent strstr_m work really badly broke our string_sub code.
[Samba.git] / source / lib / util_str.c
blob7f3c30f61e400c2f99cc6999e95acfea8c040ef6
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;
798 * Routine to print a buffer as HEX digits, into an allocated string.
801 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
803 int i;
804 char *hex_buffer;
806 *out_hex_buffer = smb_xmalloc((len*2)+1);
807 hex_buffer = *out_hex_buffer;
809 for (i = 0; i < len; i++)
810 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
814 Check if a string is part of a list.
817 BOOL in_list(char *s,char *list,BOOL casesensitive)
819 pstring tok;
820 const char *p=list;
822 if (!list)
823 return(False);
825 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
826 if (casesensitive) {
827 if (strcmp(tok,s) == 0)
828 return(True);
829 } else {
830 if (StrCaseCmp(tok,s) == 0)
831 return(True);
834 return(False);
837 /* this is used to prevent lots of mallocs of size 1 */
838 static char *null_string = NULL;
841 Set a string value, allocing the space for the string
844 static BOOL string_init(char **dest,const char *src)
846 size_t l;
847 if (!src)
848 src = "";
850 l = strlen(src);
852 if (l == 0) {
853 if (!null_string) {
854 if((null_string = (char *)malloc(1)) == NULL) {
855 DEBUG(0,("string_init: malloc fail for null_string.\n"));
856 return False;
858 *null_string = 0;
860 *dest = null_string;
861 } else {
862 (*dest) = strdup(src);
863 if ((*dest) == NULL) {
864 DEBUG(0,("Out of memory in string_init\n"));
865 return False;
868 return(True);
872 Free a string value.
875 void string_free(char **s)
877 if (!s || !(*s))
878 return;
879 if (*s == null_string)
880 *s = NULL;
881 SAFE_FREE(*s);
885 Set a string value, deallocating any existing space, and allocing the space
886 for the string
889 BOOL string_set(char **dest,const char *src)
891 string_free(dest);
892 return(string_init(dest,src));
896 Substitute a string for a pattern in another string. Make sure there is
897 enough room!
899 This routine looks for pattern in s and replaces it with
900 insert. It may do multiple replacements.
902 Any of " ; ' $ or ` in the insert string are replaced with _
903 if len==0 then the string cannot be extended. This is different from the old
904 use of len==0 which was for no length checks to be done.
907 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
909 char *p;
910 ssize_t ls,lp,li, i;
912 if (!insert || !pattern || !*pattern || !s)
913 return;
915 ls = (ssize_t)strlen(s);
916 lp = (ssize_t)strlen(pattern);
917 li = (ssize_t)strlen(insert);
919 if (len == 0)
920 len = ls + 1; /* len is number of *bytes* */
922 while (lp <= ls && (p = strstr_m(s,pattern))) {
923 if (ls + (li-lp) >= len) {
924 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
925 (int)(ls + (li-lp) - len),
926 pattern, (int)len));
927 break;
929 if (li != lp) {
930 memmove(p+li,p+lp,strlen(p+lp)+1);
932 for (i=0;i<li;i++) {
933 switch (insert[i]) {
934 case '`':
935 case '"':
936 case '\'':
937 case ';':
938 case '$':
939 case '%':
940 case '\r':
941 case '\n':
942 p[i] = '_';
943 break;
944 default:
945 p[i] = insert[i];
948 s = p + li;
949 ls += (li-lp);
953 void fstring_sub(char *s,const char *pattern,const char *insert)
955 string_sub(s, pattern, insert, sizeof(fstring));
958 void pstring_sub(char *s,const char *pattern,const char *insert)
960 string_sub(s, pattern, insert, sizeof(pstring));
964 Similar to string_sub, but it will accept only allocated strings
965 and may realloc them so pay attention at what you pass on no
966 pointers inside strings, no pstrings or const may be passed
967 as string.
970 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
972 char *p, *in;
973 char *s;
974 ssize_t ls,lp,li,ld, i;
976 if (!insert || !pattern || !*pattern || !string || !*string)
977 return NULL;
979 s = string;
981 in = strdup(insert);
982 if (!in) {
983 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
984 return NULL;
986 ls = (ssize_t)strlen(s);
987 lp = (ssize_t)strlen(pattern);
988 li = (ssize_t)strlen(insert);
989 ld = li - lp;
990 for (i=0;i<li;i++) {
991 switch (in[i]) {
992 case '`':
993 case '"':
994 case '\'':
995 case ';':
996 case '$':
997 case '%':
998 case '\r':
999 case '\n':
1000 in[i] = '_';
1001 default:
1002 /* ok */
1003 break;
1007 while ((p = strstr_m(s,pattern))) {
1008 if (ld > 0) {
1009 int offset = PTR_DIFF(s,string);
1010 char *t = Realloc(string, ls + ld + 1);
1011 if (!t) {
1012 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1013 SAFE_FREE(in);
1014 return NULL;
1016 string = t;
1017 p = t + offset + (p - s);
1019 if (li != lp) {
1020 memmove(p+li,p+lp,strlen(p+lp)+1);
1022 memcpy(p, in, li);
1023 s = p + li;
1024 ls += ld;
1026 SAFE_FREE(in);
1027 return string;
1031 Similar to string_sub() but allows for any character to be substituted.
1032 Use with caution!
1033 if len==0 then the string cannot be extended. This is different from the old
1034 use of len==0 which was for no length checks to be done.
1037 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1039 char *p;
1040 ssize_t ls,lp,li;
1042 if (!insert || !pattern || !s)
1043 return;
1045 ls = (ssize_t)strlen(s);
1046 lp = (ssize_t)strlen(pattern);
1047 li = (ssize_t)strlen(insert);
1049 if (!*pattern)
1050 return;
1052 if (len == 0)
1053 len = ls + 1; /* len is number of *bytes* */
1055 while (lp <= ls && (p = strstr_m(s,pattern))) {
1056 if (ls + (li-lp) >= len) {
1057 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1058 (int)(ls + (li-lp) - len),
1059 pattern, (int)len));
1060 break;
1062 if (li != lp) {
1063 memmove(p+li,p+lp,strlen(p+lp)+1);
1065 memcpy(p, insert, li);
1066 s = p + li;
1067 ls += (li-lp);
1072 Similar to all_string_sub but for unicode strings.
1073 Return a new allocated unicode string.
1074 similar to string_sub() but allows for any character to be substituted.
1075 Use with caution!
1078 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1079 const smb_ucs2_t *insert)
1081 smb_ucs2_t *r, *rp;
1082 const smb_ucs2_t *sp;
1083 size_t lr, lp, li, lt;
1085 if (!insert || !pattern || !*pattern || !s)
1086 return NULL;
1088 lt = (size_t)strlen_w(s);
1089 lp = (size_t)strlen_w(pattern);
1090 li = (size_t)strlen_w(insert);
1092 if (li > lp) {
1093 const smb_ucs2_t *st = s;
1094 int ld = li - lp;
1095 while ((sp = strstr_w(st, pattern))) {
1096 st = sp + lp;
1097 lt += ld;
1101 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1102 if (!r) {
1103 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1104 return NULL;
1107 while ((sp = strstr_w(s, pattern))) {
1108 memcpy(rp, s, (sp - s));
1109 rp += ((sp - s) / sizeof(smb_ucs2_t));
1110 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1111 s = sp + lp;
1112 rp += li;
1114 lr = ((rp - r) / sizeof(smb_ucs2_t));
1115 if (lr < lt) {
1116 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1117 rp += (lt - lr);
1119 *rp = 0;
1121 return r;
1124 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1125 const char *insert)
1127 wpstring p, i;
1129 if (!insert || !pattern || !s)
1130 return NULL;
1131 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1132 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1133 return all_string_sub_w(s, p, i);
1136 #if 0
1138 Splits out the front and back at a separator.
1141 static void split_at_last_component(char *path, char *front, char sep, char *back)
1143 char *p = strrchr_m(path, sep);
1145 if (p != NULL)
1146 *p = 0;
1148 if (front != NULL)
1149 pstrcpy(front, path);
1151 if (p != NULL) {
1152 if (back != NULL)
1153 pstrcpy(back, p+1);
1154 *p = '\\';
1155 } else {
1156 if (back != NULL)
1157 back[0] = 0;
1160 #endif
1163 Write an octal as a string.
1166 const char *octal_string(int i)
1168 static char ret[64];
1169 if (i == -1)
1170 return "-1";
1171 slprintf(ret, sizeof(ret)-1, "0%o", i);
1172 return ret;
1177 Truncate a string at a specified length.
1180 char *string_truncate(char *s, unsigned int length)
1182 if (s && strlen(s) > length)
1183 s[length] = 0;
1184 return s;
1188 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1189 We convert via ucs2 for now.
1192 char *strchr_m(const char *src, char c)
1194 wpstring ws;
1195 pstring s2;
1196 smb_ucs2_t *p;
1197 const char *s;
1199 /* this is quite a common operation, so we want it to be
1200 fast. We optimise for the ascii case, knowing that all our
1201 supported multi-byte character sets are ascii-compatible
1202 (ie. they match for the first 128 chars) */
1204 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1205 if (*s == c)
1206 return (char *)s;
1209 if (!*s)
1210 return NULL;
1212 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1213 /* With compose characters we must restart from the beginning. JRA. */
1214 s = src;
1215 #endif
1217 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1218 p = strchr_w(ws, UCS2_CHAR(c));
1219 if (!p)
1220 return NULL;
1221 *p = 0;
1222 pull_ucs2_pstring(s2, ws);
1223 return (char *)(s+strlen(s2));
1226 char *strrchr_m(const char *s, char c)
1228 /* this is quite a common operation, so we want it to be
1229 fast. We optimise for the ascii case, knowing that all our
1230 supported multi-byte character sets are ascii-compatible
1231 (ie. they match for the first 128 chars). Also, in Samba
1232 we only search for ascii characters in 'c' and that
1233 in all mb character sets with a compound character
1234 containing c, if 'c' is not a match at position
1235 p, then p[-1] > 0x7f. JRA. */
1238 size_t len = strlen(s);
1239 const char *cp = s;
1240 BOOL got_mb = False;
1242 if (len == 0)
1243 return NULL;
1244 cp += (len - 1);
1245 do {
1246 if (c == *cp) {
1247 /* Could be a match. Part of a multibyte ? */
1248 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1249 /* Yep - go slow :-( */
1250 got_mb = True;
1251 break;
1253 /* No - we have a match ! */
1254 return (char *)cp;
1256 } while (cp-- != s);
1257 if (!got_mb)
1258 return NULL;
1261 /* String contained a non-ascii char. Slow path. */
1263 wpstring ws;
1264 pstring s2;
1265 smb_ucs2_t *p;
1267 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1268 p = strrchr_w(ws, UCS2_CHAR(c));
1269 if (!p)
1270 return NULL;
1271 *p = 0;
1272 pull_ucs2_pstring(s2, ws);
1273 return (char *)(s+strlen(s2));
1277 /***********************************************************************
1278 Return the equivalent of doing strrchr 'n' times - always going
1279 backwards.
1280 ***********************************************************************/
1282 char *strnrchr_m(const char *s, char c, unsigned int n)
1284 wpstring ws;
1285 pstring s2;
1286 smb_ucs2_t *p;
1288 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1289 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1290 if (!p)
1291 return NULL;
1292 *p = 0;
1293 pull_ucs2_pstring(s2, ws);
1294 return (char *)(s+strlen(s2));
1297 /***********************************************************************
1298 strstr_m - We convert via ucs2 for now.
1299 ***********************************************************************/
1301 char *strstr_m(const char *src, const char *findstr)
1303 smb_ucs2_t *p;
1304 smb_ucs2_t *src_w, *find_w;
1305 const char *s;
1306 char *s2;
1307 char *retp;
1309 size_t findstr_len = 0;
1310 size_t find_w_len;
1312 /* Samba does single character findstr calls a *lot*. */
1313 if (findstr[1] == '\0')
1314 return strchr_m(src, *findstr);
1316 /* We optimise for the ascii case, knowing that all our
1317 supported multi-byte character sets are ascii-compatible
1318 (ie. they match for the first 128 chars) */
1320 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1321 if (*s == *findstr) {
1322 if (!findstr_len)
1323 findstr_len = strlen(findstr);
1325 if (strncmp(s, findstr, findstr_len) == 0) {
1326 return (char *)s;
1331 if (!*s)
1332 return NULL;
1334 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1335 /* With compose characters we must restart from the beginning. JRA. */
1336 s = src;
1337 #endif
1339 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1340 DEBUG(0,("strstr_m: src malloc fail\n"));
1341 return NULL;
1344 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1345 SAFE_FREE(src_w);
1346 DEBUG(0,("strstr_m: find malloc fail\n"));
1347 return NULL;
1350 find_w_len = strlen_w(find_w);
1352 for (p = src_w; (p = strchr_w(p, *find_w)) != NULL; p++) {
1353 if (strncmp_w(p, find_w, find_w_len) == 0)
1354 break;
1356 if (!p) {
1357 SAFE_FREE(src_w);
1358 SAFE_FREE(find_w);
1359 return NULL;
1361 *p = 0;
1362 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1363 SAFE_FREE(src_w);
1364 SAFE_FREE(find_w);
1365 DEBUG(0,("strstr_m: dest malloc fail\n"));
1366 return NULL;
1368 retp = (char *)(s+strlen(s2));
1369 SAFE_FREE(src_w);
1370 SAFE_FREE(find_w);
1371 SAFE_FREE(s2);
1372 return retp;
1376 Convert a string to lower case.
1379 void strlower_m(char *s)
1381 size_t len;
1383 /* this is quite a common operation, so we want it to be
1384 fast. We optimise for the ascii case, knowing that all our
1385 supported multi-byte character sets are ascii-compatible
1386 (ie. they match for the first 128 chars) */
1388 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1389 *s = tolower((unsigned char)*s);
1390 s++;
1393 if (!*s)
1394 return;
1396 /* I assume that lowercased string takes the same number of bytes
1397 * as source string even in UTF-8 encoding. (VIV) */
1398 len = strlen(s) + 1;
1399 errno = 0;
1400 unix_strlower(s,len,s,len);
1401 /* Catch mb conversion errors that may not terminate. */
1402 if (errno)
1403 s[len-1] = '\0';
1407 Convert a string to upper case.
1410 void strupper_m(char *s)
1412 size_t len;
1414 /* this is quite a common operation, so we want it to be
1415 fast. We optimise for the ascii case, knowing that all our
1416 supported multi-byte character sets are ascii-compatible
1417 (ie. they match for the first 128 chars) */
1419 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1420 *s = toupper((unsigned char)*s);
1421 s++;
1424 if (!*s)
1425 return;
1427 /* I assume that lowercased string takes the same number of bytes
1428 * as source string even in multibyte encoding. (VIV) */
1429 len = strlen(s) + 1;
1430 errno = 0;
1431 unix_strupper(s,len,s,len);
1432 /* Catch mb conversion errors that may not terminate. */
1433 if (errno)
1434 s[len-1] = '\0';
1438 Return a RFC2254 binary string representation of a buffer.
1439 Used in LDAP filters.
1440 Caller must free.
1443 char *binary_string(char *buf, int len)
1445 char *s;
1446 int i, j;
1447 const char *hex = "0123456789ABCDEF";
1448 s = malloc(len * 3 + 1);
1449 if (!s)
1450 return NULL;
1451 for (j=i=0;i<len;i++) {
1452 s[j] = '\\';
1453 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1454 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1455 j += 3;
1457 s[j] = 0;
1458 return s;
1462 Just a typesafety wrapper for snprintf into a pstring.
1465 int pstr_sprintf(pstring s, const char *fmt, ...)
1467 va_list ap;
1468 int ret;
1470 va_start(ap, fmt);
1471 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1472 va_end(ap);
1473 return ret;
1478 Just a typesafety wrapper for snprintf into a fstring.
1481 int fstr_sprintf(fstring s, const char *fmt, ...)
1483 va_list ap;
1484 int ret;
1486 va_start(ap, fmt);
1487 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1488 va_end(ap);
1489 return ret;
1493 #ifndef HAVE_STRNDUP
1495 Some platforms don't have strndup.
1498 char *strndup(const char *s, size_t n)
1500 char *ret;
1502 n = strnlen(s, n);
1503 ret = malloc(n+1);
1504 if (!ret)
1505 return NULL;
1506 memcpy(ret, s, n);
1507 ret[n] = 0;
1509 return ret;
1511 #endif
1513 #ifndef HAVE_STRNLEN
1515 Some platforms don't have strnlen
1518 size_t strnlen(const char *s, size_t n)
1520 int i;
1521 for (i=0; s[i] && i<n; i++)
1522 /* noop */ ;
1523 return i;
1525 #endif
1528 List of Strings manipulation functions
1531 #define S_LIST_ABS 16 /* List Allocation Block Size */
1533 char **str_list_make(const char *string, const char *sep)
1535 char **list, **rlist;
1536 const char *str;
1537 char *s;
1538 int num, lsize;
1539 pstring tok;
1541 if (!string || !*string)
1542 return NULL;
1543 s = strdup(string);
1544 if (!s) {
1545 DEBUG(0,("str_list_make: Unable to allocate memory"));
1546 return NULL;
1548 if (!sep) sep = LIST_SEP;
1550 num = lsize = 0;
1551 list = NULL;
1553 str = s;
1554 while (next_token(&str, tok, sep, sizeof(tok))) {
1555 if (num == lsize) {
1556 lsize += S_LIST_ABS;
1557 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1558 if (!rlist) {
1559 DEBUG(0,("str_list_make: Unable to allocate memory"));
1560 str_list_free(&list);
1561 SAFE_FREE(s);
1562 return NULL;
1563 } else
1564 list = rlist;
1565 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1568 list[num] = strdup(tok);
1569 if (!list[num]) {
1570 DEBUG(0,("str_list_make: Unable to allocate memory"));
1571 str_list_free(&list);
1572 SAFE_FREE(s);
1573 return NULL;
1576 num++;
1579 SAFE_FREE(s);
1580 return list;
1583 BOOL str_list_copy(char ***dest, const char **src)
1585 char **list, **rlist;
1586 int num, lsize;
1588 *dest = NULL;
1589 if (!src)
1590 return False;
1592 num = lsize = 0;
1593 list = NULL;
1595 while (src[num]) {
1596 if (num == lsize) {
1597 lsize += S_LIST_ABS;
1598 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1599 if (!rlist) {
1600 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1601 str_list_free(&list);
1602 return False;
1603 } else
1604 list = rlist;
1605 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1608 list[num] = strdup(src[num]);
1609 if (!list[num]) {
1610 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1611 str_list_free(&list);
1612 return False;
1615 num++;
1618 *dest = list;
1619 return True;
1623 * Return true if all the elements of the list match exactly.
1625 BOOL str_list_compare(char **list1, char **list2)
1627 int num;
1629 if (!list1 || !list2)
1630 return (list1 == list2);
1632 for (num = 0; list1[num]; num++) {
1633 if (!list2[num])
1634 return False;
1635 if (!strcsequal(list1[num], list2[num]))
1636 return False;
1638 if (list2[num])
1639 return False; /* if list2 has more elements than list1 fail */
1641 return True;
1644 void str_list_free(char ***list)
1646 char **tlist;
1648 if (!list || !*list)
1649 return;
1650 tlist = *list;
1651 for(; *tlist; tlist++)
1652 SAFE_FREE(*tlist);
1653 SAFE_FREE(*list);
1656 /******************************************************************************
1657 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1658 for the work
1659 *****************************************************************************/
1661 BOOL str_list_sub_basic( char **list, const char *smb_name )
1663 char *s, *tmpstr;
1665 while ( *list ) {
1666 s = *list;
1667 tmpstr = alloc_sub_basic(smb_name, s);
1668 if ( !tmpstr ) {
1669 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1670 return False;
1673 *list = tmpstr;
1675 list++;
1678 return True;
1681 /******************************************************************************
1682 substritute a specific pattern in a string list
1683 *****************************************************************************/
1685 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1687 char *p, *s, *t;
1688 ssize_t ls, lp, li, ld, i, d;
1690 if (!list)
1691 return False;
1692 if (!pattern)
1693 return False;
1694 if (!insert)
1695 return False;
1697 lp = (ssize_t)strlen(pattern);
1698 li = (ssize_t)strlen(insert);
1699 ld = li -lp;
1701 while (*list) {
1702 s = *list;
1703 ls = (ssize_t)strlen(s);
1705 while ((p = strstr_m(s, pattern))) {
1706 t = *list;
1707 d = p -t;
1708 if (ld) {
1709 t = (char *) malloc(ls +ld +1);
1710 if (!t) {
1711 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1712 return False;
1714 memcpy(t, *list, d);
1715 memcpy(t +d +li, p +lp, ls -d -lp +1);
1716 SAFE_FREE(*list);
1717 *list = t;
1718 ls += ld;
1719 s = t +d +li;
1722 for (i = 0; i < li; i++) {
1723 switch (insert[i]) {
1724 case '`':
1725 case '"':
1726 case '\'':
1727 case ';':
1728 case '$':
1729 case '%':
1730 case '\r':
1731 case '\n':
1732 t[d +i] = '_';
1733 break;
1734 default:
1735 t[d +i] = insert[i];
1741 list++;
1744 return True;
1748 #define IPSTR_LIST_SEP ","
1749 #define IPSTR_LIST_CHAR ','
1752 * Add ip string representation to ipstr list. Used also
1753 * as part of @function ipstr_list_make
1755 * @param ipstr_list pointer to string containing ip list;
1756 * MUST BE already allocated and IS reallocated if necessary
1757 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1758 * as a result of reallocation)
1759 * @param ip IP address which is to be added to list
1760 * @return pointer to string appended with new ip and possibly
1761 * reallocated to new length
1764 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1766 char* new_ipstr = NULL;
1768 /* arguments checking */
1769 if (!ipstr_list || !service) return NULL;
1771 /* attempt to convert ip to a string and append colon separator to it */
1772 if (*ipstr_list) {
1773 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1774 inet_ntoa(service->ip), service->port);
1775 SAFE_FREE(*ipstr_list);
1776 } else {
1777 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1779 *ipstr_list = new_ipstr;
1780 return *ipstr_list;
1785 * Allocate and initialise an ipstr list using ip adresses
1786 * passed as arguments.
1788 * @param ipstr_list pointer to string meant to be allocated and set
1789 * @param ip_list array of ip addresses to place in the list
1790 * @param ip_count number of addresses stored in ip_list
1791 * @return pointer to allocated ip string
1794 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1796 int i;
1798 /* arguments checking */
1799 if (!ip_list && !ipstr_list) return 0;
1801 *ipstr_list = NULL;
1803 /* process ip addresses given as arguments */
1804 for (i = 0; i < ip_count; i++)
1805 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1807 return (*ipstr_list);
1812 * Parse given ip string list into array of ip addresses
1813 * (as ip_service structures)
1814 * e.g. 192.168.1.100:389,192.168.1.78, ...
1816 * @param ipstr ip string list to be parsed
1817 * @param ip_list pointer to array of ip addresses which is
1818 * allocated by this function and must be freed by caller
1819 * @return number of succesfully parsed addresses
1822 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1824 fstring token_str;
1825 size_t count;
1826 int i;
1828 if (!ipstr_list || !ip_list)
1829 return 0;
1831 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1832 if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1833 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1834 return 0;
1837 for ( i=0;
1838 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1839 i++ )
1841 struct in_addr addr;
1842 unsigned port = 0;
1843 char *p = strchr(token_str, ':');
1845 if (p) {
1846 *p = 0;
1847 port = atoi(p+1);
1850 /* convert single token to ip address */
1851 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1852 break;
1854 (*ip_list)[i].ip = addr;
1855 (*ip_list)[i].port = port;
1858 return count;
1863 * Safely free ip string list
1865 * @param ipstr_list ip string list to be freed
1868 void ipstr_list_free(char* ipstr_list)
1870 SAFE_FREE(ipstr_list);
1875 Unescape a URL encoded string, in place.
1878 void rfc1738_unescape(char *buf)
1880 char *p=buf;
1882 while (p && *p && (p=strchr_m(p,'%'))) {
1883 int c1 = p[1];
1884 int c2 = p[2];
1886 if (c1 >= '0' && c1 <= '9')
1887 c1 = c1 - '0';
1888 else if (c1 >= 'A' && c1 <= 'F')
1889 c1 = 10 + c1 - 'A';
1890 else if (c1 >= 'a' && c1 <= 'f')
1891 c1 = 10 + c1 - 'a';
1892 else {p++; continue;}
1894 if (c2 >= '0' && c2 <= '9')
1895 c2 = c2 - '0';
1896 else if (c2 >= 'A' && c2 <= 'F')
1897 c2 = 10 + c2 - 'A';
1898 else if (c2 >= 'a' && c2 <= 'f')
1899 c2 = 10 + c2 - 'a';
1900 else {p++; continue;}
1902 *p = (c1<<4) | c2;
1904 memmove(p+1, p+3, strlen(p+3)+1);
1905 p++;
1909 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1912 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1914 DATA_BLOB base64_decode_data_blob(const char *s)
1916 int bit_offset, byte_offset, idx, i, n;
1917 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1918 unsigned char *d = decoded.data;
1919 char *p;
1921 n=i=0;
1923 while (*s && (p=strchr_m(b64,*s))) {
1924 idx = (int)(p - b64);
1925 byte_offset = (i*6)/8;
1926 bit_offset = (i*6)%8;
1927 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1928 if (bit_offset < 3) {
1929 d[byte_offset] |= (idx << (2-bit_offset));
1930 n = byte_offset+1;
1931 } else {
1932 d[byte_offset] |= (idx >> (bit_offset-2));
1933 d[byte_offset+1] = 0;
1934 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1935 n = byte_offset+2;
1937 s++; i++;
1940 if (*s == '=') n -= 1;
1942 /* fix up length */
1943 decoded.length = n;
1944 return decoded;
1948 * Decode a base64 string in-place - wrapper for the above
1950 void base64_decode_inplace(char *s)
1952 DATA_BLOB decoded = base64_decode_data_blob(s);
1953 memcpy(s, decoded.data, decoded.length);
1954 /* null terminate */
1955 s[decoded.length] = '\0';
1957 data_blob_free(&decoded);
1961 * Encode a base64 string into a malloc()ed string caller to free.
1963 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1965 char * base64_encode_data_blob(DATA_BLOB data)
1967 int bits = 0;
1968 int char_count = 0;
1969 size_t out_cnt = 0;
1970 size_t len = data.length;
1971 size_t output_len = data.length * 2;
1972 char *result = malloc(output_len); /* get us plenty of space */
1974 while (len-- && out_cnt < (data.length * 2) - 5) {
1975 int c = (unsigned char) *(data.data++);
1976 bits += c;
1977 char_count++;
1978 if (char_count == 3) {
1979 result[out_cnt++] = b64[bits >> 18];
1980 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1981 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1982 result[out_cnt++] = b64[bits & 0x3f];
1983 bits = 0;
1984 char_count = 0;
1985 } else {
1986 bits <<= 8;
1989 if (char_count != 0) {
1990 bits <<= 16 - (8 * char_count);
1991 result[out_cnt++] = b64[bits >> 18];
1992 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1993 if (char_count == 1) {
1994 result[out_cnt++] = '=';
1995 result[out_cnt++] = '=';
1996 } else {
1997 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1998 result[out_cnt++] = '=';
2001 result[out_cnt] = '\0'; /* terminate */
2002 return result;
2005 /* read a SMB_BIG_UINT from a string */
2006 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2009 SMB_BIG_UINT val = -1;
2010 const char *p = nptr;
2012 while (p && *p && isspace(*p))
2013 p++;
2014 #ifdef LARGE_SMB_OFF_T
2015 sscanf(p,"%llu",&val);
2016 #else /* LARGE_SMB_OFF_T */
2017 sscanf(p,"%lu",&val);
2018 #endif /* LARGE_SMB_OFF_T */
2019 if (entptr) {
2020 while (p && *p && isdigit(*p))
2021 p++;
2022 *entptr = p;
2025 return val;