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