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