source: branches/samba-3.5.x/source3/lib/util_str.c

Last change on this file was 773, checked in by Herwig Bauernfeind, 12 years ago

Samba Server 3.5: Update branch to 3.5.20

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