The cli_send_tconX code already determines to send \\server\share to port 139
[samba.git] / source3 / lib / util_str.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-2001
5    Copyright (C) Simo Sorce      2001-2002
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 /****************************************************************************
25  Get the next token from a string, return False if none found.
26  Handles double-quotes. 
27  Based on a routine by GJC@VILLAGE.COM. 
28  Extensively modified by Andrew.Tridgell@anu.edu.au
29 ****************************************************************************/
30
31 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
32 {
33         const char *s;
34         BOOL quoted;
35         size_t len=1;
36
37         if (!ptr)
38                 return(False);
39
40         s = *ptr;
41
42         /* default to simple separators */
43         if (!sep)
44                 sep = " \t\n\r";
45
46         /* find the first non sep char */
47         while (*s && strchr_m(sep,*s))
48                 s++;
49         
50         /* nothing left? */
51         if (! *s)
52                 return(False);
53         
54         /* copy over the token */
55         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
56                 if (*s == '\"') {
57                         quoted = !quoted;
58                 } else {
59                         len++;
60                         *buff++ = *s;
61                 }
62         }
63         
64         *ptr = (*s) ? s+1 : s;  
65         *buff = 0;
66         
67         return(True);
68 }
69
70 /****************************************************************************
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!
74 ****************************************************************************/
75
76 static char *last_ptr=NULL;
77
78 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
79 {
80         BOOL ret;
81         if (!ptr)
82                 ptr = (const char **)&last_ptr;
83
84         ret = next_token(ptr, buff, sep, bufsize);
85         last_ptr = *ptr;
86         return ret;     
87 }
88
89 static uint16 tmpbuf[sizeof(pstring)];
90
91 void set_first_token(char *ptr)
92 {
93         last_ptr = ptr;
94 }
95
96 /****************************************************************************
97  Convert list of tokens to array; dependent on above routine.
98  Uses last_ptr from above - bit of a hack.
99 ****************************************************************************/
100
101 char **toktocliplist(int *ctok, const char *sep)
102 {
103         char *s=last_ptr;
104         int ictok=0;
105         char **ret, **iret;
106
107         if (!sep)
108                 sep = " \t\n\r";
109
110         while(*s && strchr_m(sep,*s))
111                 s++;
112
113         /* nothing left? */
114         if (!*s)
115                 return(NULL);
116
117         do {
118                 ictok++;
119                 while(*s && (!strchr_m(sep,*s)))
120                         s++;
121                 while(*s && strchr_m(sep,*s))
122                         *s++=0;
123         } while(*s);
124         
125         *ctok=ictok;
126         s=last_ptr;
127         
128         if (!(ret=iret=malloc(ictok*sizeof(char *))))
129                 return NULL;
130         
131         while(ictok--) {    
132                 *iret++=s;
133                 while(*s++)
134                         ;
135                 while(!*s)
136                         s++;
137         }
138
139         return ret;
140 }
141
142 /*******************************************************************
143  Case insensitive string compararison.
144 ********************************************************************/
145
146 int StrCaseCmp(const char *s, const char *t)
147 {
148         pstring buf1, buf2;
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);
152 }
153
154 /*******************************************************************
155  Case insensitive string compararison, length limited.
156 ********************************************************************/
157
158 int StrnCaseCmp(const char *s, const char *t, size_t n)
159 {
160         pstring buf1, buf2;
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);
164 }
165
166 /*******************************************************************
167  Compare 2 strings.
168 ********************************************************************/
169
170 BOOL strequal(const char *s1, const char *s2)
171 {
172         if (s1 == s2)
173                 return(True);
174         if (!s1 || !s2)
175                 return(False);
176   
177         return(StrCaseCmp(s1,s2)==0);
178 }
179
180 /*******************************************************************
181  Compare 2 strings up to and including the nth char.
182 ******************************************************************/
183
184 BOOL strnequal(const char *s1,const char *s2,size_t n)
185 {
186   if (s1 == s2)
187           return(True);
188   if (!s1 || !s2 || !n)
189           return(False);
190   
191   return(StrnCaseCmp(s1,s2,n)==0);
192 }
193
194 /*******************************************************************
195  Compare 2 strings (case sensitive).
196 ********************************************************************/
197
198 BOOL strcsequal(const char *s1,const char *s2)
199 {
200   if (s1 == s2)
201           return(True);
202   if (!s1 || !s2)
203           return(False);
204   
205   return(strcmp(s1,s2)==0);
206 }
207
208 /***************************************************************************
209 Do a case-insensitive, whitespace-ignoring string compare.
210 ***************************************************************************/
211
212 int strwicmp(const char *psz1, const char *psz2)
213 {
214         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
215         /* appropriate value. */
216         if (psz1 == psz2)
217                 return (0);
218         else if (psz1 == NULL)
219                 return (-1);
220         else if (psz2 == NULL)
221                 return (1);
222
223         /* sync the strings on first non-whitespace */
224         while (1) {
225                 while (isspace((int)*psz1))
226                         psz1++;
227                 while (isspace((int)*psz2))
228                         psz2++;
229                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
230                     || *psz2 == '\0')
231                         break;
232                 psz1++;
233                 psz2++;
234         }
235         return (*psz1 - *psz2);
236 }
237
238
239 /*******************************************************************
240  Convert a string to upper case, but don't modify it.
241 ********************************************************************/
242
243 char *strupper_static(const char *s)
244 {
245         static pstring str;
246
247         pstrcpy(str, s);
248         strupper(str);
249
250         return str;
251 }
252
253 /*******************************************************************
254  Convert a string to "normal" form.
255 ********************************************************************/
256
257 void strnorm(char *s)
258 {
259         extern int case_default;
260         if (case_default == CASE_UPPER)
261                 strupper(s);
262         else
263                 strlower(s);
264 }
265
266 /*******************************************************************
267  Check if a string is in "normal" case.
268 ********************************************************************/
269
270 BOOL strisnormal(const char *s)
271 {
272         extern int case_default;
273         if (case_default == CASE_UPPER)
274                 return(!strhaslower(s));
275         
276         return(!strhasupper(s));
277 }
278
279
280 /****************************************************************************
281  String replace.
282  NOTE: oldc and newc must be 7 bit characters
283 ****************************************************************************/
284
285 void string_replace(char *s,char oldc,char newc)
286 {
287         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
288         string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
289         pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
290 }
291
292 /*******************************************************************
293  Skip past some strings in a buffer.
294 ********************************************************************/
295
296 char *skip_string(char *buf,size_t n)
297 {
298         while (n--)
299                 buf += strlen(buf) + 1;
300         return(buf);
301 }
302
303 /*******************************************************************
304  Count the number of characters in a string. Normally this will
305  be the same as the number of bytes in a string for single byte strings,
306  but will be different for multibyte.
307 ********************************************************************/
308
309 size_t str_charnum(const char *s)
310 {
311         uint16 tmpbuf2[sizeof(pstring)];
312         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
313         return strlen_w(tmpbuf2);
314 }
315
316 /*******************************************************************
317  Count the number of characters in a string. Normally this will
318  be the same as the number of bytes in a string for single byte strings,
319  but will be different for multibyte.
320 ********************************************************************/
321
322 size_t str_ascii_charnum(const char *s)
323 {
324         pstring tmpbuf2;
325         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
326         return strlen(tmpbuf2);
327 }
328
329 /*******************************************************************
330  Trim the specified elements off the front and back of a string.
331 ********************************************************************/
332
333 BOOL trim_string(char *s,const char *front,const char *back)
334 {
335         BOOL ret = False;
336         size_t front_len;
337         size_t back_len;
338         size_t len;
339
340         /* Ignore null or empty strings. */
341         if (!s || (s[0] == '\0'))
342                 return False;
343
344         front_len       = front? strlen(front) : 0;
345         back_len        = back? strlen(back) : 0;
346
347         len = strlen(s);
348
349         if (front_len) {
350                 while (len && strncmp(s, front, front_len)==0) {
351                         memcpy(s, s+front_len, (len-front_len)+1);
352                         len -= front_len;
353                         ret=True;
354                 }
355         }
356         
357         if (back_len) {
358                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
359                         s[len-back_len]='\0';
360                         len -= back_len;
361                         ret=True;
362                 }
363         }
364         return ret;
365 }
366
367 /****************************************************************************
368  Does a string have any uppercase chars in it?
369 ****************************************************************************/
370
371 BOOL strhasupper(const char *s)
372 {
373         smb_ucs2_t *ptr;
374         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
375         for(ptr=tmpbuf;*ptr;ptr++)
376                 if(isupper_w(*ptr))
377                         return True;
378         return(False);
379 }
380
381 /****************************************************************************
382  Does a string have any lowercase chars in it?
383 ****************************************************************************/
384
385 BOOL strhaslower(const char *s)
386 {
387         smb_ucs2_t *ptr;
388         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
389         for(ptr=tmpbuf;*ptr;ptr++)
390                 if(islower_w(*ptr))
391                         return True;
392         return(False);
393 }
394
395 /****************************************************************************
396  Find the number of 'c' chars in a string
397 ****************************************************************************/
398
399 size_t count_chars(const char *s,char c)
400 {
401         smb_ucs2_t *ptr;
402         int count;
403         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
404         for(count=0,ptr=tmpbuf;*ptr;ptr++)
405                 if(*ptr==UCS2_CHAR(c))
406                         count++;
407         return(count);
408 }
409
410 /*******************************************************************
411 Return True if a string consists only of one particular character.
412 ********************************************************************/
413
414 BOOL str_is_all(const char *s,char c)
415 {
416         smb_ucs2_t *ptr;
417
418         if(s == NULL)
419                 return False;
420         if(!*s)
421                 return False;
422   
423         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
424         for(ptr=tmpbuf;*ptr;ptr++)
425                 if(*ptr!=UCS2_CHAR(c))
426                         return False;
427
428         return True;
429 }
430
431 /*******************************************************************
432  Safe string copy into a known length string. maxlength does not
433  include the terminating zero.
434 ********************************************************************/
435
436 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
437 {
438         size_t len;
439
440         if (!dest) {
441                 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
442                 return NULL;
443         }
444
445 #ifdef DEVELOPER
446         /* We intentionally write out at the extremity of the destination
447          * string.  If the destination is too short (e.g. pstrcpy into mallocd
448          * or fstring) then this should cause an error under a memory
449          * checker. */
450         dest[maxlength] = '\0';
451 #endif
452
453         if (!src) {
454                 *dest = 0;
455                 return dest;
456         }  
457
458         len = strlen(src);
459
460         if (len > maxlength) {
461                 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
462                          (unsigned int)(len-maxlength), len, maxlength, src));
463                 len = maxlength;
464         }
465       
466         memmove(dest, src, len);
467         dest[len] = 0;
468         return dest;
469 }  
470
471 /*******************************************************************
472  Safe string cat into a string. maxlength does not
473  include the terminating zero.
474 ********************************************************************/
475
476 char *safe_strcat(char *dest, const char *src, size_t maxlength)
477 {
478         size_t src_len, dest_len;
479
480         if (!dest) {
481                 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
482                 return NULL;
483         }
484
485         if (!src)
486                 return dest;
487         
488         src_len = strlen(src);
489         dest_len = strlen(dest);
490
491         if (src_len + dest_len > maxlength) {
492                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
493                          (int)(src_len + dest_len - maxlength), src));
494                 if (maxlength > dest_len) {
495                         memcpy(&dest[dest_len], src, maxlength - dest_len);
496                 }
497                 dest[maxlength] = 0;
498                 return NULL;
499         }
500         
501         memcpy(&dest[dest_len], src, src_len);
502         dest[dest_len + src_len] = 0;
503         return dest;
504 }
505
506 /*******************************************************************
507  Paranoid strcpy into a buffer of given length (includes terminating
508  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
509  and replaces with '_'. Deliberately does *NOT* check for multibyte
510  characters. Don't change it !
511 ********************************************************************/
512
513 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
514 {
515         size_t len, i;
516
517         if (!dest) {
518                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
519                 return NULL;
520         }
521
522         if (!src) {
523                 *dest = 0;
524                 return dest;
525         }  
526
527         len = strlen(src);
528         if (len >= maxlength)
529                 len = maxlength - 1;
530
531         if (!other_safe_chars)
532                 other_safe_chars = "";
533
534         for(i = 0; i < len; i++) {
535                 int val = (src[i] & 0xff);
536                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
537                         dest[i] = src[i];
538                 else
539                         dest[i] = '_';
540         }
541
542         dest[i] = '\0';
543
544         return dest;
545 }
546
547 /****************************************************************************
548  Like strncpy but always null terminates. Make sure there is room!
549  The variable n should always be one less than the available size.
550 ****************************************************************************/
551
552 char *StrnCpy(char *dest,const char *src,size_t n)
553 {
554         char *d = dest;
555         if (!dest)
556                 return(NULL);
557         if (!src) {
558                 *dest = 0;
559                 return(dest);
560         }
561         while (n-- && (*d++ = *src++))
562                 ;
563         *d = 0;
564         return(dest);
565 }
566
567 /****************************************************************************
568  Like strncpy but copies up to the character marker.  always null terminates.
569  returns a pointer to the character marker in the source string (src).
570 ****************************************************************************/
571
572 char *strncpyn(char *dest, const char *src, size_t n, char c)
573 {
574         char *p;
575         size_t str_len;
576
577         p = strchr_m(src, c);
578         if (p == NULL) {
579                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
580                 return NULL;
581         }
582
583         str_len = PTR_DIFF(p, src);
584         strncpy(dest, src, MIN(n, str_len));
585         dest[str_len] = '\0';
586
587         return p;
588 }
589
590 /*************************************************************
591  Routine to get hex characters and turn them into a 16 byte array.
592  the array can be variable length, and any non-hex-numeric
593  characters are skipped.  "0xnn" or "0Xnn" is specially catered
594  for.
595
596  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
597
598 **************************************************************/
599
600 size_t strhex_to_str(char *p, size_t len, const char *strhex)
601 {
602         size_t i;
603         size_t num_chars = 0;
604         unsigned char   lonybble, hinybble;
605         const char     *hexchars = "0123456789ABCDEF";
606         char           *p1 = NULL, *p2 = NULL;
607
608         for (i = 0; i < len && strhex[i] != 0; i++) {
609                 if (strnequal(hexchars, "0x", 2)) {
610                         i++; /* skip two chars */
611                         continue;
612                 }
613
614                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
615                         break;
616
617                 i++; /* next hex digit */
618
619                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
620                         break;
621
622                 /* get the two nybbles */
623                 hinybble = PTR_DIFF(p1, hexchars);
624                 lonybble = PTR_DIFF(p2, hexchars);
625
626                 p[num_chars] = (hinybble << 4) | lonybble;
627                 num_chars++;
628
629                 p1 = NULL;
630                 p2 = NULL;
631         }
632         return num_chars;
633 }
634
635 /****************************************************************************
636  Check if a string is part of a list.
637 ****************************************************************************/
638
639 BOOL in_list(char *s,char *list,BOOL casesensitive)
640 {
641         pstring tok;
642         const char *p=list;
643
644         if (!list)
645                 return(False);
646
647         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
648                 if (casesensitive) {
649                         if (strcmp(tok,s) == 0)
650                                 return(True);
651                 } else {
652                         if (StrCaseCmp(tok,s) == 0)
653                                 return(True);
654                 }
655         }
656         return(False);
657 }
658
659 /* this is used to prevent lots of mallocs of size 1 */
660 static char *null_string = NULL;
661
662 /****************************************************************************
663  Set a string value, allocing the space for the string
664 ****************************************************************************/
665
666 static BOOL string_init(char **dest,const char *src)
667 {
668         size_t l;
669         if (!src)     
670                 src = "";
671
672         l = strlen(src);
673
674         if (l == 0) {
675                 if (!null_string) {
676                         if((null_string = (char *)malloc(1)) == NULL) {
677                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
678                                 return False;
679                         }
680                         *null_string = 0;
681                 }
682                 *dest = null_string;
683         } else {
684                 (*dest) = strdup(src);
685                 if ((*dest) == NULL) {
686                         DEBUG(0,("Out of memory in string_init\n"));
687                         return False;
688                 }
689         }
690         return(True);
691 }
692
693 /****************************************************************************
694  Free a string value.
695 ****************************************************************************/
696
697 void string_free(char **s)
698 {
699         if (!s || !(*s))
700                 return;
701         if (*s == null_string)
702                 *s = NULL;
703         SAFE_FREE(*s);
704 }
705
706 /****************************************************************************
707  Set a string value, deallocating any existing space, and allocing the space
708  for the string
709 ****************************************************************************/
710
711 BOOL string_set(char **dest,const char *src)
712 {
713         string_free(dest);
714         return(string_init(dest,src));
715 }
716
717 /****************************************************************************
718  Substitute a string for a pattern in another string. Make sure there is 
719  enough room!
720
721  This routine looks for pattern in s and replaces it with 
722  insert. It may do multiple replacements.
723
724  Any of " ; ' $ or ` in the insert string are replaced with _
725  if len==0 then the string cannot be extended. This is different from the old
726  use of len==0 which was for no length checks to be done.
727 ****************************************************************************/
728
729 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
730 {
731         char *p;
732         ssize_t ls,lp,li, i;
733
734         if (!insert || !pattern || !*pattern || !s)
735                 return;
736
737         ls = (ssize_t)strlen(s);
738         lp = (ssize_t)strlen(pattern);
739         li = (ssize_t)strlen(insert);
740
741         if (len == 0)
742                 len = ls + 1; /* len is number of *bytes* */
743
744         while (lp <= ls && (p = strstr(s,pattern))) {
745                 if (ls + (li-lp) >= len) {
746                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
747                                  (int)(ls + (li-lp) - len),
748                                  pattern, (int)len));
749                         break;
750                 }
751                 if (li != lp) {
752                         memmove(p+li,p+lp,strlen(p+lp)+1);
753                 }
754                 for (i=0;i<li;i++) {
755                         switch (insert[i]) {
756                         case '`':
757                         case '"':
758                         case '\'':
759                         case ';':
760                         case '$':
761                         case '%':
762                         case '\r':
763                         case '\n':
764                                 p[i] = '_';
765                                 break;
766                         default:
767                                 p[i] = insert[i];
768                         }
769                 }
770                 s = p + li;
771                 ls += (li-lp);
772         }
773 }
774
775 void fstring_sub(char *s,const char *pattern,const char *insert)
776 {
777         string_sub(s, pattern, insert, sizeof(fstring));
778 }
779
780 void pstring_sub(char *s,const char *pattern,const char *insert)
781 {
782         string_sub(s, pattern, insert, sizeof(pstring));
783 }
784
785 /****************************************************************************
786  Similar to string_sub, but it will accept only allocated strings
787  and may realloc them so pay attention at what you pass on no
788  pointers inside strings, no pstrings or const may be passed
789  as string.
790 ****************************************************************************/
791
792 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
793 {
794         char *p, *in;
795         char *s;
796         ssize_t ls,lp,li,ld, i;
797
798         if (!insert || !pattern || !*pattern || !string || !*string)
799                 return NULL;
800
801         s = string;
802
803         in = strdup(insert);
804         if (!in) {
805                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
806                 return NULL;
807         }
808         ls = (ssize_t)strlen(s);
809         lp = (ssize_t)strlen(pattern);
810         li = (ssize_t)strlen(insert);
811         ld = li - lp;
812         for (i=0;i<li;i++) {
813                 switch (in[i]) {
814                         case '`':
815                         case '"':
816                         case '\'':
817                         case ';':
818                         case '$':
819                         case '%':
820                         case '\r':
821                         case '\n':
822                                 in[i] = '_';
823                         default:
824                                 /* ok */
825                                 break;
826                 }
827         }
828         
829         while ((p = strstr(s,pattern))) {
830                 if (ld > 0) {
831                         char *t = Realloc(string, ls + ld + 1);
832                         if (!t) {
833                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
834                                 SAFE_FREE(in);
835                                 return NULL;
836                         }
837                         string = t;
838                         p = t + (p - s);
839                 }
840                 if (li != lp) {
841                         memmove(p+li,p+lp,strlen(p+lp)+1);
842                 }
843                 memcpy(p, in, li);
844                 s = p + li;
845                 ls += ld;
846         }
847         SAFE_FREE(in);
848         return string;
849 }
850
851 /****************************************************************************
852  Similar to string_sub() but allows for any character to be substituted. 
853  Use with caution!
854  if len==0 then the string cannot be extended. This is different from the old
855  use of len==0 which was for no length checks to be done.
856 ****************************************************************************/
857
858 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
859 {
860         char *p;
861         ssize_t ls,lp,li;
862
863         if (!insert || !pattern || !s)
864                 return;
865
866         ls = (ssize_t)strlen(s);
867         lp = (ssize_t)strlen(pattern);
868         li = (ssize_t)strlen(insert);
869
870         if (!*pattern)
871                 return;
872         
873         if (len == 0)
874                 len = ls + 1; /* len is number of *bytes* */
875         
876         while (lp <= ls && (p = strstr(s,pattern))) {
877                 if (ls + (li-lp) >= len) {
878                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
879                                  (int)(ls + (li-lp) - len),
880                                  pattern, (int)len));
881                         break;
882                 }
883                 if (li != lp) {
884                         memmove(p+li,p+lp,strlen(p+lp)+1);
885                 }
886                 memcpy(p, insert, li);
887                 s = p + li;
888                 ls += (li-lp);
889         }
890 }
891
892 /****************************************************************************
893  Similar to all_string_sub but for unicode strings.
894  Return a new allocated unicode string.
895  similar to string_sub() but allows for any character to be substituted.
896  Use with caution!
897 ****************************************************************************/
898
899 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
900                                 const smb_ucs2_t *insert)
901 {
902         smb_ucs2_t *r, *rp;
903         const smb_ucs2_t *sp;
904         size_t  lr, lp, li, lt;
905
906         if (!insert || !pattern || !*pattern || !s)
907                 return NULL;
908
909         lt = (size_t)strlen_w(s);
910         lp = (size_t)strlen_w(pattern);
911         li = (size_t)strlen_w(insert);
912
913         if (li > lp) {
914                 const smb_ucs2_t *st = s;
915                 int ld = li - lp;
916                 while ((sp = strstr_w(st, pattern))) {
917                         st = sp + lp;
918                         lt += ld;
919                 }
920         }
921
922         r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
923         if (!r) {
924                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
925                 return NULL;
926         }
927
928         while ((sp = strstr_w(s, pattern))) {
929                 memcpy(rp, s, (sp - s));
930                 rp += ((sp - s) / sizeof(smb_ucs2_t));
931                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
932                 s = sp + lp;
933                 rp += li;
934         }
935         lr = ((rp - r) / sizeof(smb_ucs2_t));
936         if (lr < lt) {
937                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
938                 rp += (lt - lr);
939         }
940         *rp = 0;
941
942         return r;
943 }
944
945 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
946                                              const char *insert)
947 {
948         wpstring p, i;
949
950         if (!insert || !pattern || !s)
951                 return NULL;
952         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
953         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
954         return all_string_sub_w(s, p, i);
955 }
956
957 /****************************************************************************
958  Splits out the front and back at a separator.
959 ****************************************************************************/
960
961 void split_at_last_component(char *path, char *front, char sep, char *back)
962 {
963         char *p = strrchr_m(path, sep);
964
965         if (p != NULL)
966                 *p = 0;
967
968         if (front != NULL)
969                 pstrcpy(front, path);
970
971         if (p != NULL) {
972                 if (back != NULL)
973                         pstrcpy(back, p+1);
974                 *p = '\\';
975         } else {
976                 if (back != NULL)
977                         back[0] = 0;
978         }
979 }
980
981 /****************************************************************************
982  Write an octal as a string.
983 ****************************************************************************/
984
985 const char *octal_string(int i)
986 {
987         static char ret[64];
988         if (i == -1)
989                 return "-1";
990         slprintf(ret, sizeof(ret)-1, "0%o", i);
991         return ret;
992 }
993
994
995 /****************************************************************************
996  Truncate a string at a specified length.
997 ****************************************************************************/
998
999 char *string_truncate(char *s, int length)
1000 {
1001         if (s && strlen(s) > length)
1002                 s[length] = 0;
1003         return s;
1004 }
1005
1006 /****************************************************************************
1007  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1008  We convert via ucs2 for now.
1009 ****************************************************************************/
1010
1011 char *strchr_m(const char *s, char c)
1012 {
1013         wpstring ws;
1014         pstring s2;
1015         smb_ucs2_t *p;
1016
1017         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1018         p = strchr_w(ws, UCS2_CHAR(c));
1019         if (!p)
1020                 return NULL;
1021         *p = 0;
1022         pull_ucs2_pstring(s2, ws);
1023         return (char *)(s+strlen(s2));
1024 }
1025
1026 char *strrchr_m(const char *s, char c)
1027 {
1028         wpstring ws;
1029         pstring s2;
1030         smb_ucs2_t *p;
1031
1032         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1033         p = strrchr_w(ws, UCS2_CHAR(c));
1034         if (!p)
1035                 return NULL;
1036         *p = 0;
1037         pull_ucs2_pstring(s2, ws);
1038         return (char *)(s+strlen(s2));
1039 }
1040
1041 /*******************************************************************
1042  Convert a string to lower case.
1043 ********************************************************************/
1044
1045 void strlower_m(char *s)
1046 {
1047         /* this is quite a common operation, so we want it to be
1048            fast. We optimise for the ascii case, knowing that all our
1049            supported multi-byte character sets are ascii-compatible
1050            (ie. they match for the first 128 chars) */
1051
1052         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1053                 *s = tolower((unsigned char)*s);
1054                 s++;
1055         }
1056
1057         if (!*s)
1058                 return;
1059
1060         /* I assume that lowercased string takes the same number of bytes
1061          * as source string even in UTF-8 encoding. (VIV) */
1062         unix_strlower(s,strlen(s)+1,s,strlen(s)+1);     
1063 }
1064
1065 /*******************************************************************
1066  Duplicate convert a string to lower case.
1067 ********************************************************************/
1068
1069 char *strdup_lower(const char *s)
1070 {
1071         char *t = strdup(s);
1072         if (t == NULL) {
1073                 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1074                 return NULL;
1075         }
1076         strlower_m(t);
1077         return t;
1078 }
1079
1080 /*******************************************************************
1081  Convert a string to upper case.
1082 ********************************************************************/
1083
1084 void strupper_m(char *s)
1085 {
1086         /* this is quite a common operation, so we want it to be
1087            fast. We optimise for the ascii case, knowing that all our
1088            supported multi-byte character sets are ascii-compatible
1089            (ie. they match for the first 128 chars) */
1090
1091         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1092                 *s = toupper((unsigned char)*s);
1093                 s++;
1094         }
1095
1096         if (!*s)
1097                 return;
1098
1099         /* I assume that lowercased string takes the same number of bytes
1100          * as source string even in multibyte encoding. (VIV) */
1101         unix_strupper(s,strlen(s)+1,s,strlen(s)+1);     
1102 }
1103
1104 /*******************************************************************
1105  Convert a string to upper case.
1106 ********************************************************************/
1107
1108 char *strdup_upper(const char *s)
1109 {
1110         char *t = strdup(s);
1111         if (t == NULL) {
1112                 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1113                 return NULL;
1114         }
1115         strupper_m(t);
1116         return t;
1117 }
1118
1119 /*******************************************************************
1120  Return a RFC2254 binary string representation of a buffer.
1121  Used in LDAP filters.
1122  Caller must free.
1123 ********************************************************************/
1124
1125 char *binary_string(char *buf, int len)
1126 {
1127         char *s;
1128         int i, j;
1129         const char *hex = "0123456789ABCDEF";
1130         s = malloc(len * 3 + 1);
1131         if (!s)
1132                 return NULL;
1133         for (j=i=0;i<len;i++) {
1134                 s[j] = '\\';
1135                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1136                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1137                 j += 3;
1138         }
1139         s[j] = 0;
1140         return s;
1141 }
1142
1143 /*******************************************************************
1144  Just a typesafety wrapper for snprintf into a pstring.
1145 ********************************************************************/
1146
1147  int pstr_sprintf(pstring s, const char *fmt, ...)
1148 {
1149         va_list ap;
1150         int ret;
1151
1152         va_start(ap, fmt);
1153         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1154         va_end(ap);
1155         return ret;
1156 }
1157
1158 /*******************************************************************
1159  Just a typesafety wrapper for snprintf into a fstring.
1160 ********************************************************************/
1161
1162  int fstr_sprintf(fstring s, const char *fmt, ...)
1163 {
1164         va_list ap;
1165         int ret;
1166
1167         va_start(ap, fmt);
1168         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1169         va_end(ap);
1170         return ret;
1171 }
1172
1173 #ifndef HAVE_STRNDUP
1174 /*******************************************************************
1175  Some platforms don't have strndup.
1176 ********************************************************************/
1177
1178  char *strndup(const char *s, size_t n)
1179 {
1180         char *ret;
1181         
1182         n = strnlen(s, n);
1183         ret = malloc(n+1);
1184         if (!ret)
1185                 return NULL;
1186         memcpy(ret, s, n);
1187         ret[n] = 0;
1188
1189         return ret;
1190 }
1191 #endif
1192
1193 #ifndef HAVE_STRNLEN
1194 /*******************************************************************
1195  Some platforms don't have strnlen
1196 ********************************************************************/
1197
1198  size_t strnlen(const char *s, size_t n)
1199 {
1200         int i;
1201         for (i=0; s[i] && i<n; i++)
1202                 /* noop */ ;
1203         return i;
1204 }
1205 #endif
1206
1207 /***********************************************************
1208  List of Strings manipulation functions
1209 ***********************************************************/
1210
1211 #define S_LIST_ABS 16 /* List Allocation Block Size */
1212
1213 char **str_list_make(const char *string, const char *sep)
1214 {
1215         char **list, **rlist;
1216         const char *str;
1217         char *s;
1218         int num, lsize;
1219         pstring tok;
1220         
1221         if (!string || !*string)
1222                 return NULL;
1223         s = strdup(string);
1224         if (!s) {
1225                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1226                 return NULL;
1227         }
1228         if (!sep) sep = LIST_SEP;
1229         
1230         num = lsize = 0;
1231         list = NULL;
1232         
1233         str = s;
1234         while (next_token(&str, tok, sep, sizeof(tok))) {               
1235                 if (num == lsize) {
1236                         lsize += S_LIST_ABS;
1237                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1238                         if (!rlist) {
1239                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1240                                 str_list_free(&list);
1241                                 SAFE_FREE(s);
1242                                 return NULL;
1243                         } else
1244                                 list = rlist;
1245                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1246                 }
1247                 
1248                 list[num] = strdup(tok);
1249                 if (!list[num]) {
1250                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1251                         str_list_free(&list);
1252                         SAFE_FREE(s);
1253                         return NULL;
1254                 }
1255         
1256                 num++;  
1257         }
1258         
1259         SAFE_FREE(s);
1260         return list;
1261 }
1262
1263 BOOL str_list_copy(char ***dest, const char **src)
1264 {
1265         char **list, **rlist;
1266         int num, lsize;
1267         
1268         *dest = NULL;
1269         if (!src)
1270                 return False;
1271         
1272         num = lsize = 0;
1273         list = NULL;
1274                 
1275         while (src[num]) {
1276                 if (num == lsize) {
1277                         lsize += S_LIST_ABS;
1278                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1279                         if (!rlist) {
1280                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1281                                 str_list_free(&list);
1282                                 return False;
1283                         } else
1284                                 list = rlist;
1285                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1286                 }
1287                 
1288                 list[num] = strdup(src[num]);
1289                 if (!list[num]) {
1290                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1291                         str_list_free(&list);
1292                         return False;
1293                 }
1294
1295                 num++;
1296         }
1297         
1298         *dest = list;
1299         return True;    
1300 }
1301
1302 /***********************************************************
1303  Return true if all the elements of the list match exactly.
1304 ***********************************************************/
1305
1306 BOOL str_list_compare(char **list1, char **list2)
1307 {
1308         int num;
1309         
1310         if (!list1 || !list2)
1311                 return (list1 == list2); 
1312         
1313         for (num = 0; list1[num]; num++) {
1314                 if (!list2[num])
1315                         return False;
1316                 if (!strcsequal(list1[num], list2[num]))
1317                         return False;
1318         }
1319         if (list2[num])
1320                 return False; /* if list2 has more elements than list1 fail */
1321         
1322         return True;
1323 }
1324
1325 void str_list_free(char ***list)
1326 {
1327         char **tlist;
1328         
1329         if (!list || !*list)
1330                 return;
1331         tlist = *list;
1332         for(; *tlist; tlist++)
1333                 SAFE_FREE(*tlist);
1334         SAFE_FREE(*list);
1335 }
1336
1337 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1338 {
1339         char *p, *s, *t;
1340         ssize_t ls, lp, li, ld, i, d;
1341
1342         if (!list)
1343                 return False;
1344         if (!pattern)
1345                 return False;
1346         if (!insert)
1347                 return False;
1348
1349         lp = (ssize_t)strlen(pattern);
1350         li = (ssize_t)strlen(insert);
1351         ld = li -lp;
1352                         
1353         while (*list) {
1354                 s = *list;
1355                 ls = (ssize_t)strlen(s);
1356
1357                 while ((p = strstr(s, pattern))) {
1358                         t = *list;
1359                         d = p -t;
1360                         if (ld) {
1361                                 t = (char *) malloc(ls +ld +1);
1362                                 if (!t) {
1363                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1364                                         return False;
1365                                 }
1366                                 memcpy(t, *list, d);
1367                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1368                                 SAFE_FREE(*list);
1369                                 *list = t;
1370                                 ls += ld;
1371                                 s = t +d +li;
1372                         }
1373                         
1374                         for (i = 0; i < li; i++) {
1375                                 switch (insert[i]) {
1376                                         case '`':
1377                                         case '"':
1378                                         case '\'':
1379                                         case ';':
1380                                         case '$':
1381                                         case '%':
1382                                         case '\r':
1383                                         case '\n':
1384                                                 t[d +i] = '_';
1385                                                 break;
1386                                         default:
1387                                                 t[d +i] = insert[i];
1388                                 }
1389                         }       
1390                 }
1391                 
1392                 list++;
1393         }
1394         
1395         return True;
1396 }
1397
1398
1399 #define IPSTR_LIST_SEP  ","
1400
1401 /**
1402  * Add ip string representation to ipstr list. Used also
1403  * as part of @function ipstr_list_make
1404  *
1405  * @param ipstr_list pointer to string containing ip list;
1406  *        MUST BE already allocated and IS reallocated if necessary
1407  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1408  *        as a result of reallocation)
1409  * @param ip IP address which is to be added to list
1410  * @return pointer to string appended with new ip and possibly
1411  *         reallocated to new length
1412  **/
1413
1414 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1415 {
1416         char* new_ipstr = NULL;
1417         
1418         /* arguments checking */
1419         if (!ipstr_list || !ip) return NULL;
1420
1421         /* attempt to convert ip to a string and append colon separator to it */
1422         if (*ipstr_list) {
1423                 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1424                 SAFE_FREE(*ipstr_list);
1425         } else {
1426                 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1427         }
1428         *ipstr_list = new_ipstr;
1429         return *ipstr_list;
1430 }
1431
1432
1433 /**
1434  * Allocate and initialise an ipstr list using ip adresses
1435  * passed as arguments.
1436  *
1437  * @param ipstr_list pointer to string meant to be allocated and set
1438  * @param ip_list array of ip addresses to place in the list
1439  * @param ip_count number of addresses stored in ip_list
1440  * @return pointer to allocated ip string
1441  **/
1442  
1443 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1444 {
1445         int i;
1446         
1447         /* arguments checking */
1448         if (!ip_list && !ipstr_list) return 0;
1449
1450         *ipstr_list = NULL;
1451         
1452         /* process ip addresses given as arguments */
1453         for (i = 0; i < ip_count; i++)
1454                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1455         
1456         return (*ipstr_list);
1457 }
1458
1459
1460 /**
1461  * Parse given ip string list into array of ip addresses
1462  * (as in_addr structures)
1463  *
1464  * @param ipstr ip string list to be parsed 
1465  * @param ip_list pointer to array of ip addresses which is
1466  *        allocated by this function and must be freed by caller
1467  * @return number of succesfully parsed addresses
1468  **/
1469  
1470 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1471 {
1472         fstring token_str;
1473         int count;
1474
1475         if (!ipstr_list || !ip_list) return 0;
1476         
1477         for (*ip_list = NULL, count = 0;
1478              next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1479              count++) {
1480              
1481                 struct in_addr addr;
1482
1483                 /* convert single token to ip address */
1484                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1485                         break;
1486                 
1487                 /* prepare place for another in_addr structure */
1488                 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1489                 if (!*ip_list) return -1;
1490                 
1491                 (*ip_list)[count] = addr;
1492         }
1493         
1494         return count;
1495 }
1496
1497
1498 /**
1499  * Safely free ip string list
1500  *
1501  * @param ipstr_list ip string list to be freed
1502  **/
1503
1504 void ipstr_list_free(char* ipstr_list)
1505 {
1506         SAFE_FREE(ipstr_list);
1507 }
1508
1509
1510 /***********************************************************
1511  Unescape a URL encoded string, in place.
1512 ***********************************************************/
1513
1514 void rfc1738_unescape(char *buf)
1515 {
1516         char *p=buf;
1517
1518         while ((p=strchr_m(p,'+')))
1519                 *p = ' ';
1520
1521         p = buf;
1522
1523         while (p && *p && (p=strchr_m(p,'%'))) {
1524                 int c1 = p[1];
1525                 int c2 = p[2];
1526
1527                 if (c1 >= '0' && c1 <= '9')
1528                         c1 = c1 - '0';
1529                 else if (c1 >= 'A' && c1 <= 'F')
1530                         c1 = 10 + c1 - 'A';
1531                 else if (c1 >= 'a' && c1 <= 'f')
1532                         c1 = 10 + c1 - 'a';
1533                 else {p++; continue;}
1534
1535                 if (c2 >= '0' && c2 <= '9')
1536                         c2 = c2 - '0';
1537                 else if (c2 >= 'A' && c2 <= 'F')
1538                         c2 = 10 + c2 - 'A';
1539                 else if (c2 >= 'a' && c2 <= 'f')
1540                         c2 = 10 + c2 - 'a';
1541                 else {p++; continue;}
1542                         
1543                 *p = (c1<<4) | c2;
1544
1545                 memmove(p+1, p+3, strlen(p+3)+1);
1546                 p++;
1547         }
1548 }
1549
1550 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1551
1552 /***************************************************************************
1553 decode a base64 string into a DATA_BLOB - simple and slow algorithm
1554   ***************************************************************************/
1555 DATA_BLOB base64_decode_data_blob(const char *s)
1556 {
1557         int bit_offset, byte_offset, idx, i, n;
1558         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1559         unsigned char *d = decoded.data;
1560         char *p;
1561
1562         n=i=0;
1563
1564         while (*s && (p=strchr_m(b64,*s))) {
1565                 idx = (int)(p - b64);
1566                 byte_offset = (i*6)/8;
1567                 bit_offset = (i*6)%8;
1568                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1569                 if (bit_offset < 3) {
1570                         d[byte_offset] |= (idx << (2-bit_offset));
1571                         n = byte_offset+1;
1572                 } else {
1573                         d[byte_offset] |= (idx >> (bit_offset-2));
1574                         d[byte_offset+1] = 0;
1575                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1576                         n = byte_offset+2;
1577                 }
1578                 s++; i++;
1579         }
1580
1581         /* fix up length */
1582         decoded.length = n;
1583         return decoded;
1584 }
1585
1586 /***************************************************************************
1587 decode a base64 string in-place - wrapper for the above
1588 ***************************************************************************/
1589 void base64_decode(char *s)
1590 {
1591         DATA_BLOB decoded = base64_decode_data_blob(s);
1592         memcpy(s, decoded.data, decoded.length);
1593         data_blob_free(&decoded);
1594
1595         /* null terminate */
1596         s[decoded.length] = '\0';
1597 }
1598
1599 /***************************************************************************
1600 encode a base64 string into a malloc()ed string caller to free.
1601
1602 From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1603 ***************************************************************************/
1604 char * base64_encode_data_blob(DATA_BLOB data)
1605 {
1606         int bits = 0;
1607         int char_count = 0;
1608         size_t out_cnt = 0;
1609         size_t len = data.length;
1610         size_t output_len = data.length * 2;
1611         char *result = malloc(output_len); /* get us plenty of space */
1612
1613         while (len-- && out_cnt < (data.length * 2) - 5) {
1614                 int c = (unsigned char) *(data.data++);
1615                 bits += c;
1616                 char_count++;
1617                 if (char_count == 3) {
1618                         result[out_cnt++] = b64[bits >> 18];
1619                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1620                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1621             result[out_cnt++] = b64[bits & 0x3f];
1622             bits = 0;
1623             char_count = 0;
1624         } else {
1625             bits <<= 8;
1626         }
1627     }
1628     if (char_count != 0) {
1629         bits <<= 16 - (8 * char_count);
1630         result[out_cnt++] = b64[bits >> 18];
1631         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1632         if (char_count == 1) {
1633             result[out_cnt++] = '=';
1634             result[out_cnt++] = '=';
1635         } else {
1636             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1637             result[out_cnt++] = '=';
1638         }
1639     }
1640     result[out_cnt] = '\0';     /* terminate */
1641     return result;
1642 }
1643
1644 #ifdef VALGRIND
1645 size_t valgrind_strlen(const char *s)
1646 {
1647         size_t count;
1648         for(count = 0; *s++; count++)
1649                 ;
1650         return count;
1651 }
1652 #endif