s3: Fix Coverity ID 2289: Uninitialized read
[Samba.git] / source3 / lib / util_str.c
blob6edf64deeab6550d5b4055f4be16438faec437c9
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
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
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.
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.
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/>.
25 #include "includes.h"
27 const char toupper_ascii_fast_table[128] = {
28 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
38 /**
39 * Case insensitive string compararison.
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.
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.
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.
53 * If we find a non-ascii character we fall back to converting via
54 * iconv.
56 * This should never be slower than convering the whole thing, and
57 * often faster.
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.
64 * Even better is to implement strcasecmp for each encoding and use a
65 * function pointer.
66 **/
67 int StrCaseCmp(const char *s, const char *t)
70 const char *ps, *pt;
71 size_t size;
72 smb_ucs2_t *buffer_s, *buffer_t;
73 int ret;
75 for (ps = s, pt = t; ; ps++, pt++) {
76 char us, ut;
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;
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;
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 */
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 */
114 ret = strcasecmp_w(buffer_s, buffer_t);
115 TALLOC_FREE(buffer_s);
116 TALLOC_FREE(buffer_t);
117 return ret;
122 Case insensitive string compararison, length limited.
124 int StrnCaseCmp(const char *s, const char *t, size_t len)
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;
132 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
133 char us, ut;
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;
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;
156 if (n == len) {
157 return 0;
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 */
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 */
175 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
176 TALLOC_FREE(buffer_s);
177 TALLOC_FREE(buffer_t);
178 return ret;
182 * Compare 2 strings.
184 * @note The comparison is case-insensitive.
186 bool strequal(const char *s1, const char *s2)
188 if (s1 == s2)
189 return(true);
190 if (!s1 || !s2)
191 return(false);
193 return(StrCaseCmp(s1,s2)==0);
197 * Compare 2 strings up to and including the nth char.
199 * @note The comparison is case-insensitive.
201 bool strnequal(const char *s1,const char *s2,size_t n)
203 if (s1 == s2)
204 return(true);
205 if (!s1 || !s2 || !n)
206 return(false);
208 return(StrnCaseCmp(s1,s2,n)==0);
212 Compare 2 strings (case sensitive).
215 bool strcsequal(const char *s1,const char *s2)
217 if (s1 == s2)
218 return(true);
219 if (!s1 || !s2)
220 return(false);
222 return(strcmp(s1,s2)==0);
226 Do a case-insensitive, whitespace-ignoring string compare.
229 int strwicmp(const char *psz1, const char *psz2)
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);
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++;
252 return (*psz1 - *psz2);
256 Convert a string to "normal" form.
259 void strnorm(char *s, int case_default)
261 if (case_default == CASE_UPPER)
262 strupper_m(s);
263 else
264 strlower_m(s);
268 Check if a string is in "normal" case.
271 bool strisnormal(const char *s, int case_default)
273 if (case_default == CASE_UPPER)
274 return(!strhaslower(s));
276 return(!strhasupper(s));
281 String replace.
282 NOTE: oldc and newc must be 7 bit characters
284 void string_replace( char *s, char oldc, char newc )
286 char *p;
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) */
293 for (p = s; *p; p++) {
294 if (*p & 0x80) /* mb string - slow path. */
295 break;
296 if (*p == oldc) {
297 *p = newc;
301 if (!*p)
302 return;
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
310 while (*p) {
311 size_t c_size;
312 next_codepoint(p, &c_size);
314 if (c_size == 1) {
315 if (*p == oldc) {
316 *p = newc;
319 p += c_size;
324 * Skip past some strings in a buffer - old version - no checks.
325 * **/
327 char *push_skip_string(char *buf)
329 buf += strlen(buf) + 1;
330 return(buf);
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.
339 char *skip_string(const char *base, size_t len, char *buf)
341 const char *end_ptr = base + len;
343 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
344 return NULL;
347 /* Skip the string */
348 while (*buf) {
349 buf++;
350 if (buf >= end_ptr) {
351 return NULL;
354 /* Skip the '\0' */
355 buf++;
356 return buf;
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.
365 size_t str_charnum(const char *s)
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;
372 ret = strlen_w(tmpbuf2);
373 TALLOC_FREE(tmpbuf2);
374 return ret;
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.
383 size_t str_ascii_charnum(const char *s)
385 size_t ret, converted_size;
386 char *tmpbuf2 = NULL;
387 if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
388 return 0;
390 ret = strlen(tmpbuf2);
391 TALLOC_FREE(tmpbuf2);
392 return ret;
395 bool trim_char(char *s,char cfront,char cback)
397 bool ret = false;
398 char *ep;
399 char *fp = s;
401 /* Ignore null or empty strings. */
402 if (!s || (s[0] == '\0'))
403 return false;
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;
413 if (fp != s)
414 ret = true;
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';
429 bs[0] = cback;
430 bs[1] = '\0';
431 return trim_string(s, cfront ? fs : NULL, bs);
432 } else {
433 ep--;
436 if (ep < fp) {
437 /* We ate the string. */
438 s[0] = '\0';
439 return true;
443 ep[1] = '\0';
444 memmove(s, fp, ep-fp+2);
445 return ret;
449 Does a string have any uppercase chars in it?
452 bool strhasupper(const char *s)
454 smb_ucs2_t *tmp, *p;
455 bool ret;
456 size_t converted_size;
458 if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
459 return false;
462 for(p = tmp; *p != 0; p++) {
463 if(isupper_w(*p)) {
464 break;
468 ret = (*p != 0);
469 TALLOC_FREE(tmp);
470 return ret;
474 Does a string have any lowercase chars in it?
477 bool strhaslower(const char *s)
479 smb_ucs2_t *tmp, *p;
480 bool ret;
481 size_t converted_size;
483 if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
484 return false;
487 for(p = tmp; *p != 0; p++) {
488 if(islower_w(*p)) {
489 break;
493 ret = (*p != 0);
494 TALLOC_FREE(tmp);
495 return ret;
499 Safe string copy into a known length string. maxlength does not
500 include the terminating zero.
503 char *safe_strcpy_fn(const char *fn,
504 int line,
505 char *dest,
506 const char *src,
507 size_t maxlength)
509 size_t len;
511 if (!dest) {
512 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
513 "called from [%s][%d]\n", fn, line));
514 return NULL;
517 #ifdef DEVELOPER
518 clobber_region(fn,line,dest, maxlength+1);
519 #endif
521 if (!src) {
522 *dest = 0;
523 return dest;
526 len = strnlen(src, maxlength+1);
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;
536 memmove(dest, src, len);
537 dest[len] = 0;
538 return dest;
542 Safe string cat into a string. maxlength does not
543 include the terminating zero.
545 char *safe_strcat_fn(const char *fn,
546 int line,
547 char *dest,
548 const char *src,
549 size_t maxlength)
551 size_t src_len, dest_len;
553 if (!dest) {
554 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
555 "called from [%s][%d]\n", fn, line));
556 return NULL;
559 if (!src)
560 return dest;
562 src_len = strnlen(src, maxlength + 1);
563 dest_len = strnlen(dest, maxlength + 1);
565 #ifdef DEVELOPER
566 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
567 #endif
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);
576 dest[maxlength] = 0;
577 return NULL;
580 memcpy(&dest[dest_len], src, src_len);
581 dest[dest_len + src_len] = 0;
582 return dest;
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. Don't change it !
592 char *alpha_strcpy_fn(const char *fn,
593 int line,
594 char *dest,
595 const char *src,
596 const char *other_safe_chars,
597 size_t maxlength)
599 size_t len, i;
601 #ifdef DEVELOPER
602 clobber_region(fn, line, dest, maxlength);
603 #endif
605 if (!dest) {
606 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
607 "called from [%s][%d]\n", fn, line));
608 return NULL;
611 if (!src) {
612 *dest = 0;
613 return dest;
616 len = strlen(src);
617 if (len >= maxlength)
618 len = maxlength - 1;
620 if (!other_safe_chars)
621 other_safe_chars = "";
623 for(i = 0; i < len; i++) {
624 int val = (src[i] & 0xff);
625 if (isupper_ascii(val) || islower_ascii(val) ||
626 isdigit(val) || strchr_m(other_safe_chars, val))
627 dest[i] = src[i];
628 else
629 dest[i] = '_';
632 dest[i] = '\0';
634 return dest;
638 Like strncpy but always null terminates. Make sure there is room!
639 The variable n should always be one less than the available size.
641 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
643 char *d = dest;
645 #ifdef DEVELOPER
646 clobber_region(fn, line, dest, n+1);
647 #endif
649 if (!dest) {
650 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
651 "called from [%s][%d]\n", fn, line));
652 return(NULL);
655 if (!src) {
656 *dest = 0;
657 return(dest);
660 while (n-- && (*d = *src)) {
661 d++;
662 src++;
665 *d = 0;
666 return(dest);
669 #if 0
671 Like strncpy but copies up to the character marker. always null terminates.
672 returns a pointer to the character marker in the source string (src).
675 static char *strncpyn(char *dest, const char *src, size_t n, char c)
677 char *p;
678 size_t str_len;
680 #ifdef DEVELOPER
681 clobber_region(dest, n+1);
682 #endif
683 p = strchr_m(src, c);
684 if (p == NULL) {
685 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
686 return NULL;
689 str_len = PTR_DIFF(p, src);
690 strncpy(dest, src, MIN(n, str_len));
691 dest[str_len] = '\0';
693 return p;
695 #endif
698 Check if a string is part of a list.
701 bool in_list(const char *s, const char *list, bool casesensitive)
703 char *tok = NULL;
704 bool ret = false;
705 TALLOC_CTX *frame;
707 if (!list) {
708 return false;
711 frame = talloc_stackframe();
712 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
713 if (casesensitive) {
714 if (strcmp(tok,s) == 0) {
715 ret = true;
716 break;
718 } else {
719 if (StrCaseCmp(tok,s) == 0) {
720 ret = true;
721 break;
725 TALLOC_FREE(frame);
726 return ret;
729 /* this is used to prevent lots of mallocs of size 1 */
730 static const char null_string[] = "";
733 Set a string value, allocing the space for the string
736 static bool string_init(char **dest,const char *src)
738 size_t l;
740 if (!src)
741 src = "";
743 l = strlen(src);
745 if (l == 0) {
746 *dest = CONST_DISCARD(char*, null_string);
747 } else {
748 (*dest) = SMB_STRDUP(src);
749 if ((*dest) == NULL) {
750 DEBUG(0,("Out of memory in string_init\n"));
751 return false;
754 return(true);
758 Free a string value.
761 void string_free(char **s)
763 if (!s || !(*s))
764 return;
765 if (*s == null_string)
766 *s = NULL;
767 SAFE_FREE(*s);
771 Set a string value, deallocating any existing space, and allocing the space
772 for the string
775 bool string_set(char **dest,const char *src)
777 string_free(dest);
778 return(string_init(dest,src));
782 Substitute a string for a pattern in another string. Make sure there is
783 enough room!
785 This routine looks for pattern in s and replaces it with
786 insert. It may do multiple replacements or just one.
788 Any of " ; ' $ or ` in the insert string are replaced with _
789 if len==0 then the string cannot be extended. This is different from the old
790 use of len==0 which was for no length checks to be done.
793 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
794 bool remove_unsafe_characters, bool replace_once,
795 bool allow_trailing_dollar)
797 char *p;
798 ssize_t ls,lp,li, i;
800 if (!insert || !pattern || !*pattern || !s)
801 return;
803 ls = (ssize_t)strlen(s);
804 lp = (ssize_t)strlen(pattern);
805 li = (ssize_t)strlen(insert);
807 if (len == 0)
808 len = ls + 1; /* len is number of *bytes* */
810 while (lp <= ls && (p = strstr_m(s,pattern))) {
811 if (ls + (li-lp) >= len) {
812 DEBUG(0,("ERROR: string overflow by "
813 "%d in string_sub(%.50s, %d)\n",
814 (int)(ls + (li-lp) - len),
815 pattern, (int)len));
816 break;
818 if (li != lp) {
819 memmove(p+li,p+lp,strlen(p+lp)+1);
821 for (i=0;i<li;i++) {
822 switch (insert[i]) {
823 case '$':
824 /* allow a trailing $
825 * (as in machine accounts) */
826 if (allow_trailing_dollar && (i == li - 1 )) {
827 p[i] = insert[i];
828 break;
830 case '`':
831 case '"':
832 case '\'':
833 case ';':
834 case '%':
835 case '\r':
836 case '\n':
837 if ( remove_unsafe_characters ) {
838 p[i] = '_';
839 /* yes this break should be here
840 * since we want to fall throw if
841 * not replacing unsafe chars */
842 break;
844 default:
845 p[i] = insert[i];
848 s = p + li;
849 ls += (li-lp);
851 if (replace_once)
852 break;
856 void string_sub_once(char *s, const char *pattern,
857 const char *insert, size_t len)
859 string_sub2( s, pattern, insert, len, true, true, false );
862 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
864 string_sub2( s, pattern, insert, len, true, false, false );
867 void fstring_sub(char *s,const char *pattern,const char *insert)
869 string_sub(s, pattern, insert, sizeof(fstring));
873 Similar to string_sub2, but it will accept only allocated strings
874 and may realloc them so pay attention at what you pass on no
875 pointers inside strings, no const may be passed
876 as string.
879 char *realloc_string_sub2(char *string,
880 const char *pattern,
881 const char *insert,
882 bool remove_unsafe_characters,
883 bool allow_trailing_dollar)
885 char *p, *in;
886 char *s;
887 ssize_t ls,lp,li,ld, i;
889 if (!insert || !pattern || !*pattern || !string || !*string)
890 return NULL;
892 s = string;
894 in = SMB_STRDUP(insert);
895 if (!in) {
896 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
897 return NULL;
899 ls = (ssize_t)strlen(s);
900 lp = (ssize_t)strlen(pattern);
901 li = (ssize_t)strlen(insert);
902 ld = li - lp;
903 for (i=0;i<li;i++) {
904 switch (in[i]) {
905 case '$':
906 /* allow a trailing $
907 * (as in machine accounts) */
908 if (allow_trailing_dollar && (i == li - 1 )) {
909 break;
911 case '`':
912 case '"':
913 case '\'':
914 case ';':
915 case '%':
916 case '\r':
917 case '\n':
918 if ( remove_unsafe_characters ) {
919 in[i] = '_';
920 break;
922 default:
923 /* ok */
924 break;
928 while ((p = strstr_m(s,pattern))) {
929 if (ld > 0) {
930 int offset = PTR_DIFF(s,string);
931 string = (char *)SMB_REALLOC(string, ls + ld + 1);
932 if (!string) {
933 DEBUG(0, ("realloc_string_sub: "
934 "out of memory!\n"));
935 SAFE_FREE(in);
936 return NULL;
938 p = string + offset + (p - s);
940 if (li != lp) {
941 memmove(p+li,p+lp,strlen(p+lp)+1);
943 memcpy(p, in, li);
944 s = p + li;
945 ls += ld;
947 SAFE_FREE(in);
948 return string;
951 char *realloc_string_sub(char *string,
952 const char *pattern,
953 const char *insert)
955 return realloc_string_sub2(string, pattern, insert, true, false);
959 * Internal guts of talloc_string_sub and talloc_all_string_sub.
960 * talloc version of string_sub2.
963 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
964 const char *pattern,
965 const char *insert,
966 bool remove_unsafe_characters,
967 bool replace_once,
968 bool allow_trailing_dollar)
970 char *p, *in;
971 char *s;
972 char *string;
973 ssize_t ls,lp,li,ld, i;
975 if (!insert || !pattern || !*pattern || !src) {
976 return NULL;
979 string = talloc_strdup(mem_ctx, src);
980 if (string == NULL) {
981 DEBUG(0, ("talloc_string_sub2: "
982 "talloc_strdup failed\n"));
983 return NULL;
986 s = string;
988 in = SMB_STRDUP(insert);
989 if (!in) {
990 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
991 return NULL;
993 ls = (ssize_t)strlen(s);
994 lp = (ssize_t)strlen(pattern);
995 li = (ssize_t)strlen(insert);
996 ld = li - lp;
998 for (i=0;i<li;i++) {
999 switch (in[i]) {
1000 case '$':
1001 /* allow a trailing $
1002 * (as in machine accounts) */
1003 if (allow_trailing_dollar && (i == li - 1 )) {
1004 break;
1006 case '`':
1007 case '"':
1008 case '\'':
1009 case ';':
1010 case '%':
1011 case '\r':
1012 case '\n':
1013 if (remove_unsafe_characters) {
1014 in[i] = '_';
1015 break;
1017 default:
1018 /* ok */
1019 break;
1023 while ((p = strstr_m(s,pattern))) {
1024 if (ld > 0) {
1025 int offset = PTR_DIFF(s,string);
1026 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1027 ls + ld + 1);
1028 if (!string) {
1029 DEBUG(0, ("talloc_string_sub: out of "
1030 "memory!\n"));
1031 SAFE_FREE(in);
1032 return NULL;
1034 p = string + offset + (p - s);
1036 if (li != lp) {
1037 memmove(p+li,p+lp,strlen(p+lp)+1);
1039 memcpy(p, in, li);
1040 s = p + li;
1041 ls += ld;
1043 if (replace_once) {
1044 break;
1047 SAFE_FREE(in);
1048 return string;
1051 /* Same as string_sub, but returns a talloc'ed string */
1053 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1054 const char *src,
1055 const char *pattern,
1056 const char *insert)
1058 return talloc_string_sub2(mem_ctx, src, pattern, insert,
1059 true, false, false);
1063 Similar to string_sub() but allows for any character to be substituted.
1064 Use with caution!
1065 if len==0 then the string cannot be extended. This is different from the old
1066 use of len==0 which was for no length checks to be done.
1069 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1071 char *p;
1072 ssize_t ls,lp,li;
1074 if (!insert || !pattern || !s)
1075 return;
1077 ls = (ssize_t)strlen(s);
1078 lp = (ssize_t)strlen(pattern);
1079 li = (ssize_t)strlen(insert);
1081 if (!*pattern)
1082 return;
1084 if (len == 0)
1085 len = ls + 1; /* len is number of *bytes* */
1087 while (lp <= ls && (p = strstr_m(s,pattern))) {
1088 if (ls + (li-lp) >= len) {
1089 DEBUG(0,("ERROR: string overflow by "
1090 "%d in all_string_sub(%.50s, %d)\n",
1091 (int)(ls + (li-lp) - len),
1092 pattern, (int)len));
1093 break;
1095 if (li != lp) {
1096 memmove(p+li,p+lp,strlen(p+lp)+1);
1098 memcpy(p, insert, li);
1099 s = p + li;
1100 ls += (li-lp);
1104 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1105 const char *src,
1106 const char *pattern,
1107 const char *insert)
1109 return talloc_string_sub2(ctx, src, pattern, insert,
1110 false, false, false);
1114 Write an octal as a string.
1117 char *octal_string(int i)
1119 char *result;
1120 if (i == -1) {
1121 result = talloc_strdup(talloc_tos(), "-1");
1123 else {
1124 result = talloc_asprintf(talloc_tos(), "0%o", i);
1126 SMB_ASSERT(result != NULL);
1127 return result;
1132 Truncate a string at a specified length.
1135 char *string_truncate(char *s, unsigned int length)
1137 if (s && strlen(s) > length)
1138 s[length] = 0;
1139 return s;
1143 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1144 We convert via ucs2 for now.
1147 char *strchr_m(const char *src, char c)
1149 smb_ucs2_t *ws = NULL;
1150 char *s2 = NULL;
1151 smb_ucs2_t *p;
1152 const char *s;
1153 char *ret;
1154 size_t converted_size;
1156 /* characters below 0x3F are guaranteed to not appear in
1157 non-initial position in multi-byte charsets */
1158 if ((c & 0xC0) == 0) {
1159 return strchr(src, c);
1162 /* this is quite a common operation, so we want it to be
1163 fast. We optimise for the ascii case, knowing that all our
1164 supported multi-byte character sets are ascii-compatible
1165 (ie. they match for the first 128 chars) */
1167 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1168 if (*s == c)
1169 return (char *)s;
1172 if (!*s)
1173 return NULL;
1175 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1176 /* With compose characters we must restart from the beginning. JRA. */
1177 s = src;
1178 #endif
1180 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1181 /* Wrong answer, but what can we do... */
1182 return strchr(src, c);
1184 p = strchr_w(ws, UCS2_CHAR(c));
1185 if (!p) {
1186 TALLOC_FREE(ws);
1187 return NULL;
1189 *p = 0;
1190 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1191 SAFE_FREE(ws);
1192 /* Wrong answer, but what can we do... */
1193 return strchr(src, c);
1195 ret = (char *)(s+strlen(s2));
1196 TALLOC_FREE(ws);
1197 TALLOC_FREE(s2);
1198 return ret;
1201 char *strrchr_m(const char *s, char c)
1203 /* characters below 0x3F are guaranteed to not appear in
1204 non-initial position in multi-byte charsets */
1205 if ((c & 0xC0) == 0) {
1206 return strrchr(s, c);
1209 /* this is quite a common operation, so we want it to be
1210 fast. We optimise for the ascii case, knowing that all our
1211 supported multi-byte character sets are ascii-compatible
1212 (ie. they match for the first 128 chars). Also, in Samba
1213 we only search for ascii characters in 'c' and that
1214 in all mb character sets with a compound character
1215 containing c, if 'c' is not a match at position
1216 p, then p[-1] > 0x7f. JRA. */
1219 size_t len = strlen(s);
1220 const char *cp = s;
1221 bool got_mb = false;
1223 if (len == 0)
1224 return NULL;
1225 cp += (len - 1);
1226 do {
1227 if (c == *cp) {
1228 /* Could be a match. Part of a multibyte ? */
1229 if ((cp > s) &&
1230 (((unsigned char)cp[-1]) & 0x80)) {
1231 /* Yep - go slow :-( */
1232 got_mb = true;
1233 break;
1235 /* No - we have a match ! */
1236 return (char *)cp;
1238 } while (cp-- != s);
1239 if (!got_mb)
1240 return NULL;
1243 /* String contained a non-ascii char. Slow path. */
1245 smb_ucs2_t *ws = NULL;
1246 char *s2 = NULL;
1247 smb_ucs2_t *p;
1248 char *ret;
1249 size_t converted_size;
1251 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1252 /* Wrong answer, but what can we do. */
1253 return strrchr(s, c);
1255 p = strrchr_w(ws, UCS2_CHAR(c));
1256 if (!p) {
1257 TALLOC_FREE(ws);
1258 return NULL;
1260 *p = 0;
1261 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1262 TALLOC_FREE(ws);
1263 /* Wrong answer, but what can we do. */
1264 return strrchr(s, c);
1266 ret = (char *)(s+strlen(s2));
1267 TALLOC_FREE(ws);
1268 TALLOC_FREE(s2);
1269 return ret;
1273 /***********************************************************************
1274 Return the equivalent of doing strrchr 'n' times - always going
1275 backwards.
1276 ***********************************************************************/
1278 char *strnrchr_m(const char *s, char c, unsigned int n)
1280 smb_ucs2_t *ws = NULL;
1281 char *s2 = NULL;
1282 smb_ucs2_t *p;
1283 char *ret;
1284 size_t converted_size;
1286 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1287 /* Too hard to try and get right. */
1288 return NULL;
1290 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1291 if (!p) {
1292 TALLOC_FREE(ws);
1293 return NULL;
1295 *p = 0;
1296 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1297 TALLOC_FREE(ws);
1298 /* Too hard to try and get right. */
1299 return NULL;
1301 ret = (char *)(s+strlen(s2));
1302 TALLOC_FREE(ws);
1303 TALLOC_FREE(s2);
1304 return ret;
1307 /***********************************************************************
1308 strstr_m - We convert via ucs2 for now.
1309 ***********************************************************************/
1311 char *strstr_m(const char *src, const char *findstr)
1313 smb_ucs2_t *p;
1314 smb_ucs2_t *src_w, *find_w;
1315 const char *s;
1316 char *s2;
1317 char *retp;
1319 size_t converted_size, findstr_len = 0;
1321 /* for correctness */
1322 if (!findstr[0]) {
1323 return (char*)src;
1326 /* Samba does single character findstr calls a *lot*. */
1327 if (findstr[1] == '\0')
1328 return strchr_m(src, *findstr);
1330 /* We optimise for the ascii case, knowing that all our
1331 supported multi-byte character sets are ascii-compatible
1332 (ie. they match for the first 128 chars) */
1334 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1335 if (*s == *findstr) {
1336 if (!findstr_len)
1337 findstr_len = strlen(findstr);
1339 if (strncmp(s, findstr, findstr_len) == 0) {
1340 return (char *)s;
1345 if (!*s)
1346 return NULL;
1348 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1349 /* 'make check' fails unless we do this */
1351 /* With compose characters we must restart from the beginning. JRA. */
1352 s = src;
1353 #endif
1355 if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
1356 DEBUG(0,("strstr_m: src malloc fail\n"));
1357 return NULL;
1360 if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
1361 TALLOC_FREE(src_w);
1362 DEBUG(0,("strstr_m: find malloc fail\n"));
1363 return NULL;
1366 p = strstr_w(src_w, find_w);
1368 if (!p) {
1369 TALLOC_FREE(src_w);
1370 TALLOC_FREE(find_w);
1371 return NULL;
1374 *p = 0;
1375 if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
1376 TALLOC_FREE(src_w);
1377 TALLOC_FREE(find_w);
1378 DEBUG(0,("strstr_m: dest malloc fail\n"));
1379 return NULL;
1381 retp = (char *)(s+strlen(s2));
1382 TALLOC_FREE(src_w);
1383 TALLOC_FREE(find_w);
1384 TALLOC_FREE(s2);
1385 return retp;
1389 Convert a string to lower case.
1392 void strlower_m(char *s)
1394 size_t len;
1395 int errno_save;
1397 /* this is quite a common operation, so we want it to be
1398 fast. We optimise for the ascii case, knowing that all our
1399 supported multi-byte character sets are ascii-compatible
1400 (ie. they match for the first 128 chars) */
1402 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1403 *s = tolower_ascii((unsigned char)*s);
1404 s++;
1407 if (!*s)
1408 return;
1410 /* I assume that lowercased string takes the same number of bytes
1411 * as source string even in UTF-8 encoding. (VIV) */
1412 len = strlen(s) + 1;
1413 errno_save = errno;
1414 errno = 0;
1415 unix_strlower(s,len,s,len);
1416 /* Catch mb conversion errors that may not terminate. */
1417 if (errno)
1418 s[len-1] = '\0';
1419 errno = errno_save;
1423 Convert a string to upper case.
1426 void strupper_m(char *s)
1428 size_t len;
1429 int errno_save;
1431 /* this is quite a common operation, so we want it to be
1432 fast. We optimise for the ascii case, knowing that all our
1433 supported multi-byte character sets are ascii-compatible
1434 (ie. they match for the first 128 chars) */
1436 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1437 *s = toupper_ascii_fast((unsigned char)*s);
1438 s++;
1441 if (!*s)
1442 return;
1444 /* I assume that lowercased string takes the same number of bytes
1445 * as source string even in multibyte encoding. (VIV) */
1446 len = strlen(s) + 1;
1447 errno_save = errno;
1448 errno = 0;
1449 unix_strupper(s,len,s,len);
1450 /* Catch mb conversion errors that may not terminate. */
1451 if (errno)
1452 s[len-1] = '\0';
1453 errno = errno_save;
1457 * Calculate the number of units (8 or 16-bit, depending on the
1458 * destination charset), that would be needed to convert the input
1459 * string which is expected to be in in src_charset encoding to the
1460 * destination charset (which should be a unicode charset).
1463 size_t strlen_m_ext(const char *s, const charset_t src_charset,
1464 const charset_t dst_charset)
1466 size_t count = 0;
1468 if (!s) {
1469 return 0;
1472 while (*s && !(((uint8_t)*s) & 0x80)) {
1473 s++;
1474 count++;
1477 if (!*s) {
1478 return count;
1481 while (*s) {
1482 size_t c_size;
1483 codepoint_t c = next_codepoint_ext(s, src_charset, &c_size);
1484 s += c_size;
1486 switch (dst_charset) {
1487 case CH_UTF16LE:
1488 case CH_UTF16BE:
1489 case CH_UTF16MUNGED:
1490 if (c < 0x10000) {
1491 /* Unicode char fits into 16 bits. */
1492 count += 1;
1493 } else {
1494 /* Double-width unicode char - 32 bits. */
1495 count += 2;
1497 break;
1498 case CH_UTF8:
1500 * this only checks ranges, and does not
1501 * check for invalid codepoints
1503 if (c < 0x80) {
1504 count += 1;
1505 } else if (c < 0x800) {
1506 count += 2;
1507 } else if (c < 0x1000) {
1508 count += 3;
1509 } else {
1510 count += 4;
1512 break;
1513 default:
1515 * non-unicode encoding:
1516 * assume that each codepoint fits into
1517 * one unit in the destination encoding.
1519 count += 1;
1523 return count;
1526 size_t strlen_m_ext_term(const char *s, const charset_t src_charset,
1527 const charset_t dst_charset)
1529 if (!s) {
1530 return 0;
1532 return strlen_m_ext(s, src_charset, dst_charset) + 1;
1536 * Calculate the number of 16-bit units that would bee needed to convert
1537 * the input string which is expected to be in CH_UNIX encoding to UTF16.
1539 * This will be the same as the number of bytes in a string for single
1540 * byte strings, but will be different for multibyte.
1543 size_t strlen_m(const char *s)
1545 return strlen_m_ext(s, CH_UNIX, CH_UTF16LE);
1549 Count the number of UCS2 characters in a string including the null
1550 terminator.
1553 size_t strlen_m_term(const char *s)
1555 if (!s) {
1556 return 0;
1558 return strlen_m(s) + 1;
1562 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1563 * if a string is there, include the terminator.
1566 size_t strlen_m_term_null(const char *s)
1568 size_t len;
1569 if (!s) {
1570 return 0;
1572 len = strlen_m(s);
1573 if (len == 0) {
1574 return 0;
1577 return len+1;
1580 Return a RFC2254 binary string representation of a buffer.
1581 Used in LDAP filters.
1582 Caller must free.
1585 char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len)
1587 char *s;
1588 int i, j;
1589 const char *hex = "0123456789ABCDEF";
1590 s = talloc_array(mem_ctx, char, len * 3 + 1);
1591 if (s == NULL) {
1592 return NULL;
1594 for (j=i=0;i<len;i++) {
1595 s[j] = '\\';
1596 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1597 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1598 j += 3;
1600 s[j] = 0;
1601 return s;
1604 char *binary_string(char *buf, int len)
1606 char *s;
1607 int i, j;
1608 const char *hex = "0123456789ABCDEF";
1609 s = (char *)SMB_MALLOC(len * 2 + 1);
1610 if (!s)
1611 return NULL;
1612 for (j=i=0;i<len;i++) {
1613 s[j] = hex[((unsigned char)buf[i]) >> 4];
1614 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1615 j += 2;
1617 s[j] = 0;
1618 return s;
1622 Just a typesafety wrapper for snprintf into a fstring.
1625 int fstr_sprintf(fstring s, const char *fmt, ...)
1627 va_list ap;
1628 int ret;
1630 va_start(ap, fmt);
1631 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1632 va_end(ap);
1633 return ret;
1637 List of Strings manipulation functions
1640 #define S_LIST_ABS 16 /* List Allocation Block Size */
1642 /******************************************************************************
1643 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1644 for the work
1645 *****************************************************************************/
1647 bool str_list_sub_basic( char **list, const char *smb_name,
1648 const char *domain_name )
1650 TALLOC_CTX *ctx = list;
1651 char *s, *tmpstr;
1653 while ( *list ) {
1654 s = *list;
1655 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1656 if ( !tmpstr ) {
1657 DEBUG(0,("str_list_sub_basic: "
1658 "alloc_sub_basic() return NULL!\n"));
1659 return false;
1662 TALLOC_FREE(*list);
1663 *list = tmpstr;
1665 list++;
1668 return true;
1671 /******************************************************************************
1672 substitute a specific pattern in a string list
1673 *****************************************************************************/
1675 bool str_list_substitute(char **list, const char *pattern, const char *insert)
1677 TALLOC_CTX *ctx = list;
1678 char *p, *s, *t;
1679 ssize_t ls, lp, li, ld, i, d;
1681 if (!list)
1682 return false;
1683 if (!pattern)
1684 return false;
1685 if (!insert)
1686 return false;
1688 lp = (ssize_t)strlen(pattern);
1689 li = (ssize_t)strlen(insert);
1690 ld = li -lp;
1692 while (*list) {
1693 s = *list;
1694 ls = (ssize_t)strlen(s);
1696 while ((p = strstr_m(s, pattern))) {
1697 t = *list;
1698 d = p -t;
1699 if (ld) {
1700 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
1701 if (!t) {
1702 DEBUG(0,("str_list_substitute: "
1703 "Unable to allocate memory"));
1704 return false;
1706 memcpy(t, *list, d);
1707 memcpy(t +d +li, p +lp, ls -d -lp +1);
1708 TALLOC_FREE(*list);
1709 *list = t;
1710 ls += ld;
1711 s = t +d +li;
1714 for (i = 0; i < li; i++) {
1715 switch (insert[i]) {
1716 case '`':
1717 case '"':
1718 case '\'':
1719 case ';':
1720 case '$':
1721 case '%':
1722 case '\r':
1723 case '\n':
1724 t[d +i] = '_';
1725 break;
1726 default:
1727 t[d +i] = insert[i];
1732 list++;
1735 return true;
1739 #define IPSTR_LIST_SEP ","
1740 #define IPSTR_LIST_CHAR ','
1743 * Add ip string representation to ipstr list. Used also
1744 * as part of @function ipstr_list_make
1746 * @param ipstr_list pointer to string containing ip list;
1747 * MUST BE already allocated and IS reallocated if necessary
1748 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1749 * as a result of reallocation)
1750 * @param ip IP address which is to be added to list
1751 * @return pointer to string appended with new ip and possibly
1752 * reallocated to new length
1755 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1757 char *new_ipstr = NULL;
1758 char addr_buf[INET6_ADDRSTRLEN];
1759 int ret;
1761 /* arguments checking */
1762 if (!ipstr_list || !service) {
1763 return NULL;
1766 print_sockaddr(addr_buf,
1767 sizeof(addr_buf),
1768 &service->ss);
1770 /* attempt to convert ip to a string and append colon separator to it */
1771 if (*ipstr_list) {
1772 if (service->ss.ss_family == AF_INET) {
1773 /* IPv4 */
1774 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1775 IPSTR_LIST_SEP, addr_buf,
1776 service->port);
1777 } else {
1778 /* IPv6 */
1779 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1780 IPSTR_LIST_SEP, addr_buf,
1781 service->port);
1783 SAFE_FREE(*ipstr_list);
1784 } else {
1785 if (service->ss.ss_family == AF_INET) {
1786 /* IPv4 */
1787 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1788 service->port);
1789 } else {
1790 /* IPv6 */
1791 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1792 service->port);
1795 if (ret == -1) {
1796 return NULL;
1798 *ipstr_list = new_ipstr;
1799 return *ipstr_list;
1803 * Allocate and initialise an ipstr list using ip adresses
1804 * passed as arguments.
1806 * @param ipstr_list pointer to string meant to be allocated and set
1807 * @param ip_list array of ip addresses to place in the list
1808 * @param ip_count number of addresses stored in ip_list
1809 * @return pointer to allocated ip string
1812 char *ipstr_list_make(char **ipstr_list,
1813 const struct ip_service *ip_list,
1814 int ip_count)
1816 int i;
1818 /* arguments checking */
1819 if (!ip_list || !ipstr_list) {
1820 return 0;
1823 *ipstr_list = NULL;
1825 /* process ip addresses given as arguments */
1826 for (i = 0; i < ip_count; i++) {
1827 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1830 return (*ipstr_list);
1835 * Parse given ip string list into array of ip addresses
1836 * (as ip_service structures)
1837 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1839 * @param ipstr ip string list to be parsed
1840 * @param ip_list pointer to array of ip addresses which is
1841 * allocated by this function and must be freed by caller
1842 * @return number of successfully parsed addresses
1845 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1847 TALLOC_CTX *frame;
1848 char *token_str = NULL;
1849 size_t count;
1850 int i;
1852 if (!ipstr_list || !ip_list)
1853 return 0;
1855 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1856 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1857 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1858 (unsigned long)count));
1859 return 0;
1862 frame = talloc_stackframe();
1863 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1864 IPSTR_LIST_SEP) && i<count; i++ ) {
1865 char *s = token_str;
1866 char *p = strrchr(token_str, ':');
1868 if (p) {
1869 *p = 0;
1870 (*ip_list)[i].port = atoi(p+1);
1873 /* convert single token to ip address */
1874 if (token_str[0] == '[') {
1875 /* IPv6 address. */
1876 s++;
1877 p = strchr(token_str, ']');
1878 if (!p) {
1879 continue;
1881 *p = '\0';
1883 if (!interpret_string_addr(&(*ip_list)[i].ss,
1885 AI_NUMERICHOST)) {
1886 continue;
1889 TALLOC_FREE(frame);
1890 return count;
1894 * Safely free ip string list
1896 * @param ipstr_list ip string list to be freed
1899 void ipstr_list_free(char* ipstr_list)
1901 SAFE_FREE(ipstr_list);
1904 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1907 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1909 DATA_BLOB base64_decode_data_blob(const char *s)
1911 int bit_offset, byte_offset, idx, i, n;
1912 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1913 unsigned char *d = decoded.data;
1914 char *p;
1916 n=i=0;
1918 while (*s && (p=strchr_m(b64,*s))) {
1919 idx = (int)(p - b64);
1920 byte_offset = (i*6)/8;
1921 bit_offset = (i*6)%8;
1922 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1923 if (bit_offset < 3) {
1924 d[byte_offset] |= (idx << (2-bit_offset));
1925 n = byte_offset+1;
1926 } else {
1927 d[byte_offset] |= (idx >> (bit_offset-2));
1928 d[byte_offset+1] = 0;
1929 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1930 n = byte_offset+2;
1932 s++; i++;
1935 if ((n > 0) && (*s == '=')) {
1936 n -= 1;
1939 /* fix up length */
1940 decoded.length = n;
1941 return decoded;
1945 * Decode a base64 string in-place - wrapper for the above
1947 void base64_decode_inplace(char *s)
1949 DATA_BLOB decoded = base64_decode_data_blob(s);
1951 if ( decoded.length != 0 ) {
1952 memcpy(s, decoded.data, decoded.length);
1954 /* null terminate */
1955 s[decoded.length] = '\0';
1956 } else {
1957 *s = '\0';
1960 data_blob_free(&decoded);
1964 * Encode a base64 string into a talloc()ed string caller to free.
1966 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
1967 * with adjustments
1970 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
1972 int bits = 0;
1973 int char_count = 0;
1974 size_t out_cnt, len, output_len;
1975 char *result;
1977 if (!data.length || !data.data)
1978 return NULL;
1980 out_cnt = 0;
1981 len = data.length;
1982 output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
1983 * random but should be enough for
1984 * the = and \0 */
1985 result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
1986 SMB_ASSERT(result != NULL);
1988 while (len--) {
1989 int c = (unsigned char) *(data.data++);
1990 bits += c;
1991 char_count++;
1992 if (char_count == 3) {
1993 result[out_cnt++] = b64[bits >> 18];
1994 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1995 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1996 result[out_cnt++] = b64[bits & 0x3f];
1997 bits = 0;
1998 char_count = 0;
1999 } else {
2000 bits <<= 8;
2003 if (char_count != 0) {
2004 bits <<= 16 - (8 * char_count);
2005 result[out_cnt++] = b64[bits >> 18];
2006 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2007 if (char_count == 1) {
2008 result[out_cnt++] = '=';
2009 result[out_cnt++] = '=';
2010 } else {
2011 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2012 result[out_cnt++] = '=';
2015 result[out_cnt] = '\0'; /* terminate */
2016 return result;
2019 /* read a SMB_BIG_UINT from a string */
2020 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2023 uint64_t val = (uint64_t)-1;
2024 const char *p = nptr;
2026 if (!p) {
2027 if (entptr) {
2028 *entptr = p;
2030 return val;
2033 while (*p && isspace(*p))
2034 p++;
2036 sscanf(p,"%"PRIu64,&val);
2037 if (entptr) {
2038 while (*p && isdigit(*p))
2039 p++;
2040 *entptr = p;
2043 return val;
2046 /* Convert a size specification to a count of bytes. We accept the following
2047 * suffixes:
2048 * bytes if there is no suffix
2049 * kK kibibytes
2050 * mM mebibytes
2051 * gG gibibytes
2052 * tT tibibytes
2053 * pP whatever the ISO name for petabytes is
2055 * Returns 0 if the string can't be converted.
2057 SMB_OFF_T conv_str_size(const char * str)
2059 SMB_OFF_T lval_orig;
2060 SMB_OFF_T lval;
2061 char * end;
2063 if (str == NULL || *str == '\0') {
2064 return 0;
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 */);
2073 #else
2074 lval = strtoul(str, &end, 10 /* base */);
2075 #endif
2077 if (end == NULL || end == str) {
2078 return 0;
2081 if (*end == '\0') {
2082 return lval;
2085 lval_orig = lval;
2087 if (strwicmp(end, "K") == 0) {
2088 lval *= (SMB_OFF_T)1024;
2089 } else if (strwicmp(end, "M") == 0) {
2090 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2091 } else if (strwicmp(end, "G") == 0) {
2092 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2093 (SMB_OFF_T)1024);
2094 } else if (strwicmp(end, "T") == 0) {
2095 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2096 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2097 } else if (strwicmp(end, "P") == 0) {
2098 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2099 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2100 (SMB_OFF_T)1024);
2101 } else {
2102 return 0;
2106 * Primitive attempt to detect wrapping on platforms with
2107 * 4-byte SMB_OFF_T. It's better to let the caller handle a
2108 * failure than some random number.
2110 if (lval_orig <= lval) {
2111 return 0;
2114 return lval;
2117 void string_append(char **left, const char *right)
2119 int new_len = strlen(right) + 1;
2121 if (*left == NULL) {
2122 *left = (char *)SMB_MALLOC(new_len);
2123 if (*left == NULL) {
2124 return;
2126 *left[0] = '\0';
2127 } else {
2128 new_len += strlen(*left);
2129 *left = (char *)SMB_REALLOC(*left, new_len);
2132 if (*left == NULL) {
2133 return;
2136 safe_strcat(*left, right, new_len-1);
2139 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2140 const char *str, const char ***strings,
2141 int *num)
2143 char *dup_str = talloc_strdup(mem_ctx, str);
2145 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2146 const char *, (*num)+1);
2148 if ((*strings == NULL) || (dup_str == NULL)) {
2149 *num = 0;
2150 return false;
2153 (*strings)[*num] = dup_str;
2154 *num += 1;
2155 return true;
2158 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2159 * error checking in between. The indiation that something weird happened is
2160 * string==NULL */
2162 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2163 size_t *bufsize, const char *fmt, ...)
2165 va_list ap;
2166 char *newstr;
2167 int ret;
2168 bool increased;
2170 /* len<0 is an internal marker that something failed */
2171 if (*len < 0)
2172 goto error;
2174 if (*string == NULL) {
2175 if (*bufsize == 0)
2176 *bufsize = 128;
2178 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2179 if (*string == NULL)
2180 goto error;
2183 va_start(ap, fmt);
2184 ret = vasprintf(&newstr, fmt, ap);
2185 va_end(ap);
2187 if (ret < 0)
2188 goto error;
2190 increased = false;
2192 while ((*len)+ret >= *bufsize) {
2193 increased = true;
2194 *bufsize *= 2;
2195 if (*bufsize >= (1024*1024*256))
2196 goto error;
2199 if (increased) {
2200 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2201 *bufsize);
2202 if (*string == NULL) {
2203 goto error;
2207 StrnCpy((*string)+(*len), newstr, ret);
2208 (*len) += ret;
2209 free(newstr);
2210 return;
2212 error:
2213 *len = -1;
2214 *string = NULL;
2218 * asprintf into a string and strupper_m it after that.
2221 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2223 va_list ap;
2224 char *result;
2225 int ret;
2227 va_start(ap, fmt);
2228 ret = vasprintf(&result, fmt, ap);
2229 va_end(ap);
2231 if (ret == -1)
2232 return -1;
2234 strupper_m(result);
2235 *strp = result;
2236 return ret;
2239 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2241 va_list ap;
2242 char *ret;
2244 va_start(ap, fmt);
2245 ret = talloc_vasprintf(t, fmt, ap);
2246 va_end(ap);
2248 if (ret == NULL) {
2249 return NULL;
2251 strupper_m(ret);
2252 return ret;
2255 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
2257 va_list ap;
2258 char *ret;
2260 va_start(ap, fmt);
2261 ret = talloc_vasprintf(t, fmt, ap);
2262 va_end(ap);
2264 if (ret == NULL) {
2265 return NULL;
2267 strlower_m(ret);
2268 return ret;
2273 Returns the substring from src between the first occurrence of
2274 the char "front" and the first occurence of the char "back".
2275 Mallocs the return string which must be freed. Not for use
2276 with wide character strings.
2278 char *sstring_sub(const char *src, char front, char back)
2280 char *temp1, *temp2, *temp3;
2281 ptrdiff_t len;
2283 temp1 = strchr(src, front);
2284 if (temp1 == NULL) return NULL;
2285 temp2 = strchr(src, back);
2286 if (temp2 == NULL) return NULL;
2287 len = temp2 - temp1;
2288 if (len <= 0) return NULL;
2289 temp3 = (char*)SMB_MALLOC(len);
2290 if (temp3 == NULL) {
2291 DEBUG(1,("Malloc failure in sstring_sub\n"));
2292 return NULL;
2294 memcpy(temp3, temp1+1, len-1);
2295 temp3[len-1] = '\0';
2296 return temp3;
2299 /********************************************************************
2300 Check a string for any occurrences of a specified list of invalid
2301 characters.
2302 ********************************************************************/
2304 bool validate_net_name( const char *name,
2305 const char *invalid_chars,
2306 int max_len)
2308 int i;
2310 if (!name) {
2311 return false;
2314 for ( i=0; i<max_len && name[i]; i++ ) {
2315 /* fail if strchr_m() finds one of the invalid characters */
2316 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2317 return false;
2321 return true;
2325 /*******************************************************************
2326 Add a shell escape character '\' to any character not in a known list
2327 of characters. UNIX charset format.
2328 *******************************************************************/
2330 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2331 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2333 char *escape_shell_string(const char *src)
2335 size_t srclen = strlen(src);
2336 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2337 char *dest = ret;
2338 bool in_s_quote = false;
2339 bool in_d_quote = false;
2340 bool next_escaped = false;
2342 if (!ret) {
2343 return NULL;
2346 while (*src) {
2347 size_t c_size;
2348 codepoint_t c = next_codepoint(src, &c_size);
2350 if (c == INVALID_CODEPOINT) {
2351 SAFE_FREE(ret);
2352 return NULL;
2355 if (c_size > 1) {
2356 memcpy(dest, src, c_size);
2357 src += c_size;
2358 dest += c_size;
2359 next_escaped = false;
2360 continue;
2364 * Deal with backslash escaped state.
2365 * This only lasts for one character.
2368 if (next_escaped) {
2369 *dest++ = *src++;
2370 next_escaped = false;
2371 continue;
2375 * Deal with single quote state. The
2376 * only thing we care about is exiting
2377 * this state.
2380 if (in_s_quote) {
2381 if (*src == '\'') {
2382 in_s_quote = false;
2384 *dest++ = *src++;
2385 continue;
2389 * Deal with double quote state. The most
2390 * complex state. We must cope with \, meaning
2391 * possibly escape next char (depending what it
2392 * is), ", meaning exit this state, and possibly
2393 * add an \ escape to any unprotected character
2394 * (listed in INSIDE_DQUOTE_LIST).
2397 if (in_d_quote) {
2398 if (*src == '\\') {
2400 * Next character might be escaped.
2401 * We have to peek. Inside double
2402 * quotes only INSIDE_DQUOTE_LIST
2403 * characters are escaped by a \.
2406 char nextchar;
2408 c = next_codepoint(&src[1], &c_size);
2409 if (c == INVALID_CODEPOINT) {
2410 SAFE_FREE(ret);
2411 return NULL;
2413 if (c_size > 1) {
2415 * Don't escape the next char.
2416 * Just copy the \.
2418 *dest++ = *src++;
2419 continue;
2422 nextchar = src[1];
2424 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2425 (int)nextchar)) {
2426 next_escaped = true;
2428 *dest++ = *src++;
2429 continue;
2432 if (*src == '\"') {
2433 /* Exit double quote state. */
2434 in_d_quote = false;
2435 *dest++ = *src++;
2436 continue;
2440 * We know the character isn't \ or ",
2441 * so escape it if it's any of the other
2442 * possible unprotected characters.
2445 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2446 *dest++ = '\\';
2448 *dest++ = *src++;
2449 continue;
2453 * From here to the end of the loop we're
2454 * not in the single or double quote state.
2457 if (*src == '\\') {
2458 /* Next character must be escaped. */
2459 next_escaped = true;
2460 *dest++ = *src++;
2461 continue;
2464 if (*src == '\'') {
2465 /* Go into single quote state. */
2466 in_s_quote = true;
2467 *dest++ = *src++;
2468 continue;
2471 if (*src == '\"') {
2472 /* Go into double quote state. */
2473 in_d_quote = true;
2474 *dest++ = *src++;
2475 continue;
2478 /* Check if we need to escape the character. */
2480 if (!strchr(INCLUDE_LIST, (int)*src)) {
2481 *dest++ = '\\';
2483 *dest++ = *src++;
2485 *dest++ = '\0';
2486 return ret;
2489 /***************************************************
2490 str_list_make, v3 version. The v4 version does not
2491 look at quoted strings with embedded blanks, so
2492 do NOT merge this function please!
2493 ***************************************************/
2495 #define S_LIST_ABS 16 /* List Allocation Block Size */
2497 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
2498 const char *sep)
2500 char **list;
2501 const char *str;
2502 char *s, *tok;
2503 int num, lsize;
2505 if (!string || !*string)
2506 return NULL;
2508 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
2509 if (list == NULL) {
2510 return NULL;
2512 lsize = S_LIST_ABS;
2514 s = talloc_strdup(list, string);
2515 if (s == NULL) {
2516 DEBUG(0,("str_list_make: Unable to allocate memory"));
2517 TALLOC_FREE(list);
2518 return NULL;
2520 if (!sep) sep = LIST_SEP;
2522 num = 0;
2523 str = s;
2525 while (next_token_talloc(list, &str, &tok, sep)) {
2527 if (num == lsize) {
2528 char **tmp;
2530 lsize += S_LIST_ABS;
2532 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
2533 lsize + 1);
2534 if (tmp == NULL) {
2535 DEBUG(0,("str_list_make: "
2536 "Unable to allocate memory"));
2537 TALLOC_FREE(list);
2538 return NULL;
2541 list = tmp;
2543 memset (&list[num], 0,
2544 ((sizeof(char**)) * (S_LIST_ABS +1)));
2547 list[num] = tok;
2548 num += 1;
2551 list[num] = NULL;
2553 TALLOC_FREE(s);
2554 return list;
2557 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
2559 fstring tmp;
2561 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
2562 return talloc_strdup(mem_ctx, tmp);