s3-lib: Rely on uint64_t in conv_str_size()
[Samba.git] / source3 / lib / util_str.c
blobb15dd7907ba38221bb08b97d79362279d43c7bd5
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 Convert a string to "normal" form.
215 void strnorm(char *s, int case_default)
217 if (case_default == CASE_UPPER)
218 strupper_m(s);
219 else
220 strlower_m(s);
224 * Skip past some strings in a buffer - old version - no checks.
225 * **/
227 char *push_skip_string(char *buf)
229 buf += strlen(buf) + 1;
230 return(buf);
234 Skip past a string in a buffer. Buffer may not be
235 null terminated. end_ptr points to the first byte after
236 then end of the buffer.
239 char *skip_string(const char *base, size_t len, char *buf)
241 const char *end_ptr = base + len;
243 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
244 return NULL;
247 /* Skip the string */
248 while (*buf) {
249 buf++;
250 if (buf >= end_ptr) {
251 return NULL;
254 /* Skip the '\0' */
255 buf++;
256 return buf;
260 Count the number of characters in a string. Normally this will
261 be the same as the number of bytes in a string for single byte strings,
262 but will be different for multibyte.
265 size_t str_charnum(const char *s)
267 size_t ret, converted_size;
268 smb_ucs2_t *tmpbuf2 = NULL;
269 if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
270 return 0;
272 ret = strlen_w(tmpbuf2);
273 TALLOC_FREE(tmpbuf2);
274 return ret;
277 bool trim_char(char *s,char cfront,char cback)
279 bool ret = false;
280 char *ep;
281 char *fp = s;
283 /* Ignore null or empty strings. */
284 if (!s || (s[0] == '\0'))
285 return false;
287 if (cfront) {
288 while (*fp && *fp == cfront)
289 fp++;
290 if (!*fp) {
291 /* We ate the string. */
292 s[0] = '\0';
293 return true;
295 if (fp != s)
296 ret = true;
299 ep = fp + strlen(fp) - 1;
300 if (cback) {
301 /* Attempt ascii only. Bail for mb strings. */
302 while ((ep >= fp) && (*ep == cback)) {
303 ret = true;
304 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
305 /* Could be mb... bail back to tim_string. */
306 char fs[2], bs[2];
307 if (cfront) {
308 fs[0] = cfront;
309 fs[1] = '\0';
311 bs[0] = cback;
312 bs[1] = '\0';
313 return trim_string(s, cfront ? fs : NULL, bs);
314 } else {
315 ep--;
318 if (ep < fp) {
319 /* We ate the string. */
320 s[0] = '\0';
321 return true;
325 ep[1] = '\0';
326 memmove(s, fp, ep-fp+2);
327 return ret;
331 Safe string copy into a known length string. maxlength does not
332 include the terminating zero.
335 char *safe_strcpy_fn(char *dest,
336 const char *src,
337 size_t maxlength)
339 size_t len;
341 if (!dest) {
342 smb_panic("ERROR: NULL dest in safe_strcpy");
345 if (!src) {
346 *dest = 0;
347 return dest;
350 len = strnlen(src, maxlength+1);
352 if (len > maxlength) {
353 DEBUG(0,("ERROR: string overflow by "
354 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
355 (unsigned long)(len-maxlength), (unsigned long)len,
356 (unsigned long)maxlength, src));
357 len = maxlength;
360 memmove(dest, src, len);
361 dest[len] = 0;
362 return dest;
366 Safe string cat into a string. maxlength does not
367 include the terminating zero.
369 char *safe_strcat_fn(char *dest,
370 const char *src,
371 size_t maxlength)
373 size_t src_len, dest_len;
375 if (!dest) {
376 smb_panic("ERROR: NULL dest in safe_strcat");
379 if (!src)
380 return dest;
382 src_len = strnlen(src, maxlength + 1);
383 dest_len = strnlen(dest, maxlength + 1);
385 if (src_len + dest_len > maxlength) {
386 DEBUG(0,("ERROR: string overflow by %d "
387 "in safe_strcat [%.50s]\n",
388 (int)(src_len + dest_len - maxlength), src));
389 if (maxlength > dest_len) {
390 memcpy(&dest[dest_len], src, maxlength - dest_len);
392 dest[maxlength] = 0;
393 return NULL;
396 memcpy(&dest[dest_len], src, src_len);
397 dest[dest_len + src_len] = 0;
398 return dest;
402 Like strncpy but always null terminates. Make sure there is room!
403 The variable n should always be one less than the available size.
405 char *StrnCpy(char *dest,const char *src,size_t n)
407 char *d = dest;
409 if (!dest) {
410 smb_panic("ERROR: NULL dest in StrnCpy");
413 if (!src) {
414 *dest = 0;
415 return(dest);
418 while (n-- && (*d = *src)) {
419 d++;
420 src++;
423 *d = 0;
424 return(dest);
428 Check if a string is part of a list.
431 bool in_list(const char *s, const char *list, bool casesensitive)
433 char *tok = NULL;
434 bool ret = false;
435 TALLOC_CTX *frame;
437 if (!list) {
438 return false;
441 frame = talloc_stackframe();
442 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
443 if (casesensitive) {
444 if (strcmp(tok,s) == 0) {
445 ret = true;
446 break;
448 } else {
449 if (StrCaseCmp(tok,s) == 0) {
450 ret = true;
451 break;
455 TALLOC_FREE(frame);
456 return ret;
459 /* this is used to prevent lots of mallocs of size 1 */
460 static const char null_string[] = "";
463 Set a string value, allocing the space for the string
466 static bool string_init(char **dest,const char *src)
468 size_t l;
470 if (!src)
471 src = "";
473 l = strlen(src);
475 if (l == 0) {
476 *dest = CONST_DISCARD(char*, null_string);
477 } else {
478 (*dest) = SMB_STRDUP(src);
479 if ((*dest) == NULL) {
480 DEBUG(0,("Out of memory in string_init\n"));
481 return false;
484 return(true);
488 Free a string value.
491 void string_free(char **s)
493 if (!s || !(*s))
494 return;
495 if (*s == null_string)
496 *s = NULL;
497 SAFE_FREE(*s);
501 Set a string value, deallocating any existing space, and allocing the space
502 for the string
505 bool string_set(char **dest,const char *src)
507 string_free(dest);
508 return(string_init(dest,src));
511 void fstring_sub(char *s,const char *pattern,const char *insert)
513 string_sub(s, pattern, insert, sizeof(fstring));
517 Similar to string_sub2, but it will accept only allocated strings
518 and may realloc them so pay attention at what you pass on no
519 pointers inside strings, no const may be passed
520 as string.
523 char *realloc_string_sub2(char *string,
524 const char *pattern,
525 const char *insert,
526 bool remove_unsafe_characters,
527 bool allow_trailing_dollar)
529 char *p, *in;
530 char *s;
531 ssize_t ls,lp,li,ld, i;
533 if (!insert || !pattern || !*pattern || !string || !*string)
534 return NULL;
536 s = string;
538 in = SMB_STRDUP(insert);
539 if (!in) {
540 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
541 return NULL;
543 ls = (ssize_t)strlen(s);
544 lp = (ssize_t)strlen(pattern);
545 li = (ssize_t)strlen(insert);
546 ld = li - lp;
547 for (i=0;i<li;i++) {
548 switch (in[i]) {
549 case '$':
550 /* allow a trailing $
551 * (as in machine accounts) */
552 if (allow_trailing_dollar && (i == li - 1 )) {
553 break;
555 case '`':
556 case '"':
557 case '\'':
558 case ';':
559 case '%':
560 case '\r':
561 case '\n':
562 if ( remove_unsafe_characters ) {
563 in[i] = '_';
564 break;
566 default:
567 /* ok */
568 break;
572 while ((p = strstr_m(s,pattern))) {
573 if (ld > 0) {
574 int offset = PTR_DIFF(s,string);
575 string = (char *)SMB_REALLOC(string, ls + ld + 1);
576 if (!string) {
577 DEBUG(0, ("realloc_string_sub: "
578 "out of memory!\n"));
579 SAFE_FREE(in);
580 return NULL;
582 p = string + offset + (p - s);
584 if (li != lp) {
585 memmove(p+li,p+lp,strlen(p+lp)+1);
587 memcpy(p, in, li);
588 s = p + li;
589 ls += ld;
591 SAFE_FREE(in);
592 return string;
595 char *realloc_string_sub(char *string,
596 const char *pattern,
597 const char *insert)
599 return realloc_string_sub2(string, pattern, insert, true, false);
603 * Internal guts of talloc_string_sub and talloc_all_string_sub.
604 * talloc version of string_sub2.
607 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
608 const char *pattern,
609 const char *insert,
610 bool remove_unsafe_characters,
611 bool replace_once,
612 bool allow_trailing_dollar)
614 char *p, *in;
615 char *s;
616 char *string;
617 ssize_t ls,lp,li,ld, i;
619 if (!insert || !pattern || !*pattern || !src) {
620 return NULL;
623 string = talloc_strdup(mem_ctx, src);
624 if (string == NULL) {
625 DEBUG(0, ("talloc_string_sub2: "
626 "talloc_strdup failed\n"));
627 return NULL;
630 s = string;
632 in = SMB_STRDUP(insert);
633 if (!in) {
634 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
635 return NULL;
637 ls = (ssize_t)strlen(s);
638 lp = (ssize_t)strlen(pattern);
639 li = (ssize_t)strlen(insert);
640 ld = li - lp;
642 for (i=0;i<li;i++) {
643 switch (in[i]) {
644 case '$':
645 /* allow a trailing $
646 * (as in machine accounts) */
647 if (allow_trailing_dollar && (i == li - 1 )) {
648 break;
650 case '`':
651 case '"':
652 case '\'':
653 case ';':
654 case '%':
655 case '\r':
656 case '\n':
657 if (remove_unsafe_characters) {
658 in[i] = '_';
659 break;
661 default:
662 /* ok */
663 break;
667 while ((p = strstr_m(s,pattern))) {
668 if (ld > 0) {
669 int offset = PTR_DIFF(s,string);
670 string = (char *)TALLOC_REALLOC(mem_ctx, string,
671 ls + ld + 1);
672 if (!string) {
673 DEBUG(0, ("talloc_string_sub: out of "
674 "memory!\n"));
675 SAFE_FREE(in);
676 return NULL;
678 p = string + offset + (p - s);
680 if (li != lp) {
681 memmove(p+li,p+lp,strlen(p+lp)+1);
683 memcpy(p, in, li);
684 s = p + li;
685 ls += ld;
687 if (replace_once) {
688 break;
691 SAFE_FREE(in);
692 return string;
695 /* Same as string_sub, but returns a talloc'ed string */
697 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
698 const char *src,
699 const char *pattern,
700 const char *insert)
702 return talloc_string_sub2(mem_ctx, src, pattern, insert,
703 true, false, false);
706 char *talloc_all_string_sub(TALLOC_CTX *ctx,
707 const char *src,
708 const char *pattern,
709 const char *insert)
711 return talloc_string_sub2(ctx, src, pattern, insert,
712 false, false, false);
716 Write an octal as a string.
719 char *octal_string(int i)
721 char *result;
722 if (i == -1) {
723 result = talloc_strdup(talloc_tos(), "-1");
725 else {
726 result = talloc_asprintf(talloc_tos(), "0%o", i);
728 SMB_ASSERT(result != NULL);
729 return result;
734 Truncate a string at a specified length.
737 char *string_truncate(char *s, unsigned int length)
739 if (s && strlen(s) > length)
740 s[length] = 0;
741 return s;
745 /***********************************************************************
746 Return the equivalent of doing strrchr 'n' times - always going
747 backwards.
748 ***********************************************************************/
750 char *strnrchr_m(const char *s, char c, unsigned int n)
752 smb_ucs2_t *ws = NULL;
753 char *s2 = NULL;
754 smb_ucs2_t *p;
755 char *ret;
756 size_t converted_size;
758 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
759 /* Too hard to try and get right. */
760 return NULL;
762 p = strnrchr_w(ws, UCS2_CHAR(c), n);
763 if (!p) {
764 TALLOC_FREE(ws);
765 return NULL;
767 *p = 0;
768 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
769 TALLOC_FREE(ws);
770 /* Too hard to try and get right. */
771 return NULL;
773 ret = (char *)(s+strlen(s2));
774 TALLOC_FREE(ws);
775 TALLOC_FREE(s2);
776 return ret;
779 static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
781 size_t size;
782 smb_ucs2_t *buffer = NULL;
783 bool ret;
785 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
786 (void **)(void *)&buffer, &size))
788 smb_panic("failed to create UCS2 buffer");
790 if (!strlower_w(buffer) && (dest == src)) {
791 TALLOC_FREE(buffer);
792 return srclen;
794 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
795 TALLOC_FREE(buffer);
796 return ret;
801 Convert a string to lower case.
804 void strlower_m(char *s)
806 size_t len;
807 int errno_save;
809 /* this is quite a common operation, so we want it to be
810 fast. We optimise for the ascii case, knowing that all our
811 supported multi-byte character sets are ascii-compatible
812 (ie. they match for the first 128 chars) */
814 while (*s && !(((unsigned char)s[0]) & 0x80)) {
815 *s = tolower_ascii((unsigned char)*s);
816 s++;
819 if (!*s)
820 return;
822 /* I assume that lowercased string takes the same number of bytes
823 * as source string even in UTF-8 encoding. (VIV) */
824 len = strlen(s) + 1;
825 errno_save = errno;
826 errno = 0;
827 unix_strlower(s,len,s,len);
828 /* Catch mb conversion errors that may not terminate. */
829 if (errno)
830 s[len-1] = '\0';
831 errno = errno_save;
834 static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
836 size_t size;
837 smb_ucs2_t *buffer;
838 bool ret;
840 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
841 return (size_t)-1;
844 if (!strupper_w(buffer) && (dest == src)) {
845 TALLOC_FREE(buffer);
846 return srclen;
849 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
850 TALLOC_FREE(buffer);
851 return ret;
855 Convert a string to upper case.
858 void strupper_m(char *s)
860 size_t len;
861 int errno_save;
863 /* this is quite a common operation, so we want it to be
864 fast. We optimise for the ascii case, knowing that all our
865 supported multi-byte character sets are ascii-compatible
866 (ie. they match for the first 128 chars) */
868 while (*s && !(((unsigned char)s[0]) & 0x80)) {
869 *s = toupper_ascii_fast((unsigned char)*s);
870 s++;
873 if (!*s)
874 return;
876 /* I assume that lowercased string takes the same number of bytes
877 * as source string even in multibyte encoding. (VIV) */
878 len = strlen(s) + 1;
879 errno_save = errno;
880 errno = 0;
881 unix_strupper(s,len,s,len);
882 /* Catch mb conversion errors that may not terminate. */
883 if (errno)
884 s[len-1] = '\0';
885 errno = errno_save;
889 Just a typesafety wrapper for snprintf into a fstring.
892 int fstr_sprintf(fstring s, const char *fmt, ...)
894 va_list ap;
895 int ret;
897 va_start(ap, fmt);
898 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
899 va_end(ap);
900 return ret;
904 List of Strings manipulation functions
907 #define S_LIST_ABS 16 /* List Allocation Block Size */
909 /******************************************************************************
910 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
911 for the work
912 *****************************************************************************/
914 bool str_list_sub_basic( char **list, const char *smb_name,
915 const char *domain_name )
917 TALLOC_CTX *ctx = list;
918 char *s, *tmpstr;
920 while ( *list ) {
921 s = *list;
922 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
923 if ( !tmpstr ) {
924 DEBUG(0,("str_list_sub_basic: "
925 "alloc_sub_basic() return NULL!\n"));
926 return false;
929 TALLOC_FREE(*list);
930 *list = tmpstr;
932 list++;
935 return true;
938 /******************************************************************************
939 substitute a specific pattern in a string list
940 *****************************************************************************/
942 bool str_list_substitute(char **list, const char *pattern, const char *insert)
944 TALLOC_CTX *ctx = list;
945 char *p, *s, *t;
946 ssize_t ls, lp, li, ld, i, d;
948 if (!list)
949 return false;
950 if (!pattern)
951 return false;
952 if (!insert)
953 return false;
955 lp = (ssize_t)strlen(pattern);
956 li = (ssize_t)strlen(insert);
957 ld = li -lp;
959 while (*list) {
960 s = *list;
961 ls = (ssize_t)strlen(s);
963 while ((p = strstr_m(s, pattern))) {
964 t = *list;
965 d = p -t;
966 if (ld) {
967 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
968 if (!t) {
969 DEBUG(0,("str_list_substitute: "
970 "Unable to allocate memory"));
971 return false;
973 memcpy(t, *list, d);
974 memcpy(t +d +li, p +lp, ls -d -lp +1);
975 TALLOC_FREE(*list);
976 *list = t;
977 ls += ld;
978 s = t +d +li;
981 for (i = 0; i < li; i++) {
982 switch (insert[i]) {
983 case '`':
984 case '"':
985 case '\'':
986 case ';':
987 case '$':
988 case '%':
989 case '\r':
990 case '\n':
991 t[d +i] = '_';
992 break;
993 default:
994 t[d +i] = insert[i];
999 list++;
1002 return true;
1006 #define IPSTR_LIST_SEP ","
1007 #define IPSTR_LIST_CHAR ','
1010 * Add ip string representation to ipstr list. Used also
1011 * as part of @function ipstr_list_make
1013 * @param ipstr_list pointer to string containing ip list;
1014 * MUST BE already allocated and IS reallocated if necessary
1015 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1016 * as a result of reallocation)
1017 * @param ip IP address which is to be added to list
1018 * @return pointer to string appended with new ip and possibly
1019 * reallocated to new length
1022 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1024 char *new_ipstr = NULL;
1025 char addr_buf[INET6_ADDRSTRLEN];
1026 int ret;
1028 /* arguments checking */
1029 if (!ipstr_list || !service) {
1030 return NULL;
1033 print_sockaddr(addr_buf,
1034 sizeof(addr_buf),
1035 &service->ss);
1037 /* attempt to convert ip to a string and append colon separator to it */
1038 if (*ipstr_list) {
1039 if (service->ss.ss_family == AF_INET) {
1040 /* IPv4 */
1041 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1042 IPSTR_LIST_SEP, addr_buf,
1043 service->port);
1044 } else {
1045 /* IPv6 */
1046 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1047 IPSTR_LIST_SEP, addr_buf,
1048 service->port);
1050 SAFE_FREE(*ipstr_list);
1051 } else {
1052 if (service->ss.ss_family == AF_INET) {
1053 /* IPv4 */
1054 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1055 service->port);
1056 } else {
1057 /* IPv6 */
1058 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1059 service->port);
1062 if (ret == -1) {
1063 return NULL;
1065 *ipstr_list = new_ipstr;
1066 return *ipstr_list;
1070 * Allocate and initialise an ipstr list using ip adresses
1071 * passed as arguments.
1073 * @param ipstr_list pointer to string meant to be allocated and set
1074 * @param ip_list array of ip addresses to place in the list
1075 * @param ip_count number of addresses stored in ip_list
1076 * @return pointer to allocated ip string
1079 char *ipstr_list_make(char **ipstr_list,
1080 const struct ip_service *ip_list,
1081 int ip_count)
1083 int i;
1085 /* arguments checking */
1086 if (!ip_list || !ipstr_list) {
1087 return 0;
1090 *ipstr_list = NULL;
1092 /* process ip addresses given as arguments */
1093 for (i = 0; i < ip_count; i++) {
1094 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1097 return (*ipstr_list);
1102 * Parse given ip string list into array of ip addresses
1103 * (as ip_service structures)
1104 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1106 * @param ipstr ip string list to be parsed
1107 * @param ip_list pointer to array of ip addresses which is
1108 * allocated by this function and must be freed by caller
1109 * @return number of successfully parsed addresses
1112 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1114 TALLOC_CTX *frame;
1115 char *token_str = NULL;
1116 size_t count;
1117 int i;
1119 if (!ipstr_list || !ip_list)
1120 return 0;
1122 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1123 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1124 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1125 (unsigned long)count));
1126 return 0;
1129 frame = talloc_stackframe();
1130 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1131 IPSTR_LIST_SEP) && i<count; i++ ) {
1132 char *s = token_str;
1133 char *p = strrchr(token_str, ':');
1135 if (p) {
1136 *p = 0;
1137 (*ip_list)[i].port = atoi(p+1);
1140 /* convert single token to ip address */
1141 if (token_str[0] == '[') {
1142 /* IPv6 address. */
1143 s++;
1144 p = strchr(token_str, ']');
1145 if (!p) {
1146 continue;
1148 *p = '\0';
1150 if (!interpret_string_addr(&(*ip_list)[i].ss,
1152 AI_NUMERICHOST)) {
1153 continue;
1156 TALLOC_FREE(frame);
1157 return count;
1161 * Safely free ip string list
1163 * @param ipstr_list ip string list to be freed
1166 void ipstr_list_free(char* ipstr_list)
1168 SAFE_FREE(ipstr_list);
1171 /* read a SMB_BIG_UINT from a string */
1172 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1175 uint64_t val = (uint64_t)-1;
1176 const char *p = nptr;
1178 if (!p) {
1179 if (entptr) {
1180 *entptr = p;
1182 return val;
1185 while (*p && isspace(*p))
1186 p++;
1188 sscanf(p,"%"PRIu64,&val);
1189 if (entptr) {
1190 while (*p && isdigit(*p))
1191 p++;
1192 *entptr = p;
1195 return val;
1198 /* Convert a size specification to a count of bytes. We accept the following
1199 * suffixes:
1200 * bytes if there is no suffix
1201 * kK kibibytes
1202 * mM mebibytes
1203 * gG gibibytes
1204 * tT tibibytes
1205 * pP whatever the ISO name for petabytes is
1207 * Returns 0 if the string can't be converted.
1209 uint64_t conv_str_size(const char * str)
1211 uint64_t lval_orig;
1212 uint64_t lval;
1213 char * end;
1215 if (str == NULL || *str == '\0') {
1216 return 0;
1219 lval = strtoull(str, &end, 10 /* base */);
1221 if (end == NULL || end == str) {
1222 return 0;
1225 if (*end == '\0') {
1226 return lval;
1229 lval_orig = lval;
1231 if (strwicmp(end, "K") == 0) {
1232 lval *= 1024ULL;
1233 } else if (strwicmp(end, "M") == 0) {
1234 lval *= (1024ULL * 1024ULL);
1235 } else if (strwicmp(end, "G") == 0) {
1236 lval *= (1024ULL * 1024ULL *
1237 1024ULL);
1238 } else if (strwicmp(end, "T") == 0) {
1239 lval *= (1024ULL * 1024ULL *
1240 1024ULL * 1024ULL);
1241 } else if (strwicmp(end, "P") == 0) {
1242 lval *= (1024ULL * 1024ULL *
1243 1024ULL * 1024ULL *
1244 1024ULL);
1245 } else {
1246 return 0;
1249 return lval;
1252 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1253 * error checking in between. The indiation that something weird happened is
1254 * string==NULL */
1256 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
1257 size_t *bufsize, const char *fmt, ...)
1259 va_list ap;
1260 char *newstr;
1261 int ret;
1262 bool increased;
1264 /* len<0 is an internal marker that something failed */
1265 if (*len < 0)
1266 goto error;
1268 if (*string == NULL) {
1269 if (*bufsize == 0)
1270 *bufsize = 128;
1272 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
1273 if (*string == NULL)
1274 goto error;
1277 va_start(ap, fmt);
1278 ret = vasprintf(&newstr, fmt, ap);
1279 va_end(ap);
1281 if (ret < 0)
1282 goto error;
1284 increased = false;
1286 while ((*len)+ret >= *bufsize) {
1287 increased = true;
1288 *bufsize *= 2;
1289 if (*bufsize >= (1024*1024*256))
1290 goto error;
1293 if (increased) {
1294 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
1295 *bufsize);
1296 if (*string == NULL) {
1297 goto error;
1301 StrnCpy((*string)+(*len), newstr, ret);
1302 (*len) += ret;
1303 free(newstr);
1304 return;
1306 error:
1307 *len = -1;
1308 *string = NULL;
1312 * asprintf into a string and strupper_m it after that.
1315 int asprintf_strupper_m(char **strp, const char *fmt, ...)
1317 va_list ap;
1318 char *result;
1319 int ret;
1321 va_start(ap, fmt);
1322 ret = vasprintf(&result, fmt, ap);
1323 va_end(ap);
1325 if (ret == -1)
1326 return -1;
1328 strupper_m(result);
1329 *strp = result;
1330 return ret;
1333 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
1335 va_list ap;
1336 char *ret;
1338 va_start(ap, fmt);
1339 ret = talloc_vasprintf(t, fmt, ap);
1340 va_end(ap);
1342 if (ret == NULL) {
1343 return NULL;
1345 strupper_m(ret);
1346 return ret;
1349 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
1351 va_list ap;
1352 char *ret;
1354 va_start(ap, fmt);
1355 ret = talloc_vasprintf(t, fmt, ap);
1356 va_end(ap);
1358 if (ret == NULL) {
1359 return NULL;
1361 strlower_m(ret);
1362 return ret;
1367 Returns the substring from src between the first occurrence of
1368 the char "front" and the first occurence of the char "back".
1369 Mallocs the return string which must be freed. Not for use
1370 with wide character strings.
1372 char *sstring_sub(const char *src, char front, char back)
1374 char *temp1, *temp2, *temp3;
1375 ptrdiff_t len;
1377 temp1 = strchr(src, front);
1378 if (temp1 == NULL) return NULL;
1379 temp2 = strchr(src, back);
1380 if (temp2 == NULL) return NULL;
1381 len = temp2 - temp1;
1382 if (len <= 0) return NULL;
1383 temp3 = (char*)SMB_MALLOC(len);
1384 if (temp3 == NULL) {
1385 DEBUG(1,("Malloc failure in sstring_sub\n"));
1386 return NULL;
1388 memcpy(temp3, temp1+1, len-1);
1389 temp3[len-1] = '\0';
1390 return temp3;
1393 /********************************************************************
1394 Check a string for any occurrences of a specified list of invalid
1395 characters.
1396 ********************************************************************/
1398 bool validate_net_name( const char *name,
1399 const char *invalid_chars,
1400 int max_len)
1402 int i;
1404 if (!name) {
1405 return false;
1408 for ( i=0; i<max_len && name[i]; i++ ) {
1409 /* fail if strchr_m() finds one of the invalid characters */
1410 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
1411 return false;
1415 return true;
1419 /*******************************************************************
1420 Add a shell escape character '\' to any character not in a known list
1421 of characters. UNIX charset format.
1422 *******************************************************************/
1424 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1425 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1427 char *escape_shell_string(const char *src)
1429 size_t srclen = strlen(src);
1430 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
1431 char *dest = ret;
1432 bool in_s_quote = false;
1433 bool in_d_quote = false;
1434 bool next_escaped = false;
1436 if (!ret) {
1437 return NULL;
1440 while (*src) {
1441 size_t c_size;
1442 codepoint_t c = next_codepoint(src, &c_size);
1444 if (c == INVALID_CODEPOINT) {
1445 SAFE_FREE(ret);
1446 return NULL;
1449 if (c_size > 1) {
1450 memcpy(dest, src, c_size);
1451 src += c_size;
1452 dest += c_size;
1453 next_escaped = false;
1454 continue;
1458 * Deal with backslash escaped state.
1459 * This only lasts for one character.
1462 if (next_escaped) {
1463 *dest++ = *src++;
1464 next_escaped = false;
1465 continue;
1469 * Deal with single quote state. The
1470 * only thing we care about is exiting
1471 * this state.
1474 if (in_s_quote) {
1475 if (*src == '\'') {
1476 in_s_quote = false;
1478 *dest++ = *src++;
1479 continue;
1483 * Deal with double quote state. The most
1484 * complex state. We must cope with \, meaning
1485 * possibly escape next char (depending what it
1486 * is), ", meaning exit this state, and possibly
1487 * add an \ escape to any unprotected character
1488 * (listed in INSIDE_DQUOTE_LIST).
1491 if (in_d_quote) {
1492 if (*src == '\\') {
1494 * Next character might be escaped.
1495 * We have to peek. Inside double
1496 * quotes only INSIDE_DQUOTE_LIST
1497 * characters are escaped by a \.
1500 char nextchar;
1502 c = next_codepoint(&src[1], &c_size);
1503 if (c == INVALID_CODEPOINT) {
1504 SAFE_FREE(ret);
1505 return NULL;
1507 if (c_size > 1) {
1509 * Don't escape the next char.
1510 * Just copy the \.
1512 *dest++ = *src++;
1513 continue;
1516 nextchar = src[1];
1518 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
1519 (int)nextchar)) {
1520 next_escaped = true;
1522 *dest++ = *src++;
1523 continue;
1526 if (*src == '\"') {
1527 /* Exit double quote state. */
1528 in_d_quote = false;
1529 *dest++ = *src++;
1530 continue;
1534 * We know the character isn't \ or ",
1535 * so escape it if it's any of the other
1536 * possible unprotected characters.
1539 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
1540 *dest++ = '\\';
1542 *dest++ = *src++;
1543 continue;
1547 * From here to the end of the loop we're
1548 * not in the single or double quote state.
1551 if (*src == '\\') {
1552 /* Next character must be escaped. */
1553 next_escaped = true;
1554 *dest++ = *src++;
1555 continue;
1558 if (*src == '\'') {
1559 /* Go into single quote state. */
1560 in_s_quote = true;
1561 *dest++ = *src++;
1562 continue;
1565 if (*src == '\"') {
1566 /* Go into double quote state. */
1567 in_d_quote = true;
1568 *dest++ = *src++;
1569 continue;
1572 /* Check if we need to escape the character. */
1574 if (!strchr(INCLUDE_LIST, (int)*src)) {
1575 *dest++ = '\\';
1577 *dest++ = *src++;
1579 *dest++ = '\0';
1580 return ret;
1583 /***************************************************
1584 str_list_make, v3 version. The v4 version does not
1585 look at quoted strings with embedded blanks, so
1586 do NOT merge this function please!
1587 ***************************************************/
1589 #define S_LIST_ABS 16 /* List Allocation Block Size */
1591 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
1592 const char *sep)
1594 char **list;
1595 const char *str;
1596 char *s, *tok;
1597 int num, lsize;
1599 if (!string || !*string)
1600 return NULL;
1602 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1603 if (list == NULL) {
1604 return NULL;
1606 lsize = S_LIST_ABS;
1608 s = talloc_strdup(list, string);
1609 if (s == NULL) {
1610 DEBUG(0,("str_list_make: Unable to allocate memory"));
1611 TALLOC_FREE(list);
1612 return NULL;
1614 if (!sep) sep = LIST_SEP;
1616 num = 0;
1617 str = s;
1619 while (next_token_talloc(list, &str, &tok, sep)) {
1621 if (num == lsize) {
1622 char **tmp;
1624 lsize += S_LIST_ABS;
1626 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1627 lsize + 1);
1628 if (tmp == NULL) {
1629 DEBUG(0,("str_list_make: "
1630 "Unable to allocate memory"));
1631 TALLOC_FREE(list);
1632 return NULL;
1635 list = tmp;
1637 memset (&list[num], 0,
1638 ((sizeof(char**)) * (S_LIST_ABS +1)));
1641 list[num] = tok;
1642 num += 1;
1645 list[num] = NULL;
1647 TALLOC_FREE(s);
1648 return list;
1651 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
1653 fstring tmp;
1655 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
1656 return talloc_strdup(mem_ctx, tmp);