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