source: vendor/3.5.9/source3/lib/util_str.c

Last change on this file was 597, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update vendor to version 3.5.9

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