s3-lib Replace StrCaseCmp() with strcasecmp_m()
[ddiss/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 const char toupper_ascii_fast_table[128] = {
28         0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34         0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
36 };
37
38 /**
39  Case insensitive string compararison, length limited.
40 **/
41 int StrnCaseCmp(const char *s, const char *t, size_t len)
42 {
43         size_t n = 0;
44         const char *ps, *pt;
45         size_t size;
46         smb_ucs2_t *buffer_s, *buffer_t;
47         int ret;
48
49         for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
50                 char us, ut;
51
52                 if (!*ps && !*pt)
53                         return 0; /* both ended */
54                 else if (!*ps)
55                         return -1; /* s is a prefix */
56                 else if (!*pt)
57                         return +1; /* t is a prefix */
58                 else if ((*ps & 0x80) || (*pt & 0x80))
59                         /* not ascii anymore, do it the
60                          * hard way from here on in */
61                         break;
62
63                 us = toupper_ascii_fast(*ps);
64                 ut = toupper_ascii_fast(*pt);
65                 if (us == ut)
66                         continue;
67                 else if (us < ut)
68                         return -1;
69                 else if (us > ut)
70                         return +1;
71         }
72
73         if (n == len) {
74                 return 0;
75         }
76
77         if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
78                 return strncmp(ps, pt, len-n);
79                 /* Not quite the right answer, but finding the right one
80                    under this failure case is expensive,
81                    and it's pretty close */
82         }
83
84         if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
85                 TALLOC_FREE(buffer_s);
86                 return strncmp(ps, pt, len-n);
87                 /* Not quite the right answer, but finding the right one
88                    under this failure case is expensive,
89                    and it's pretty close */
90         }
91
92         ret = strncasecmp_w(buffer_s, buffer_t, len-n);
93         TALLOC_FREE(buffer_s);
94         TALLOC_FREE(buffer_t);
95         return ret;
96 }
97
98 /**
99  * Compare 2 strings up to and including the nth char.
100  *
101  * @note The comparison is case-insensitive.
102  **/
103 bool strnequal(const char *s1,const char *s2,size_t n)
104 {
105         if (s1 == s2)
106                 return(true);
107         if (!s1 || !s2 || !n)
108                 return(false);
109
110         return(StrnCaseCmp(s1,s2,n)==0);
111 }
112
113 /**
114  Convert a string to "normal" form.
115 **/
116
117 void strnorm(char *s, int case_default)
118 {
119         if (case_default == CASE_UPPER)
120                 strupper_m(s);
121         else
122                 strlower_m(s);
123 }
124
125 /**
126  *  Skip past some strings in a buffer - old version - no checks.
127  *  **/
128
129 char *push_skip_string(char *buf)
130 {
131         buf += strlen(buf) + 1;
132         return(buf);
133 }
134
135 /**
136  Skip past a string in a buffer. Buffer may not be
137  null terminated. end_ptr points to the first byte after
138  then end of the buffer.
139 **/
140
141 char *skip_string(const char *base, size_t len, char *buf)
142 {
143         const char *end_ptr = base + len;
144
145         if (end_ptr < base || !base || !buf || buf >= end_ptr) {
146                 return NULL;
147         }
148
149         /* Skip the string */
150         while (*buf) {
151                 buf++;
152                 if (buf >= end_ptr) {
153                         return NULL;
154                 }
155         }
156         /* Skip the '\0' */
157         buf++;
158         return buf;
159 }
160
161 /**
162  Count the number of characters in a string. Normally this will
163  be the same as the number of bytes in a string for single byte strings,
164  but will be different for multibyte.
165 **/
166
167 size_t str_charnum(const char *s)
168 {
169         size_t ret, converted_size;
170         smb_ucs2_t *tmpbuf2 = NULL;
171         if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
172                 return 0;
173         }
174         ret = strlen_w(tmpbuf2);
175         TALLOC_FREE(tmpbuf2);
176         return ret;
177 }
178
179 bool trim_char(char *s,char cfront,char cback)
180 {
181         bool ret = false;
182         char *ep;
183         char *fp = s;
184
185         /* Ignore null or empty strings. */
186         if (!s || (s[0] == '\0'))
187                 return false;
188
189         if (cfront) {
190                 while (*fp && *fp == cfront)
191                         fp++;
192                 if (!*fp) {
193                         /* We ate the string. */
194                         s[0] = '\0';
195                         return true;
196                 }
197                 if (fp != s)
198                         ret = true;
199         }
200
201         ep = fp + strlen(fp) - 1;
202         if (cback) {
203                 /* Attempt ascii only. Bail for mb strings. */
204                 while ((ep >= fp) && (*ep == cback)) {
205                         ret = true;
206                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
207                                 /* Could be mb... bail back to tim_string. */
208                                 char fs[2], bs[2];
209                                 if (cfront) {
210                                         fs[0] = cfront;
211                                         fs[1] = '\0';
212                                 }
213                                 bs[0] = cback;
214                                 bs[1] = '\0';
215                                 return trim_string(s, cfront ? fs : NULL, bs);
216                         } else {
217                                 ep--;
218                         }
219                 }
220                 if (ep < fp) {
221                         /* We ate the string. */
222                         s[0] = '\0';
223                         return true;
224                 }
225         }
226
227         ep[1] = '\0';
228         memmove(s, fp, ep-fp+2);
229         return ret;
230 }
231
232 /**
233  Like strncpy but always null terminates. Make sure there is room!
234  The variable n should always be one less than the available size.
235 **/
236 char *StrnCpy(char *dest,const char *src,size_t n)
237 {
238         char *d = dest;
239
240         if (!dest) {
241                 smb_panic("ERROR: NULL dest in StrnCpy");
242         }
243
244         if (!src) {
245                 *dest = 0;
246                 return(dest);
247         }
248
249         while (n-- && (*d = *src)) {
250                 d++;
251                 src++;
252         }
253
254         *d = 0;
255         return(dest);
256 }
257
258 /**
259  Check if a string is part of a list.
260 **/
261
262 bool in_list(const char *s, const char *list, bool casesensitive)
263 {
264         char *tok = NULL;
265         bool ret = false;
266         TALLOC_CTX *frame;
267
268         if (!list) {
269                 return false;
270         }
271
272         frame = talloc_stackframe();
273         while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
274                 if (casesensitive) {
275                         if (strcmp(tok,s) == 0) {
276                                 ret = true;
277                                 break;
278                         }
279                 } else {
280                         if (strcasecmp_m(tok,s) == 0) {
281                                 ret = true;
282                                 break;
283                         }
284                 }
285         }
286         TALLOC_FREE(frame);
287         return ret;
288 }
289
290 /* this is used to prevent lots of mallocs of size 1 */
291 static const char null_string[] = "";
292
293 /**
294  Set a string value, allocing the space for the string
295 **/
296
297 static bool string_init(char **dest,const char *src)
298 {
299         size_t l;
300
301         if (!src)
302                 src = "";
303
304         l = strlen(src);
305
306         if (l == 0) {
307                 *dest = discard_const_p(char, null_string);
308         } else {
309                 (*dest) = SMB_STRDUP(src);
310                 if ((*dest) == NULL) {
311                         DEBUG(0,("Out of memory in string_init\n"));
312                         return false;
313                 }
314         }
315         return(true);
316 }
317
318 /**
319  Free a string value.
320 **/
321
322 void string_free(char **s)
323 {
324         if (!s || !(*s))
325                 return;
326         if (*s == null_string)
327                 *s = NULL;
328         SAFE_FREE(*s);
329 }
330
331 /**
332  Set a string value, deallocating any existing space, and allocing the space
333  for the string
334 **/
335
336 bool string_set(char **dest,const char *src)
337 {
338         string_free(dest);
339         return(string_init(dest,src));
340 }
341
342 void fstring_sub(char *s,const char *pattern,const char *insert)
343 {
344         string_sub(s, pattern, insert, sizeof(fstring));
345 }
346
347 /**
348  Similar to string_sub2, but it will accept only allocated strings
349  and may realloc them so pay attention at what you pass on no
350  pointers inside strings, no const may be passed
351  as string.
352 **/
353
354 char *realloc_string_sub2(char *string,
355                         const char *pattern,
356                         const char *insert,
357                         bool remove_unsafe_characters,
358                         bool allow_trailing_dollar)
359 {
360         char *p, *in;
361         char *s;
362         ssize_t ls,lp,li,ld, i;
363
364         if (!insert || !pattern || !*pattern || !string || !*string)
365                 return NULL;
366
367         s = string;
368
369         in = SMB_STRDUP(insert);
370         if (!in) {
371                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
372                 return NULL;
373         }
374         ls = (ssize_t)strlen(s);
375         lp = (ssize_t)strlen(pattern);
376         li = (ssize_t)strlen(insert);
377         ld = li - lp;
378         for (i=0;i<li;i++) {
379                 switch (in[i]) {
380                         case '$':
381                                 /* allow a trailing $
382                                  * (as in machine accounts) */
383                                 if (allow_trailing_dollar && (i == li - 1 )) {
384                                         break;
385                                 }
386                         case '`':
387                         case '"':
388                         case '\'':
389                         case ';':
390                         case '%':
391                         case '\r':
392                         case '\n':
393                                 if ( remove_unsafe_characters ) {
394                                         in[i] = '_';
395                                         break;
396                                 }
397                         default:
398                                 /* ok */
399                                 break;
400                 }
401         }
402
403         while ((p = strstr_m(s,pattern))) {
404                 if (ld > 0) {
405                         int offset = PTR_DIFF(s,string);
406                         string = (char *)SMB_REALLOC(string, ls + ld + 1);
407                         if (!string) {
408                                 DEBUG(0, ("realloc_string_sub: "
409                                         "out of memory!\n"));
410                                 SAFE_FREE(in);
411                                 return NULL;
412                         }
413                         p = string + offset + (p - s);
414                 }
415                 if (li != lp) {
416                         memmove(p+li,p+lp,strlen(p+lp)+1);
417                 }
418                 memcpy(p, in, li);
419                 s = p + li;
420                 ls += ld;
421         }
422         SAFE_FREE(in);
423         return string;
424 }
425
426 char *realloc_string_sub(char *string,
427                         const char *pattern,
428                         const char *insert)
429 {
430         return realloc_string_sub2(string, pattern, insert, true, false);
431 }
432
433 /*
434  * Internal guts of talloc_string_sub and talloc_all_string_sub.
435  * talloc version of string_sub2.
436  */
437
438 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
439                         const char *pattern,
440                         const char *insert,
441                         bool remove_unsafe_characters,
442                         bool replace_once,
443                         bool allow_trailing_dollar)
444 {
445         char *p, *in;
446         char *s;
447         char *string;
448         ssize_t ls,lp,li,ld, i;
449
450         if (!insert || !pattern || !*pattern || !src) {
451                 return NULL;
452         }
453
454         string = talloc_strdup(mem_ctx, src);
455         if (string == NULL) {
456                 DEBUG(0, ("talloc_string_sub2: "
457                         "talloc_strdup failed\n"));
458                 return NULL;
459         }
460
461         s = string;
462
463         in = SMB_STRDUP(insert);
464         if (!in) {
465                 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
466                 return NULL;
467         }
468         ls = (ssize_t)strlen(s);
469         lp = (ssize_t)strlen(pattern);
470         li = (ssize_t)strlen(insert);
471         ld = li - lp;
472
473         for (i=0;i<li;i++) {
474                 switch (in[i]) {
475                         case '$':
476                                 /* allow a trailing $
477                                  * (as in machine accounts) */
478                                 if (allow_trailing_dollar && (i == li - 1 )) {
479                                         break;
480                                 }
481                         case '`':
482                         case '"':
483                         case '\'':
484                         case ';':
485                         case '%':
486                         case '\r':
487                         case '\n':
488                                 if (remove_unsafe_characters) {
489                                         in[i] = '_';
490                                         break;
491                                 }
492                         default:
493                                 /* ok */
494                                 break;
495                 }
496         }
497
498         while ((p = strstr_m(s,pattern))) {
499                 if (ld > 0) {
500                         int offset = PTR_DIFF(s,string);
501                         string = (char *)TALLOC_REALLOC(mem_ctx, string,
502                                                         ls + ld + 1);
503                         if (!string) {
504                                 DEBUG(0, ("talloc_string_sub: out of "
505                                           "memory!\n"));
506                                 SAFE_FREE(in);
507                                 return NULL;
508                         }
509                         p = string + offset + (p - s);
510                 }
511                 if (li != lp) {
512                         memmove(p+li,p+lp,strlen(p+lp)+1);
513                 }
514                 memcpy(p, in, li);
515                 s = p + li;
516                 ls += ld;
517
518                 if (replace_once) {
519                         break;
520                 }
521         }
522         SAFE_FREE(in);
523         return string;
524 }
525
526 /* Same as string_sub, but returns a talloc'ed string */
527
528 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
529                         const char *src,
530                         const char *pattern,
531                         const char *insert)
532 {
533         return talloc_string_sub2(mem_ctx, src, pattern, insert,
534                         true, false, false);
535 }
536
537 char *talloc_all_string_sub(TALLOC_CTX *ctx,
538                                 const char *src,
539                                 const char *pattern,
540                                 const char *insert)
541 {
542         return talloc_string_sub2(ctx, src, pattern, insert,
543                         false, false, false);
544 }
545
546 /**
547  Write an octal as a string.
548 **/
549
550 char *octal_string(int i)
551 {
552         char *result;
553         if (i == -1) {
554                 result = talloc_strdup(talloc_tos(), "-1");
555         }
556         else {
557                 result = talloc_asprintf(talloc_tos(), "0%o", i);
558         }
559         SMB_ASSERT(result != NULL);
560         return result;
561 }
562
563
564 /**
565  Truncate a string at a specified length.
566 **/
567
568 char *string_truncate(char *s, unsigned int length)
569 {
570         if (s && strlen(s) > length)
571                 s[length] = 0;
572         return s;
573 }
574
575
576 /***********************************************************************
577  Return the equivalent of doing strrchr 'n' times - always going
578  backwards.
579 ***********************************************************************/
580
581 char *strnrchr_m(const char *s, char c, unsigned int n)
582 {
583         smb_ucs2_t *ws = NULL;
584         char *s2 = NULL;
585         smb_ucs2_t *p;
586         char *ret;
587         size_t converted_size;
588
589         if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
590                 /* Too hard to try and get right. */
591                 return NULL;
592         }
593         p = strnrchr_w(ws, UCS2_CHAR(c), n);
594         if (!p) {
595                 TALLOC_FREE(ws);
596                 return NULL;
597         }
598         *p = 0;
599         if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
600                 TALLOC_FREE(ws);
601                 /* Too hard to try and get right. */
602                 return NULL;
603         }
604         ret = discard_const_p(char, (s+strlen(s2)));
605         TALLOC_FREE(ws);
606         TALLOC_FREE(s2);
607         return ret;
608 }
609
610 static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
611 {
612         size_t size;
613         smb_ucs2_t *buffer = NULL;
614         bool ret;
615
616         if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
617                                    (void **)(void *)&buffer, &size))
618         {
619                 smb_panic("failed to create UCS2 buffer");
620         }
621         if (!strlower_w(buffer) && (dest == src)) {
622                 TALLOC_FREE(buffer);
623                 return srclen;
624         }
625         ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
626         TALLOC_FREE(buffer);
627         return ret;
628 }
629
630 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
631
632 /**
633  Convert a string to lower case.
634 **/
635 _PUBLIC_ void strlower_m(char *s)
636 {
637         char *d;
638         struct smb_iconv_handle *iconv_handle;
639
640         iconv_handle = get_iconv_handle();
641
642         d = s;
643
644         while (*s) {
645                 size_t c_size, c_size2;
646                 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
647                 c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
648                 if (c_size2 > c_size) {
649                         DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
650                                  c, tolower_m(c), (int)c_size, (int)c_size2));
651                         smb_panic("codepoint expansion in strlower_m\n");
652                 }
653                 s += c_size;
654                 d += c_size2;
655         }
656         *d = 0;
657 }
658
659 #endif
660
661 /**
662  Convert a string to lower case.
663 **/
664
665 void strlower_m(char *s)
666 {
667         size_t len;
668         int errno_save;
669
670         /* this is quite a common operation, so we want it to be
671            fast. We optimise for the ascii case, knowing that all our
672            supported multi-byte character sets are ascii-compatible
673            (ie. they match for the first 128 chars) */
674
675         while (*s && !(((unsigned char)s[0]) & 0x80)) {
676                 *s = tolower_ascii((unsigned char)*s);
677                 s++;
678         }
679
680         if (!*s)
681                 return;
682
683         /* I assume that lowercased string takes the same number of bytes
684          * as source string even in UTF-8 encoding. (VIV) */
685         len = strlen(s) + 1;
686         errno_save = errno;
687         errno = 0;
688         unix_strlower(s,len,s,len);
689         /* Catch mb conversion errors that may not terminate. */
690         if (errno)
691                 s[len-1] = '\0';
692         errno = errno_save;
693 }
694
695 static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
696 {
697         size_t size;
698         smb_ucs2_t *buffer;
699         bool ret;
700
701         if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
702                 return (size_t)-1;
703         }
704
705         if (!strupper_w(buffer) && (dest == src)) {
706                 TALLOC_FREE(buffer);
707                 return srclen;
708         }
709
710         ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
711         TALLOC_FREE(buffer);
712         return ret;
713 }
714
715 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
716
717 /**
718  Convert a string to UPPER case.
719 **/
720 _PUBLIC_ void strupper_m(char *s)
721 {
722         char *d;
723         struct smb_iconv_handle *iconv_handle;
724
725         iconv_handle = get_iconv_handle();
726
727         d = s;
728
729         while (*s) {
730                 size_t c_size, c_size2;
731                 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
732                 c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
733                 if (c_size2 > c_size) {
734                         DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
735                                  c, toupper_m(c), (int)c_size, (int)c_size2));
736                         smb_panic("codepoint expansion in strupper_m\n");
737                 }
738                 s += c_size;
739                 d += c_size2;
740         }
741         *d = 0;
742 }
743
744 #endif
745
746 /**
747  Convert a string to upper case.
748 **/
749
750 void strupper_m(char *s)
751 {
752         size_t len;
753         int errno_save;
754
755         /* this is quite a common operation, so we want it to be
756            fast. We optimise for the ascii case, knowing that all our
757            supported multi-byte character sets are ascii-compatible
758            (ie. they match for the first 128 chars) */
759
760         while (*s && !(((unsigned char)s[0]) & 0x80)) {
761                 *s = toupper_ascii_fast((unsigned char)*s);
762                 s++;
763         }
764
765         if (!*s)
766                 return;
767
768         /* I assume that lowercased string takes the same number of bytes
769          * as source string even in multibyte encoding. (VIV) */
770         len = strlen(s) + 1;
771         errno_save = errno;
772         errno = 0;
773         unix_strupper(s,len,s,len);
774         /* Catch mb conversion errors that may not terminate. */
775         if (errno)
776                 s[len-1] = '\0';
777         errno = errno_save;
778 }
779
780 /**
781  Just a typesafety wrapper for snprintf into a fstring.
782 **/
783
784 int fstr_sprintf(fstring s, const char *fmt, ...)
785 {
786         va_list ap;
787         int ret;
788
789         va_start(ap, fmt);
790         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
791         va_end(ap);
792         return ret;
793 }
794
795 /**
796  List of Strings manipulation functions
797 **/
798
799 #define S_LIST_ABS 16 /* List Allocation Block Size */
800
801 /******************************************************************************
802  version of standard_sub_basic() for string lists; uses talloc_sub_basic()
803  for the work
804  *****************************************************************************/
805
806 bool str_list_sub_basic( char **list, const char *smb_name,
807                          const char *domain_name )
808 {
809         TALLOC_CTX *ctx = list;
810         char *s, *tmpstr;
811
812         while ( *list ) {
813                 s = *list;
814                 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
815                 if ( !tmpstr ) {
816                         DEBUG(0,("str_list_sub_basic: "
817                                 "alloc_sub_basic() return NULL!\n"));
818                         return false;
819                 }
820
821                 TALLOC_FREE(*list);
822                 *list = tmpstr;
823
824                 list++;
825         }
826
827         return true;
828 }
829
830 /******************************************************************************
831  substitute a specific pattern in a string list
832  *****************************************************************************/
833
834 bool str_list_substitute(char **list, const char *pattern, const char *insert)
835 {
836         TALLOC_CTX *ctx = list;
837         char *p, *s, *t;
838         ssize_t ls, lp, li, ld, i, d;
839
840         if (!list)
841                 return false;
842         if (!pattern)
843                 return false;
844         if (!insert)
845                 return false;
846
847         lp = (ssize_t)strlen(pattern);
848         li = (ssize_t)strlen(insert);
849         ld = li -lp;
850
851         while (*list) {
852                 s = *list;
853                 ls = (ssize_t)strlen(s);
854
855                 while ((p = strstr_m(s, pattern))) {
856                         t = *list;
857                         d = p -t;
858                         if (ld) {
859                                 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
860                                 if (!t) {
861                                         DEBUG(0,("str_list_substitute: "
862                                                 "Unable to allocate memory"));
863                                         return false;
864                                 }
865                                 memcpy(t, *list, d);
866                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
867                                 TALLOC_FREE(*list);
868                                 *list = t;
869                                 ls += ld;
870                                 s = t +d +li;
871                         }
872
873                         for (i = 0; i < li; i++) {
874                                 switch (insert[i]) {
875                                         case '`':
876                                         case '"':
877                                         case '\'':
878                                         case ';':
879                                         case '$':
880                                         case '%':
881                                         case '\r':
882                                         case '\n':
883                                                 t[d +i] = '_';
884                                                 break;
885                                         default:
886                                                 t[d +i] = insert[i];
887                                 }
888                         }
889                 }
890
891                 list++;
892         }
893
894         return true;
895 }
896
897
898 #define IPSTR_LIST_SEP  ","
899 #define IPSTR_LIST_CHAR ','
900
901 /**
902  * Add ip string representation to ipstr list. Used also
903  * as part of @function ipstr_list_make
904  *
905  * @param ipstr_list pointer to string containing ip list;
906  *        MUST BE already allocated and IS reallocated if necessary
907  * @param ipstr_size pointer to current size of ipstr_list (might be changed
908  *        as a result of reallocation)
909  * @param ip IP address which is to be added to list
910  * @return pointer to string appended with new ip and possibly
911  *         reallocated to new length
912  **/
913
914 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
915 {
916         char *new_ipstr = NULL;
917         char addr_buf[INET6_ADDRSTRLEN];
918         int ret;
919
920         /* arguments checking */
921         if (!ipstr_list || !service) {
922                 return NULL;
923         }
924
925         print_sockaddr(addr_buf,
926                         sizeof(addr_buf),
927                         &service->ss);
928
929         /* attempt to convert ip to a string and append colon separator to it */
930         if (*ipstr_list) {
931                 if (service->ss.ss_family == AF_INET) {
932                         /* IPv4 */
933                         ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
934                                        IPSTR_LIST_SEP, addr_buf,
935                                        service->port);
936                 } else {
937                         /* IPv6 */
938                         ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
939                                        IPSTR_LIST_SEP, addr_buf,
940                                        service->port);
941                 }
942                 SAFE_FREE(*ipstr_list);
943         } else {
944                 if (service->ss.ss_family == AF_INET) {
945                         /* IPv4 */
946                         ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
947                                        service->port);
948                 } else {
949                         /* IPv6 */
950                         ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
951                                        service->port);
952                 }
953         }
954         if (ret == -1) {
955                 return NULL;
956         }
957         *ipstr_list = new_ipstr;
958         return *ipstr_list;
959 }
960
961 /**
962  * Allocate and initialise an ipstr list using ip adresses
963  * passed as arguments.
964  *
965  * @param ipstr_list pointer to string meant to be allocated and set
966  * @param ip_list array of ip addresses to place in the list
967  * @param ip_count number of addresses stored in ip_list
968  * @return pointer to allocated ip string
969  **/
970
971 char *ipstr_list_make(char **ipstr_list,
972                         const struct ip_service *ip_list,
973                         int ip_count)
974 {
975         int i;
976
977         /* arguments checking */
978         if (!ip_list || !ipstr_list) {
979                 return 0;
980         }
981
982         *ipstr_list = NULL;
983
984         /* process ip addresses given as arguments */
985         for (i = 0; i < ip_count; i++) {
986                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
987         }
988
989         return (*ipstr_list);
990 }
991
992
993 /**
994  * Parse given ip string list into array of ip addresses
995  * (as ip_service structures)
996  *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
997  *
998  * @param ipstr ip string list to be parsed
999  * @param ip_list pointer to array of ip addresses which is
1000  *        allocated by this function and must be freed by caller
1001  * @return number of successfully parsed addresses
1002  **/
1003
1004 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1005 {
1006         TALLOC_CTX *frame;
1007         char *token_str = NULL;
1008         size_t count;
1009         int i;
1010
1011         if (!ipstr_list || !ip_list)
1012                 return 0;
1013
1014         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1015         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1016                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1017                                         (unsigned long)count));
1018                 return 0;
1019         }
1020
1021         frame = talloc_stackframe();
1022         for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1023                                 IPSTR_LIST_SEP) && i<count; i++ ) {
1024                 char *s = token_str;
1025                 char *p = strrchr(token_str, ':');
1026
1027                 if (p) {
1028                         *p = 0;
1029                         (*ip_list)[i].port = atoi(p+1);
1030                 }
1031
1032                 /* convert single token to ip address */
1033                 if (token_str[0] == '[') {
1034                         /* IPv6 address. */
1035                         s++;
1036                         p = strchr(token_str, ']');
1037                         if (!p) {
1038                                 continue;
1039                         }
1040                         *p = '\0';
1041                 }
1042                 if (!interpret_string_addr(&(*ip_list)[i].ss,
1043                                         s,
1044                                         AI_NUMERICHOST)) {
1045                         continue;
1046                 }
1047         }
1048         TALLOC_FREE(frame);
1049         return count;
1050 }
1051
1052 /**
1053  * Safely free ip string list
1054  *
1055  * @param ipstr_list ip string list to be freed
1056  **/
1057
1058 void ipstr_list_free(char* ipstr_list)
1059 {
1060         SAFE_FREE(ipstr_list);
1061 }
1062
1063 /* read a SMB_BIG_UINT from a string */
1064 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1065 {
1066
1067         uint64_t val = (uint64_t)-1;
1068         const char *p = nptr;
1069
1070         if (!p) {
1071                 if (entptr) {
1072                         *entptr = p;
1073                 }
1074                 return val;
1075         }
1076
1077         while (*p && isspace(*p))
1078                 p++;
1079
1080         sscanf(p,"%"PRIu64,&val);
1081         if (entptr) {
1082                 while (*p && isdigit(*p))
1083                         p++;
1084                 *entptr = p;
1085         }
1086
1087         return val;
1088 }
1089
1090 /* Convert a size specification to a count of bytes. We accept the following
1091  * suffixes:
1092  *          bytes if there is no suffix
1093  *      kK  kibibytes
1094  *      mM  mebibytes
1095  *      gG  gibibytes
1096  *      tT  tibibytes
1097  *      pP  whatever the ISO name for petabytes is
1098  *
1099  *  Returns 0 if the string can't be converted.
1100  */
1101 uint64_t conv_str_size(const char * str)
1102 {
1103         uint64_t lval_orig;
1104         uint64_t lval;
1105         char * end;
1106
1107         if (str == NULL || *str == '\0') {
1108                 return 0;
1109         }
1110
1111         lval = strtoull(str, &end, 10 /* base */);
1112
1113         if (end == NULL || end == str) {
1114                 return 0;
1115         }
1116
1117         if (*end == '\0') {
1118                 return lval;
1119         }
1120
1121         lval_orig = lval;
1122
1123         if (strwicmp(end, "K") == 0) {
1124                 lval *= 1024ULL;
1125         } else if (strwicmp(end, "M") == 0) {
1126                 lval *= (1024ULL * 1024ULL);
1127         } else if (strwicmp(end, "G") == 0) {
1128                 lval *= (1024ULL * 1024ULL *
1129                          1024ULL);
1130         } else if (strwicmp(end, "T") == 0) {
1131                 lval *= (1024ULL * 1024ULL *
1132                          1024ULL * 1024ULL);
1133         } else if (strwicmp(end, "P") == 0) {
1134                 lval *= (1024ULL * 1024ULL *
1135                          1024ULL * 1024ULL *
1136                          1024ULL);
1137         } else {
1138                 return 0;
1139         }
1140
1141         return lval;
1142 }
1143
1144 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1145  * error checking in between. The indiation that something weird happened is
1146  * string==NULL */
1147
1148 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
1149                     size_t *bufsize, const char *fmt, ...)
1150 {
1151         va_list ap;
1152         char *newstr;
1153         int ret;
1154         bool increased;
1155
1156         /* len<0 is an internal marker that something failed */
1157         if (*len < 0)
1158                 goto error;
1159
1160         if (*string == NULL) {
1161                 if (*bufsize == 0)
1162                         *bufsize = 128;
1163
1164                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
1165                 if (*string == NULL)
1166                         goto error;
1167         }
1168
1169         va_start(ap, fmt);
1170         ret = vasprintf(&newstr, fmt, ap);
1171         va_end(ap);
1172
1173         if (ret < 0)
1174                 goto error;
1175
1176         increased = false;
1177
1178         while ((*len)+ret >= *bufsize) {
1179                 increased = true;
1180                 *bufsize *= 2;
1181                 if (*bufsize >= (1024*1024*256))
1182                         goto error;
1183         }
1184
1185         if (increased) {
1186                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
1187                                                *bufsize);
1188                 if (*string == NULL) {
1189                         goto error;
1190                 }
1191         }
1192
1193         StrnCpy((*string)+(*len), newstr, ret);
1194         (*len) += ret;
1195         free(newstr);
1196         return;
1197
1198  error:
1199         *len = -1;
1200         *string = NULL;
1201 }
1202
1203 /*
1204  * asprintf into a string and strupper_m it after that.
1205  */
1206
1207 int asprintf_strupper_m(char **strp, const char *fmt, ...)
1208 {
1209         va_list ap;
1210         char *result;
1211         int ret;
1212
1213         va_start(ap, fmt);
1214         ret = vasprintf(&result, fmt, ap);
1215         va_end(ap);
1216
1217         if (ret == -1)
1218                 return -1;
1219
1220         strupper_m(result);
1221         *strp = result;
1222         return ret;
1223 }
1224
1225 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
1226 {
1227         va_list ap;
1228         char *ret;
1229
1230         va_start(ap, fmt);
1231         ret = talloc_vasprintf(t, fmt, ap);
1232         va_end(ap);
1233
1234         if (ret == NULL) {
1235                 return NULL;
1236         }
1237         strupper_m(ret);
1238         return ret;
1239 }
1240
1241 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
1242 {
1243         va_list ap;
1244         char *ret;
1245
1246         va_start(ap, fmt);
1247         ret = talloc_vasprintf(t, fmt, ap);
1248         va_end(ap);
1249
1250         if (ret == NULL) {
1251                 return NULL;
1252         }
1253         strlower_m(ret);
1254         return ret;
1255 }
1256
1257
1258 /*
1259    Returns the substring from src between the first occurrence of
1260    the char "front" and the first occurence of the char "back".
1261    Mallocs the return string which must be freed.  Not for use
1262    with wide character strings.
1263 */
1264 char *sstring_sub(const char *src, char front, char back)
1265 {
1266         char *temp1, *temp2, *temp3;
1267         ptrdiff_t len;
1268
1269         temp1 = strchr(src, front);
1270         if (temp1 == NULL) return NULL;
1271         temp2 = strchr(src, back);
1272         if (temp2 == NULL) return NULL;
1273         len = temp2 - temp1;
1274         if (len <= 0) return NULL;
1275         temp3 = (char*)SMB_MALLOC(len);
1276         if (temp3 == NULL) {
1277                 DEBUG(1,("Malloc failure in sstring_sub\n"));
1278                 return NULL;
1279         }
1280         memcpy(temp3, temp1+1, len-1);
1281         temp3[len-1] = '\0';
1282         return temp3;
1283 }
1284
1285 /********************************************************************
1286  Check a string for any occurrences of a specified list of invalid
1287  characters.
1288 ********************************************************************/
1289
1290 bool validate_net_name( const char *name,
1291                 const char *invalid_chars,
1292                 int max_len)
1293 {
1294         int i;
1295
1296         if (!name) {
1297                 return false;
1298         }
1299
1300         for ( i=0; i<max_len && name[i]; i++ ) {
1301                 /* fail if strchr_m() finds one of the invalid characters */
1302                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
1303                         return false;
1304                 }
1305         }
1306
1307         return true;
1308 }
1309
1310
1311 /*******************************************************************
1312  Add a shell escape character '\' to any character not in a known list
1313  of characters. UNIX charset format.
1314 *******************************************************************/
1315
1316 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1317 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1318
1319 char *escape_shell_string(const char *src)
1320 {
1321         size_t srclen = strlen(src);
1322         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
1323         char *dest = ret;
1324         bool in_s_quote = false;
1325         bool in_d_quote = false;
1326         bool next_escaped = false;
1327
1328         if (!ret) {
1329                 return NULL;
1330         }
1331
1332         while (*src) {
1333                 size_t c_size;
1334                 codepoint_t c = next_codepoint(src, &c_size);
1335
1336                 if (c == INVALID_CODEPOINT) {
1337                         SAFE_FREE(ret);
1338                         return NULL;
1339                 }
1340
1341                 if (c_size > 1) {
1342                         memcpy(dest, src, c_size);
1343                         src += c_size;
1344                         dest += c_size;
1345                         next_escaped = false;
1346                         continue;
1347                 }
1348
1349                 /*
1350                  * Deal with backslash escaped state.
1351                  * This only lasts for one character.
1352                  */
1353
1354                 if (next_escaped) {
1355                         *dest++ = *src++;
1356                         next_escaped = false;
1357                         continue;
1358                 }
1359
1360                 /*
1361                  * Deal with single quote state. The
1362                  * only thing we care about is exiting
1363                  * this state.
1364                  */
1365
1366                 if (in_s_quote) {
1367                         if (*src == '\'') {
1368                                 in_s_quote = false;
1369                         }
1370                         *dest++ = *src++;
1371                         continue;
1372                 }
1373
1374                 /*
1375                  * Deal with double quote state. The most
1376                  * complex state. We must cope with \, meaning
1377                  * possibly escape next char (depending what it
1378                  * is), ", meaning exit this state, and possibly
1379                  * add an \ escape to any unprotected character
1380                  * (listed in INSIDE_DQUOTE_LIST).
1381                  */
1382
1383                 if (in_d_quote) {
1384                         if (*src == '\\') {
1385                                 /*
1386                                  * Next character might be escaped.
1387                                  * We have to peek. Inside double
1388                                  * quotes only INSIDE_DQUOTE_LIST
1389                                  * characters are escaped by a \.
1390                                  */
1391
1392                                 char nextchar;
1393
1394                                 c = next_codepoint(&src[1], &c_size);
1395                                 if (c == INVALID_CODEPOINT) {
1396                                         SAFE_FREE(ret);
1397                                         return NULL;
1398                                 }
1399                                 if (c_size > 1) {
1400                                         /*
1401                                          * Don't escape the next char.
1402                                          * Just copy the \.
1403                                          */
1404                                         *dest++ = *src++;
1405                                         continue;
1406                                 }
1407
1408                                 nextchar = src[1];
1409
1410                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
1411                                                         (int)nextchar)) {
1412                                         next_escaped = true;
1413                                 }
1414                                 *dest++ = *src++;
1415                                 continue;
1416                         }
1417
1418                         if (*src == '\"') {
1419                                 /* Exit double quote state. */
1420                                 in_d_quote = false;
1421                                 *dest++ = *src++;
1422                                 continue;
1423                         }
1424
1425                         /*
1426                          * We know the character isn't \ or ",
1427                          * so escape it if it's any of the other
1428                          * possible unprotected characters.
1429                          */
1430
1431                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
1432                                 *dest++ = '\\';
1433                         }
1434                         *dest++ = *src++;
1435                         continue;
1436                 }
1437
1438                 /*
1439                  * From here to the end of the loop we're
1440                  * not in the single or double quote state.
1441                  */
1442
1443                 if (*src == '\\') {
1444                         /* Next character must be escaped. */
1445                         next_escaped = true;
1446                         *dest++ = *src++;
1447                         continue;
1448                 }
1449
1450                 if (*src == '\'') {
1451                         /* Go into single quote state. */
1452                         in_s_quote = true;
1453                         *dest++ = *src++;
1454                         continue;
1455                 }
1456
1457                 if (*src == '\"') {
1458                         /* Go into double quote state. */
1459                         in_d_quote = true;
1460                         *dest++ = *src++;
1461                         continue;
1462                 }
1463
1464                 /* Check if we need to escape the character. */
1465
1466                 if (!strchr(INCLUDE_LIST, (int)*src)) {
1467                         *dest++ = '\\';
1468                 }
1469                 *dest++ = *src++;
1470         }
1471         *dest++ = '\0';
1472         return ret;
1473 }
1474
1475 /***************************************************
1476  str_list_make, v3 version. The v4 version does not
1477  look at quoted strings with embedded blanks, so
1478  do NOT merge this function please!
1479 ***************************************************/
1480
1481 #define S_LIST_ABS 16 /* List Allocation Block Size */
1482
1483 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
1484         const char *sep)
1485 {
1486         char **list;
1487         const char *str;
1488         char *s, *tok;
1489         int num, lsize;
1490
1491         if (!string || !*string)
1492                 return NULL;
1493
1494         list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1495         if (list == NULL) {
1496                 return NULL;
1497         }
1498         lsize = S_LIST_ABS;
1499
1500         s = talloc_strdup(list, string);
1501         if (s == NULL) {
1502                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1503                 TALLOC_FREE(list);
1504                 return NULL;
1505         }
1506         if (!sep) sep = LIST_SEP;
1507
1508         num = 0;
1509         str = s;
1510
1511         while (next_token_talloc(list, &str, &tok, sep)) {
1512
1513                 if (num == lsize) {
1514                         char **tmp;
1515
1516                         lsize += S_LIST_ABS;
1517
1518                         tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1519                                                    lsize + 1);
1520                         if (tmp == NULL) {
1521                                 DEBUG(0,("str_list_make: "
1522                                         "Unable to allocate memory"));
1523                                 TALLOC_FREE(list);
1524                                 return NULL;
1525                         }
1526
1527                         list = tmp;
1528
1529                         memset (&list[num], 0,
1530                                 ((sizeof(char**)) * (S_LIST_ABS +1)));
1531                 }
1532
1533                 list[num] = tok;
1534                 num += 1;
1535         }
1536
1537         list[num] = NULL;
1538
1539         TALLOC_FREE(s);
1540         return list;
1541 }
1542
1543 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
1544 {
1545         fstring tmp;
1546
1547         alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
1548         return talloc_strdup(mem_ctx, tmp);
1549 }