Remove smbldap_get_single_pstring() and all pstrings
[jra/samba/.git] / source / lib / util_str.c
1 /*
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4
5    Copyright (C) Andrew Tridgell 1992-2001
6    Copyright (C) Simo Sorce      2001-2002
7    Copyright (C) Martin Pool     2003
8    Copyright (C) James Peach     2006
9    Copyright (C) Jeremy Allison  1992-2007
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26
27 /**
28  * @file
29  * @brief String utilities.
30  **/
31
32 /**
33  * Internal function to get the next token from a string, return false if none
34  * found.  Handles double-quotes.  This is the work horse function called by
35  * next_token() and next_token_no_ltrim().
36  *
37  * Based on a routine by GJC@VILLAGE.COM.
38  * Extensively modified by Andrew.Tridgell@anu.edu.au
39  */
40 static bool next_token_internal(const char **ptr,
41                                 char *buff,
42                                 const char *sep,
43                                 size_t bufsize,
44                                 bool ltrim)
45 {
46         char *s;
47         char *pbuf;
48         bool quoted;
49         size_t len=1;
50
51         if (!ptr)
52                 return(false);
53
54         s = (char *)*ptr;
55
56         /* default to simple separators */
57         if (!sep)
58                 sep = " \t\n\r";
59
60         /* find the first non sep char, if left-trimming is requested */
61         if (ltrim) {
62                 while (*s && strchr_m(sep,*s))
63                         s++;
64         }
65
66         /* nothing left? */
67         if (! *s)
68                 return(false);
69
70         /* copy over the token */
71         pbuf = buff;
72         for (quoted = false; len < bufsize && *s &&
73                         (quoted || !strchr_m(sep,*s)); s++) {
74                 if ( *s == '\"' ) {
75                         quoted = !quoted;
76                 } else {
77                         len++;
78                         *pbuf++ = *s;
79                 }
80         }
81
82         *ptr = (*s) ? s+1 : s;
83         *pbuf = 0;
84
85         return(true);
86 }
87
88 /*
89  * Get the next token from a string, return false if none found.  Handles
90  * double-quotes.  This version trims leading separator characters before
91  * looking for a token.
92  */
93 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
94 {
95     return next_token_internal(ptr, buff, sep, bufsize, true);
96 }
97
98 /*
99  * Get the next token from a string, return false if none found.  Handles
100  * double-quotes.  This version does not trim leading separator characters
101  * before looking for a token.
102  */
103 bool next_token_no_ltrim(const char **ptr,
104                          char *buff,
105                          const char *sep,
106                          size_t bufsize)
107 {
108     return next_token_internal(ptr, buff, sep, bufsize, false);
109 }
110
111 /**
112 This is like next_token but is not re-entrant and "remembers" the first
113 parameter so you can pass NULL. This is useful for user interface code
114 but beware the fact that it is not re-entrant!
115 **/
116
117 static const char *last_ptr=NULL;
118
119 bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
120 {
121         bool ret;
122         if (!ptr)
123                 ptr = &last_ptr;
124
125         ret = next_token(ptr, buff, sep, bufsize);
126         last_ptr = *ptr;
127         return ret;
128 }
129
130 void set_first_token(char *ptr)
131 {
132         last_ptr = ptr;
133 }
134
135 /**
136  Convert list of tokens to array; dependent on above routine.
137  Uses last_ptr from above - bit of a hack.
138 **/
139
140 char **toktocliplist(int *ctok, const char *sep)
141 {
142         char *s=(char *)last_ptr;
143         int ictok=0;
144         char **ret, **iret;
145
146         if (!sep)
147                 sep = " \t\n\r";
148
149         while(*s && strchr_m(sep,*s))
150                 s++;
151
152         /* nothing left? */
153         if (!*s)
154                 return(NULL);
155
156         do {
157                 ictok++;
158                 while(*s && (!strchr_m(sep,*s)))
159                         s++;
160                 while(*s && strchr_m(sep,*s))
161                         *s++=0;
162         } while(*s);
163
164         *ctok=ictok;
165         s=(char *)last_ptr;
166
167         if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
168                 return NULL;
169
170         while(ictok--) {
171                 *iret++=s;
172                 if (ictok > 0) {
173                         while(*s++)
174                                 ;
175                         while(!*s)
176                                 s++;
177                 }
178         }
179
180         ret[*ctok] = NULL;
181         return ret;
182 }
183
184 /**
185  * Case insensitive string compararison.
186  *
187  * iconv does not directly give us a way to compare strings in
188  * arbitrary unix character sets -- all we can is convert and then
189  * compare.  This is expensive.
190  *
191  * As an optimization, we do a first pass that considers only the
192  * prefix of the strings that is entirely 7-bit.  Within this, we
193  * check whether they have the same value.
194  *
195  * Hopefully this will often give the answer without needing to copy.
196  * In particular it should speed comparisons to literal ascii strings
197  * or comparisons of strings that are "obviously" different.
198  *
199  * If we find a non-ascii character we fall back to converting via
200  * iconv.
201  *
202  * This should never be slower than convering the whole thing, and
203  * often faster.
204  *
205  * A different optimization would be to compare for bitwise equality
206  * in the binary encoding.  (It would be possible thought hairy to do
207  * both simultaneously.)  But in that case if they turn out to be
208  * different, we'd need to restart the whole thing.
209  *
210  * Even better is to implement strcasecmp for each encoding and use a
211  * function pointer.
212  **/
213 int StrCaseCmp(const char *s, const char *t)
214 {
215
216         const char *ps, *pt;
217         size_t size;
218         smb_ucs2_t *buffer_s, *buffer_t;
219         int ret;
220
221         for (ps = s, pt = t; ; ps++, pt++) {
222                 char us, ut;
223
224                 if (!*ps && !*pt)
225                         return 0; /* both ended */
226                 else if (!*ps)
227                         return -1; /* s is a prefix */
228                 else if (!*pt)
229                         return +1; /* t is a prefix */
230                 else if ((*ps & 0x80) || (*pt & 0x80))
231                         /* not ascii anymore, do it the hard way
232                          * from here on in */
233                         break;
234
235                 us = toupper_ascii(*ps);
236                 ut = toupper_ascii(*pt);
237                 if (us == ut)
238                         continue;
239                 else if (us < ut)
240                         return -1;
241                 else if (us > ut)
242                         return +1;
243         }
244
245         size = push_ucs2_allocate(&buffer_s, ps);
246         if (size == (size_t)-1) {
247                 return strcmp(ps, pt);
248                 /* Not quite the right answer, but finding the right one
249                    under this failure case is expensive, and it's pretty
250                    close */
251         }
252
253         size = push_ucs2_allocate(&buffer_t, pt);
254         if (size == (size_t)-1) {
255                 SAFE_FREE(buffer_s);
256                 return strcmp(ps, pt);
257                 /* Not quite the right answer, but finding the right one
258                    under this failure case is expensive, and it's pretty
259                    close */
260         }
261
262         ret = strcasecmp_w(buffer_s, buffer_t);
263         SAFE_FREE(buffer_s);
264         SAFE_FREE(buffer_t);
265         return ret;
266 }
267
268
269 /**
270  Case insensitive string compararison, length limited.
271 **/
272 int StrnCaseCmp(const char *s, const char *t, size_t len)
273 {
274         size_t n = 0;
275         const char *ps, *pt;
276         size_t size;
277         smb_ucs2_t *buffer_s, *buffer_t;
278         int ret;
279
280         for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
281                 char us, ut;
282
283                 if (!*ps && !*pt)
284                         return 0; /* both ended */
285                 else if (!*ps)
286                         return -1; /* s is a prefix */
287                 else if (!*pt)
288                         return +1; /* t is a prefix */
289                 else if ((*ps & 0x80) || (*pt & 0x80))
290                         /* not ascii anymore, do it the
291                          * hard way from here on in */
292                         break;
293
294                 us = toupper_ascii(*ps);
295                 ut = toupper_ascii(*pt);
296                 if (us == ut)
297                         continue;
298                 else if (us < ut)
299                         return -1;
300                 else if (us > ut)
301                         return +1;
302         }
303
304         if (n == len) {
305                 return 0;
306         }
307
308         size = push_ucs2_allocate(&buffer_s, ps);
309         if (size == (size_t)-1) {
310                 return strncmp(ps, pt, len-n);
311                 /* Not quite the right answer, but finding the right one
312                    under this failure case is expensive,
313                    and it's pretty close */
314         }
315
316         size = push_ucs2_allocate(&buffer_t, pt);
317         if (size == (size_t)-1) {
318                 SAFE_FREE(buffer_s);
319                 return strncmp(ps, pt, len-n);
320                 /* Not quite the right answer, but finding the right one
321                    under this failure case is expensive,
322                    and it's pretty close */
323         }
324
325         ret = strncasecmp_w(buffer_s, buffer_t, len-n);
326         SAFE_FREE(buffer_s);
327         SAFE_FREE(buffer_t);
328         return ret;
329 }
330
331 /**
332  * Compare 2 strings.
333  *
334  * @note The comparison is case-insensitive.
335  **/
336 bool strequal(const char *s1, const char *s2)
337 {
338         if (s1 == s2)
339                 return(true);
340         if (!s1 || !s2)
341                 return(false);
342
343         return(StrCaseCmp(s1,s2)==0);
344 }
345
346 /**
347  * Compare 2 strings up to and including the nth char.
348  *
349  * @note The comparison is case-insensitive.
350  **/
351 bool strnequal(const char *s1,const char *s2,size_t n)
352 {
353         if (s1 == s2)
354                 return(true);
355         if (!s1 || !s2 || !n)
356                 return(false);
357
358         return(StrnCaseCmp(s1,s2,n)==0);
359 }
360
361 /**
362  Compare 2 strings (case sensitive).
363 **/
364
365 bool strcsequal(const char *s1,const char *s2)
366 {
367         if (s1 == s2)
368                 return(true);
369         if (!s1 || !s2)
370                 return(false);
371
372         return(strcmp(s1,s2)==0);
373 }
374
375 /**
376 Do a case-insensitive, whitespace-ignoring string compare.
377 **/
378
379 int strwicmp(const char *psz1, const char *psz2)
380 {
381         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
382         /* appropriate value. */
383         if (psz1 == psz2)
384                 return (0);
385         else if (psz1 == NULL)
386                 return (-1);
387         else if (psz2 == NULL)
388                 return (1);
389
390         /* sync the strings on first non-whitespace */
391         while (1) {
392                 while (isspace((int)*psz1))
393                         psz1++;
394                 while (isspace((int)*psz2))
395                         psz2++;
396                 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
397                                 *psz1 == '\0' || *psz2 == '\0')
398                         break;
399                 psz1++;
400                 psz2++;
401         }
402         return (*psz1 - *psz2);
403 }
404
405
406 /**
407  Convert a string to upper case, but don't modify it.
408 **/
409
410 char *strupper_static(const char *s)
411 {
412         static char *str = NULL;
413
414         SAFE_FREE(str);
415         str = SMB_STRDUP(s);
416         strupper_m(str);
417         return str;
418 }
419
420 /**
421  Convert a string to "normal" form.
422 **/
423
424 void strnorm(char *s, int case_default)
425 {
426         if (case_default == CASE_UPPER)
427                 strupper_m(s);
428         else
429                 strlower_m(s);
430 }
431
432 /**
433  Check if a string is in "normal" case.
434 **/
435
436 bool strisnormal(const char *s, int case_default)
437 {
438         if (case_default == CASE_UPPER)
439                 return(!strhaslower(s));
440
441         return(!strhasupper(s));
442 }
443
444
445 /**
446  String replace.
447  NOTE: oldc and newc must be 7 bit characters
448 **/
449 void string_replace( char *s, char oldc, char newc )
450 {
451         char *p;
452
453         /* this is quite a common operation, so we want it to be
454            fast. We optimise for the ascii case, knowing that all our
455            supported multi-byte character sets are ascii-compatible
456            (ie. they match for the first 128 chars) */
457
458         for (p = s; *p; p++) {
459                 if (*p & 0x80) /* mb string - slow path. */
460                         break;
461                 if (*p == oldc) {
462                         *p = newc;
463                 }
464         }
465
466         if (!*p)
467                 return;
468
469         /* Slow (mb) path. */
470 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
471         /* With compose characters we must restart from the beginning. JRA. */
472         p = s;
473 #endif
474
475         while (*p) {
476                 size_t c_size;
477                 next_codepoint(p, &c_size);
478
479                 if (c_size == 1) {
480                         if (*p == oldc) {
481                                 *p = newc;
482                         }
483                 }
484                 p += c_size;
485         }
486 }
487
488 /**
489  *  Skip past some strings in a buffer - old version - no checks.
490  *  **/
491
492 char *push_skip_string(char *buf)
493 {
494         buf += strlen(buf) + 1;
495         return(buf);
496 }
497
498 /**
499  Skip past a string in a buffer. Buffer may not be
500  null terminated. end_ptr points to the first byte after
501  then end of the buffer.
502 **/
503
504 char *skip_string(const char *base, size_t len, char *buf)
505 {
506         const char *end_ptr = base + len;
507
508         if (end_ptr < base || !base || !buf || buf >= end_ptr) {
509                 return NULL;
510         }
511
512         /* Skip the string */
513         while (*buf) {
514                 buf++;
515                 if (buf >= end_ptr) {
516                         return NULL;
517                 }
518         }
519         /* Skip the '\0' */
520         buf++;
521         return buf;
522 }
523
524 /**
525  Count the number of characters in a string. Normally this will
526  be the same as the number of bytes in a string for single byte strings,
527  but will be different for multibyte.
528 **/
529
530 size_t str_charnum(const char *s)
531 {
532         size_t ret;
533         smb_ucs2_t *tmpbuf2 = NULL;
534         if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
535                 return 0;
536         }
537         ret = strlen_w(tmpbuf2);
538         SAFE_FREE(tmpbuf2);
539         return ret;
540 }
541
542 /**
543  Count the number of characters in a string. Normally this will
544  be the same as the number of bytes in a string for single byte strings,
545  but will be different for multibyte.
546 **/
547
548 size_t str_ascii_charnum(const char *s)
549 {
550         size_t ret;
551         char *tmpbuf2 = NULL;
552         if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
553                 return 0;
554         }
555         ret = strlen(tmpbuf2);
556         SAFE_FREE(tmpbuf2);
557         return ret;
558 }
559
560 bool trim_char(char *s,char cfront,char cback)
561 {
562         bool ret = false;
563         char *ep;
564         char *fp = s;
565
566         /* Ignore null or empty strings. */
567         if (!s || (s[0] == '\0'))
568                 return false;
569
570         if (cfront) {
571                 while (*fp && *fp == cfront)
572                         fp++;
573                 if (!*fp) {
574                         /* We ate the string. */
575                         s[0] = '\0';
576                         return true;
577                 }
578                 if (fp != s)
579                         ret = true;
580         }
581
582         ep = fp + strlen(fp) - 1;
583         if (cback) {
584                 /* Attempt ascii only. Bail for mb strings. */
585                 while ((ep >= fp) && (*ep == cback)) {
586                         ret = true;
587                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
588                                 /* Could be mb... bail back to tim_string. */
589                                 char fs[2], bs[2];
590                                 if (cfront) {
591                                         fs[0] = cfront;
592                                         fs[1] = '\0';
593                                 }
594                                 bs[0] = cback;
595                                 bs[1] = '\0';
596                                 return trim_string(s, cfront ? fs : NULL, bs);
597                         } else {
598                                 ep--;
599                         }
600                 }
601                 if (ep < fp) {
602                         /* We ate the string. */
603                         s[0] = '\0';
604                         return true;
605                 }
606         }
607
608         ep[1] = '\0';
609         memmove(s, fp, ep-fp+2);
610         return ret;
611 }
612
613 /**
614  Trim the specified elements off the front and back of a string.
615 **/
616
617 bool trim_string(char *s,const char *front,const char *back)
618 {
619         bool ret = false;
620         size_t front_len;
621         size_t back_len;
622         size_t len;
623
624         /* Ignore null or empty strings. */
625         if (!s || (s[0] == '\0'))
626                 return false;
627
628         front_len       = front? strlen(front) : 0;
629         back_len        = back? strlen(back) : 0;
630
631         len = strlen(s);
632
633         if (front_len) {
634                 while (len && strncmp(s, front, front_len)==0) {
635                         /* Must use memmove here as src & dest can
636                          * easily overlap. Found by valgrind. JRA. */
637                         memmove(s, s+front_len, (len-front_len)+1);
638                         len -= front_len;
639                         ret=true;
640                 }
641         }
642
643         if (back_len) {
644                 while ((len >= back_len) &&
645                                 strncmp(s+len-back_len,back,back_len)==0) {
646                         s[len-back_len]='\0';
647                         len -= back_len;
648                         ret=true;
649                 }
650         }
651         return ret;
652 }
653
654 /**
655  Does a string have any uppercase chars in it?
656 **/
657
658 bool strhasupper(const char *s)
659 {
660         smb_ucs2_t *tmp, *p;
661         bool ret;
662
663         if (push_ucs2_allocate(&tmp, s) == -1) {
664                 return false;
665         }
666
667         for(p = tmp; *p != 0; p++) {
668                 if(isupper_w(*p)) {
669                         break;
670                 }
671         }
672
673         ret = (*p != 0);
674         SAFE_FREE(tmp);
675         return ret;
676 }
677
678 /**
679  Does a string have any lowercase chars in it?
680 **/
681
682 bool strhaslower(const char *s)
683 {
684         smb_ucs2_t *tmp, *p;
685         bool ret;
686
687         if (push_ucs2_allocate(&tmp, s) == -1) {
688                 return false;
689         }
690
691         for(p = tmp; *p != 0; p++) {
692                 if(islower_w(*p)) {
693                         break;
694                 }
695         }
696
697         ret = (*p != 0);
698         SAFE_FREE(tmp);
699         return ret;
700 }
701
702 /**
703  Find the number of 'c' chars in a string
704 **/
705
706 size_t count_chars(const char *s,char c)
707 {
708         smb_ucs2_t *ptr;
709         int count;
710         smb_ucs2_t *alloc_tmpbuf = NULL;
711
712         if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
713                 return 0;
714         }
715
716         for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
717                 if(*ptr==UCS2_CHAR(c))
718                         count++;
719
720         SAFE_FREE(alloc_tmpbuf);
721         return(count);
722 }
723
724 /**
725  Safe string copy into a known length string. maxlength does not
726  include the terminating zero.
727 **/
728
729 char *safe_strcpy_fn(const char *fn,
730                 int line,
731                 char *dest,
732                 const char *src,
733                 size_t maxlength)
734 {
735         size_t len;
736
737         if (!dest) {
738                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
739                         "called from [%s][%d]\n", fn, line));
740                 return NULL;
741         }
742
743 #ifdef DEVELOPER
744         clobber_region(fn,line,dest, maxlength+1);
745 #endif
746
747         if (!src) {
748                 *dest = 0;
749                 return dest;
750         }
751
752         len = strnlen(src, maxlength+1);
753
754         if (len > maxlength) {
755                 DEBUG(0,("ERROR: string overflow by "
756                         "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
757                          (unsigned long)(len-maxlength), (unsigned long)len,
758                          (unsigned long)maxlength, src));
759                 len = maxlength;
760         }
761
762         memmove(dest, src, len);
763         dest[len] = 0;
764         return dest;
765 }
766
767 /**
768  Safe string cat into a string. maxlength does not
769  include the terminating zero.
770 **/
771 char *safe_strcat_fn(const char *fn,
772                 int line,
773                 char *dest,
774                 const char *src,
775                 size_t maxlength)
776 {
777         size_t src_len, dest_len;
778
779         if (!dest) {
780                 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
781                         "called from [%s][%d]\n", fn, line));
782                 return NULL;
783         }
784
785         if (!src)
786                 return dest;
787
788         src_len = strnlen(src, maxlength + 1);
789         dest_len = strnlen(dest, maxlength + 1);
790
791 #ifdef DEVELOPER
792         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
793 #endif
794
795         if (src_len + dest_len > maxlength) {
796                 DEBUG(0,("ERROR: string overflow by %d "
797                         "in safe_strcat [%.50s]\n",
798                          (int)(src_len + dest_len - maxlength), src));
799                 if (maxlength > dest_len) {
800                         memcpy(&dest[dest_len], src, maxlength - dest_len);
801                 }
802                 dest[maxlength] = 0;
803                 return NULL;
804         }
805
806         memcpy(&dest[dest_len], src, src_len);
807         dest[dest_len + src_len] = 0;
808         return dest;
809 }
810
811 /**
812  Paranoid strcpy into a buffer of given length (includes terminating
813  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
814  and replaces with '_'. Deliberately does *NOT* check for multibyte
815  characters. Don't change it !
816 **/
817
818 char *alpha_strcpy_fn(const char *fn,
819                 int line,
820                 char *dest,
821                 const char *src,
822                 const char *other_safe_chars,
823                 size_t maxlength)
824 {
825         size_t len, i;
826
827 #ifdef DEVELOPER
828         clobber_region(fn, line, dest, maxlength);
829 #endif
830
831         if (!dest) {
832                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
833                         "called from [%s][%d]\n", fn, line));
834                 return NULL;
835         }
836
837         if (!src) {
838                 *dest = 0;
839                 return dest;
840         }
841
842         len = strlen(src);
843         if (len >= maxlength)
844                 len = maxlength - 1;
845
846         if (!other_safe_chars)
847                 other_safe_chars = "";
848
849         for(i = 0; i < len; i++) {
850                 int val = (src[i] & 0xff);
851                 if (isupper_ascii(val) || islower_ascii(val) ||
852                                 isdigit(val) || strchr_m(other_safe_chars, val))
853                         dest[i] = src[i];
854                 else
855                         dest[i] = '_';
856         }
857
858         dest[i] = '\0';
859
860         return dest;
861 }
862
863 /**
864  Like strncpy but always null terminates. Make sure there is room!
865  The variable n should always be one less than the available size.
866 **/
867 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
868 {
869         char *d = dest;
870
871 #ifdef DEVELOPER
872         clobber_region(fn, line, dest, n+1);
873 #endif
874
875         if (!dest) {
876                 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
877                         "called from [%s][%d]\n", fn, line));
878                 return(NULL);
879         }
880
881         if (!src) {
882                 *dest = 0;
883                 return(dest);
884         }
885
886         while (n-- && (*d = *src)) {
887                 d++;
888                 src++;
889         }
890
891         *d = 0;
892         return(dest);
893 }
894
895 #if 0
896 /**
897  Like strncpy but copies up to the character marker.  always null terminates.
898  returns a pointer to the character marker in the source string (src).
899 **/
900
901 static char *strncpyn(char *dest, const char *src, size_t n, char c)
902 {
903         char *p;
904         size_t str_len;
905
906 #ifdef DEVELOPER
907         clobber_region(dest, n+1);
908 #endif
909         p = strchr_m(src, c);
910         if (p == NULL) {
911                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
912                 return NULL;
913         }
914
915         str_len = PTR_DIFF(p, src);
916         strncpy(dest, src, MIN(n, str_len));
917         dest[str_len] = '\0';
918
919         return p;
920 }
921 #endif
922
923 /**
924  Routine to get hex characters and turn them into a 16 byte array.
925  the array can be variable length, and any non-hex-numeric
926  characters are skipped.  "0xnn" or "0Xnn" is specially catered
927  for.
928
929  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
930
931 **/
932
933 size_t strhex_to_str(char *p, size_t len, const char *strhex)
934 {
935         size_t i;
936         size_t num_chars = 0;
937         unsigned char   lonybble, hinybble;
938         const char     *hexchars = "0123456789ABCDEF";
939         char           *p1 = NULL, *p2 = NULL;
940
941         for (i = 0; i < len && strhex[i] != 0; i++) {
942                 if (strnequal(hexchars, "0x", 2)) {
943                         i++; /* skip two chars */
944                         continue;
945                 }
946
947                 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
948                         break;
949
950                 i++; /* next hex digit */
951
952                 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
953                         break;
954
955                 /* get the two nybbles */
956                 hinybble = PTR_DIFF(p1, hexchars);
957                 lonybble = PTR_DIFF(p2, hexchars);
958
959                 p[num_chars] = (hinybble << 4) | lonybble;
960                 num_chars++;
961
962                 p1 = NULL;
963                 p2 = NULL;
964         }
965         return num_chars;
966 }
967
968 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
969 {
970         DATA_BLOB ret_blob;
971
972         if (mem_ctx != NULL)
973                 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
974         else
975                 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
976
977         ret_blob.length = strhex_to_str((char*)ret_blob.data,
978                                         strlen(strhex),
979                                         strhex);
980
981         return ret_blob;
982 }
983
984 /**
985  * Routine to print a buffer as HEX digits, into an allocated string.
986  */
987
988 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
989 {
990         int i;
991         char *hex_buffer;
992
993         hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
994
995         for (i = 0; i < len; i++)
996                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
997
998         return hex_buffer;
999 }
1000
1001 /**
1002  Check if a string is part of a list.
1003 **/
1004
1005 bool in_list(const char *s, const char *list, bool casesensitive)
1006 {
1007         char *tok;
1008         const char *p=list;
1009         size_t bufsize = strlen(list);
1010         bool ret = false;
1011
1012         if (!list)
1013                 return(false);
1014
1015         /* We know a token can't be larger
1016          * than the entire list. */
1017
1018         tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1019         if (!tok) {
1020                 return false;
1021         }
1022
1023         while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1024                 if (casesensitive) {
1025                         if (strcmp(tok,s) == 0) {
1026                                 ret = true;
1027                                 break;
1028                         }
1029                 } else {
1030                         if (StrCaseCmp(tok,s) == 0) {
1031                                 ret = true;
1032                                 break;
1033                         }
1034                 }
1035         }
1036
1037         SAFE_FREE(tok);
1038         return ret;
1039 }
1040
1041 /* this is used to prevent lots of mallocs of size 1 */
1042 static const char *null_string = "";
1043
1044 /**
1045  Set a string value, allocing the space for the string
1046 **/
1047
1048 static bool string_init(char **dest,const char *src)
1049 {
1050         size_t l;
1051
1052         if (!src)
1053                 src = "";
1054
1055         l = strlen(src);
1056
1057         if (l == 0) {
1058                 *dest = CONST_DISCARD(char*, null_string);
1059         } else {
1060                 (*dest) = SMB_STRDUP(src);
1061                 if ((*dest) == NULL) {
1062                         DEBUG(0,("Out of memory in string_init\n"));
1063                         return false;
1064                 }
1065         }
1066         return(true);
1067 }
1068
1069 /**
1070  Free a string value.
1071 **/
1072
1073 void string_free(char **s)
1074 {
1075         if (!s || !(*s))
1076                 return;
1077         if (*s == null_string)
1078                 *s = NULL;
1079         SAFE_FREE(*s);
1080 }
1081
1082 /**
1083  Set a string value, deallocating any existing space, and allocing the space
1084  for the string
1085 **/
1086
1087 bool string_set(char **dest,const char *src)
1088 {
1089         string_free(dest);
1090         return(string_init(dest,src));
1091 }
1092
1093 /**
1094  Substitute a string for a pattern in another string. Make sure there is
1095  enough room!
1096
1097  This routine looks for pattern in s and replaces it with
1098  insert. It may do multiple replacements or just one.
1099
1100  Any of " ; ' $ or ` in the insert string are replaced with _
1101  if len==0 then the string cannot be extended. This is different from the old
1102  use of len==0 which was for no length checks to be done.
1103 **/
1104
1105 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1106                  bool remove_unsafe_characters, bool replace_once,
1107                  bool allow_trailing_dollar)
1108 {
1109         char *p;
1110         ssize_t ls,lp,li, i;
1111
1112         if (!insert || !pattern || !*pattern || !s)
1113                 return;
1114
1115         ls = (ssize_t)strlen(s);
1116         lp = (ssize_t)strlen(pattern);
1117         li = (ssize_t)strlen(insert);
1118
1119         if (len == 0)
1120                 len = ls + 1; /* len is number of *bytes* */
1121
1122         while (lp <= ls && (p = strstr_m(s,pattern))) {
1123                 if (ls + (li-lp) >= len) {
1124                         DEBUG(0,("ERROR: string overflow by "
1125                                 "%d in string_sub(%.50s, %d)\n",
1126                                  (int)(ls + (li-lp) - len),
1127                                  pattern, (int)len));
1128                         break;
1129                 }
1130                 if (li != lp) {
1131                         memmove(p+li,p+lp,strlen(p+lp)+1);
1132                 }
1133                 for (i=0;i<li;i++) {
1134                         switch (insert[i]) {
1135                         case '`':
1136                         case '"':
1137                         case '\'':
1138                         case ';':
1139                         case '$':
1140                                 /* allow a trailing $
1141                                  * (as in machine accounts) */
1142                                 if (allow_trailing_dollar && (i == li - 1 )) {
1143                                         p[i] = insert[i];
1144                                         break;
1145                                 }
1146                         case '%':
1147                         case '\r':
1148                         case '\n':
1149                                 if ( remove_unsafe_characters ) {
1150                                         p[i] = '_';
1151                                         /* yes this break should be here
1152                                          * since we want to fall throw if
1153                                          * not replacing unsafe chars */
1154                                         break;
1155                                 }
1156                         default:
1157                                 p[i] = insert[i];
1158                         }
1159                 }
1160                 s = p + li;
1161                 ls += (li-lp);
1162
1163                 if (replace_once)
1164                         break;
1165         }
1166 }
1167
1168 void string_sub_once(char *s, const char *pattern,
1169                 const char *insert, size_t len)
1170 {
1171         string_sub2( s, pattern, insert, len, true, true, false );
1172 }
1173
1174 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1175 {
1176         string_sub2( s, pattern, insert, len, true, false, false );
1177 }
1178
1179 void fstring_sub(char *s,const char *pattern,const char *insert)
1180 {
1181         string_sub(s, pattern, insert, sizeof(fstring));
1182 }
1183
1184 void pstring_sub(char *s,const char *pattern,const char *insert)
1185 {
1186         string_sub(s, pattern, insert, sizeof(pstring));
1187 }
1188
1189 /**
1190  Similar to string_sub2, but it will accept only allocated strings
1191  and may realloc them so pay attention at what you pass on no
1192  pointers inside strings, no pstrings or const may be passed
1193  as string.
1194 **/
1195
1196 char *realloc_string_sub2(char *string,
1197                         const char *pattern,
1198                         const char *insert,
1199                         bool remove_unsafe_characters,
1200                         bool allow_trailing_dollar)
1201 {
1202         char *p, *in;
1203         char *s;
1204         ssize_t ls,lp,li,ld, i;
1205
1206         if (!insert || !pattern || !*pattern || !string || !*string)
1207                 return NULL;
1208
1209         s = string;
1210
1211         in = SMB_STRDUP(insert);
1212         if (!in) {
1213                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1214                 return NULL;
1215         }
1216         ls = (ssize_t)strlen(s);
1217         lp = (ssize_t)strlen(pattern);
1218         li = (ssize_t)strlen(insert);
1219         ld = li - lp;
1220         for (i=0;i<li;i++) {
1221                 switch (in[i]) {
1222                         case '`':
1223                         case '"':
1224                         case '\'':
1225                         case ';':
1226                         case '$':
1227                                 /* allow a trailing $
1228                                  * (as in machine accounts) */
1229                                 if (allow_trailing_dollar && (i == li - 1 )) {
1230                                         break;
1231                                 }
1232                         case '%':
1233                         case '\r':
1234                         case '\n':
1235                                 if ( remove_unsafe_characters ) {
1236                                         in[i] = '_';
1237                                         break;
1238                                 }
1239                         default:
1240                                 /* ok */
1241                                 break;
1242                 }
1243         }
1244
1245         while ((p = strstr_m(s,pattern))) {
1246                 if (ld > 0) {
1247                         int offset = PTR_DIFF(s,string);
1248                         string = (char *)SMB_REALLOC(string, ls + ld + 1);
1249                         if (!string) {
1250                                 DEBUG(0, ("realloc_string_sub: "
1251                                         "out of memory!\n"));
1252                                 SAFE_FREE(in);
1253                                 return NULL;
1254                         }
1255                         p = string + offset + (p - s);
1256                 }
1257                 if (li != lp) {
1258                         memmove(p+li,p+lp,strlen(p+lp)+1);
1259                 }
1260                 memcpy(p, in, li);
1261                 s = p + li;
1262                 ls += ld;
1263         }
1264         SAFE_FREE(in);
1265         return string;
1266 }
1267
1268 char *realloc_string_sub(char *string,
1269                         const char *pattern,
1270                         const char *insert)
1271 {
1272         return realloc_string_sub2(string, pattern, insert, true, false);
1273 }
1274
1275 /*
1276  * Internal guts of talloc_string_sub and talloc_all_string_sub.
1277  * 'filter' differentiates between them.
1278  */
1279
1280 static char *talloc_string_sub_internal(TALLOC_CTX *mem_ctx, const char *src,
1281                         const char *pattern, const char *insert, bool filter)
1282 {
1283         char *p, *in;
1284         char *s;
1285         char *string;
1286         ssize_t ls,lp,li,ld, i;
1287
1288         if (!insert || !pattern || !*pattern || !src || !*src) {
1289                 return NULL;
1290         }
1291
1292         string = talloc_strdup(mem_ctx, src);
1293         if (string == NULL) {
1294                 DEBUG(0, ("talloc_string_sub_internal: "
1295                         "talloc_strdup failed\n"));
1296                 return NULL;
1297         }
1298
1299         s = string;
1300
1301         in = SMB_STRDUP(insert);
1302         if (!in) {
1303                 DEBUG(0, ("talloc_string_sub_internal: ENOMEM\n"));
1304                 return NULL;
1305         }
1306         ls = (ssize_t)strlen(s);
1307         lp = (ssize_t)strlen(pattern);
1308         li = (ssize_t)strlen(insert);
1309         ld = li - lp;
1310
1311         if (filter) {
1312                 for (i=0;i<li;i++) {
1313                         switch (in[i]) {
1314                                 case '`':
1315                                 case '"':
1316                                 case '\'':
1317                                 case ';':
1318                                 case '$':
1319                                 case '%':
1320                                 case '\r':
1321                                 case '\n':
1322                                         in[i] = '_';
1323                                 default:
1324                                         /* ok */
1325                                         break;
1326                         }
1327                 }
1328         }
1329
1330         while ((p = strstr_m(s,pattern))) {
1331                 if (ld > 0) {
1332                         int offset = PTR_DIFF(s,string);
1333                         string = (char *)TALLOC_REALLOC(mem_ctx, string,
1334                                                         ls + ld + 1);
1335                         if (!string) {
1336                                 DEBUG(0, ("talloc_string_sub: out of "
1337                                           "memory!\n"));
1338                                 SAFE_FREE(in);
1339                                 return NULL;
1340                         }
1341                         p = string + offset + (p - s);
1342                 }
1343                 if (li != lp) {
1344                         memmove(p+li,p+lp,strlen(p+lp)+1);
1345                 }
1346                 memcpy(p, in, li);
1347                 s = p + li;
1348                 ls += ld;
1349         }
1350         SAFE_FREE(in);
1351         return string;
1352 }
1353
1354 /* Same as string_sub, but returns a talloc'ed string */
1355
1356 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1357                         const char *pattern, const char *insert)
1358 {
1359         return talloc_string_sub_internal(mem_ctx, src, pattern, insert, true);
1360 }
1361
1362 /**
1363  Similar to string_sub() but allows for any character to be substituted.
1364  Use with caution!
1365  if len==0 then the string cannot be extended. This is different from the old
1366  use of len==0 which was for no length checks to be done.
1367 **/
1368
1369 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1370 {
1371         char *p;
1372         ssize_t ls,lp,li;
1373
1374         if (!insert || !pattern || !s)
1375                 return;
1376
1377         ls = (ssize_t)strlen(s);
1378         lp = (ssize_t)strlen(pattern);
1379         li = (ssize_t)strlen(insert);
1380
1381         if (!*pattern)
1382                 return;
1383
1384         if (len == 0)
1385                 len = ls + 1; /* len is number of *bytes* */
1386
1387         while (lp <= ls && (p = strstr_m(s,pattern))) {
1388                 if (ls + (li-lp) >= len) {
1389                         DEBUG(0,("ERROR: string overflow by "
1390                                 "%d in all_string_sub(%.50s, %d)\n",
1391                                  (int)(ls + (li-lp) - len),
1392                                  pattern, (int)len));
1393                         break;
1394                 }
1395                 if (li != lp) {
1396                         memmove(p+li,p+lp,strlen(p+lp)+1);
1397                 }
1398                 memcpy(p, insert, li);
1399                 s = p + li;
1400                 ls += (li-lp);
1401         }
1402 }
1403
1404 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1405                                 const char *src,
1406                                 const char *pattern,
1407                                 const char *insert)
1408 {
1409         return talloc_string_sub_internal(ctx, src, pattern, insert, false);
1410 }
1411
1412 /**
1413  Similar to all_string_sub but for unicode strings.
1414  Return a new allocated unicode string.
1415  similar to string_sub() but allows for any character to be substituted.
1416  Use with caution!
1417 **/
1418
1419 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s,
1420                                 const smb_ucs2_t *pattern,
1421                                 const smb_ucs2_t *insert)
1422 {
1423         smb_ucs2_t *r, *rp;
1424         const smb_ucs2_t *sp;
1425         size_t  lr, lp, li, lt;
1426
1427         if (!insert || !pattern || !*pattern || !s)
1428                 return NULL;
1429
1430         lt = (size_t)strlen_w(s);
1431         lp = (size_t)strlen_w(pattern);
1432         li = (size_t)strlen_w(insert);
1433
1434         if (li > lp) {
1435                 const smb_ucs2_t *st = s;
1436                 int ld = li - lp;
1437                 while ((sp = strstr_w(st, pattern))) {
1438                         st = sp + lp;
1439                         lt += ld;
1440                 }
1441         }
1442
1443         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1444         if (!r) {
1445                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1446                 return NULL;
1447         }
1448
1449         while ((sp = strstr_w(s, pattern))) {
1450                 memcpy(rp, s, (sp - s));
1451                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1452                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1453                 s = sp + lp;
1454                 rp += li;
1455         }
1456         lr = ((rp - r) / sizeof(smb_ucs2_t));
1457         if (lr < lt) {
1458                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1459                 rp += (lt - lr);
1460         }
1461         *rp = 0;
1462
1463         return r;
1464 }
1465
1466 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1467                                              const char *insert)
1468 {
1469         wpstring p, i;
1470
1471         if (!insert || !pattern || !s)
1472                 return NULL;
1473         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1474         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1475         return all_string_sub_w(s, p, i);
1476 }
1477
1478 #if 0
1479 /**
1480  Splits out the front and back at a separator.
1481 **/
1482
1483 static void split_at_last_component(char *path, char *front, char sep,
1484                 char *back)
1485 {
1486         char *p = strrchr_m(path, sep);
1487
1488         if (p != NULL)
1489                 *p = 0;
1490
1491         if (front != NULL)
1492                 pstrcpy(front, path);
1493
1494         if (p != NULL) {
1495                 if (back != NULL)
1496                         pstrcpy(back, p+1);
1497                 *p = '\\';
1498         } else {
1499                 if (back != NULL)
1500                         back[0] = 0;
1501         }
1502 }
1503 #endif
1504
1505 /**
1506  Write an octal as a string.
1507 **/
1508
1509 const char *octal_string(int i)
1510 {
1511         static char ret[64];
1512         if (i == -1)
1513                 return "-1";
1514         slprintf(ret, sizeof(ret)-1, "0%o", i);
1515         return ret;
1516 }
1517
1518
1519 /**
1520  Truncate a string at a specified length.
1521 **/
1522
1523 char *string_truncate(char *s, unsigned int length)
1524 {
1525         if (s && strlen(s) > length)
1526                 s[length] = 0;
1527         return s;
1528 }
1529
1530 /**
1531  Strchr and strrchr_m are very hard to do on general multi-byte strings.
1532  We convert via ucs2 for now.
1533 **/
1534
1535 char *strchr_m(const char *src, char c)
1536 {
1537         smb_ucs2_t *ws = NULL;
1538         char *s2 = NULL;
1539         smb_ucs2_t *p;
1540         const char *s;
1541         char *ret;
1542
1543         /* characters below 0x3F are guaranteed to not appear in
1544            non-initial position in multi-byte charsets */
1545         if ((c & 0xC0) == 0) {
1546                 return strchr(src, c);
1547         }
1548
1549         /* this is quite a common operation, so we want it to be
1550            fast. We optimise for the ascii case, knowing that all our
1551            supported multi-byte character sets are ascii-compatible
1552            (ie. they match for the first 128 chars) */
1553
1554         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1555                 if (*s == c)
1556                         return (char *)s;
1557         }
1558
1559         if (!*s)
1560                 return NULL;
1561
1562 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1563         /* With compose characters we must restart from the beginning. JRA. */
1564         s = src;
1565 #endif
1566
1567         if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1568                 /* Wrong answer, but what can we do... */
1569                 return strchr(src, c);
1570         }
1571         p = strchr_w(ws, UCS2_CHAR(c));
1572         if (!p) {
1573                 SAFE_FREE(ws);
1574                 return NULL;
1575         }
1576         *p = 0;
1577         if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1578                 SAFE_FREE(ws);
1579                 /* Wrong answer, but what can we do... */
1580                 return strchr(src, c);
1581         }
1582         ret = (char *)(s+strlen(s2));
1583         SAFE_FREE(ws);
1584         SAFE_FREE(s2);
1585         return ret;
1586 }
1587
1588 char *strrchr_m(const char *s, char c)
1589 {
1590         /* characters below 0x3F are guaranteed to not appear in
1591            non-initial position in multi-byte charsets */
1592         if ((c & 0xC0) == 0) {
1593                 return strrchr(s, c);
1594         }
1595
1596         /* this is quite a common operation, so we want it to be
1597            fast. We optimise for the ascii case, knowing that all our
1598            supported multi-byte character sets are ascii-compatible
1599            (ie. they match for the first 128 chars). Also, in Samba
1600            we only search for ascii characters in 'c' and that
1601            in all mb character sets with a compound character
1602            containing c, if 'c' is not a match at position
1603            p, then p[-1] > 0x7f. JRA. */
1604
1605         {
1606                 size_t len = strlen(s);
1607                 const char *cp = s;
1608                 bool got_mb = false;
1609
1610                 if (len == 0)
1611                         return NULL;
1612                 cp += (len - 1);
1613                 do {
1614                         if (c == *cp) {
1615                                 /* Could be a match. Part of a multibyte ? */
1616                                 if ((cp > s) &&
1617                                         (((unsigned char)cp[-1]) & 0x80)) {
1618                                         /* Yep - go slow :-( */
1619                                         got_mb = true;
1620                                         break;
1621                                 }
1622                                 /* No - we have a match ! */
1623                                 return (char *)cp;
1624                         }
1625                 } while (cp-- != s);
1626                 if (!got_mb)
1627                         return NULL;
1628         }
1629
1630         /* String contained a non-ascii char. Slow path. */
1631         {
1632                 smb_ucs2_t *ws = NULL;
1633                 char *s2 = NULL;
1634                 smb_ucs2_t *p;
1635                 char *ret;
1636
1637                 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1638                         /* Wrong answer, but what can we do. */
1639                         return strrchr(s, c);
1640                 }
1641                 p = strrchr_w(ws, UCS2_CHAR(c));
1642                 if (!p) {
1643                         SAFE_FREE(ws);
1644                         return NULL;
1645                 }
1646                 *p = 0;
1647                 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1648                         SAFE_FREE(ws);
1649                         /* Wrong answer, but what can we do. */
1650                         return strrchr(s, c);
1651                 }
1652                 ret = (char *)(s+strlen(s2));
1653                 SAFE_FREE(ws);
1654                 SAFE_FREE(s2);
1655                 return ret;
1656         }
1657 }
1658
1659 /***********************************************************************
1660  Return the equivalent of doing strrchr 'n' times - always going
1661  backwards.
1662 ***********************************************************************/
1663
1664 char *strnrchr_m(const char *s, char c, unsigned int n)
1665 {
1666         smb_ucs2_t *ws = NULL;
1667         char *s2 = NULL;
1668         smb_ucs2_t *p;
1669         char *ret;
1670
1671         if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1672                 /* Too hard to try and get right. */
1673                 return NULL;
1674         }
1675         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1676         if (!p) {
1677                 SAFE_FREE(ws);
1678                 return NULL;
1679         }
1680         *p = 0;
1681         if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1682                 SAFE_FREE(ws);
1683                 /* Too hard to try and get right. */
1684                 return NULL;
1685         }
1686         ret = (char *)(s+strlen(s2));
1687         SAFE_FREE(ws);
1688         SAFE_FREE(s2);
1689         return ret;
1690 }
1691
1692 /***********************************************************************
1693  strstr_m - We convert via ucs2 for now.
1694 ***********************************************************************/
1695
1696 char *strstr_m(const char *src, const char *findstr)
1697 {
1698         smb_ucs2_t *p;
1699         smb_ucs2_t *src_w, *find_w;
1700         const char *s;
1701         char *s2;
1702         char *retp;
1703
1704         size_t findstr_len = 0;
1705
1706         /* for correctness */
1707         if (!findstr[0]) {
1708                 return (char*)src;
1709         }
1710
1711         /* Samba does single character findstr calls a *lot*. */
1712         if (findstr[1] == '\0')
1713                 return strchr_m(src, *findstr);
1714
1715         /* We optimise for the ascii case, knowing that all our
1716            supported multi-byte character sets are ascii-compatible
1717            (ie. they match for the first 128 chars) */
1718
1719         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1720                 if (*s == *findstr) {
1721                         if (!findstr_len)
1722                                 findstr_len = strlen(findstr);
1723
1724                         if (strncmp(s, findstr, findstr_len) == 0) {
1725                                 return (char *)s;
1726                         }
1727                 }
1728         }
1729
1730         if (!*s)
1731                 return NULL;
1732
1733 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1734         /* 'make check' fails unless we do this */
1735
1736         /* With compose characters we must restart from the beginning. JRA. */
1737         s = src;
1738 #endif
1739
1740         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1741                 DEBUG(0,("strstr_m: src malloc fail\n"));
1742                 return NULL;
1743         }
1744
1745         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1746                 SAFE_FREE(src_w);
1747                 DEBUG(0,("strstr_m: find malloc fail\n"));
1748                 return NULL;
1749         }
1750
1751         p = strstr_w(src_w, find_w);
1752
1753         if (!p) {
1754                 SAFE_FREE(src_w);
1755                 SAFE_FREE(find_w);
1756                 return NULL;
1757         }
1758
1759         *p = 0;
1760         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1761                 SAFE_FREE(src_w);
1762                 SAFE_FREE(find_w);
1763                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1764                 return NULL;
1765         }
1766         retp = (char *)(s+strlen(s2));
1767         SAFE_FREE(src_w);
1768         SAFE_FREE(find_w);
1769         SAFE_FREE(s2);
1770         return retp;
1771 }
1772
1773 /**
1774  Convert a string to lower case.
1775 **/
1776
1777 void strlower_m(char *s)
1778 {
1779         size_t len;
1780         int errno_save;
1781
1782         /* this is quite a common operation, so we want it to be
1783            fast. We optimise for the ascii case, knowing that all our
1784            supported multi-byte character sets are ascii-compatible
1785            (ie. they match for the first 128 chars) */
1786
1787         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1788                 *s = tolower_ascii((unsigned char)*s);
1789                 s++;
1790         }
1791
1792         if (!*s)
1793                 return;
1794
1795         /* I assume that lowercased string takes the same number of bytes
1796          * as source string even in UTF-8 encoding. (VIV) */
1797         len = strlen(s) + 1;
1798         errno_save = errno;
1799         errno = 0;
1800         unix_strlower(s,len,s,len);
1801         /* Catch mb conversion errors that may not terminate. */
1802         if (errno)
1803                 s[len-1] = '\0';
1804         errno = errno_save;
1805 }
1806
1807 /**
1808  Convert a string to upper case.
1809 **/
1810
1811 void strupper_m(char *s)
1812 {
1813         size_t len;
1814         int errno_save;
1815
1816         /* this is quite a common operation, so we want it to be
1817            fast. We optimise for the ascii case, knowing that all our
1818            supported multi-byte character sets are ascii-compatible
1819            (ie. they match for the first 128 chars) */
1820
1821         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1822                 *s = toupper_ascii((unsigned char)*s);
1823                 s++;
1824         }
1825
1826         if (!*s)
1827                 return;
1828
1829         /* I assume that lowercased string takes the same number of bytes
1830          * as source string even in multibyte encoding. (VIV) */
1831         len = strlen(s) + 1;
1832         errno_save = errno;
1833         errno = 0;
1834         unix_strupper(s,len,s,len);
1835         /* Catch mb conversion errors that may not terminate. */
1836         if (errno)
1837                 s[len-1] = '\0';
1838         errno = errno_save;
1839 }
1840
1841 /**
1842  Count the number of UCS2 characters in a string. Normally this will
1843  be the same as the number of bytes in a string for single byte strings,
1844  but will be different for multibyte.
1845 **/
1846
1847 size_t strlen_m(const char *s)
1848 {
1849         size_t count = 0;
1850
1851         if (!s) {
1852                 return 0;
1853         }
1854
1855         while (*s && !(((uint8_t)*s) & 0x80)) {
1856                 s++;
1857                 count++;
1858         }
1859
1860         if (!*s) {
1861                 return count;
1862         }
1863
1864         while (*s) {
1865                 size_t c_size;
1866                 codepoint_t c = next_codepoint(s, &c_size);
1867                 if (c < 0x10000) {
1868                         /* Unicode char fits into 16 bits. */
1869                         count += 1;
1870                 } else {
1871                         /* Double-width unicode char - 32 bits. */
1872                         count += 2;
1873                 }
1874                 s += c_size;
1875         }
1876
1877         return count;
1878 }
1879
1880 /**
1881  Count the number of UCS2 characters in a string including the null
1882  terminator.
1883 **/
1884
1885 size_t strlen_m_term(const char *s)
1886 {
1887         if (!s) {
1888                 return 0;
1889         }
1890         return strlen_m(s) + 1;
1891 }
1892
1893 /*
1894  * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1895  * if a string is there, include the terminator.
1896  */
1897
1898 size_t strlen_m_term_null(const char *s)
1899 {
1900         size_t len;
1901         if (!s) {
1902                 return 0;
1903         }
1904         len = strlen_m(s);
1905         if (len == 0) {
1906                 return 0;
1907         }
1908
1909         return len+1;
1910 }
1911 /**
1912  Return a RFC2254 binary string representation of a buffer.
1913  Used in LDAP filters.
1914  Caller must free.
1915 **/
1916
1917 char *binary_string_rfc2254(char *buf, int len)
1918 {
1919         char *s;
1920         int i, j;
1921         const char *hex = "0123456789ABCDEF";
1922         s = (char *)SMB_MALLOC(len * 3 + 1);
1923         if (!s)
1924                 return NULL;
1925         for (j=i=0;i<len;i++) {
1926                 s[j] = '\\';
1927                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1928                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1929                 j += 3;
1930         }
1931         s[j] = 0;
1932         return s;
1933 }
1934
1935 char *binary_string(char *buf, int len)
1936 {
1937         char *s;
1938         int i, j;
1939         const char *hex = "0123456789ABCDEF";
1940         s = (char *)SMB_MALLOC(len * 2 + 1);
1941         if (!s)
1942                 return NULL;
1943         for (j=i=0;i<len;i++) {
1944                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1945                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1946                 j += 2;
1947         }
1948         s[j] = 0;
1949         return s;
1950 }
1951 /**
1952  Just a typesafety wrapper for snprintf into a pstring.
1953 **/
1954
1955  int pstr_sprintf(pstring s, const char *fmt, ...)
1956 {
1957         va_list ap;
1958         int ret;
1959
1960         va_start(ap, fmt);
1961         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1962         va_end(ap);
1963         return ret;
1964 }
1965
1966
1967 /**
1968  Just a typesafety wrapper for snprintf into a fstring.
1969 **/
1970
1971 int fstr_sprintf(fstring s, const char *fmt, ...)
1972 {
1973         va_list ap;
1974         int ret;
1975
1976         va_start(ap, fmt);
1977         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1978         va_end(ap);
1979         return ret;
1980 }
1981
1982 /**
1983  List of Strings manipulation functions
1984 **/
1985
1986 #define S_LIST_ABS 16 /* List Allocation Block Size */
1987
1988 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
1989                 const char *string,
1990                 const char *sep)
1991 {
1992         char **list, **rlist;
1993         const char *str;
1994         char *s;
1995         int num, lsize;
1996         pstring tok;
1997
1998         if (!string || !*string)
1999                 return NULL;
2000         if (mem_ctx) {
2001                 s = talloc_strdup(mem_ctx, string);
2002         } else {
2003                 s = SMB_STRDUP(string);
2004         }
2005         if (!s) {
2006                 DEBUG(0,("str_list_make: Unable to allocate memory"));
2007                 return NULL;
2008         }
2009         if (!sep) sep = LIST_SEP;
2010
2011         num = lsize = 0;
2012         list = NULL;
2013
2014         str = s;
2015         while (next_token(&str, tok, sep, sizeof(tok))) {
2016                 if (num == lsize) {
2017                         lsize += S_LIST_ABS;
2018                         if (mem_ctx) {
2019                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
2020                                                 char *, lsize +1);
2021                         } else {
2022                                 /* We need to keep the old list on
2023                                  * error so we can free the elements
2024                                    if the realloc fails. */
2025                                 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2026                                                 char *, lsize +1);
2027                         }
2028                         if (!rlist) {
2029                                 DEBUG(0,("str_list_make: "
2030                                         "Unable to allocate memory"));
2031                                 str_list_free(&list);
2032                                 if (mem_ctx) {
2033                                         TALLOC_FREE(s);
2034                                 } else {
2035                                         SAFE_FREE(s);
2036                                 }
2037                                 return NULL;
2038                         } else {
2039                                 list = rlist;
2040                         }
2041                         memset (&list[num], 0,
2042                                         ((sizeof(char**)) * (S_LIST_ABS +1)));
2043                 }
2044
2045                 if (mem_ctx) {
2046                         list[num] = talloc_strdup(mem_ctx, tok);
2047                 } else {
2048                         list[num] = SMB_STRDUP(tok);
2049                 }
2050
2051                 if (!list[num]) {
2052                         DEBUG(0,("str_list_make: Unable to allocate memory"));
2053                         str_list_free(&list);
2054                         if (mem_ctx) {
2055                                 TALLOC_FREE(s);
2056                         } else {
2057                                 SAFE_FREE(s);
2058                         }
2059                         return NULL;
2060                 }
2061
2062                 num++;
2063         }
2064
2065         if (mem_ctx) {
2066                 TALLOC_FREE(s);
2067         } else {
2068                 SAFE_FREE(s);
2069         }
2070
2071         return list;
2072 }
2073
2074 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
2075                 const char *string,
2076                 const char *sep)
2077 {
2078         return str_list_make_internal(mem_ctx, string, sep);
2079 }
2080
2081 char **str_list_make(const char *string, const char *sep)
2082 {
2083         return str_list_make_internal(NULL, string, sep);
2084 }
2085
2086 bool str_list_copy(char ***dest, const char **src)
2087 {
2088         char **list, **rlist;
2089         int num, lsize;
2090
2091         *dest = NULL;
2092         if (!src)
2093                 return false;
2094
2095         num = lsize = 0;
2096         list = NULL;
2097
2098         while (src[num]) {
2099                 if (num == lsize) {
2100                         lsize += S_LIST_ABS;
2101                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2102                                         char *, lsize +1);
2103                         if (!rlist) {
2104                                 DEBUG(0,("str_list_copy: "
2105                                         "Unable to re-allocate memory"));
2106                                 str_list_free(&list);
2107                                 return false;
2108                         } else {
2109                                 list = rlist;
2110                         }
2111                         memset (&list[num], 0,
2112                                         ((sizeof(char **)) * (S_LIST_ABS +1)));
2113                 }
2114
2115                 list[num] = SMB_STRDUP(src[num]);
2116                 if (!list[num]) {
2117                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
2118                         str_list_free(&list);
2119                         return false;
2120                 }
2121
2122                 num++;
2123         }
2124
2125         *dest = list;
2126         return true;
2127 }
2128
2129 /**
2130  * Return true if all the elements of the list match exactly.
2131  **/
2132 bool str_list_compare(char **list1, char **list2)
2133 {
2134         int num;
2135
2136         if (!list1 || !list2)
2137                 return (list1 == list2);
2138
2139         for (num = 0; list1[num]; num++) {
2140                 if (!list2[num])
2141                         return false;
2142                 if (!strcsequal(list1[num], list2[num]))
2143                         return false;
2144         }
2145         if (list2[num])
2146                 return false; /* if list2 has more elements than list1 fail */
2147
2148         return true;
2149 }
2150
2151 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2152 {
2153         char **tlist;
2154
2155         if (!list || !*list)
2156                 return;
2157         tlist = *list;
2158         for(; *tlist; tlist++) {
2159                 if (mem_ctx) {
2160                         TALLOC_FREE(*tlist);
2161                 } else {
2162                         SAFE_FREE(*tlist);
2163                 }
2164         }
2165         if (mem_ctx) {
2166                 TALLOC_FREE(*tlist);
2167         } else {
2168                 SAFE_FREE(*list);
2169         }
2170 }
2171
2172 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2173 {
2174         str_list_free_internal(mem_ctx, list);
2175 }
2176
2177 void str_list_free(char ***list)
2178 {
2179         str_list_free_internal(NULL, list);
2180 }
2181
2182 /******************************************************************************
2183  *****************************************************************************/
2184
2185 int str_list_count( const char **list )
2186 {
2187         int i = 0;
2188
2189         if ( ! list )
2190                 return 0;
2191
2192         /* count the number of list members */
2193
2194         for ( i=0; *list; i++, list++ );
2195
2196         return i;
2197 }
2198
2199 /******************************************************************************
2200  version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2201  for the work
2202  *****************************************************************************/
2203
2204 bool str_list_sub_basic( char **list, const char *smb_name,
2205                          const char *domain_name )
2206 {
2207         char *s, *tmpstr;
2208
2209         while ( *list ) {
2210                 s = *list;
2211                 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2212                 if ( !tmpstr ) {
2213                         DEBUG(0,("str_list_sub_basic: "
2214                                 "alloc_sub_basic() return NULL!\n"));
2215                         return false;
2216                 }
2217
2218                 SAFE_FREE(*list);
2219                 *list = tmpstr;
2220
2221                 list++;
2222         }
2223
2224         return true;
2225 }
2226
2227 /******************************************************************************
2228  substritute a specific pattern in a string list
2229  *****************************************************************************/
2230
2231 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2232 {
2233         char *p, *s, *t;
2234         ssize_t ls, lp, li, ld, i, d;
2235
2236         if (!list)
2237                 return false;
2238         if (!pattern)
2239                 return false;
2240         if (!insert)
2241                 return false;
2242
2243         lp = (ssize_t)strlen(pattern);
2244         li = (ssize_t)strlen(insert);
2245         ld = li -lp;
2246
2247         while (*list) {
2248                 s = *list;
2249                 ls = (ssize_t)strlen(s);
2250
2251                 while ((p = strstr_m(s, pattern))) {
2252                         t = *list;
2253                         d = p -t;
2254                         if (ld) {
2255                                 t = (char *) SMB_MALLOC(ls +ld +1);
2256                                 if (!t) {
2257                                         DEBUG(0,("str_list_substitute: "
2258                                                 "Unable to allocate memory"));
2259                                         return false;
2260                                 }
2261                                 memcpy(t, *list, d);
2262                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
2263                                 SAFE_FREE(*list);
2264                                 *list = t;
2265                                 ls += ld;
2266                                 s = t +d +li;
2267                         }
2268
2269                         for (i = 0; i < li; i++) {
2270                                 switch (insert[i]) {
2271                                         case '`':
2272                                         case '"':
2273                                         case '\'':
2274                                         case ';':
2275                                         case '$':
2276                                         case '%':
2277                                         case '\r':
2278                                         case '\n':
2279                                                 t[d +i] = '_';
2280                                                 break;
2281                                         default:
2282                                                 t[d +i] = insert[i];
2283                                 }
2284                         }
2285                 }
2286
2287                 list++;
2288         }
2289
2290         return true;
2291 }
2292
2293
2294 #define IPSTR_LIST_SEP  ","
2295 #define IPSTR_LIST_CHAR ','
2296
2297 /**
2298  * Add ip string representation to ipstr list. Used also
2299  * as part of @function ipstr_list_make
2300  *
2301  * @param ipstr_list pointer to string containing ip list;
2302  *        MUST BE already allocated and IS reallocated if necessary
2303  * @param ipstr_size pointer to current size of ipstr_list (might be changed
2304  *        as a result of reallocation)
2305  * @param ip IP address which is to be added to list
2306  * @return pointer to string appended with new ip and possibly
2307  *         reallocated to new length
2308  **/
2309
2310 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2311 {
2312         char *new_ipstr = NULL;
2313         char addr_buf[INET6_ADDRSTRLEN];
2314
2315         /* arguments checking */
2316         if (!ipstr_list || !service) {
2317                 return NULL;
2318         }
2319
2320         print_sockaddr(addr_buf,
2321                         sizeof(addr_buf),
2322                         &service->ss);
2323
2324         /* attempt to convert ip to a string and append colon separator to it */
2325         if (*ipstr_list) {
2326                 if (service->ss.ss_family == AF_INET) {
2327                         /* IPv4 */
2328                         asprintf(&new_ipstr, "%s%s%s:%d",
2329                                         *ipstr_list,
2330                                         IPSTR_LIST_SEP,
2331                                         addr_buf,
2332                                         service->port);
2333                 } else {
2334                         /* IPv6 */
2335                         asprintf(&new_ipstr, "%s%s[%s]:%d",
2336                                         *ipstr_list,
2337                                         IPSTR_LIST_SEP,
2338                                         addr_buf,
2339                                         service->port);
2340                 }
2341                 SAFE_FREE(*ipstr_list);
2342         } else {
2343                 if (service->ss.ss_family == AF_INET) {
2344                         /* IPv4 */
2345                         asprintf(&new_ipstr, "%s:%d",
2346                                 addr_buf,
2347                                 service->port);
2348                 } else {
2349                         /* IPv6 */
2350                         asprintf(&new_ipstr, "[%s]:%d",
2351                                 addr_buf,
2352                                 service->port);
2353                 }
2354         }
2355         *ipstr_list = new_ipstr;
2356         return *ipstr_list;
2357 }
2358
2359 /**
2360  * Allocate and initialise an ipstr list using ip adresses
2361  * passed as arguments.
2362  *
2363  * @param ipstr_list pointer to string meant to be allocated and set
2364  * @param ip_list array of ip addresses to place in the list
2365  * @param ip_count number of addresses stored in ip_list
2366  * @return pointer to allocated ip string
2367  **/
2368
2369 char *ipstr_list_make(char **ipstr_list,
2370                         const struct ip_service *ip_list,
2371                         int ip_count)
2372 {
2373         int i;
2374
2375         /* arguments checking */
2376         if (!ip_list || !ipstr_list) {
2377                 return 0;
2378         }
2379
2380         *ipstr_list = NULL;
2381
2382         /* process ip addresses given as arguments */
2383         for (i = 0; i < ip_count; i++) {
2384                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2385         }
2386
2387         return (*ipstr_list);
2388 }
2389
2390
2391 /**
2392  * Parse given ip string list into array of ip addresses
2393  * (as ip_service structures)
2394  *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2395  *
2396  * @param ipstr ip string list to be parsed
2397  * @param ip_list pointer to array of ip addresses which is
2398  *        allocated by this function and must be freed by caller
2399  * @return number of succesfully parsed addresses
2400  **/
2401
2402 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2403 {
2404         fstring token_str;
2405         size_t count;
2406         int i;
2407
2408         if (!ipstr_list || !ip_list)
2409                 return 0;
2410
2411         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2412         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2413                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2414                                         (unsigned long)count));
2415                 return 0;
2416         }
2417
2418         for ( i=0; next_token(&ipstr_list, token_str,
2419                                 IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
2420                 char *s = token_str;
2421                 char *p = strrchr(token_str, ':');
2422
2423                 if (p) {
2424                         *p = 0;
2425                         (*ip_list)[i].port = atoi(p+1);
2426                 }
2427
2428                 /* convert single token to ip address */
2429                 if (token_str[0] == '[') {
2430                         /* IPv6 address. */
2431                         s++;
2432                         p = strchr(token_str, ']');
2433                         if (!p) {
2434                                 continue;
2435                         }
2436                         *p = '\0';
2437                 }
2438                 if (!interpret_string_addr(&(*ip_list)[i].ss,
2439                                         s,
2440                                         AI_NUMERICHOST)) {
2441                         continue;
2442                 }
2443         }
2444
2445         return count;
2446 }
2447
2448 /**
2449  * Safely free ip string list
2450  *
2451  * @param ipstr_list ip string list to be freed
2452  **/
2453
2454 void ipstr_list_free(char* ipstr_list)
2455 {
2456         SAFE_FREE(ipstr_list);
2457 }
2458
2459 /**
2460  Unescape a URL encoded string, in place.
2461 **/
2462
2463 void rfc1738_unescape(char *buf)
2464 {
2465         char *p=buf;
2466
2467         while (p && *p && (p=strchr_m(p,'%'))) {
2468                 int c1 = p[1];
2469                 int c2 = p[2];
2470
2471                 if (c1 >= '0' && c1 <= '9')
2472                         c1 = c1 - '0';
2473                 else if (c1 >= 'A' && c1 <= 'F')
2474                         c1 = 10 + c1 - 'A';
2475                 else if (c1 >= 'a' && c1 <= 'f')
2476                         c1 = 10 + c1 - 'a';
2477                 else {p++; continue;}
2478
2479                 if (c2 >= '0' && c2 <= '9')
2480                         c2 = c2 - '0';
2481                 else if (c2 >= 'A' && c2 <= 'F')
2482                         c2 = 10 + c2 - 'A';
2483                 else if (c2 >= 'a' && c2 <= 'f')
2484                         c2 = 10 + c2 - 'a';
2485                 else {p++; continue;}
2486
2487                 *p = (c1<<4) | c2;
2488
2489                 memmove(p+1, p+3, strlen(p+3)+1);
2490                 p++;
2491         }
2492 }
2493
2494 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2495
2496 /**
2497  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2498  **/
2499 DATA_BLOB base64_decode_data_blob(const char *s)
2500 {
2501         int bit_offset, byte_offset, idx, i, n;
2502         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2503         unsigned char *d = decoded.data;
2504         char *p;
2505
2506         n=i=0;
2507
2508         while (*s && (p=strchr_m(b64,*s))) {
2509                 idx = (int)(p - b64);
2510                 byte_offset = (i*6)/8;
2511                 bit_offset = (i*6)%8;
2512                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2513                 if (bit_offset < 3) {
2514                         d[byte_offset] |= (idx << (2-bit_offset));
2515                         n = byte_offset+1;
2516                 } else {
2517                         d[byte_offset] |= (idx >> (bit_offset-2));
2518                         d[byte_offset+1] = 0;
2519                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2520                         n = byte_offset+2;
2521                 }
2522                 s++; i++;
2523         }
2524
2525         if ((n > 0) && (*s == '=')) {
2526                 n -= 1;
2527         }
2528
2529         /* fix up length */
2530         decoded.length = n;
2531         return decoded;
2532 }
2533
2534 /**
2535  * Decode a base64 string in-place - wrapper for the above
2536  **/
2537 void base64_decode_inplace(char *s)
2538 {
2539         DATA_BLOB decoded = base64_decode_data_blob(s);
2540
2541         if ( decoded.length != 0 ) {
2542                 memcpy(s, decoded.data, decoded.length);
2543
2544                 /* null terminate */
2545                 s[decoded.length] = '\0';
2546         } else {
2547                 *s = '\0';
2548         }
2549
2550         data_blob_free(&decoded);
2551 }
2552
2553 /**
2554  * Encode a base64 string into a malloc()ed string caller to free.
2555  *
2556  * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2557  * with adjustments
2558  **/
2559
2560 char *base64_encode_data_blob(DATA_BLOB data)
2561 {
2562         int bits = 0;
2563         int char_count = 0;
2564         size_t out_cnt, len, output_len;
2565         char *result;
2566
2567         if (!data.length || !data.data)
2568                 return NULL;
2569
2570         out_cnt = 0;
2571         len = data.length;
2572         output_len = data.length * 2;
2573         result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */
2574         SMB_ASSERT(result != NULL);
2575
2576         while (len-- && out_cnt < (data.length * 2) - 5) {
2577                 int c = (unsigned char) *(data.data++);
2578                 bits += c;
2579                 char_count++;
2580                 if (char_count == 3) {
2581                         result[out_cnt++] = b64[bits >> 18];
2582                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2583                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2584                         result[out_cnt++] = b64[bits & 0x3f];
2585                         bits = 0;
2586                         char_count = 0;
2587                 } else {
2588                         bits <<= 8;
2589                 }
2590         }
2591         if (char_count != 0) {
2592                 bits <<= 16 - (8 * char_count);
2593                 result[out_cnt++] = b64[bits >> 18];
2594                 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2595                 if (char_count == 1) {
2596                         result[out_cnt++] = '=';
2597                         result[out_cnt++] = '=';
2598                 } else {
2599                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2600                         result[out_cnt++] = '=';
2601                 }
2602         }
2603         result[out_cnt] = '\0'; /* terminate */
2604         return result;
2605 }
2606
2607 /* read a SMB_BIG_UINT from a string */
2608 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2609 {
2610
2611         SMB_BIG_UINT val = -1;
2612         const char *p = nptr;
2613
2614         if (!p) {
2615                 if (entptr) {
2616                         *entptr = p;
2617                 }
2618                 return val;
2619         }
2620
2621         while (*p && isspace(*p))
2622                 p++;
2623
2624 #ifdef LARGE_SMB_OFF_T
2625         sscanf(p,"%llu",&val);
2626 #else /* LARGE_SMB_OFF_T */
2627         sscanf(p,"%lu",&val);
2628 #endif /* LARGE_SMB_OFF_T */
2629         if (entptr) {
2630                 while (*p && isdigit(*p))
2631                         p++;
2632                 *entptr = p;
2633         }
2634
2635         return val;
2636 }
2637
2638 /* Convert a size specification to a count of bytes. We accept the following
2639  * suffixes:
2640  *          bytes if there is no suffix
2641  *      kK  kibibytes
2642  *      mM  mebibytes
2643  *      gG  gibibytes
2644  *      tT  tibibytes
2645  *      pP  whatever the ISO name for petabytes is
2646  *
2647  *  Returns 0 if the string can't be converted.
2648  */
2649 SMB_OFF_T conv_str_size(const char * str)
2650 {
2651         SMB_OFF_T lval;
2652         char * end;
2653
2654         if (str == NULL || *str == '\0') {
2655                 return 0;
2656         }
2657
2658 #ifdef HAVE_STRTOULL
2659         if (sizeof(SMB_OFF_T) == 8) {
2660             lval = strtoull(str, &end, 10 /* base */);
2661         } else {
2662             lval = strtoul(str, &end, 10 /* base */);
2663         }
2664 #else
2665         lval = strtoul(str, &end, 10 /* base */);
2666 #endif
2667
2668         if (end == NULL || end == str) {
2669                 return 0;
2670         }
2671
2672         if (*end) {
2673                 SMB_OFF_T lval_orig = lval;
2674
2675                 if (strwicmp(end, "K") == 0) {
2676                         lval *= (SMB_OFF_T)1024;
2677                 } else if (strwicmp(end, "M") == 0) {
2678                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2679                 } else if (strwicmp(end, "G") == 0) {
2680                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2681                                 (SMB_OFF_T)1024);
2682                 } else if (strwicmp(end, "T") == 0) {
2683                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2684                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2685                 } else if (strwicmp(end, "P") == 0) {
2686                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2687                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2688                                 (SMB_OFF_T)1024);
2689                 } else {
2690                         return 0;
2691                 }
2692
2693                 /* Primitive attempt to detect wrapping on platforms with
2694                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2695                  * a failure than some random number.
2696                  */
2697                 if (lval_orig <= lval) {
2698                         return 0;
2699                 }
2700         }
2701
2702         return lval;
2703 }
2704
2705 void string_append(char **left, const char *right)
2706 {
2707         int new_len = strlen(right) + 1;
2708
2709         if (*left == NULL) {
2710                 *left = (char *)SMB_MALLOC(new_len);
2711                 *left[0] = '\0';
2712         } else {
2713                 new_len += strlen(*left);
2714                 *left = (char *)SMB_REALLOC(*left, new_len);
2715         }
2716
2717         if (*left == NULL) {
2718                 return;
2719         }
2720
2721         safe_strcat(*left, right, new_len-1);
2722 }
2723
2724 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2725                          const char *str, const char ***strings,
2726                          int *num)
2727 {
2728         char *dup_str = talloc_strdup(mem_ctx, str);
2729
2730         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2731                         const char *, (*num)+1);
2732
2733         if ((*strings == NULL) || (dup_str == NULL)) {
2734                 *num = 0;
2735                 return false;
2736         }
2737
2738         (*strings)[*num] = dup_str;
2739         *num += 1;
2740         return true;
2741 }
2742
2743 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2744  * error checking in between. The indiation that something weird happened is
2745  * string==NULL */
2746
2747 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2748                     size_t *bufsize, const char *fmt, ...)
2749 {
2750         va_list ap;
2751         char *newstr;
2752         int ret;
2753         bool increased;
2754
2755         /* len<0 is an internal marker that something failed */
2756         if (*len < 0)
2757                 goto error;
2758
2759         if (*string == NULL) {
2760                 if (*bufsize == 0)
2761                         *bufsize = 128;
2762
2763                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2764                 if (*string == NULL)
2765                         goto error;
2766         }
2767
2768         va_start(ap, fmt);
2769         ret = vasprintf(&newstr, fmt, ap);
2770         va_end(ap);
2771
2772         if (ret < 0)
2773                 goto error;
2774
2775         increased = false;
2776
2777         while ((*len)+ret >= *bufsize) {
2778                 increased = true;
2779                 *bufsize *= 2;
2780                 if (*bufsize >= (1024*1024*256))
2781                         goto error;
2782         }
2783
2784         if (increased) {
2785                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2786                                                *bufsize);
2787                 if (*string == NULL) {
2788                         goto error;
2789                 }
2790         }
2791
2792         StrnCpy((*string)+(*len), newstr, ret);
2793         (*len) += ret;
2794         free(newstr);
2795         return;
2796
2797  error:
2798         *len = -1;
2799         *string = NULL;
2800 }
2801
2802 /*
2803    Returns the substring from src between the first occurrence of
2804    the char "front" and the first occurence of the char "back".
2805    Mallocs the return string which must be freed.  Not for use
2806    with wide character strings.
2807 */
2808 char *sstring_sub(const char *src, char front, char back)
2809 {
2810         char *temp1, *temp2, *temp3;
2811         ptrdiff_t len;
2812
2813         temp1 = strchr(src, front);
2814         if (temp1 == NULL) return NULL;
2815         temp2 = strchr(src, back);
2816         if (temp2 == NULL) return NULL;
2817         len = temp2 - temp1;
2818         if (len <= 0) return NULL;
2819         temp3 = (char*)SMB_MALLOC(len);
2820         if (temp3 == NULL) {
2821                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2822                 return NULL;
2823         }
2824         memcpy(temp3, temp1+1, len-1);
2825         temp3[len-1] = '\0';
2826         return temp3;
2827 }
2828
2829 /********************************************************************
2830  Check a string for any occurrences of a specified list of invalid
2831  characters.
2832 ********************************************************************/
2833
2834 bool validate_net_name( const char *name,
2835                 const char *invalid_chars,
2836                 int max_len)
2837 {
2838         int i;
2839
2840         for ( i=0; i<max_len && name[i]; i++ ) {
2841                 /* fail if strchr_m() finds one of the invalid characters */
2842                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2843                         return false;
2844                 }
2845         }
2846
2847         return true;
2848 }
2849
2850
2851 /**
2852 return the number of bytes occupied by a buffer in ASCII format
2853 the result includes the null termination
2854 limited by 'n' bytes
2855 **/
2856 size_t ascii_len_n(const char *src, size_t n)
2857 {
2858         size_t len;
2859
2860         len = strnlen(src, n);
2861         if (len+1 <= n) {
2862                 len += 1;
2863         }
2864
2865         return len;
2866 }
2867
2868 /**
2869 return the number of bytes occupied by a buffer in CH_UTF16 format
2870 the result includes the null termination
2871 **/
2872 size_t utf16_len(const void *buf)
2873 {
2874         size_t len;
2875
2876         for (len = 0; SVAL(buf,len); len += 2) ;
2877
2878         return len + 2;
2879 }
2880
2881 /**
2882 return the number of bytes occupied by a buffer in CH_UTF16 format
2883 the result includes the null termination
2884 limited by 'n' bytes
2885 **/
2886 size_t utf16_len_n(const void *src, size_t n)
2887 {
2888         size_t len;
2889
2890         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2891
2892         if (len+2 <= n) {
2893                 len += 2;
2894         }
2895
2896         return len;
2897 }
2898
2899 /*******************************************************************
2900  Add a shell escape character '\' to any character not in a known list
2901  of characters. UNIX charset format.
2902 *******************************************************************/
2903
2904 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2905 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2906
2907 char *escape_shell_string(const char *src)
2908 {
2909         size_t srclen = strlen(src);
2910         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2911         char *dest = ret;
2912         bool in_s_quote = false;
2913         bool in_d_quote = false;
2914         bool next_escaped = false;
2915
2916         if (!ret) {
2917                 return NULL;
2918         }
2919
2920         while (*src) {
2921                 size_t c_size;
2922                 codepoint_t c = next_codepoint(src, &c_size);
2923
2924                 if (c == INVALID_CODEPOINT) {
2925                         SAFE_FREE(ret);
2926                         return NULL;
2927                 }
2928
2929                 if (c_size > 1) {
2930                         memcpy(dest, src, c_size);
2931                         src += c_size;
2932                         dest += c_size;
2933                         next_escaped = false;
2934                         continue;
2935                 }
2936
2937                 /*
2938                  * Deal with backslash escaped state.
2939                  * This only lasts for one character.
2940                  */
2941
2942                 if (next_escaped) {
2943                         *dest++ = *src++;
2944                         next_escaped = false;
2945                         continue;
2946                 }
2947
2948                 /*
2949                  * Deal with single quote state. The
2950                  * only thing we care about is exiting
2951                  * this state.
2952                  */
2953
2954                 if (in_s_quote) {
2955                         if (*src == '\'') {
2956                                 in_s_quote = false;
2957                         }
2958                         *dest++ = *src++;
2959                         continue;
2960                 }
2961
2962                 /*
2963                  * Deal with double quote state. The most
2964                  * complex state. We must cope with \, meaning
2965                  * possibly escape next char (depending what it
2966                  * is), ", meaning exit this state, and possibly
2967                  * add an \ escape to any unprotected character
2968                  * (listed in INSIDE_DQUOTE_LIST).
2969                  */
2970
2971                 if (in_d_quote) {
2972                         if (*src == '\\') {
2973                                 /*
2974                                  * Next character might be escaped.
2975                                  * We have to peek. Inside double
2976                                  * quotes only INSIDE_DQUOTE_LIST
2977                                  * characters are escaped by a \.
2978                                  */
2979
2980                                 char nextchar;
2981
2982                                 c = next_codepoint(&src[1], &c_size);
2983                                 if (c == INVALID_CODEPOINT) {
2984                                         SAFE_FREE(ret);
2985                                         return NULL;
2986                                 }
2987                                 if (c_size > 1) {
2988                                         /*
2989                                          * Don't escape the next char.
2990                                          * Just copy the \.
2991                                          */
2992                                         *dest++ = *src++;
2993                                         continue;
2994                                 }
2995
2996                                 nextchar = src[1];
2997
2998                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2999                                                         (int)nextchar)) {
3000                                         next_escaped = true;
3001                                 }
3002                                 *dest++ = *src++;
3003                                 continue;
3004                         }
3005
3006                         if (*src == '\"') {
3007                                 /* Exit double quote state. */
3008                                 in_d_quote = false;
3009                                 *dest++ = *src++;
3010                                 continue;
3011                         }
3012
3013                         /*
3014                          * We know the character isn't \ or ",
3015                          * so escape it if it's any of the other
3016                          * possible unprotected characters.
3017                          */
3018
3019                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
3020                                 *dest++ = '\\';
3021                         }
3022                         *dest++ = *src++;
3023                         continue;
3024                 }
3025
3026                 /*
3027                  * From here to the end of the loop we're
3028                  * not in the single or double quote state.
3029                  */
3030
3031                 if (*src == '\\') {
3032                         /* Next character must be escaped. */
3033                         next_escaped = true;
3034                         *dest++ = *src++;
3035                         continue;
3036                 }
3037
3038                 if (*src == '\'') {
3039                         /* Go into single quote state. */
3040                         in_s_quote = true;
3041                         *dest++ = *src++;
3042                         continue;
3043                 }
3044
3045                 if (*src == '\"') {
3046                         /* Go into double quote state. */
3047                         in_d_quote = true;
3048                         *dest++ = *src++;
3049                         continue;
3050                 }
3051
3052                 /* Check if we need to escape the character. */
3053
3054                 if (!strchr(INCLUDE_LIST, (int)*src)) {
3055                         *dest++ = '\\';
3056                 }
3057                 *dest++ = *src++;
3058         }
3059         *dest++ = '\0';
3060         return ret;
3061 }