Fix typos.
[Samba.git] / source / lib / util_str.c
blob3059a1b6bdde3624a18b0a9224b5aa1c4873548b
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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 /**
28 * @file
29 * @brief String utilities.
30 **/
32 /**
33 * Internal function to get the next token from a string, return False if none
34 * found. Handles double-quotes. This is the work horse function called by
35 * next_token() and next_token_no_ltrim().
37 * Based on a routine by GJC@VILLAGE.COM.
38 * Extensively modified by Andrew.Tridgell@anu.edu.au
40 static BOOL next_token_internal(const char **ptr,
41 char *buff,
42 const char *sep,
43 size_t bufsize,
44 BOOL ltrim)
46 char *s;
47 char *pbuf;
48 BOOL quoted;
49 size_t len=1;
51 if (!ptr)
52 return(False);
54 s = (char *)*ptr;
56 /* default to simple separators */
57 if (!sep)
58 sep = " \t\n\r";
60 /* find the first non sep char, if left-trimming is requested */
61 if (ltrim) {
62 while (*s && strchr_m(sep,*s))
63 s++;
66 /* nothing left? */
67 if (! *s)
68 return(False);
70 /* copy over the token */
71 pbuf = buff;
72 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
73 if ( *s == '\"' ) {
74 quoted = !quoted;
75 } else {
76 len++;
77 *pbuf++ = *s;
81 *ptr = (*s) ? s+1 : s;
82 *pbuf = 0;
84 return(True);
88 * Get the next token from a string, return False if none found. Handles
89 * double-quotes. This version trims leading separator characters before
90 * looking for a token.
92 BOOL next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
94 return next_token_internal(ptr, buff, sep, bufsize, True);
98 * Get the next token from a string, return False if none found. Handles
99 * double-quotes. This version does not trim leading separator characters
100 * before looking for a token.
102 BOOL next_token_no_ltrim(const char **ptr,
103 char *buff,
104 const char *sep,
105 size_t bufsize)
107 return next_token_internal(ptr, buff, sep, bufsize, False);
111 This is like next_token but is not re-entrant and "remembers" the first
112 parameter so you can pass NULL. This is useful for user interface code
113 but beware the fact that it is not re-entrant!
116 static const char *last_ptr=NULL;
118 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
120 BOOL ret;
121 if (!ptr)
122 ptr = &last_ptr;
124 ret = next_token(ptr, buff, sep, bufsize);
125 last_ptr = *ptr;
126 return ret;
129 static uint16 tmpbuf[sizeof(pstring)];
131 void set_first_token(char *ptr)
133 last_ptr = ptr;
137 Convert list of tokens to array; dependent on above routine.
138 Uses last_ptr from above - bit of a hack.
141 char **toktocliplist(int *ctok, const char *sep)
143 char *s=(char *)last_ptr;
144 int ictok=0;
145 char **ret, **iret;
147 if (!sep)
148 sep = " \t\n\r";
150 while(*s && strchr_m(sep,*s))
151 s++;
153 /* nothing left? */
154 if (!*s)
155 return(NULL);
157 do {
158 ictok++;
159 while(*s && (!strchr_m(sep,*s)))
160 s++;
161 while(*s && strchr_m(sep,*s))
162 *s++=0;
163 } while(*s);
165 *ctok=ictok;
166 s=(char *)last_ptr;
168 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
169 return NULL;
171 while(ictok--) {
172 *iret++=s;
173 if (ictok > 0) {
174 while(*s++)
176 while(!*s)
177 s++;
181 ret[*ctok] = NULL;
182 return ret;
186 * Case insensitive string compararison.
188 * iconv does not directly give us a way to compare strings in
189 * arbitrary unix character sets -- all we can is convert and then
190 * compare. This is expensive.
192 * As an optimization, we do a first pass that considers only the
193 * prefix of the strings that is entirely 7-bit. Within this, we
194 * check whether they have the same value.
196 * Hopefully this will often give the answer without needing to copy.
197 * In particular it should speed comparisons to literal ascii strings
198 * or comparisons of strings that are "obviously" different.
200 * If we find a non-ascii character we fall back to converting via
201 * iconv.
203 * This should never be slower than convering the whole thing, and
204 * often faster.
206 * A different optimization would be to compare for bitwise equality
207 * in the binary encoding. (It would be possible thought hairy to do
208 * both simultaneously.) But in that case if they turn out to be
209 * different, we'd need to restart the whole thing.
211 * Even better is to implement strcasecmp for each encoding and use a
212 * function pointer.
214 int StrCaseCmp(const char *s, const char *t)
217 const char *ps, *pt;
218 size_t size;
219 smb_ucs2_t *buffer_s, *buffer_t;
220 int ret;
222 for (ps = s, pt = t; ; ps++, pt++) {
223 char us, ut;
225 if (!*ps && !*pt)
226 return 0; /* both ended */
227 else if (!*ps)
228 return -1; /* s is a prefix */
229 else if (!*pt)
230 return +1; /* t is a prefix */
231 else if ((*ps & 0x80) || (*pt & 0x80))
232 /* not ascii anymore, do it the hard way from here on in */
233 break;
235 us = toupper_ascii(*ps);
236 ut = toupper_ascii(*pt);
237 if (us == ut)
238 continue;
239 else if (us < ut)
240 return -1;
241 else if (us > ut)
242 return +1;
245 size = push_ucs2_allocate(&buffer_s, ps);
246 if (size == (size_t)-1) {
247 return strcmp(ps, pt);
248 /* Not quite the right answer, but finding the right one
249 under this failure case is expensive, and it's pretty close */
252 size = push_ucs2_allocate(&buffer_t, pt);
253 if (size == (size_t)-1) {
254 SAFE_FREE(buffer_s);
255 return strcmp(ps, pt);
256 /* Not quite the right answer, but finding the right one
257 under this failure case is expensive, and it's pretty close */
260 ret = strcasecmp_w(buffer_s, buffer_t);
261 SAFE_FREE(buffer_s);
262 SAFE_FREE(buffer_t);
263 return ret;
268 Case insensitive string compararison, length limited.
270 int StrnCaseCmp(const char *s, const char *t, size_t n)
272 pstring buf1, buf2;
273 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
274 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
275 return strncmp(buf1,buf2,n);
279 * Compare 2 strings.
281 * @note The comparison is case-insensitive.
283 BOOL strequal(const char *s1, const char *s2)
285 if (s1 == s2)
286 return(True);
287 if (!s1 || !s2)
288 return(False);
290 return(StrCaseCmp(s1,s2)==0);
294 * Compare 2 strings up to and including the nth char.
296 * @note The comparison is case-insensitive.
298 BOOL strnequal(const char *s1,const char *s2,size_t n)
300 if (s1 == s2)
301 return(True);
302 if (!s1 || !s2 || !n)
303 return(False);
305 return(StrnCaseCmp(s1,s2,n)==0);
309 Compare 2 strings (case sensitive).
312 BOOL strcsequal(const char *s1,const char *s2)
314 if (s1 == s2)
315 return(True);
316 if (!s1 || !s2)
317 return(False);
319 return(strcmp(s1,s2)==0);
323 Do a case-insensitive, whitespace-ignoring string compare.
326 int strwicmp(const char *psz1, const char *psz2)
328 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
329 /* appropriate value. */
330 if (psz1 == psz2)
331 return (0);
332 else if (psz1 == NULL)
333 return (-1);
334 else if (psz2 == NULL)
335 return (1);
337 /* sync the strings on first non-whitespace */
338 while (1) {
339 while (isspace((int)*psz1))
340 psz1++;
341 while (isspace((int)*psz2))
342 psz2++;
343 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
344 || *psz2 == '\0')
345 break;
346 psz1++;
347 psz2++;
349 return (*psz1 - *psz2);
354 Convert a string to upper case, but don't modify it.
357 char *strupper_static(const char *s)
359 static pstring str;
361 pstrcpy(str, s);
362 strupper_m(str);
364 return str;
368 Convert a string to "normal" form.
371 void strnorm(char *s, int case_default)
373 if (case_default == CASE_UPPER)
374 strupper_m(s);
375 else
376 strlower_m(s);
380 Check if a string is in "normal" case.
383 BOOL strisnormal(const char *s, int case_default)
385 if (case_default == CASE_UPPER)
386 return(!strhaslower(s));
388 return(!strhasupper(s));
393 String replace.
394 NOTE: oldc and newc must be 7 bit characters
398 String replace.
399 NOTE: oldc and newc must be 7 bit characters
401 void string_replace( char *s, char oldc, char newc )
403 char *p;
405 /* this is quite a common operation, so we want it to be
406 fast. We optimise for the ascii case, knowing that all our
407 supported multi-byte character sets are ascii-compatible
408 (ie. they match for the first 128 chars) */
410 for (p = s; *p; p++) {
411 if (*p & 0x80) /* mb string - slow path. */
412 break;
413 if (*p == oldc) {
414 *p = newc;
418 if (!*p)
419 return;
421 /* Slow (mb) path. */
422 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
423 /* With compose characters we must restart from the beginning. JRA. */
424 p = s;
425 #endif
427 while (*p) {
428 size_t c_size;
429 next_codepoint(p, &c_size);
431 if (c_size == 1) {
432 if (*p == oldc) {
433 *p = newc;
436 p += c_size;
441 * Skip past some strings in a buffer - old version - no checks.
442 * **/
444 char *push_skip_string(char *buf)
446 buf += strlen(buf) + 1;
447 return(buf);
451 Skip past a string in a buffer. Buffer may not be
452 null terminated. end_ptr points to the first byte after
453 then end of the buffer.
456 char *skip_string(const char *base, size_t len, char *buf)
458 const char *end_ptr = base + len;
460 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
461 return NULL;
464 /* Skip the string */
465 while (*buf) {
466 buf++;
467 if (buf >= end_ptr) {
468 return NULL;
471 /* Skip the '\0' */
472 buf++;
473 return buf;
477 Count the number of characters in a string. Normally this will
478 be the same as the number of bytes in a string for single byte strings,
479 but will be different for multibyte.
482 size_t str_charnum(const char *s)
484 uint16 tmpbuf2[sizeof(pstring)];
485 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
486 return strlen_w(tmpbuf2);
490 Count the number of characters in a string. Normally this will
491 be the same as the number of bytes in a string for single byte strings,
492 but will be different for multibyte.
495 size_t str_ascii_charnum(const char *s)
497 pstring tmpbuf2;
498 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
499 return strlen(tmpbuf2);
502 BOOL trim_char(char *s,char cfront,char cback)
504 BOOL ret = False;
505 char *ep;
506 char *fp = s;
508 /* Ignore null or empty strings. */
509 if (!s || (s[0] == '\0'))
510 return False;
512 if (cfront) {
513 while (*fp && *fp == cfront)
514 fp++;
515 if (!*fp) {
516 /* We ate the string. */
517 s[0] = '\0';
518 return True;
520 if (fp != s)
521 ret = True;
524 ep = fp + strlen(fp) - 1;
525 if (cback) {
526 /* Attempt ascii only. Bail for mb strings. */
527 while ((ep >= fp) && (*ep == cback)) {
528 ret = True;
529 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
530 /* Could be mb... bail back to tim_string. */
531 char fs[2], bs[2];
532 if (cfront) {
533 fs[0] = cfront;
534 fs[1] = '\0';
536 bs[0] = cback;
537 bs[1] = '\0';
538 return trim_string(s, cfront ? fs : NULL, bs);
539 } else {
540 ep--;
543 if (ep < fp) {
544 /* We ate the string. */
545 s[0] = '\0';
546 return True;
550 ep[1] = '\0';
551 memmove(s, fp, ep-fp+2);
552 return ret;
556 Trim the specified elements off the front and back of a string.
559 BOOL trim_string(char *s,const char *front,const char *back)
561 BOOL ret = False;
562 size_t front_len;
563 size_t back_len;
564 size_t len;
566 /* Ignore null or empty strings. */
567 if (!s || (s[0] == '\0'))
568 return False;
570 front_len = front? strlen(front) : 0;
571 back_len = back? strlen(back) : 0;
573 len = strlen(s);
575 if (front_len) {
576 while (len && strncmp(s, front, front_len)==0) {
577 /* Must use memmove here as src & dest can
578 * easily overlap. Found by valgrind. JRA. */
579 memmove(s, s+front_len, (len-front_len)+1);
580 len -= front_len;
581 ret=True;
585 if (back_len) {
586 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
587 s[len-back_len]='\0';
588 len -= back_len;
589 ret=True;
592 return ret;
596 Does a string have any uppercase chars in it?
599 BOOL strhasupper(const char *s)
601 smb_ucs2_t *ptr;
602 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
603 for(ptr=tmpbuf;*ptr;ptr++)
604 if(isupper_w(*ptr))
605 return True;
606 return(False);
610 Does a string have any lowercase chars in it?
613 BOOL strhaslower(const char *s)
615 smb_ucs2_t *ptr;
616 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
617 for(ptr=tmpbuf;*ptr;ptr++)
618 if(islower_w(*ptr))
619 return True;
620 return(False);
624 Find the number of 'c' chars in a string
627 size_t count_chars(const char *s,char c)
629 smb_ucs2_t *ptr;
630 int count;
631 smb_ucs2_t *alloc_tmpbuf = NULL;
633 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
634 return 0;
637 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
638 if(*ptr==UCS2_CHAR(c))
639 count++;
641 SAFE_FREE(alloc_tmpbuf);
642 return(count);
646 Safe string copy into a known length string. maxlength does not
647 include the terminating zero.
650 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
652 size_t len;
654 if (!dest) {
655 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
656 return NULL;
659 #ifdef DEVELOPER
660 clobber_region(fn,line,dest, maxlength+1);
661 #endif
663 if (!src) {
664 *dest = 0;
665 return dest;
668 len = strnlen(src, maxlength+1);
670 if (len > maxlength) {
671 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
672 (unsigned long)(len-maxlength), (unsigned long)len,
673 (unsigned long)maxlength, src));
674 len = maxlength;
677 memmove(dest, src, len);
678 dest[len] = 0;
679 return dest;
683 Safe string cat into a string. maxlength does not
684 include the terminating zero.
686 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
688 size_t src_len, dest_len;
690 if (!dest) {
691 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
692 return NULL;
695 if (!src)
696 return dest;
698 src_len = strnlen(src, maxlength + 1);
699 dest_len = strnlen(dest, maxlength + 1);
701 #ifdef DEVELOPER
702 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
703 #endif
705 if (src_len + dest_len > maxlength) {
706 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
707 (int)(src_len + dest_len - maxlength), src));
708 if (maxlength > dest_len) {
709 memcpy(&dest[dest_len], src, maxlength - dest_len);
711 dest[maxlength] = 0;
712 return NULL;
715 memcpy(&dest[dest_len], src, src_len);
716 dest[dest_len + src_len] = 0;
717 return dest;
721 Paranoid strcpy into a buffer of given length (includes terminating
722 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
723 and replaces with '_'. Deliberately does *NOT* check for multibyte
724 characters. Don't change it !
726 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
728 size_t len, i;
730 #ifdef DEVELOPER
731 clobber_region(fn, line, dest, maxlength);
732 #endif
734 if (!dest) {
735 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
736 return NULL;
739 if (!src) {
740 *dest = 0;
741 return dest;
744 len = strlen(src);
745 if (len >= maxlength)
746 len = maxlength - 1;
748 if (!other_safe_chars)
749 other_safe_chars = "";
751 for(i = 0; i < len; i++) {
752 int val = (src[i] & 0xff);
753 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
754 dest[i] = src[i];
755 else
756 dest[i] = '_';
759 dest[i] = '\0';
761 return dest;
765 Like strncpy but always null terminates. Make sure there is room!
766 The variable n should always be one less than the available size.
768 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
770 char *d = dest;
772 #ifdef DEVELOPER
773 clobber_region(fn, line, dest, n+1);
774 #endif
776 if (!dest) {
777 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
778 return(NULL);
781 if (!src) {
782 *dest = 0;
783 return(dest);
786 while (n-- && (*d = *src)) {
787 d++;
788 src++;
791 *d = 0;
792 return(dest);
795 #if 0
797 Like strncpy but copies up to the character marker. always null terminates.
798 returns a pointer to the character marker in the source string (src).
801 static char *strncpyn(char *dest, const char *src, size_t n, char c)
803 char *p;
804 size_t str_len;
806 #ifdef DEVELOPER
807 clobber_region(dest, n+1);
808 #endif
809 p = strchr_m(src, c);
810 if (p == NULL) {
811 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
812 return NULL;
815 str_len = PTR_DIFF(p, src);
816 strncpy(dest, src, MIN(n, str_len));
817 dest[str_len] = '\0';
819 return p;
821 #endif
824 Routine to get hex characters and turn them into a 16 byte array.
825 the array can be variable length, and any non-hex-numeric
826 characters are skipped. "0xnn" or "0Xnn" is specially catered
827 for.
829 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
833 size_t strhex_to_str(char *p, size_t len, const char *strhex)
835 size_t i;
836 size_t num_chars = 0;
837 unsigned char lonybble, hinybble;
838 const char *hexchars = "0123456789ABCDEF";
839 char *p1 = NULL, *p2 = NULL;
841 for (i = 0; i < len && strhex[i] != 0; i++) {
842 if (strnequal(hexchars, "0x", 2)) {
843 i++; /* skip two chars */
844 continue;
847 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
848 break;
850 i++; /* next hex digit */
852 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
853 break;
855 /* get the two nybbles */
856 hinybble = PTR_DIFF(p1, hexchars);
857 lonybble = PTR_DIFF(p2, hexchars);
859 p[num_chars] = (hinybble << 4) | lonybble;
860 num_chars++;
862 p1 = NULL;
863 p2 = NULL;
865 return num_chars;
868 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
870 DATA_BLOB ret_blob;
872 if (mem_ctx != NULL)
873 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
874 else
875 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
877 ret_blob.length = strhex_to_str((char*)ret_blob.data,
878 strlen(strhex),
879 strhex);
881 return ret_blob;
885 * Routine to print a buffer as HEX digits, into an allocated string.
888 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
890 int i;
891 char *hex_buffer;
893 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
895 for (i = 0; i < len; i++)
896 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
898 return hex_buffer;
902 Check if a string is part of a list.
905 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
907 pstring tok;
908 const char *p=list;
910 if (!list)
911 return(False);
913 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
914 if (casesensitive) {
915 if (strcmp(tok,s) == 0)
916 return(True);
917 } else {
918 if (StrCaseCmp(tok,s) == 0)
919 return(True);
922 return(False);
925 /* this is used to prevent lots of mallocs of size 1 */
926 static const char *null_string = "";
929 Set a string value, allocing the space for the string
932 static BOOL string_init(char **dest,const char *src)
934 size_t l;
936 if (!src)
937 src = "";
939 l = strlen(src);
941 if (l == 0) {
942 *dest = CONST_DISCARD(char*, null_string);
943 } else {
944 (*dest) = SMB_STRDUP(src);
945 if ((*dest) == NULL) {
946 DEBUG(0,("Out of memory in string_init\n"));
947 return False;
950 return(True);
954 Free a string value.
957 void string_free(char **s)
959 if (!s || !(*s))
960 return;
961 if (*s == null_string)
962 *s = NULL;
963 SAFE_FREE(*s);
967 Set a string value, deallocating any existing space, and allocing the space
968 for the string
971 BOOL string_set(char **dest,const char *src)
973 string_free(dest);
974 return(string_init(dest,src));
978 Substitute a string for a pattern in another string. Make sure there is
979 enough room!
981 This routine looks for pattern in s and replaces it with
982 insert. It may do multiple replacements or just one.
984 Any of " ; ' $ or ` in the insert string are replaced with _
985 if len==0 then the string cannot be extended. This is different from the old
986 use of len==0 which was for no length checks to be done.
989 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
990 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
992 char *p;
993 ssize_t ls,lp,li, i;
995 if (!insert || !pattern || !*pattern || !s)
996 return;
998 ls = (ssize_t)strlen(s);
999 lp = (ssize_t)strlen(pattern);
1000 li = (ssize_t)strlen(insert);
1002 if (len == 0)
1003 len = ls + 1; /* len is number of *bytes* */
1005 while (lp <= ls && (p = strstr_m(s,pattern))) {
1006 if (ls + (li-lp) >= len) {
1007 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1008 (int)(ls + (li-lp) - len),
1009 pattern, (int)len));
1010 break;
1012 if (li != lp) {
1013 memmove(p+li,p+lp,strlen(p+lp)+1);
1015 for (i=0;i<li;i++) {
1016 switch (insert[i]) {
1017 case '`':
1018 case '"':
1019 case '\'':
1020 case ';':
1021 case '$':
1022 /* allow a trailing $ (as in machine accounts) */
1023 if (allow_trailing_dollar && (i == li - 1 )) {
1024 p[i] = insert[i];
1025 break;
1027 case '%':
1028 case '\r':
1029 case '\n':
1030 if ( remove_unsafe_characters ) {
1031 p[i] = '_';
1032 /* yes this break should be here since we want to
1033 fall throw if not replacing unsafe chars */
1034 break;
1036 default:
1037 p[i] = insert[i];
1040 s = p + li;
1041 ls += (li-lp);
1043 if (replace_once)
1044 break;
1048 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1050 string_sub2( s, pattern, insert, len, True, True, False );
1053 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1055 string_sub2( s, pattern, insert, len, True, False, False );
1058 void fstring_sub(char *s,const char *pattern,const char *insert)
1060 string_sub(s, pattern, insert, sizeof(fstring));
1063 void pstring_sub(char *s,const char *pattern,const char *insert)
1065 string_sub(s, pattern, insert, sizeof(pstring));
1069 Similar to string_sub, but it will accept only allocated strings
1070 and may realloc them so pay attention at what you pass on no
1071 pointers inside strings, no pstrings or const may be passed
1072 as string.
1075 char *realloc_string_sub(char *string, const char *pattern,
1076 const char *insert)
1078 char *p, *in;
1079 char *s;
1080 ssize_t ls,lp,li,ld, i;
1082 if (!insert || !pattern || !*pattern || !string || !*string)
1083 return NULL;
1085 s = string;
1087 in = SMB_STRDUP(insert);
1088 if (!in) {
1089 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1090 return NULL;
1092 ls = (ssize_t)strlen(s);
1093 lp = (ssize_t)strlen(pattern);
1094 li = (ssize_t)strlen(insert);
1095 ld = li - lp;
1096 for (i=0;i<li;i++) {
1097 switch (in[i]) {
1098 case '`':
1099 case '"':
1100 case '\'':
1101 case ';':
1102 case '$':
1103 case '%':
1104 case '\r':
1105 case '\n':
1106 in[i] = '_';
1107 default:
1108 /* ok */
1109 break;
1113 while ((p = strstr_m(s,pattern))) {
1114 if (ld > 0) {
1115 int offset = PTR_DIFF(s,string);
1116 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1117 if (!string) {
1118 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1119 SAFE_FREE(in);
1120 return NULL;
1122 p = string + offset + (p - s);
1124 if (li != lp) {
1125 memmove(p+li,p+lp,strlen(p+lp)+1);
1127 memcpy(p, in, li);
1128 s = p + li;
1129 ls += ld;
1131 SAFE_FREE(in);
1132 return string;
1135 /* Same as string_sub, but returns a talloc'ed string */
1137 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1138 const char *pattern, const char *insert)
1140 char *p, *in;
1141 char *s;
1142 char *string;
1143 ssize_t ls,lp,li,ld, i;
1145 if (!insert || !pattern || !*pattern || !src || !*src)
1146 return NULL;
1148 string = talloc_strdup(mem_ctx, src);
1149 if (string == NULL) {
1150 DEBUG(0, ("talloc_strdup failed\n"));
1151 return NULL;
1154 s = string;
1156 in = SMB_STRDUP(insert);
1157 if (!in) {
1158 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1159 return NULL;
1161 ls = (ssize_t)strlen(s);
1162 lp = (ssize_t)strlen(pattern);
1163 li = (ssize_t)strlen(insert);
1164 ld = li - lp;
1165 for (i=0;i<li;i++) {
1166 switch (in[i]) {
1167 case '`':
1168 case '"':
1169 case '\'':
1170 case ';':
1171 case '$':
1172 case '%':
1173 case '\r':
1174 case '\n':
1175 in[i] = '_';
1176 default:
1177 /* ok */
1178 break;
1182 while ((p = strstr_m(s,pattern))) {
1183 if (ld > 0) {
1184 int offset = PTR_DIFF(s,string);
1185 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1186 ls + ld + 1);
1187 if (!string) {
1188 DEBUG(0, ("talloc_string_sub: out of "
1189 "memory!\n"));
1190 SAFE_FREE(in);
1191 return NULL;
1193 p = string + offset + (p - s);
1195 if (li != lp) {
1196 memmove(p+li,p+lp,strlen(p+lp)+1);
1198 memcpy(p, in, li);
1199 s = p + li;
1200 ls += ld;
1202 SAFE_FREE(in);
1203 return string;
1207 Similar to string_sub() but allows for any character to be substituted.
1208 Use with caution!
1209 if len==0 then the string cannot be extended. This is different from the old
1210 use of len==0 which was for no length checks to be done.
1213 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1215 char *p;
1216 ssize_t ls,lp,li;
1218 if (!insert || !pattern || !s)
1219 return;
1221 ls = (ssize_t)strlen(s);
1222 lp = (ssize_t)strlen(pattern);
1223 li = (ssize_t)strlen(insert);
1225 if (!*pattern)
1226 return;
1228 if (len == 0)
1229 len = ls + 1; /* len is number of *bytes* */
1231 while (lp <= ls && (p = strstr_m(s,pattern))) {
1232 if (ls + (li-lp) >= len) {
1233 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1234 (int)(ls + (li-lp) - len),
1235 pattern, (int)len));
1236 break;
1238 if (li != lp) {
1239 memmove(p+li,p+lp,strlen(p+lp)+1);
1241 memcpy(p, insert, li);
1242 s = p + li;
1243 ls += (li-lp);
1248 Similar to all_string_sub but for unicode strings.
1249 Return a new allocated unicode string.
1250 similar to string_sub() but allows for any character to be substituted.
1251 Use with caution!
1254 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1255 const smb_ucs2_t *insert)
1257 smb_ucs2_t *r, *rp;
1258 const smb_ucs2_t *sp;
1259 size_t lr, lp, li, lt;
1261 if (!insert || !pattern || !*pattern || !s)
1262 return NULL;
1264 lt = (size_t)strlen_w(s);
1265 lp = (size_t)strlen_w(pattern);
1266 li = (size_t)strlen_w(insert);
1268 if (li > lp) {
1269 const smb_ucs2_t *st = s;
1270 int ld = li - lp;
1271 while ((sp = strstr_w(st, pattern))) {
1272 st = sp + lp;
1273 lt += ld;
1277 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1278 if (!r) {
1279 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1280 return NULL;
1283 while ((sp = strstr_w(s, pattern))) {
1284 memcpy(rp, s, (sp - s));
1285 rp += ((sp - s) / sizeof(smb_ucs2_t));
1286 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1287 s = sp + lp;
1288 rp += li;
1290 lr = ((rp - r) / sizeof(smb_ucs2_t));
1291 if (lr < lt) {
1292 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1293 rp += (lt - lr);
1295 *rp = 0;
1297 return r;
1300 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1301 const char *insert)
1303 wpstring p, i;
1305 if (!insert || !pattern || !s)
1306 return NULL;
1307 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1308 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1309 return all_string_sub_w(s, p, i);
1312 #if 0
1314 Splits out the front and back at a separator.
1317 static void split_at_last_component(char *path, char *front, char sep, char *back)
1319 char *p = strrchr_m(path, sep);
1321 if (p != NULL)
1322 *p = 0;
1324 if (front != NULL)
1325 pstrcpy(front, path);
1327 if (p != NULL) {
1328 if (back != NULL)
1329 pstrcpy(back, p+1);
1330 *p = '\\';
1331 } else {
1332 if (back != NULL)
1333 back[0] = 0;
1336 #endif
1339 Write an octal as a string.
1342 const char *octal_string(int i)
1344 static char ret[64];
1345 if (i == -1)
1346 return "-1";
1347 slprintf(ret, sizeof(ret)-1, "0%o", i);
1348 return ret;
1353 Truncate a string at a specified length.
1356 char *string_truncate(char *s, unsigned int length)
1358 if (s && strlen(s) > length)
1359 s[length] = 0;
1360 return s;
1364 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1365 We convert via ucs2 for now.
1368 char *strchr_m(const char *src, char c)
1370 wpstring ws;
1371 pstring s2;
1372 smb_ucs2_t *p;
1373 const char *s;
1375 /* characters below 0x3F are guaranteed to not appear in
1376 non-initial position in multi-byte charsets */
1377 if ((c & 0xC0) == 0) {
1378 return strchr(src, c);
1381 /* this is quite a common operation, so we want it to be
1382 fast. We optimise for the ascii case, knowing that all our
1383 supported multi-byte character sets are ascii-compatible
1384 (ie. they match for the first 128 chars) */
1386 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1387 if (*s == c)
1388 return (char *)s;
1391 if (!*s)
1392 return NULL;
1394 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1395 /* With compose characters we must restart from the beginning. JRA. */
1396 s = src;
1397 #endif
1399 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1400 p = strchr_w(ws, UCS2_CHAR(c));
1401 if (!p)
1402 return NULL;
1403 *p = 0;
1404 pull_ucs2_pstring(s2, ws);
1405 return (char *)(s+strlen(s2));
1408 char *strrchr_m(const char *s, char c)
1410 /* characters below 0x3F are guaranteed to not appear in
1411 non-initial position in multi-byte charsets */
1412 if ((c & 0xC0) == 0) {
1413 return strrchr(s, c);
1416 /* this is quite a common operation, so we want it to be
1417 fast. We optimise for the ascii case, knowing that all our
1418 supported multi-byte character sets are ascii-compatible
1419 (ie. they match for the first 128 chars). Also, in Samba
1420 we only search for ascii characters in 'c' and that
1421 in all mb character sets with a compound character
1422 containing c, if 'c' is not a match at position
1423 p, then p[-1] > 0x7f. JRA. */
1426 size_t len = strlen(s);
1427 const char *cp = s;
1428 BOOL got_mb = False;
1430 if (len == 0)
1431 return NULL;
1432 cp += (len - 1);
1433 do {
1434 if (c == *cp) {
1435 /* Could be a match. Part of a multibyte ? */
1436 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1437 /* Yep - go slow :-( */
1438 got_mb = True;
1439 break;
1441 /* No - we have a match ! */
1442 return (char *)cp;
1444 } while (cp-- != s);
1445 if (!got_mb)
1446 return NULL;
1449 /* String contained a non-ascii char. Slow path. */
1451 wpstring ws;
1452 pstring s2;
1453 smb_ucs2_t *p;
1455 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1456 p = strrchr_w(ws, UCS2_CHAR(c));
1457 if (!p)
1458 return NULL;
1459 *p = 0;
1460 pull_ucs2_pstring(s2, ws);
1461 return (char *)(s+strlen(s2));
1465 /***********************************************************************
1466 Return the equivalent of doing strrchr 'n' times - always going
1467 backwards.
1468 ***********************************************************************/
1470 char *strnrchr_m(const char *s, char c, unsigned int n)
1472 wpstring ws;
1473 pstring s2;
1474 smb_ucs2_t *p;
1476 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1477 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1478 if (!p)
1479 return NULL;
1480 *p = 0;
1481 pull_ucs2_pstring(s2, ws);
1482 return (char *)(s+strlen(s2));
1485 /***********************************************************************
1486 strstr_m - We convert via ucs2 for now.
1487 ***********************************************************************/
1489 char *strstr_m(const char *src, const char *findstr)
1491 smb_ucs2_t *p;
1492 smb_ucs2_t *src_w, *find_w;
1493 const char *s;
1494 char *s2;
1495 char *retp;
1497 size_t findstr_len = 0;
1499 /* for correctness */
1500 if (!findstr[0]) {
1501 return (char*)src;
1504 /* Samba does single character findstr calls a *lot*. */
1505 if (findstr[1] == '\0')
1506 return strchr_m(src, *findstr);
1508 /* We optimise for the ascii case, knowing that all our
1509 supported multi-byte character sets are ascii-compatible
1510 (ie. they match for the first 128 chars) */
1512 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1513 if (*s == *findstr) {
1514 if (!findstr_len)
1515 findstr_len = strlen(findstr);
1517 if (strncmp(s, findstr, findstr_len) == 0) {
1518 return (char *)s;
1523 if (!*s)
1524 return NULL;
1526 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1527 /* 'make check' fails unless we do this */
1529 /* With compose characters we must restart from the beginning. JRA. */
1530 s = src;
1531 #endif
1533 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1534 DEBUG(0,("strstr_m: src malloc fail\n"));
1535 return NULL;
1538 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1539 SAFE_FREE(src_w);
1540 DEBUG(0,("strstr_m: find malloc fail\n"));
1541 return NULL;
1544 p = strstr_w(src_w, find_w);
1546 if (!p) {
1547 SAFE_FREE(src_w);
1548 SAFE_FREE(find_w);
1549 return NULL;
1552 *p = 0;
1553 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1554 SAFE_FREE(src_w);
1555 SAFE_FREE(find_w);
1556 DEBUG(0,("strstr_m: dest malloc fail\n"));
1557 return NULL;
1559 retp = (char *)(s+strlen(s2));
1560 SAFE_FREE(src_w);
1561 SAFE_FREE(find_w);
1562 SAFE_FREE(s2);
1563 return retp;
1567 Convert a string to lower case.
1570 void strlower_m(char *s)
1572 size_t len;
1573 int errno_save;
1575 /* this is quite a common operation, so we want it to be
1576 fast. We optimise for the ascii case, knowing that all our
1577 supported multi-byte character sets are ascii-compatible
1578 (ie. they match for the first 128 chars) */
1580 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1581 *s = tolower_ascii((unsigned char)*s);
1582 s++;
1585 if (!*s)
1586 return;
1588 /* I assume that lowercased string takes the same number of bytes
1589 * as source string even in UTF-8 encoding. (VIV) */
1590 len = strlen(s) + 1;
1591 errno_save = errno;
1592 errno = 0;
1593 unix_strlower(s,len,s,len);
1594 /* Catch mb conversion errors that may not terminate. */
1595 if (errno)
1596 s[len-1] = '\0';
1597 errno = errno_save;
1601 Convert a string to upper case.
1604 void strupper_m(char *s)
1606 size_t len;
1607 int errno_save;
1609 /* this is quite a common operation, so we want it to be
1610 fast. We optimise for the ascii case, knowing that all our
1611 supported multi-byte character sets are ascii-compatible
1612 (ie. they match for the first 128 chars) */
1614 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1615 *s = toupper_ascii((unsigned char)*s);
1616 s++;
1619 if (!*s)
1620 return;
1622 /* I assume that lowercased string takes the same number of bytes
1623 * as source string even in multibyte encoding. (VIV) */
1624 len = strlen(s) + 1;
1625 errno_save = errno;
1626 errno = 0;
1627 unix_strupper(s,len,s,len);
1628 /* Catch mb conversion errors that may not terminate. */
1629 if (errno)
1630 s[len-1] = '\0';
1631 errno = errno_save;
1635 Count the number of UCS2 characters in a string. Normally this will
1636 be the same as the number of bytes in a string for single byte strings,
1637 but will be different for multibyte.
1640 size_t strlen_m(const char *s)
1642 size_t count = 0;
1644 if (!s) {
1645 return 0;
1648 while (*s && !(((uint8_t)*s) & 0x80)) {
1649 s++;
1650 count++;
1653 if (!*s) {
1654 return count;
1657 while (*s) {
1658 size_t c_size;
1659 codepoint_t c = next_codepoint(s, &c_size);
1660 if (c < 0x10000) {
1661 /* Unicode char fits into 16 bits. */
1662 count += 1;
1663 } else {
1664 /* Double-width unicode char - 32 bits. */
1665 count += 2;
1667 s += c_size;
1670 return count;
1674 Count the number of UCS2 characters in a string including the null
1675 terminator.
1678 size_t strlen_m_term(const char *s)
1680 if (!s) {
1681 return 0;
1683 return strlen_m(s) + 1;
1687 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1688 * if a string is there, include the terminator.
1691 size_t strlen_m_term_null(const char *s)
1693 size_t len;
1694 if (!s) {
1695 return 0;
1697 len = strlen_m(s);
1698 if (len == 0) {
1699 return 0;
1702 return len+1;
1705 Return a RFC2254 binary string representation of a buffer.
1706 Used in LDAP filters.
1707 Caller must free.
1710 char *binary_string_rfc2254(char *buf, int len)
1712 char *s;
1713 int i, j;
1714 const char *hex = "0123456789ABCDEF";
1715 s = (char *)SMB_MALLOC(len * 3 + 1);
1716 if (!s)
1717 return NULL;
1718 for (j=i=0;i<len;i++) {
1719 s[j] = '\\';
1720 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1721 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1722 j += 3;
1724 s[j] = 0;
1725 return s;
1728 char *binary_string(char *buf, int len)
1730 char *s;
1731 int i, j;
1732 const char *hex = "0123456789ABCDEF";
1733 s = (char *)SMB_MALLOC(len * 2 + 1);
1734 if (!s)
1735 return NULL;
1736 for (j=i=0;i<len;i++) {
1737 s[j] = hex[((unsigned char)buf[i]) >> 4];
1738 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1739 j += 2;
1741 s[j] = 0;
1742 return s;
1745 Just a typesafety wrapper for snprintf into a pstring.
1748 int pstr_sprintf(pstring s, const char *fmt, ...)
1750 va_list ap;
1751 int ret;
1753 va_start(ap, fmt);
1754 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1755 va_end(ap);
1756 return ret;
1761 Just a typesafety wrapper for snprintf into a fstring.
1764 int fstr_sprintf(fstring s, const char *fmt, ...)
1766 va_list ap;
1767 int ret;
1769 va_start(ap, fmt);
1770 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1771 va_end(ap);
1772 return ret;
1776 List of Strings manipulation functions
1779 #define S_LIST_ABS 16 /* List Allocation Block Size */
1781 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1783 char **list, **rlist;
1784 const char *str;
1785 char *s;
1786 int num, lsize;
1787 pstring tok;
1789 if (!string || !*string)
1790 return NULL;
1791 if (mem_ctx) {
1792 s = talloc_strdup(mem_ctx, string);
1793 } else {
1794 s = SMB_STRDUP(string);
1796 if (!s) {
1797 DEBUG(0,("str_list_make: Unable to allocate memory"));
1798 return NULL;
1800 if (!sep) sep = LIST_SEP;
1802 num = lsize = 0;
1803 list = NULL;
1805 str = s;
1806 while (next_token(&str, tok, sep, sizeof(tok))) {
1807 if (num == lsize) {
1808 lsize += S_LIST_ABS;
1809 if (mem_ctx) {
1810 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1811 } else {
1812 /* We need to keep the old list on error so we can free the elements
1813 if the realloc fails. */
1814 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1816 if (!rlist) {
1817 DEBUG(0,("str_list_make: Unable to allocate memory"));
1818 str_list_free(&list);
1819 if (mem_ctx) {
1820 TALLOC_FREE(s);
1821 } else {
1822 SAFE_FREE(s);
1824 return NULL;
1825 } else {
1826 list = rlist;
1828 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1831 if (mem_ctx) {
1832 list[num] = talloc_strdup(mem_ctx, tok);
1833 } else {
1834 list[num] = SMB_STRDUP(tok);
1837 if (!list[num]) {
1838 DEBUG(0,("str_list_make: Unable to allocate memory"));
1839 str_list_free(&list);
1840 if (mem_ctx) {
1841 TALLOC_FREE(s);
1842 } else {
1843 SAFE_FREE(s);
1845 return NULL;
1848 num++;
1851 if (mem_ctx) {
1852 TALLOC_FREE(s);
1853 } else {
1854 SAFE_FREE(s);
1857 return list;
1860 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1862 return str_list_make_internal(mem_ctx, string, sep);
1865 char **str_list_make(const char *string, const char *sep)
1867 return str_list_make_internal(NULL, string, sep);
1870 BOOL str_list_copy(char ***dest, const char **src)
1872 char **list, **rlist;
1873 int num, lsize;
1875 *dest = NULL;
1876 if (!src)
1877 return False;
1879 num = lsize = 0;
1880 list = NULL;
1882 while (src[num]) {
1883 if (num == lsize) {
1884 lsize += S_LIST_ABS;
1885 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1886 if (!rlist) {
1887 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1888 str_list_free(&list);
1889 return False;
1890 } else {
1891 list = rlist;
1893 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1896 list[num] = SMB_STRDUP(src[num]);
1897 if (!list[num]) {
1898 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1899 str_list_free(&list);
1900 return False;
1903 num++;
1906 *dest = list;
1907 return True;
1911 * Return true if all the elements of the list match exactly.
1913 BOOL str_list_compare(char **list1, char **list2)
1915 int num;
1917 if (!list1 || !list2)
1918 return (list1 == list2);
1920 for (num = 0; list1[num]; num++) {
1921 if (!list2[num])
1922 return False;
1923 if (!strcsequal(list1[num], list2[num]))
1924 return False;
1926 if (list2[num])
1927 return False; /* if list2 has more elements than list1 fail */
1929 return True;
1932 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1934 char **tlist;
1936 if (!list || !*list)
1937 return;
1938 tlist = *list;
1939 for(; *tlist; tlist++) {
1940 if (mem_ctx) {
1941 TALLOC_FREE(*tlist);
1942 } else {
1943 SAFE_FREE(*tlist);
1946 if (mem_ctx) {
1947 TALLOC_FREE(*tlist);
1948 } else {
1949 SAFE_FREE(*list);
1953 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1955 str_list_free_internal(mem_ctx, list);
1958 void str_list_free(char ***list)
1960 str_list_free_internal(NULL, list);
1963 /******************************************************************************
1964 *****************************************************************************/
1966 int str_list_count( const char **list )
1968 int i = 0;
1970 if ( ! list )
1971 return 0;
1973 /* count the number of list members */
1975 for ( i=0; *list; i++, list++ );
1977 return i;
1980 /******************************************************************************
1981 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1982 for the work
1983 *****************************************************************************/
1985 BOOL str_list_sub_basic( char **list, const char *smb_name,
1986 const char *domain_name )
1988 char *s, *tmpstr;
1990 while ( *list ) {
1991 s = *list;
1992 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
1993 if ( !tmpstr ) {
1994 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1995 return False;
1998 SAFE_FREE(*list);
1999 *list = tmpstr;
2001 list++;
2004 return True;
2007 /******************************************************************************
2008 substritute a specific pattern in a string list
2009 *****************************************************************************/
2011 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2013 char *p, *s, *t;
2014 ssize_t ls, lp, li, ld, i, d;
2016 if (!list)
2017 return False;
2018 if (!pattern)
2019 return False;
2020 if (!insert)
2021 return False;
2023 lp = (ssize_t)strlen(pattern);
2024 li = (ssize_t)strlen(insert);
2025 ld = li -lp;
2027 while (*list) {
2028 s = *list;
2029 ls = (ssize_t)strlen(s);
2031 while ((p = strstr_m(s, pattern))) {
2032 t = *list;
2033 d = p -t;
2034 if (ld) {
2035 t = (char *) SMB_MALLOC(ls +ld +1);
2036 if (!t) {
2037 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2038 return False;
2040 memcpy(t, *list, d);
2041 memcpy(t +d +li, p +lp, ls -d -lp +1);
2042 SAFE_FREE(*list);
2043 *list = t;
2044 ls += ld;
2045 s = t +d +li;
2048 for (i = 0; i < li; i++) {
2049 switch (insert[i]) {
2050 case '`':
2051 case '"':
2052 case '\'':
2053 case ';':
2054 case '$':
2055 case '%':
2056 case '\r':
2057 case '\n':
2058 t[d +i] = '_';
2059 break;
2060 default:
2061 t[d +i] = insert[i];
2067 list++;
2070 return True;
2074 #define IPSTR_LIST_SEP ","
2075 #define IPSTR_LIST_CHAR ','
2078 * Add ip string representation to ipstr list. Used also
2079 * as part of @function ipstr_list_make
2081 * @param ipstr_list pointer to string containing ip list;
2082 * MUST BE already allocated and IS reallocated if necessary
2083 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2084 * as a result of reallocation)
2085 * @param ip IP address which is to be added to list
2086 * @return pointer to string appended with new ip and possibly
2087 * reallocated to new length
2090 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2092 char* new_ipstr = NULL;
2094 /* arguments checking */
2095 if (!ipstr_list || !service) return NULL;
2097 /* attempt to convert ip to a string and append colon separator to it */
2098 if (*ipstr_list) {
2099 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2100 inet_ntoa(service->ip), service->port);
2101 SAFE_FREE(*ipstr_list);
2102 } else {
2103 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2105 *ipstr_list = new_ipstr;
2106 return *ipstr_list;
2111 * Allocate and initialise an ipstr list using ip adresses
2112 * passed as arguments.
2114 * @param ipstr_list pointer to string meant to be allocated and set
2115 * @param ip_list array of ip addresses to place in the list
2116 * @param ip_count number of addresses stored in ip_list
2117 * @return pointer to allocated ip string
2120 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2122 int i;
2124 /* arguments checking */
2125 if (!ip_list || !ipstr_list) return 0;
2127 *ipstr_list = NULL;
2129 /* process ip addresses given as arguments */
2130 for (i = 0; i < ip_count; i++)
2131 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2133 return (*ipstr_list);
2138 * Parse given ip string list into array of ip addresses
2139 * (as ip_service structures)
2140 * e.g. 192.168.1.100:389,192.168.1.78, ...
2142 * @param ipstr ip string list to be parsed
2143 * @param ip_list pointer to array of ip addresses which is
2144 * allocated by this function and must be freed by caller
2145 * @return number of successfully parsed addresses
2148 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2150 fstring token_str;
2151 size_t count;
2152 int i;
2154 if (!ipstr_list || !ip_list)
2155 return 0;
2157 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2158 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2159 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2160 return 0;
2163 for ( i=0;
2164 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
2165 i++ )
2167 struct in_addr addr;
2168 unsigned port = 0;
2169 char *p = strchr(token_str, ':');
2171 if (p) {
2172 *p = 0;
2173 port = atoi(p+1);
2176 /* convert single token to ip address */
2177 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2178 break;
2180 (*ip_list)[i].ip = addr;
2181 (*ip_list)[i].port = port;
2184 return count;
2189 * Safely free ip string list
2191 * @param ipstr_list ip string list to be freed
2194 void ipstr_list_free(char* ipstr_list)
2196 SAFE_FREE(ipstr_list);
2201 Unescape a URL encoded string, in place.
2204 void rfc1738_unescape(char *buf)
2206 char *p=buf;
2208 while (p && *p && (p=strchr_m(p,'%'))) {
2209 int c1 = p[1];
2210 int c2 = p[2];
2212 if (c1 >= '0' && c1 <= '9')
2213 c1 = c1 - '0';
2214 else if (c1 >= 'A' && c1 <= 'F')
2215 c1 = 10 + c1 - 'A';
2216 else if (c1 >= 'a' && c1 <= 'f')
2217 c1 = 10 + c1 - 'a';
2218 else {p++; continue;}
2220 if (c2 >= '0' && c2 <= '9')
2221 c2 = c2 - '0';
2222 else if (c2 >= 'A' && c2 <= 'F')
2223 c2 = 10 + c2 - 'A';
2224 else if (c2 >= 'a' && c2 <= 'f')
2225 c2 = 10 + c2 - 'a';
2226 else {p++; continue;}
2228 *p = (c1<<4) | c2;
2230 memmove(p+1, p+3, strlen(p+3)+1);
2231 p++;
2235 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2238 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2240 DATA_BLOB base64_decode_data_blob(const char *s)
2242 int bit_offset, byte_offset, idx, i, n;
2243 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2244 unsigned char *d = decoded.data;
2245 char *p;
2247 n=i=0;
2249 while (*s && (p=strchr_m(b64,*s))) {
2250 idx = (int)(p - b64);
2251 byte_offset = (i*6)/8;
2252 bit_offset = (i*6)%8;
2253 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2254 if (bit_offset < 3) {
2255 d[byte_offset] |= (idx << (2-bit_offset));
2256 n = byte_offset+1;
2257 } else {
2258 d[byte_offset] |= (idx >> (bit_offset-2));
2259 d[byte_offset+1] = 0;
2260 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2261 n = byte_offset+2;
2263 s++; i++;
2266 if ((n > 0) && (*s == '=')) {
2267 n -= 1;
2270 /* fix up length */
2271 decoded.length = n;
2272 return decoded;
2276 * Decode a base64 string in-place - wrapper for the above
2278 void base64_decode_inplace(char *s)
2280 DATA_BLOB decoded = base64_decode_data_blob(s);
2282 if ( decoded.length != 0 ) {
2283 memcpy(s, decoded.data, decoded.length);
2285 /* null terminate */
2286 s[decoded.length] = '\0';
2287 } else {
2288 *s = '\0';
2291 data_blob_free(&decoded);
2295 * Encode a base64 string into a malloc()ed string caller to free.
2297 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2299 char * base64_encode_data_blob(DATA_BLOB data)
2301 int bits = 0;
2302 int char_count = 0;
2303 size_t out_cnt, len, output_len;
2304 char *result;
2306 if (!data.length || !data.data)
2307 return NULL;
2309 out_cnt = 0;
2310 len = data.length;
2311 output_len = data.length * 2;
2312 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2314 while (len-- && out_cnt < (data.length * 2) - 5) {
2315 int c = (unsigned char) *(data.data++);
2316 bits += c;
2317 char_count++;
2318 if (char_count == 3) {
2319 result[out_cnt++] = b64[bits >> 18];
2320 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2321 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2322 result[out_cnt++] = b64[bits & 0x3f];
2323 bits = 0;
2324 char_count = 0;
2325 } else {
2326 bits <<= 8;
2329 if (char_count != 0) {
2330 bits <<= 16 - (8 * char_count);
2331 result[out_cnt++] = b64[bits >> 18];
2332 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2333 if (char_count == 1) {
2334 result[out_cnt++] = '=';
2335 result[out_cnt++] = '=';
2336 } else {
2337 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2338 result[out_cnt++] = '=';
2341 result[out_cnt] = '\0'; /* terminate */
2342 return result;
2345 /* read a SMB_BIG_UINT from a string */
2346 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2349 SMB_BIG_UINT val = -1;
2350 const char *p = nptr;
2352 if (!p) {
2353 if (entptr) {
2354 *entptr = p;
2356 return val;
2359 while (*p && isspace(*p))
2360 p++;
2362 #ifdef LARGE_SMB_OFF_T
2363 sscanf(p,"%llu",&val);
2364 #else /* LARGE_SMB_OFF_T */
2365 sscanf(p,"%lu",&val);
2366 #endif /* LARGE_SMB_OFF_T */
2367 if (entptr) {
2368 while (*p && isdigit(*p))
2369 p++;
2370 *entptr = p;
2373 return val;
2376 /* Convert a size specification to a count of bytes. We accept the following
2377 * suffixes:
2378 * bytes if there is no suffix
2379 * kK kibibytes
2380 * mM mebibytes
2381 * gG gibibytes
2382 * tT tibibytes
2383 * pP whatever the ISO name for petabytes is
2385 * Returns 0 if the string can't be converted.
2387 SMB_OFF_T conv_str_size(const char * str)
2389 SMB_OFF_T lval;
2390 char * end;
2392 if (str == NULL || *str == '\0') {
2393 return 0;
2396 #ifdef HAVE_STRTOULL
2397 if (sizeof(SMB_OFF_T) == 8) {
2398 lval = strtoull(str, &end, 10 /* base */);
2399 } else {
2400 lval = strtoul(str, &end, 10 /* base */);
2402 #else
2403 lval = strtoul(str, &end, 10 /* base */);
2404 #endif
2406 if (end == NULL || end == str) {
2407 return 0;
2410 if (*end) {
2411 SMB_OFF_T lval_orig = lval;
2413 if (strwicmp(end, "K") == 0) {
2414 lval *= (SMB_OFF_T)1024;
2415 } else if (strwicmp(end, "M") == 0) {
2416 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2417 } else if (strwicmp(end, "G") == 0) {
2418 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2419 (SMB_OFF_T)1024);
2420 } else if (strwicmp(end, "T") == 0) {
2421 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2422 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2423 } else if (strwicmp(end, "P") == 0) {
2424 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2425 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2426 (SMB_OFF_T)1024);
2427 } else {
2428 return 0;
2431 /* Primitive attempt to detect wrapping on platforms with
2432 * 4-byte SMB_OFF_T. It's better to let the caller handle
2433 * a failure than some random number.
2435 if (lval_orig <= lval) {
2436 return 0;
2440 return lval;
2443 void string_append(char **left, const char *right)
2445 int new_len = strlen(right) + 1;
2447 if (*left == NULL) {
2448 *left = (char *)SMB_MALLOC(new_len);
2449 *left[0] = '\0';
2450 } else {
2451 new_len += strlen(*left);
2452 *left = (char *)SMB_REALLOC(*left, new_len);
2455 if (*left == NULL) {
2456 return;
2459 safe_strcat(*left, right, new_len-1);
2462 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2463 const char *str, const char ***strings,
2464 int *num)
2466 char *dup_str = talloc_strdup(mem_ctx, str);
2468 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2470 if ((*strings == NULL) || (dup_str == NULL)) {
2471 *num = 0;
2472 return False;
2475 (*strings)[*num] = dup_str;
2476 *num += 1;
2477 return True;
2480 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2481 * error checking in between. The indiation that something weird happened is
2482 * string==NULL */
2484 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2485 size_t *bufsize, const char *fmt, ...)
2487 va_list ap;
2488 char *newstr;
2489 int ret;
2490 BOOL increased;
2492 /* len<0 is an internal marker that something failed */
2493 if (*len < 0)
2494 goto error;
2496 if (*string == NULL) {
2497 if (*bufsize == 0)
2498 *bufsize = 128;
2500 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2501 if (*string == NULL)
2502 goto error;
2505 va_start(ap, fmt);
2506 ret = vasprintf(&newstr, fmt, ap);
2507 va_end(ap);
2509 if (ret < 0)
2510 goto error;
2512 increased = False;
2514 while ((*len)+ret >= *bufsize) {
2515 increased = True;
2516 *bufsize *= 2;
2517 if (*bufsize >= (1024*1024*256))
2518 goto error;
2521 if (increased) {
2522 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2523 *bufsize);
2524 if (*string == NULL) {
2525 goto error;
2529 StrnCpy((*string)+(*len), newstr, ret);
2530 (*len) += ret;
2531 free(newstr);
2532 return;
2534 error:
2535 *len = -1;
2536 *string = NULL;
2540 Returns the substring from src between the first occurrence of
2541 the char "front" and the first occurence of the char "back".
2542 Mallocs the return string which must be freed. Not for use
2543 with wide character strings.
2545 char *sstring_sub(const char *src, char front, char back)
2547 char *temp1, *temp2, *temp3;
2548 ptrdiff_t len;
2550 temp1 = strchr(src, front);
2551 if (temp1 == NULL) return NULL;
2552 temp2 = strchr(src, back);
2553 if (temp2 == NULL) return NULL;
2554 len = temp2 - temp1;
2555 if (len <= 0) return NULL;
2556 temp3 = (char*)SMB_MALLOC(len);
2557 if (temp3 == NULL) {
2558 DEBUG(1,("Malloc failure in sstring_sub\n"));
2559 return NULL;
2561 memcpy(temp3, temp1+1, len-1);
2562 temp3[len-1] = '\0';
2563 return temp3;
2566 /********************************************************************
2567 Check a string for any occurrences of a specified list of invalid
2568 characters.
2569 ********************************************************************/
2571 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2573 int i;
2575 for ( i=0; i<max_len && name[i]; i++ ) {
2576 /* fail if strchr_m() finds one of the invalid characters */
2577 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2578 return False;
2582 return True;
2587 return the number of bytes occupied by a buffer in ASCII format
2588 the result includes the null termination
2589 limited by 'n' bytes
2591 size_t ascii_len_n(const char *src, size_t n)
2593 size_t len;
2595 len = strnlen(src, n);
2596 if (len+1 <= n) {
2597 len += 1;
2600 return len;
2604 return the number of bytes occupied by a buffer in CH_UTF16 format
2605 the result includes the null termination
2607 size_t utf16_len(const void *buf)
2609 size_t len;
2611 for (len = 0; SVAL(buf,len); len += 2) ;
2613 return len + 2;
2617 return the number of bytes occupied by a buffer in CH_UTF16 format
2618 the result includes the null termination
2619 limited by 'n' bytes
2621 size_t utf16_len_n(const void *src, size_t n)
2623 size_t len;
2625 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2627 if (len+2 <= n) {
2628 len += 2;
2631 return len;
2634 /*******************************************************************
2635 Add a shell escape character '\' to any character not in a known list
2636 of characters. UNIX charset format.
2637 *******************************************************************/
2639 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2640 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2642 char *escape_shell_string(const char *src)
2644 size_t srclen = strlen(src);
2645 char *ret = SMB_MALLOC((srclen * 2) + 1);
2646 char *dest = ret;
2647 BOOL in_s_quote = False;
2648 BOOL in_d_quote = False;
2649 BOOL next_escaped = False;
2651 if (!ret) {
2652 return NULL;
2655 while (*src) {
2656 size_t c_size;
2657 codepoint_t c = next_codepoint(src, &c_size);
2659 if (c == INVALID_CODEPOINT) {
2660 SAFE_FREE(ret);
2661 return NULL;
2664 if (c_size > 1) {
2665 memcpy(dest, src, c_size);
2666 src += c_size;
2667 dest += c_size;
2668 next_escaped = False;
2669 continue;
2673 * Deal with backslash escaped state.
2674 * This only lasts for one character.
2677 if (next_escaped) {
2678 *dest++ = *src++;
2679 next_escaped = False;
2680 continue;
2684 * Deal with single quote state. The
2685 * only thing we care about is exiting
2686 * this state.
2689 if (in_s_quote) {
2690 if (*src == '\'') {
2691 in_s_quote = False;
2693 *dest++ = *src++;
2694 continue;
2698 * Deal with double quote state. The most
2699 * complex state. We must cope with \, meaning
2700 * possibly escape next char (depending what it
2701 * is), ", meaning exit this state, and possibly
2702 * add an \ escape to any unprotected character
2703 * (listed in INSIDE_DQUOTE_LIST).
2706 if (in_d_quote) {
2707 if (*src == '\\') {
2709 * Next character might be escaped.
2710 * We have to peek. Inside double
2711 * quotes only INSIDE_DQUOTE_LIST
2712 * characters are escaped by a \.
2715 char nextchar;
2717 c = next_codepoint(&src[1], &c_size);
2718 if (c == INVALID_CODEPOINT) {
2719 SAFE_FREE(ret);
2720 return NULL;
2722 if (c_size > 1) {
2724 * Don't escape the next char.
2725 * Just copy the \.
2727 *dest++ = *src++;
2728 continue;
2731 nextchar = src[1];
2733 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2734 next_escaped = True;
2736 *dest++ = *src++;
2737 continue;
2740 if (*src == '\"') {
2741 /* Exit double quote state. */
2742 in_d_quote = False;
2743 *dest++ = *src++;
2744 continue;
2748 * We know the character isn't \ or ",
2749 * so escape it if it's any of the other
2750 * possible unprotected characters.
2753 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2754 *dest++ = '\\';
2756 *dest++ = *src++;
2757 continue;
2761 * From here to the end of the loop we're
2762 * not in the single or double quote state.
2765 if (*src == '\\') {
2766 /* Next character must be escaped. */
2767 next_escaped = True;
2768 *dest++ = *src++;
2769 continue;
2772 if (*src == '\'') {
2773 /* Go into single quote state. */
2774 in_s_quote = True;
2775 *dest++ = *src++;
2776 continue;
2779 if (*src == '\"') {
2780 /* Go into double quote state. */
2781 in_d_quote = True;
2782 *dest++ = *src++;
2783 continue;
2786 /* Check if we need to escape the character. */
2788 if (!strchr(INCLUDE_LIST, (int)*src)) {
2789 *dest++ = '\\';
2791 *dest++ = *src++;
2793 *dest++ = '\0';
2794 return ret;