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