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