lib/replace: replace all *printf function if we replace snprintf (bug #9390)
[Samba.git] / source3 / lib / util_str.c
blobc98bebe21c129144bad7825ed7ecfcc60a189780
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 if (src == dest) {
518 return dest;
521 #ifdef DEVELOPER
522 clobber_region(fn,line,dest, maxlength+1);
523 #endif
525 if (!src) {
526 *dest = 0;
527 return dest;
530 len = strnlen(src, maxlength+1);
532 if (len > maxlength) {
533 DEBUG(0,("ERROR: string overflow by "
534 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
535 (unsigned long)(len-maxlength), (unsigned long)len,
536 (unsigned long)maxlength, src));
537 len = maxlength;
540 memmove(dest, src, len);
541 dest[len] = 0;
542 return dest;
546 Safe string cat into a string. maxlength does not
547 include the terminating zero.
549 char *safe_strcat_fn(const char *fn,
550 int line,
551 char *dest,
552 const char *src,
553 size_t maxlength)
555 size_t src_len, dest_len;
557 if (!dest) {
558 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
559 "called from [%s][%d]\n", fn, line));
560 return NULL;
563 if (!src)
564 return dest;
566 src_len = strnlen(src, maxlength + 1);
567 dest_len = strnlen(dest, maxlength + 1);
569 #ifdef DEVELOPER
570 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
571 #endif
573 if (src_len + dest_len > maxlength) {
574 DEBUG(0,("ERROR: string overflow by %d "
575 "in safe_strcat [%.50s]\n",
576 (int)(src_len + dest_len - maxlength), src));
577 if (maxlength > dest_len) {
578 memcpy(&dest[dest_len], src, maxlength - dest_len);
580 dest[maxlength] = 0;
581 return NULL;
584 memcpy(&dest[dest_len], src, src_len);
585 dest[dest_len + src_len] = 0;
586 return dest;
590 Paranoid strcpy into a buffer of given length (includes terminating
591 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
592 and replaces with '_'. Deliberately does *NOT* check for multibyte
593 characters. Treats src as an array of bytes, not as a multibyte
594 string. Any byte >0x7f is automatically converted to '_'.
595 other_safe_chars must also contain an ascii string (bytes<0x7f).
598 char *alpha_strcpy_fn(const char *fn,
599 int line,
600 char *dest,
601 const char *src,
602 const char *other_safe_chars,
603 size_t maxlength)
605 size_t len, i;
607 #ifdef DEVELOPER
608 clobber_region(fn, line, dest, maxlength);
609 #endif
611 if (!dest) {
612 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
613 "called from [%s][%d]\n", fn, line));
614 return NULL;
617 if (!src) {
618 *dest = 0;
619 return dest;
622 len = strlen(src);
623 if (len >= maxlength)
624 len = maxlength - 1;
626 if (!other_safe_chars)
627 other_safe_chars = "";
629 for(i = 0; i < len; i++) {
630 int val = (src[i] & 0xff);
631 if (val > 0x7f) {
632 dest[i] = '_';
633 continue;
635 if (isupper(val) || islower(val) ||
636 isdigit(val) || strchr(other_safe_chars, val))
637 dest[i] = src[i];
638 else
639 dest[i] = '_';
642 dest[i] = '\0';
644 return dest;
648 Like strncpy but always null terminates. Make sure there is room!
649 The variable n should always be one less than the available size.
651 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
653 char *d = dest;
655 #ifdef DEVELOPER
656 clobber_region(fn, line, dest, n+1);
657 #endif
659 if (!dest) {
660 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
661 "called from [%s][%d]\n", fn, line));
662 return(NULL);
665 if (!src) {
666 *dest = 0;
667 return(dest);
670 while (n-- && (*d = *src)) {
671 d++;
672 src++;
675 *d = 0;
676 return(dest);
679 #if 0
681 Like strncpy but copies up to the character marker. always null terminates.
682 returns a pointer to the character marker in the source string (src).
685 static char *strncpyn(char *dest, const char *src, size_t n, char c)
687 char *p;
688 size_t str_len;
690 #ifdef DEVELOPER
691 clobber_region(dest, n+1);
692 #endif
693 p = strchr_m(src, c);
694 if (p == NULL) {
695 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
696 return NULL;
699 str_len = PTR_DIFF(p, src);
700 strncpy(dest, src, MIN(n, str_len));
701 dest[str_len] = '\0';
703 return p;
705 #endif
708 Check if a string is part of a list.
711 bool in_list(const char *s, const char *list, bool casesensitive)
713 char *tok = NULL;
714 bool ret = false;
715 TALLOC_CTX *frame;
717 if (!list) {
718 return false;
721 frame = talloc_stackframe();
722 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
723 if (casesensitive) {
724 if (strcmp(tok,s) == 0) {
725 ret = true;
726 break;
728 } else {
729 if (StrCaseCmp(tok,s) == 0) {
730 ret = true;
731 break;
735 TALLOC_FREE(frame);
736 return ret;
739 /* this is used to prevent lots of mallocs of size 1 */
740 static const char null_string[] = "";
743 Set a string value, allocing the space for the string
746 static bool string_init(char **dest,const char *src)
748 size_t l;
750 if (!src)
751 src = "";
753 l = strlen(src);
755 if (l == 0) {
756 *dest = CONST_DISCARD(char*, null_string);
757 } else {
758 (*dest) = SMB_STRDUP(src);
759 if ((*dest) == NULL) {
760 DEBUG(0,("Out of memory in string_init\n"));
761 return false;
764 return(true);
768 Free a string value.
771 void string_free(char **s)
773 if (!s || !(*s))
774 return;
775 if (*s == null_string)
776 *s = NULL;
777 SAFE_FREE(*s);
781 Set a string value, deallocating any existing space, and allocing the space
782 for the string
785 bool string_set(char **dest,const char *src)
787 string_free(dest);
788 return(string_init(dest,src));
792 Substitute a string for a pattern in another string. Make sure there is
793 enough room!
795 This routine looks for pattern in s and replaces it with
796 insert. It may do multiple replacements or just one.
798 Any of " ; ' $ or ` in the insert string are replaced with _
799 if len==0 then the string cannot be extended. This is different from the old
800 use of len==0 which was for no length checks to be done.
803 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
804 bool remove_unsafe_characters, bool replace_once,
805 bool allow_trailing_dollar)
807 char *p;
808 ssize_t ls,lp,li, i;
810 if (!insert || !pattern || !*pattern || !s)
811 return;
813 ls = (ssize_t)strlen(s);
814 lp = (ssize_t)strlen(pattern);
815 li = (ssize_t)strlen(insert);
817 if (len == 0)
818 len = ls + 1; /* len is number of *bytes* */
820 while (lp <= ls && (p = strstr_m(s,pattern))) {
821 if (ls + (li-lp) >= len) {
822 DEBUG(0,("ERROR: string overflow by "
823 "%d in string_sub(%.50s, %d)\n",
824 (int)(ls + (li-lp) - len),
825 pattern, (int)len));
826 break;
828 if (li != lp) {
829 memmove(p+li,p+lp,strlen(p+lp)+1);
831 for (i=0;i<li;i++) {
832 switch (insert[i]) {
833 case '`':
834 case '"':
835 case '\'':
836 case ';':
837 case '$':
838 /* allow a trailing $
839 * (as in machine accounts) */
840 if (allow_trailing_dollar && (i == li - 1 )) {
841 p[i] = insert[i];
842 break;
844 case '%':
845 case '\r':
846 case '\n':
847 if ( remove_unsafe_characters ) {
848 p[i] = '_';
849 /* yes this break should be here
850 * since we want to fall throw if
851 * not replacing unsafe chars */
852 break;
854 default:
855 p[i] = insert[i];
858 s = p + li;
859 ls += (li-lp);
861 if (replace_once)
862 break;
866 void string_sub_once(char *s, const char *pattern,
867 const char *insert, size_t len)
869 string_sub2( s, pattern, insert, len, true, true, false );
872 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
874 string_sub2( s, pattern, insert, len, true, false, false );
877 void fstring_sub(char *s,const char *pattern,const char *insert)
879 string_sub(s, pattern, insert, sizeof(fstring));
883 Similar to string_sub2, but it will accept only allocated strings
884 and may realloc them so pay attention at what you pass on no
885 pointers inside strings, no const may be passed
886 as string.
889 char *realloc_string_sub2(char *string,
890 const char *pattern,
891 const char *insert,
892 bool remove_unsafe_characters,
893 bool allow_trailing_dollar)
895 char *p, *in;
896 char *s;
897 ssize_t ls,lp,li,ld, i;
899 if (!insert || !pattern || !*pattern || !string || !*string)
900 return NULL;
902 s = string;
904 in = SMB_STRDUP(insert);
905 if (!in) {
906 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
907 return NULL;
909 ls = (ssize_t)strlen(s);
910 lp = (ssize_t)strlen(pattern);
911 li = (ssize_t)strlen(insert);
912 ld = li - lp;
913 for (i=0;i<li;i++) {
914 switch (in[i]) {
915 case '`':
916 case '"':
917 case '\'':
918 case ';':
919 case '$':
920 /* allow a trailing $
921 * (as in machine accounts) */
922 if (allow_trailing_dollar && (i == li - 1 )) {
923 break;
925 case '%':
926 case '\r':
927 case '\n':
928 if ( remove_unsafe_characters ) {
929 in[i] = '_';
930 break;
932 default:
933 /* ok */
934 break;
938 while ((p = strstr_m(s,pattern))) {
939 if (ld > 0) {
940 int offset = PTR_DIFF(s,string);
941 string = (char *)SMB_REALLOC(string, ls + ld + 1);
942 if (!string) {
943 DEBUG(0, ("realloc_string_sub: "
944 "out of memory!\n"));
945 SAFE_FREE(in);
946 return NULL;
948 p = string + offset + (p - s);
950 if (li != lp) {
951 memmove(p+li,p+lp,strlen(p+lp)+1);
953 memcpy(p, in, li);
954 s = p + li;
955 ls += ld;
957 SAFE_FREE(in);
958 return string;
961 char *realloc_string_sub(char *string,
962 const char *pattern,
963 const char *insert)
965 return realloc_string_sub2(string, pattern, insert, true, false);
969 * Internal guts of talloc_string_sub and talloc_all_string_sub.
970 * talloc version of string_sub2.
973 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
974 const char *pattern,
975 const char *insert,
976 bool remove_unsafe_characters,
977 bool replace_once,
978 bool allow_trailing_dollar)
980 char *p, *in;
981 char *s;
982 char *string;
983 ssize_t ls,lp,li,ld, i;
985 if (!insert || !pattern || !*pattern || !src) {
986 return NULL;
989 string = talloc_strdup(mem_ctx, src);
990 if (string == NULL) {
991 DEBUG(0, ("talloc_string_sub2: "
992 "talloc_strdup failed\n"));
993 return NULL;
996 s = string;
998 in = SMB_STRDUP(insert);
999 if (!in) {
1000 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
1001 return NULL;
1003 ls = (ssize_t)strlen(s);
1004 lp = (ssize_t)strlen(pattern);
1005 li = (ssize_t)strlen(insert);
1006 ld = li - lp;
1008 for (i=0;i<li;i++) {
1009 switch (in[i]) {
1010 case '`':
1011 case '"':
1012 case '\'':
1013 case ';':
1014 case '$':
1015 /* allow a trailing $
1016 * (as in machine accounts) */
1017 if (allow_trailing_dollar && (i == li - 1 )) {
1018 break;
1020 case '%':
1021 case '\r':
1022 case '\n':
1023 if (remove_unsafe_characters) {
1024 in[i] = '_';
1025 break;
1027 default:
1028 /* ok */
1029 break;
1033 while ((p = strstr_m(s,pattern))) {
1034 if (ld > 0) {
1035 int offset = PTR_DIFF(s,string);
1036 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1037 ls + ld + 1);
1038 if (!string) {
1039 DEBUG(0, ("talloc_string_sub: out of "
1040 "memory!\n"));
1041 SAFE_FREE(in);
1042 return NULL;
1044 p = string + offset + (p - s);
1046 if (li != lp) {
1047 memmove(p+li,p+lp,strlen(p+lp)+1);
1049 memcpy(p, in, li);
1050 s = p + li;
1051 ls += ld;
1053 if (replace_once) {
1054 break;
1057 SAFE_FREE(in);
1058 return string;
1061 /* Same as string_sub, but returns a talloc'ed string */
1063 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1064 const char *src,
1065 const char *pattern,
1066 const char *insert)
1068 return talloc_string_sub2(mem_ctx, src, pattern, insert,
1069 true, false, false);
1073 Similar to string_sub() but allows for any character to be substituted.
1074 Use with caution!
1075 if len==0 then the string cannot be extended. This is different from the old
1076 use of len==0 which was for no length checks to be done.
1079 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1081 char *p;
1082 ssize_t ls,lp,li;
1084 if (!insert || !pattern || !s)
1085 return;
1087 ls = (ssize_t)strlen(s);
1088 lp = (ssize_t)strlen(pattern);
1089 li = (ssize_t)strlen(insert);
1091 if (!*pattern)
1092 return;
1094 if (len == 0)
1095 len = ls + 1; /* len is number of *bytes* */
1097 while (lp <= ls && (p = strstr_m(s,pattern))) {
1098 if (ls + (li-lp) >= len) {
1099 DEBUG(0,("ERROR: string overflow by "
1100 "%d in all_string_sub(%.50s, %d)\n",
1101 (int)(ls + (li-lp) - len),
1102 pattern, (int)len));
1103 break;
1105 if (li != lp) {
1106 memmove(p+li,p+lp,strlen(p+lp)+1);
1108 memcpy(p, insert, li);
1109 s = p + li;
1110 ls += (li-lp);
1114 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1115 const char *src,
1116 const char *pattern,
1117 const char *insert)
1119 return talloc_string_sub2(ctx, src, pattern, insert,
1120 false, false, false);
1124 Write an octal as a string.
1127 char *octal_string(int i)
1129 char *result;
1130 if (i == -1) {
1131 result = talloc_strdup(talloc_tos(), "-1");
1133 else {
1134 result = talloc_asprintf(talloc_tos(), "0%o", i);
1136 SMB_ASSERT(result != NULL);
1137 return result;
1142 Truncate a string at a specified length.
1145 char *string_truncate(char *s, unsigned int length)
1147 if (s && strlen(s) > length)
1148 s[length] = 0;
1149 return s;
1153 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1154 We convert via ucs2 for now.
1157 char *strchr_m(const char *src, char c)
1159 smb_ucs2_t *ws = NULL;
1160 char *s2 = NULL;
1161 smb_ucs2_t *p;
1162 const char *s;
1163 char *ret;
1164 size_t converted_size;
1166 /* characters below 0x3F are guaranteed to not appear in
1167 non-initial position in multi-byte charsets */
1168 if ((c & 0xC0) == 0) {
1169 return strchr(src, c);
1172 /* this is quite a common operation, so we want it to be
1173 fast. We optimise for the ascii case, knowing that all our
1174 supported multi-byte character sets are ascii-compatible
1175 (ie. they match for the first 128 chars) */
1177 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1178 if (*s == c)
1179 return (char *)s;
1182 if (!*s)
1183 return NULL;
1185 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1186 /* With compose characters we must restart from the beginning. JRA. */
1187 s = src;
1188 #endif
1190 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1191 /* Wrong answer, but what can we do... */
1192 return strchr(src, c);
1194 p = strchr_w(ws, UCS2_CHAR(c));
1195 if (!p) {
1196 TALLOC_FREE(ws);
1197 return NULL;
1199 *p = 0;
1200 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1201 SAFE_FREE(ws);
1202 /* Wrong answer, but what can we do... */
1203 return strchr(src, c);
1205 ret = (char *)(s+strlen(s2));
1206 TALLOC_FREE(ws);
1207 TALLOC_FREE(s2);
1208 return ret;
1211 char *strrchr_m(const char *s, char c)
1213 /* characters below 0x3F are guaranteed to not appear in
1214 non-initial position in multi-byte charsets */
1215 if ((c & 0xC0) == 0) {
1216 return strrchr(s, c);
1219 /* this is quite a common operation, so we want it to be
1220 fast. We optimise for the ascii case, knowing that all our
1221 supported multi-byte character sets are ascii-compatible
1222 (ie. they match for the first 128 chars). Also, in Samba
1223 we only search for ascii characters in 'c' and that
1224 in all mb character sets with a compound character
1225 containing c, if 'c' is not a match at position
1226 p, then p[-1] > 0x7f. JRA. */
1229 size_t len = strlen(s);
1230 const char *cp = s;
1231 bool got_mb = false;
1233 if (len == 0)
1234 return NULL;
1235 cp += (len - 1);
1236 do {
1237 if (c == *cp) {
1238 /* Could be a match. Part of a multibyte ? */
1239 if ((cp > s) &&
1240 (((unsigned char)cp[-1]) & 0x80)) {
1241 /* Yep - go slow :-( */
1242 got_mb = true;
1243 break;
1245 /* No - we have a match ! */
1246 return (char *)cp;
1248 } while (cp-- != s);
1249 if (!got_mb)
1250 return NULL;
1253 /* String contained a non-ascii char. Slow path. */
1255 smb_ucs2_t *ws = NULL;
1256 char *s2 = NULL;
1257 smb_ucs2_t *p;
1258 char *ret;
1259 size_t converted_size;
1261 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1262 /* Wrong answer, but what can we do. */
1263 return strrchr(s, c);
1265 p = strrchr_w(ws, UCS2_CHAR(c));
1266 if (!p) {
1267 TALLOC_FREE(ws);
1268 return NULL;
1270 *p = 0;
1271 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1272 TALLOC_FREE(ws);
1273 /* Wrong answer, but what can we do. */
1274 return strrchr(s, c);
1276 ret = (char *)(s+strlen(s2));
1277 TALLOC_FREE(ws);
1278 TALLOC_FREE(s2);
1279 return ret;
1283 /***********************************************************************
1284 Return the equivalent of doing strrchr 'n' times - always going
1285 backwards.
1286 ***********************************************************************/
1288 char *strnrchr_m(const char *s, char c, unsigned int n)
1290 smb_ucs2_t *ws = NULL;
1291 char *s2 = NULL;
1292 smb_ucs2_t *p;
1293 char *ret;
1294 size_t converted_size;
1296 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1297 /* Too hard to try and get right. */
1298 return NULL;
1300 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1301 if (!p) {
1302 TALLOC_FREE(ws);
1303 return NULL;
1305 *p = 0;
1306 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1307 TALLOC_FREE(ws);
1308 /* Too hard to try and get right. */
1309 return NULL;
1311 ret = (char *)(s+strlen(s2));
1312 TALLOC_FREE(ws);
1313 TALLOC_FREE(s2);
1314 return ret;
1317 /***********************************************************************
1318 strstr_m - We convert via ucs2 for now.
1319 ***********************************************************************/
1321 char *strstr_m(const char *src, const char *findstr)
1323 smb_ucs2_t *p;
1324 smb_ucs2_t *src_w, *find_w;
1325 const char *s;
1326 char *s2;
1327 char *retp;
1329 size_t converted_size, findstr_len = 0;
1331 /* for correctness */
1332 if (!findstr[0]) {
1333 return (char*)src;
1336 /* Samba does single character findstr calls a *lot*. */
1337 if (findstr[1] == '\0')
1338 return strchr_m(src, *findstr);
1340 /* We optimise for the ascii case, knowing that all our
1341 supported multi-byte character sets are ascii-compatible
1342 (ie. they match for the first 128 chars) */
1344 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1345 if (*s == *findstr) {
1346 if (!findstr_len)
1347 findstr_len = strlen(findstr);
1349 if (strncmp(s, findstr, findstr_len) == 0) {
1350 return (char *)s;
1355 if (!*s)
1356 return NULL;
1358 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1359 /* 'make check' fails unless we do this */
1361 /* With compose characters we must restart from the beginning. JRA. */
1362 s = src;
1363 #endif
1365 if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
1366 DEBUG(0,("strstr_m: src malloc fail\n"));
1367 return NULL;
1370 if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
1371 TALLOC_FREE(src_w);
1372 DEBUG(0,("strstr_m: find malloc fail\n"));
1373 return NULL;
1376 p = strstr_w(src_w, find_w);
1378 if (!p) {
1379 TALLOC_FREE(src_w);
1380 TALLOC_FREE(find_w);
1381 return NULL;
1384 *p = 0;
1385 if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
1386 TALLOC_FREE(src_w);
1387 TALLOC_FREE(find_w);
1388 DEBUG(0,("strstr_m: dest malloc fail\n"));
1389 return NULL;
1391 retp = (char *)(s+strlen(s2));
1392 TALLOC_FREE(src_w);
1393 TALLOC_FREE(find_w);
1394 TALLOC_FREE(s2);
1395 return retp;
1399 Convert a string to lower case.
1402 void strlower_m(char *s)
1404 size_t len;
1405 int errno_save;
1407 /* this is quite a common operation, so we want it to be
1408 fast. We optimise for the ascii case, knowing that all our
1409 supported multi-byte character sets are ascii-compatible
1410 (ie. they match for the first 128 chars) */
1412 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1413 *s = tolower_ascii((unsigned char)*s);
1414 s++;
1417 if (!*s)
1418 return;
1420 /* I assume that lowercased string takes the same number of bytes
1421 * as source string even in UTF-8 encoding. (VIV) */
1422 len = strlen(s) + 1;
1423 errno_save = errno;
1424 errno = 0;
1425 unix_strlower(s,len,s,len);
1426 /* Catch mb conversion errors that may not terminate. */
1427 if (errno)
1428 s[len-1] = '\0';
1429 errno = errno_save;
1433 Convert a string to upper case.
1436 void strupper_m(char *s)
1438 size_t len;
1439 int errno_save;
1441 /* this is quite a common operation, so we want it to be
1442 fast. We optimise for the ascii case, knowing that all our
1443 supported multi-byte character sets are ascii-compatible
1444 (ie. they match for the first 128 chars) */
1446 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1447 *s = toupper_ascii_fast((unsigned char)*s);
1448 s++;
1451 if (!*s)
1452 return;
1454 /* I assume that lowercased string takes the same number of bytes
1455 * as source string even in multibyte encoding. (VIV) */
1456 len = strlen(s) + 1;
1457 errno_save = errno;
1458 errno = 0;
1459 unix_strupper(s,len,s,len);
1460 /* Catch mb conversion errors that may not terminate. */
1461 if (errno)
1462 s[len-1] = '\0';
1463 errno = errno_save;
1467 * Calculate the number of units (8 or 16-bit, depending on the
1468 * destination charset), that would be needed to convert the input
1469 * string which is expected to be in in CH_UNIX encoding to the
1470 * destination charset (which should be a unicode charset).
1472 size_t strlen_m_ext(const char *s, const charset_t dst_charset)
1474 size_t count = 0;
1476 if (!s) {
1477 return 0;
1480 while (*s && !(((uint8_t)*s) & 0x80)) {
1481 s++;
1482 count++;
1485 if (!*s) {
1486 return count;
1489 while (*s) {
1490 size_t c_size;
1491 codepoint_t c = next_codepoint(s, &c_size);
1492 s += c_size;
1494 switch(dst_charset) {
1495 case CH_UTF16LE:
1496 case CH_UTF16BE:
1497 case CH_UTF16MUNGED:
1498 if (c < 0x10000) {
1499 /* Unicode char fits into 16 bits. */
1500 count += 1;
1501 } else {
1502 /* Double-width unicode char - 32 bits. */
1503 count += 2;
1505 break;
1506 case CH_UTF8:
1508 * this only checks ranges, and does not
1509 * check for invalid codepoints
1511 if (c < 0x80) {
1512 count += 1;
1513 } else if (c < 0x800) {
1514 count += 2;
1515 } else if (c < 0x1000) {
1516 count += 3;
1517 } else {
1518 count += 4;
1520 break;
1521 default:
1523 * non-unicode encoding:
1524 * assume that each codepoint fits into
1525 * one unit in the destination encoding.
1527 count += 1;
1531 return count;
1534 size_t strlen_m_ext_term(const char *s, const charset_t dst_charset)
1536 if (!s) {
1537 return 0;
1539 return strlen_m_ext(s, dst_charset) + 1;
1543 Count the number of UCS2 characters in a string. Normally this will
1544 be the same as the number of bytes in a string for single byte strings,
1545 but will be different for multibyte.
1548 size_t strlen_m(const char *s)
1550 return strlen_m_ext(s, CH_UTF16LE);
1554 Count the number of UCS2 characters in a string including the null
1555 terminator.
1558 size_t strlen_m_term(const char *s)
1560 if (!s) {
1561 return 0;
1563 return strlen_m(s) + 1;
1567 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1568 * if a string is there, include the terminator.
1571 size_t strlen_m_term_null(const char *s)
1573 size_t len;
1574 if (!s) {
1575 return 0;
1577 len = strlen_m(s);
1578 if (len == 0) {
1579 return 0;
1582 return len+1;
1585 Return a RFC2254 binary string representation of a buffer.
1586 Used in LDAP filters.
1587 Caller must free.
1590 char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len)
1592 char *s;
1593 int i, j;
1594 const char *hex = "0123456789ABCDEF";
1595 s = talloc_array(mem_ctx, char, len * 3 + 1);
1596 if (s == NULL) {
1597 return NULL;
1599 for (j=i=0;i<len;i++) {
1600 s[j] = '\\';
1601 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1602 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1603 j += 3;
1605 s[j] = 0;
1606 return s;
1609 char *binary_string(char *buf, int len)
1611 char *s;
1612 int i, j;
1613 const char *hex = "0123456789ABCDEF";
1614 s = (char *)SMB_MALLOC(len * 2 + 1);
1615 if (!s)
1616 return NULL;
1617 for (j=i=0;i<len;i++) {
1618 s[j] = hex[((unsigned char)buf[i]) >> 4];
1619 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1620 j += 2;
1622 s[j] = 0;
1623 return s;
1627 Just a typesafety wrapper for snprintf into a fstring.
1630 int fstr_sprintf(fstring s, const char *fmt, ...)
1632 va_list ap;
1633 int ret;
1635 va_start(ap, fmt);
1636 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1637 va_end(ap);
1638 return ret;
1642 List of Strings manipulation functions
1645 #define S_LIST_ABS 16 /* List Allocation Block Size */
1647 /******************************************************************************
1648 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1649 for the work
1650 *****************************************************************************/
1652 bool str_list_sub_basic( char **list, const char *smb_name,
1653 const char *domain_name )
1655 TALLOC_CTX *ctx = list;
1656 char *s, *tmpstr;
1658 while ( *list ) {
1659 s = *list;
1660 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1661 if ( !tmpstr ) {
1662 DEBUG(0,("str_list_sub_basic: "
1663 "alloc_sub_basic() return NULL!\n"));
1664 return false;
1667 TALLOC_FREE(*list);
1668 *list = tmpstr;
1670 list++;
1673 return true;
1676 /******************************************************************************
1677 substitute a specific pattern in a string list
1678 *****************************************************************************/
1680 bool str_list_substitute(char **list, const char *pattern, const char *insert)
1682 TALLOC_CTX *ctx = list;
1683 char *p, *s, *t;
1684 ssize_t ls, lp, li, ld, i, d;
1686 if (!list)
1687 return false;
1688 if (!pattern)
1689 return false;
1690 if (!insert)
1691 return false;
1693 lp = (ssize_t)strlen(pattern);
1694 li = (ssize_t)strlen(insert);
1695 ld = li -lp;
1697 while (*list) {
1698 s = *list;
1699 ls = (ssize_t)strlen(s);
1701 while ((p = strstr_m(s, pattern))) {
1702 t = *list;
1703 d = p -t;
1704 if (ld) {
1705 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
1706 if (!t) {
1707 DEBUG(0,("str_list_substitute: "
1708 "Unable to allocate memory"));
1709 return false;
1711 memcpy(t, *list, d);
1712 memcpy(t +d +li, p +lp, ls -d -lp +1);
1713 TALLOC_FREE(*list);
1714 *list = t;
1715 ls += ld;
1716 s = t +d +li;
1719 for (i = 0; i < li; i++) {
1720 switch (insert[i]) {
1721 case '`':
1722 case '"':
1723 case '\'':
1724 case ';':
1725 case '$':
1726 case '%':
1727 case '\r':
1728 case '\n':
1729 t[d +i] = '_';
1730 break;
1731 default:
1732 t[d +i] = insert[i];
1737 list++;
1740 return true;
1744 #define IPSTR_LIST_SEP ","
1745 #define IPSTR_LIST_CHAR ','
1748 * Add ip string representation to ipstr list. Used also
1749 * as part of @function ipstr_list_make
1751 * @param ipstr_list pointer to string containing ip list;
1752 * MUST BE already allocated and IS reallocated if necessary
1753 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1754 * as a result of reallocation)
1755 * @param ip IP address which is to be added to list
1756 * @return pointer to string appended with new ip and possibly
1757 * reallocated to new length
1760 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1762 char *new_ipstr = NULL;
1763 char addr_buf[INET6_ADDRSTRLEN];
1764 int ret;
1766 /* arguments checking */
1767 if (!ipstr_list || !service) {
1768 return NULL;
1771 print_sockaddr(addr_buf,
1772 sizeof(addr_buf),
1773 &service->ss);
1775 /* attempt to convert ip to a string and append colon separator to it */
1776 if (*ipstr_list) {
1777 if (service->ss.ss_family == AF_INET) {
1778 /* IPv4 */
1779 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1780 IPSTR_LIST_SEP, addr_buf,
1781 service->port);
1782 } else {
1783 /* IPv6 */
1784 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1785 IPSTR_LIST_SEP, addr_buf,
1786 service->port);
1788 SAFE_FREE(*ipstr_list);
1789 } else {
1790 if (service->ss.ss_family == AF_INET) {
1791 /* IPv4 */
1792 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1793 service->port);
1794 } else {
1795 /* IPv6 */
1796 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1797 service->port);
1800 if (ret == -1) {
1801 return NULL;
1803 *ipstr_list = new_ipstr;
1804 return *ipstr_list;
1808 * Allocate and initialise an ipstr list using ip adresses
1809 * passed as arguments.
1811 * @param ipstr_list pointer to string meant to be allocated and set
1812 * @param ip_list array of ip addresses to place in the list
1813 * @param ip_count number of addresses stored in ip_list
1814 * @return pointer to allocated ip string
1817 char *ipstr_list_make(char **ipstr_list,
1818 const struct ip_service *ip_list,
1819 int ip_count)
1821 int i;
1823 /* arguments checking */
1824 if (!ip_list || !ipstr_list) {
1825 return 0;
1828 *ipstr_list = NULL;
1830 /* process ip addresses given as arguments */
1831 for (i = 0; i < ip_count; i++) {
1832 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1835 return (*ipstr_list);
1840 * Parse given ip string list into array of ip addresses
1841 * (as ip_service structures)
1842 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1844 * @param ipstr ip string list to be parsed
1845 * @param ip_list pointer to array of ip addresses which is
1846 * allocated by this function and must be freed by caller
1847 * @return number of successfully parsed addresses
1850 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1852 TALLOC_CTX *frame;
1853 char *token_str = NULL;
1854 size_t count;
1855 int i;
1857 if (!ipstr_list || !ip_list)
1858 return 0;
1860 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1861 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1862 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1863 (unsigned long)count));
1864 return 0;
1867 frame = talloc_stackframe();
1868 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1869 IPSTR_LIST_SEP) && i<count; i++ ) {
1870 char *s = token_str;
1871 char *p = strrchr(token_str, ':');
1873 if (p) {
1874 *p = 0;
1875 (*ip_list)[i].port = atoi(p+1);
1878 /* convert single token to ip address */
1879 if (token_str[0] == '[') {
1880 /* IPv6 address. */
1881 s++;
1882 p = strchr(token_str, ']');
1883 if (!p) {
1884 continue;
1886 *p = '\0';
1888 if (!interpret_string_addr(&(*ip_list)[i].ss,
1890 AI_NUMERICHOST)) {
1891 continue;
1894 TALLOC_FREE(frame);
1895 return count;
1899 * Safely free ip string list
1901 * @param ipstr_list ip string list to be freed
1904 void ipstr_list_free(char* ipstr_list)
1906 SAFE_FREE(ipstr_list);
1909 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1912 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1914 DATA_BLOB base64_decode_data_blob(const char *s)
1916 int bit_offset, byte_offset, idx, i, n;
1917 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1918 unsigned char *d = decoded.data;
1919 char *p;
1921 n=i=0;
1923 while (*s && (p=strchr_m(b64,*s))) {
1924 idx = (int)(p - b64);
1925 byte_offset = (i*6)/8;
1926 bit_offset = (i*6)%8;
1927 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1928 if (bit_offset < 3) {
1929 d[byte_offset] |= (idx << (2-bit_offset));
1930 n = byte_offset+1;
1931 } else {
1932 d[byte_offset] |= (idx >> (bit_offset-2));
1933 d[byte_offset+1] = 0;
1934 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1935 n = byte_offset+2;
1937 s++; i++;
1940 if ((n > 0) && (*s == '=')) {
1941 n -= 1;
1944 /* fix up length */
1945 decoded.length = n;
1946 return decoded;
1950 * Decode a base64 string in-place - wrapper for the above
1952 void base64_decode_inplace(char *s)
1954 DATA_BLOB decoded = base64_decode_data_blob(s);
1956 if ( decoded.length != 0 ) {
1957 memcpy(s, decoded.data, decoded.length);
1959 /* null terminate */
1960 s[decoded.length] = '\0';
1961 } else {
1962 *s = '\0';
1965 data_blob_free(&decoded);
1969 * Encode a base64 string into a talloc()ed string caller to free.
1971 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
1972 * with adjustments
1975 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
1977 int bits = 0;
1978 int char_count = 0;
1979 size_t out_cnt, len, output_len;
1980 char *result;
1982 if (!data.length || !data.data)
1983 return NULL;
1985 out_cnt = 0;
1986 len = data.length;
1987 output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
1988 * random but should be enough for
1989 * the = and \0 */
1990 result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
1991 SMB_ASSERT(result != NULL);
1993 while (len--) {
1994 int c = (unsigned char) *(data.data++);
1995 bits += c;
1996 char_count++;
1997 if (char_count == 3) {
1998 result[out_cnt++] = b64[bits >> 18];
1999 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2000 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2001 result[out_cnt++] = b64[bits & 0x3f];
2002 bits = 0;
2003 char_count = 0;
2004 } else {
2005 bits <<= 8;
2008 if (char_count != 0) {
2009 bits <<= 16 - (8 * char_count);
2010 result[out_cnt++] = b64[bits >> 18];
2011 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2012 if (char_count == 1) {
2013 result[out_cnt++] = '=';
2014 result[out_cnt++] = '=';
2015 } else {
2016 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2017 result[out_cnt++] = '=';
2020 result[out_cnt] = '\0'; /* terminate */
2021 return result;
2024 /* read a SMB_BIG_UINT from a string */
2025 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2028 uint64_t val = -1;
2029 const char *p = nptr;
2031 if (!p) {
2032 if (entptr) {
2033 *entptr = p;
2035 return val;
2038 while (*p && isspace(*p))
2039 p++;
2041 sscanf(p,"%"PRIu64,&val);
2042 if (entptr) {
2043 while (*p && isdigit(*p))
2044 p++;
2045 *entptr = p;
2048 return val;
2051 /* Convert a size specification to a count of bytes. We accept the following
2052 * suffixes:
2053 * bytes if there is no suffix
2054 * kK kibibytes
2055 * mM mebibytes
2056 * gG gibibytes
2057 * tT tibibytes
2058 * pP whatever the ISO name for petabytes is
2060 * Returns 0 if the string can't be converted.
2062 SMB_OFF_T conv_str_size(const char * str)
2064 SMB_OFF_T lval;
2065 char * end;
2067 if (str == NULL || *str == '\0') {
2068 return 0;
2071 #ifdef HAVE_STRTOULL
2072 if (sizeof(SMB_OFF_T) == 8) {
2073 lval = strtoull(str, &end, 10 /* base */);
2074 } else {
2075 lval = strtoul(str, &end, 10 /* base */);
2077 #else
2078 lval = strtoul(str, &end, 10 /* base */);
2079 #endif
2081 if (end == NULL || end == str) {
2082 return 0;
2085 if (*end) {
2086 SMB_OFF_T lval_orig = lval;
2088 if (strwicmp(end, "K") == 0) {
2089 lval *= (SMB_OFF_T)1024;
2090 } else if (strwicmp(end, "M") == 0) {
2091 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2092 } else if (strwicmp(end, "G") == 0) {
2093 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2094 (SMB_OFF_T)1024);
2095 } else if (strwicmp(end, "T") == 0) {
2096 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2097 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2098 } else if (strwicmp(end, "P") == 0) {
2099 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2100 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2101 (SMB_OFF_T)1024);
2102 } else {
2103 return 0;
2106 /* Primitive attempt to detect wrapping on platforms with
2107 * 4-byte SMB_OFF_T. It's better to let the caller handle
2108 * a failure than some random number.
2110 if (lval_orig <= lval) {
2111 return 0;
2115 return lval;
2118 void string_append(char **left, const char *right)
2120 int new_len = strlen(right) + 1;
2122 if (*left == NULL) {
2123 *left = (char *)SMB_MALLOC(new_len);
2124 *left[0] = '\0';
2125 } else {
2126 new_len += strlen(*left);
2127 *left = (char *)SMB_REALLOC(*left, new_len);
2130 if (*left == NULL) {
2131 return;
2134 safe_strcat(*left, right, new_len-1);
2137 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2138 const char *str, const char ***strings,
2139 int *num)
2141 char *dup_str = talloc_strdup(mem_ctx, str);
2143 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2144 const char *, (*num)+1);
2146 if ((*strings == NULL) || (dup_str == NULL)) {
2147 *num = 0;
2148 return false;
2151 (*strings)[*num] = dup_str;
2152 *num += 1;
2153 return true;
2156 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2157 * error checking in between. The indiation that something weird happened is
2158 * string==NULL */
2160 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2161 size_t *bufsize, const char *fmt, ...)
2163 va_list ap;
2164 char *newstr;
2165 int ret;
2166 bool increased;
2168 /* len<0 is an internal marker that something failed */
2169 if (*len < 0)
2170 goto error;
2172 if (*string == NULL) {
2173 if (*bufsize == 0)
2174 *bufsize = 128;
2176 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2177 if (*string == NULL)
2178 goto error;
2181 va_start(ap, fmt);
2182 ret = vasprintf(&newstr, fmt, ap);
2183 va_end(ap);
2185 if (ret < 0)
2186 goto error;
2188 increased = false;
2190 while ((*len)+ret >= *bufsize) {
2191 increased = true;
2192 *bufsize *= 2;
2193 if (*bufsize >= (1024*1024*256))
2194 goto error;
2197 if (increased) {
2198 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2199 *bufsize);
2200 if (*string == NULL) {
2201 goto error;
2205 StrnCpy((*string)+(*len), newstr, ret);
2206 (*len) += ret;
2207 free(newstr);
2208 return;
2210 error:
2211 *len = -1;
2212 *string = NULL;
2216 * asprintf into a string and strupper_m it after that.
2219 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2221 va_list ap;
2222 char *result;
2223 int ret;
2225 va_start(ap, fmt);
2226 ret = vasprintf(&result, fmt, ap);
2227 va_end(ap);
2229 if (ret == -1)
2230 return -1;
2232 strupper_m(result);
2233 *strp = result;
2234 return ret;
2237 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2239 va_list ap;
2240 char *ret;
2242 va_start(ap, fmt);
2243 ret = talloc_vasprintf(t, fmt, ap);
2244 va_end(ap);
2246 if (ret == NULL) {
2247 return NULL;
2249 strupper_m(ret);
2250 return ret;
2253 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
2255 va_list ap;
2256 char *ret;
2258 va_start(ap, fmt);
2259 ret = talloc_vasprintf(t, fmt, ap);
2260 va_end(ap);
2262 if (ret == NULL) {
2263 return NULL;
2265 strlower_m(ret);
2266 return ret;
2271 Returns the substring from src between the first occurrence of
2272 the char "front" and the first occurence of the char "back".
2273 Mallocs the return string which must be freed. Not for use
2274 with wide character strings.
2276 char *sstring_sub(const char *src, char front, char back)
2278 char *temp1, *temp2, *temp3;
2279 ptrdiff_t len;
2281 temp1 = strchr(src, front);
2282 if (temp1 == NULL) return NULL;
2283 temp2 = strchr(src, back);
2284 if (temp2 == NULL) return NULL;
2285 len = temp2 - temp1;
2286 if (len <= 0) return NULL;
2287 temp3 = (char*)SMB_MALLOC(len);
2288 if (temp3 == NULL) {
2289 DEBUG(1,("Malloc failure in sstring_sub\n"));
2290 return NULL;
2292 memcpy(temp3, temp1+1, len-1);
2293 temp3[len-1] = '\0';
2294 return temp3;
2297 /********************************************************************
2298 Check a string for any occurrences of a specified list of invalid
2299 characters.
2300 ********************************************************************/
2302 bool validate_net_name( const char *name,
2303 const char *invalid_chars,
2304 int max_len)
2306 int i;
2308 if (!name) {
2309 return false;
2312 for ( i=0; i<max_len && name[i]; i++ ) {
2313 /* fail if strchr_m() finds one of the invalid characters */
2314 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2315 return false;
2319 return true;
2323 /*******************************************************************
2324 Add a shell escape character '\' to any character not in a known list
2325 of characters. UNIX charset format.
2326 *******************************************************************/
2328 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2329 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2331 char *escape_shell_string(const char *src)
2333 size_t srclen = strlen(src);
2334 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2335 char *dest = ret;
2336 bool in_s_quote = false;
2337 bool in_d_quote = false;
2338 bool next_escaped = false;
2340 if (!ret) {
2341 return NULL;
2344 while (*src) {
2345 size_t c_size;
2346 codepoint_t c = next_codepoint(src, &c_size);
2348 if (c == INVALID_CODEPOINT) {
2349 SAFE_FREE(ret);
2350 return NULL;
2353 if (c_size > 1) {
2354 memcpy(dest, src, c_size);
2355 src += c_size;
2356 dest += c_size;
2357 next_escaped = false;
2358 continue;
2362 * Deal with backslash escaped state.
2363 * This only lasts for one character.
2366 if (next_escaped) {
2367 *dest++ = *src++;
2368 next_escaped = false;
2369 continue;
2373 * Deal with single quote state. The
2374 * only thing we care about is exiting
2375 * this state.
2378 if (in_s_quote) {
2379 if (*src == '\'') {
2380 in_s_quote = false;
2382 *dest++ = *src++;
2383 continue;
2387 * Deal with double quote state. The most
2388 * complex state. We must cope with \, meaning
2389 * possibly escape next char (depending what it
2390 * is), ", meaning exit this state, and possibly
2391 * add an \ escape to any unprotected character
2392 * (listed in INSIDE_DQUOTE_LIST).
2395 if (in_d_quote) {
2396 if (*src == '\\') {
2398 * Next character might be escaped.
2399 * We have to peek. Inside double
2400 * quotes only INSIDE_DQUOTE_LIST
2401 * characters are escaped by a \.
2404 char nextchar;
2406 c = next_codepoint(&src[1], &c_size);
2407 if (c == INVALID_CODEPOINT) {
2408 SAFE_FREE(ret);
2409 return NULL;
2411 if (c_size > 1) {
2413 * Don't escape the next char.
2414 * Just copy the \.
2416 *dest++ = *src++;
2417 continue;
2420 nextchar = src[1];
2422 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2423 (int)nextchar)) {
2424 next_escaped = true;
2426 *dest++ = *src++;
2427 continue;
2430 if (*src == '\"') {
2431 /* Exit double quote state. */
2432 in_d_quote = false;
2433 *dest++ = *src++;
2434 continue;
2438 * We know the character isn't \ or ",
2439 * so escape it if it's any of the other
2440 * possible unprotected characters.
2443 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2444 *dest++ = '\\';
2446 *dest++ = *src++;
2447 continue;
2451 * From here to the end of the loop we're
2452 * not in the single or double quote state.
2455 if (*src == '\\') {
2456 /* Next character must be escaped. */
2457 next_escaped = true;
2458 *dest++ = *src++;
2459 continue;
2462 if (*src == '\'') {
2463 /* Go into single quote state. */
2464 in_s_quote = true;
2465 *dest++ = *src++;
2466 continue;
2469 if (*src == '\"') {
2470 /* Go into double quote state. */
2471 in_d_quote = true;
2472 *dest++ = *src++;
2473 continue;
2476 /* Check if we need to escape the character. */
2478 if (!strchr(INCLUDE_LIST, (int)*src)) {
2479 *dest++ = '\\';
2481 *dest++ = *src++;
2483 *dest++ = '\0';
2484 return ret;
2487 /***************************************************
2488 str_list_make, v3 version. The v4 version does not
2489 look at quoted strings with embedded blanks, so
2490 do NOT merge this function please!
2491 ***************************************************/
2493 #define S_LIST_ABS 16 /* List Allocation Block Size */
2495 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
2496 const char *sep)
2498 char **list;
2499 const char *str;
2500 char *s, *tok;
2501 int num, lsize;
2503 if (!string || !*string)
2504 return NULL;
2506 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
2507 if (list == NULL) {
2508 return NULL;
2510 lsize = S_LIST_ABS;
2512 s = talloc_strdup(list, string);
2513 if (s == NULL) {
2514 DEBUG(0,("str_list_make: Unable to allocate memory"));
2515 TALLOC_FREE(list);
2516 return NULL;
2518 if (!sep) sep = LIST_SEP;
2520 num = 0;
2521 str = s;
2523 while (next_token_talloc(list, &str, &tok, sep)) {
2525 if (num == lsize) {
2526 char **tmp;
2528 lsize += S_LIST_ABS;
2530 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
2531 lsize + 1);
2532 if (tmp == NULL) {
2533 DEBUG(0,("str_list_make: "
2534 "Unable to allocate memory"));
2535 TALLOC_FREE(list);
2536 return NULL;
2539 list = tmp;
2541 memset (&list[num], 0,
2542 ((sizeof(char**)) * (S_LIST_ABS +1)));
2545 list[num] = tok;
2546 num += 1;
2549 list[num] = NULL;
2551 TALLOC_FREE(s);
2552 return list;