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.
29 * @brief String utilities.
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
,
56 /* default to simple separators */
60 /* find the first non sep char, if left-trimming is requested */
62 while (*s
&& strchr_m(sep
,*s
))
70 /* copy over the token */
72 for (quoted
= False
; len
< bufsize
&& *s
&& (quoted
|| !strchr_m(sep
,*s
)); s
++) {
81 *ptr
= (*s
) ? s
+1 : s
;
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
,
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
)
124 ret
= next_token(ptr
, buff
, sep
, bufsize
);
129 static uint16 tmpbuf
[sizeof(pstring
)];
131 void set_first_token(char *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
;
150 while(*s
&& strchr_m(sep
,*s
))
159 while(*s
&& (!strchr_m(sep
,*s
)))
161 while(*s
&& strchr_m(sep
,*s
))
168 if (!(ret
=iret
=SMB_MALLOC_ARRAY(char *,ictok
+1)))
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
203 * This should never be slower than convering the whole thing, and
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
214 int StrCaseCmp(const char *s
, const char *t
)
219 smb_ucs2_t
*buffer_s
, *buffer_t
;
222 for (ps
= s
, pt
= t
; ; ps
++, pt
++) {
226 return 0; /* both ended */
228 return -1; /* s is a prefix */
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 */
235 us
= toupper_ascii(*ps
);
236 ut
= toupper_ascii(*pt
);
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) {
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
);
268 Case insensitive string compararison, length limited.
270 int StrnCaseCmp(const char *s
, const char *t
, size_t n
)
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
);
281 * @note The comparison is case-insensitive.
283 BOOL
strequal(const char *s1
, const char *s2
)
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
)
302 if (!s1
|| !s2
|| !n
)
305 return(StrnCaseCmp(s1
,s2
,n
)==0);
309 Compare 2 strings (case sensitive).
312 BOOL
strcsequal(const char *s1
,const char *s2
)
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. */
332 else if (psz1
== NULL
)
334 else if (psz2
== NULL
)
337 /* sync the strings on first non-whitespace */
339 while (isspace((int)*psz1
))
341 while (isspace((int)*psz2
))
343 if (toupper_ascii(*psz1
) != toupper_ascii(*psz2
) || *psz1
== '\0'
349 return (*psz1
- *psz2
);
354 Convert a string to upper case, but don't modify it.
357 char *strupper_static(const char *s
)
368 Convert a string to "normal" form.
371 void strnorm(char *s
, int case_default
)
373 if (case_default
== CASE_UPPER
)
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
));
394 NOTE: oldc and newc must be 7 bit characters
399 NOTE: oldc and newc must be 7 bit characters
401 void string_replace( char *s
, char oldc
, char newc
)
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. */
421 /* Slow (mb) path. */
422 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
423 /* With compose characters we must restart from the beginning. JRA. */
429 next_codepoint(p
, &c_size
);
441 * Skip past some strings in a buffer - old version - no checks.
444 char *push_skip_string(char *buf
)
446 buf
+= strlen(buf
) + 1;
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
) {
464 /* Skip the string */
467 if (buf
>= end_ptr
) {
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
)
498 push_ascii(tmpbuf2
, s
, sizeof(tmpbuf2
), STR_TERMINATE
);
499 return strlen(tmpbuf2
);
502 BOOL
trim_char(char *s
,char cfront
,char cback
)
508 /* Ignore null or empty strings. */
509 if (!s
|| (s
[0] == '\0'))
513 while (*fp
&& *fp
== cfront
)
516 /* We ate the string. */
524 ep
= fp
+ strlen(fp
) - 1;
526 /* Attempt ascii only. Bail for mb strings. */
527 while ((ep
>= fp
) && (*ep
== cback
)) {
529 if ((ep
> fp
) && (((unsigned char)ep
[-1]) & 0x80)) {
530 /* Could be mb... bail back to tim_string. */
538 return trim_string(s
, cfront
? fs
: NULL
, bs
);
544 /* We ate the string. */
551 memmove(s
, fp
, ep
-fp
+2);
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
)
566 /* Ignore null or empty strings. */
567 if (!s
|| (s
[0] == '\0'))
570 front_len
= front
? strlen(front
) : 0;
571 back_len
= back
? strlen(back
) : 0;
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);
586 while ((len
>= back_len
) && strncmp(s
+len
-back_len
,back
,back_len
)==0) {
587 s
[len
-back_len
]='\0';
596 Does a string have any uppercase chars in it?
599 BOOL
strhasupper(const char *s
)
602 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
603 for(ptr
=tmpbuf
;*ptr
;ptr
++)
610 Does a string have any lowercase chars in it?
613 BOOL
strhaslower(const char *s
)
616 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
617 for(ptr
=tmpbuf
;*ptr
;ptr
++)
624 Find the number of 'c' chars in a string
627 size_t count_chars(const char *s
,char c
)
631 smb_ucs2_t
*alloc_tmpbuf
= NULL
;
633 if (push_ucs2_allocate(&alloc_tmpbuf
, s
) == (size_t)-1) {
637 for(count
=0,ptr
=alloc_tmpbuf
;*ptr
;ptr
++)
638 if(*ptr
==UCS2_CHAR(c
))
641 SAFE_FREE(alloc_tmpbuf
);
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
)
655 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn
, line
));
660 clobber_region(fn
,line
,dest
, maxlength
+1);
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
));
677 memmove(dest
, src
, len
);
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
;
691 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn
, line
));
698 src_len
= strnlen(src
, maxlength
+ 1);
699 dest_len
= strnlen(dest
, maxlength
+ 1);
702 clobber_region(fn
, line
, dest
+ dest_len
, maxlength
+ 1 - dest_len
);
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
);
715 memcpy(&dest
[dest_len
], src
, src_len
);
716 dest
[dest_len
+ src_len
] = 0;
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
)
731 clobber_region(fn
, line
, dest
, maxlength
);
735 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn
, line
));
745 if (len
>= maxlength
)
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
))
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
)
773 clobber_region(fn
, line
, dest
, n
+1);
777 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn
, line
));
786 while (n
-- && (*d
= *src
)) {
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
)
807 clobber_region(dest
, n
+1);
809 p
= strchr_m(src
, c
);
811 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c
));
815 str_len
= PTR_DIFF(p
, src
);
816 strncpy(dest
, src
, MIN(n
, str_len
));
817 dest
[str_len
] = '\0';
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
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
)
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 */
847 if (!(p1
= strchr_m(hexchars
, toupper_ascii(strhex
[i
]))))
850 i
++; /* next hex digit */
852 if (!(p2
= strchr_m(hexchars
, toupper_ascii(strhex
[i
]))))
855 /* get the two nybbles */
856 hinybble
= PTR_DIFF(p1
, hexchars
);
857 lonybble
= PTR_DIFF(p2
, hexchars
);
859 p
[num_chars
] = (hinybble
<< 4) | lonybble
;
868 DATA_BLOB
strhex_to_data_blob(TALLOC_CTX
*mem_ctx
, const char *strhex
)
873 ret_blob
= data_blob_talloc(mem_ctx
, NULL
, strlen(strhex
)/2+1);
875 ret_blob
= data_blob(NULL
, strlen(strhex
)/2+1);
877 ret_blob
.length
= strhex_to_str((char*)ret_blob
.data
,
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
)
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
]);
902 Check if a string is part of a list.
905 BOOL
in_list(const char *s
, const char *list
, BOOL casesensitive
)
913 while (next_token(&p
,tok
,LIST_SEP
,sizeof(tok
))) {
915 if (strcmp(tok
,s
) == 0)
918 if (StrCaseCmp(tok
,s
) == 0)
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
)
942 *dest
= CONST_DISCARD(char*, null_string
);
944 (*dest
) = SMB_STRDUP(src
);
945 if ((*dest
) == NULL
) {
946 DEBUG(0,("Out of memory in string_init\n"));
957 void string_free(char **s
)
961 if (*s
== null_string
)
967 Set a string value, deallocating any existing space, and allocing the space
971 BOOL
string_set(char **dest
,const char *src
)
974 return(string_init(dest
,src
));
978 Substitute a string for a pattern in another string. Make sure there is
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
)
995 if (!insert
|| !pattern
|| !*pattern
|| !s
)
998 ls
= (ssize_t
)strlen(s
);
999 lp
= (ssize_t
)strlen(pattern
);
1000 li
= (ssize_t
)strlen(insert
);
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
));
1013 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1015 for (i
=0;i
<li
;i
++) {
1016 switch (insert
[i
]) {
1022 /* allow a trailing $ (as in machine accounts) */
1023 if (allow_trailing_dollar
&& (i
== li
- 1 )) {
1030 if ( remove_unsafe_characters
) {
1032 /* yes this break should be here since we want to
1033 fall throw if not replacing unsafe chars */
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
1075 char *realloc_string_sub(char *string
, const char *pattern
,
1080 ssize_t ls
,lp
,li
,ld
, i
;
1082 if (!insert
|| !pattern
|| !*pattern
|| !string
|| !*string
)
1087 in
= SMB_STRDUP(insert
);
1089 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1092 ls
= (ssize_t
)strlen(s
);
1093 lp
= (ssize_t
)strlen(pattern
);
1094 li
= (ssize_t
)strlen(insert
);
1096 for (i
=0;i
<li
;i
++) {
1113 while ((p
= strstr_m(s
,pattern
))) {
1115 int offset
= PTR_DIFF(s
,string
);
1116 string
= (char *)SMB_REALLOC(string
, ls
+ ld
+ 1);
1118 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1122 p
= string
+ offset
+ (p
- s
);
1125 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
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
)
1143 ssize_t ls
,lp
,li
,ld
, i
;
1145 if (!insert
|| !pattern
|| !*pattern
|| !src
|| !*src
)
1148 string
= talloc_strdup(mem_ctx
, src
);
1149 if (string
== NULL
) {
1150 DEBUG(0, ("talloc_strdup failed\n"));
1156 in
= SMB_STRDUP(insert
);
1158 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1161 ls
= (ssize_t
)strlen(s
);
1162 lp
= (ssize_t
)strlen(pattern
);
1163 li
= (ssize_t
)strlen(insert
);
1165 for (i
=0;i
<li
;i
++) {
1182 while ((p
= strstr_m(s
,pattern
))) {
1184 int offset
= PTR_DIFF(s
,string
);
1185 string
= (char *)TALLOC_REALLOC(mem_ctx
, string
,
1188 DEBUG(0, ("talloc_string_sub: out of "
1193 p
= string
+ offset
+ (p
- s
);
1196 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1207 Similar to string_sub() but allows for any character to be substituted.
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
)
1218 if (!insert
|| !pattern
|| !s
)
1221 ls
= (ssize_t
)strlen(s
);
1222 lp
= (ssize_t
)strlen(pattern
);
1223 li
= (ssize_t
)strlen(insert
);
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
));
1239 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1241 memcpy(p
, insert
, li
);
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.
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
)
1258 const smb_ucs2_t
*sp
;
1259 size_t lr
, lp
, li
, lt
;
1261 if (!insert
|| !pattern
|| !*pattern
|| !s
)
1264 lt
= (size_t)strlen_w(s
);
1265 lp
= (size_t)strlen_w(pattern
);
1266 li
= (size_t)strlen_w(insert
);
1269 const smb_ucs2_t
*st
= s
;
1271 while ((sp
= strstr_w(st
, pattern
))) {
1277 r
= rp
= SMB_MALLOC_ARRAY(smb_ucs2_t
, lt
+ 1);
1279 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
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
)));
1290 lr
= ((rp
- r
) / sizeof(smb_ucs2_t
));
1292 memcpy(rp
, s
, ((lt
- lr
) * sizeof(smb_ucs2_t
)));
1300 smb_ucs2_t
*all_string_sub_wa(smb_ucs2_t
*s
, const char *pattern
,
1305 if (!insert
|| !pattern
|| !s
)
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
);
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
);
1325 pstrcpy(front
, path
);
1339 Write an octal as a string.
1342 const char *octal_string(int i
)
1344 static char ret
[64];
1347 slprintf(ret
, sizeof(ret
)-1, "0%o", i
);
1353 Truncate a string at a specified length.
1356 char *string_truncate(char *s
, unsigned int length
)
1358 if (s
&& strlen(s
) > length
)
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
)
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
++) {
1394 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1395 /* With compose characters we must restart from the beginning. JRA. */
1399 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1400 p
= strchr_w(ws
, UCS2_CHAR(c
));
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
);
1428 BOOL got_mb
= False
;
1435 /* Could be a match. Part of a multibyte ? */
1436 if ((cp
> s
) && (((unsigned char)cp
[-1]) & 0x80)) {
1437 /* Yep - go slow :-( */
1441 /* No - we have a match ! */
1444 } while (cp
-- != s
);
1449 /* String contained a non-ascii char. Slow path. */
1455 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1456 p
= strrchr_w(ws
, UCS2_CHAR(c
));
1460 pull_ucs2_pstring(s2
, ws
);
1461 return (char *)(s
+strlen(s2
));
1465 /***********************************************************************
1466 Return the equivalent of doing strrchr 'n' times - always going
1468 ***********************************************************************/
1470 char *strnrchr_m(const char *s
, char c
, unsigned int n
)
1476 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1477 p
= strnrchr_w(ws
, UCS2_CHAR(c
), n
);
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
)
1492 smb_ucs2_t
*src_w
, *find_w
;
1497 size_t findstr_len
= 0;
1499 /* for correctness */
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
) {
1515 findstr_len
= strlen(findstr
);
1517 if (strncmp(s
, findstr
, findstr_len
) == 0) {
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. */
1533 if (push_ucs2_allocate(&src_w
, src
) == (size_t)-1) {
1534 DEBUG(0,("strstr_m: src malloc fail\n"));
1538 if (push_ucs2_allocate(&find_w
, findstr
) == (size_t)-1) {
1540 DEBUG(0,("strstr_m: find malloc fail\n"));
1544 p
= strstr_w(src_w
, find_w
);
1553 if (pull_ucs2_allocate(&s2
, src_w
) == (size_t)-1) {
1556 DEBUG(0,("strstr_m: dest malloc fail\n"));
1559 retp
= (char *)(s
+strlen(s2
));
1567 Convert a string to lower case.
1570 void strlower_m(char *s
)
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
);
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;
1593 unix_strlower(s
,len
,s
,len
);
1594 /* Catch mb conversion errors that may not terminate. */
1601 Convert a string to upper case.
1604 void strupper_m(char *s
)
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
);
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;
1627 unix_strupper(s
,len
,s
,len
);
1628 /* Catch mb conversion errors that may not terminate. */
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
)
1648 while (*s
&& !(((uint8_t)*s
) & 0x80)) {
1659 codepoint_t c
= next_codepoint(s
, &c_size
);
1661 /* Unicode char fits into 16 bits. */
1664 /* Double-width unicode char - 32 bits. */
1674 Count the number of UCS2 characters in a string including the null
1678 size_t strlen_m_term(const char *s
)
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
)
1705 Return a RFC2254 binary string representation of a buffer.
1706 Used in LDAP filters.
1710 char *binary_string_rfc2254(char *buf
, int len
)
1714 const char *hex
= "0123456789ABCDEF";
1715 s
= (char *)SMB_MALLOC(len
* 3 + 1);
1718 for (j
=i
=0;i
<len
;i
++) {
1720 s
[j
+1] = hex
[((unsigned char)buf
[i
]) >> 4];
1721 s
[j
+2] = hex
[((unsigned char)buf
[i
]) & 0xF];
1728 char *binary_string(char *buf
, int len
)
1732 const char *hex
= "0123456789ABCDEF";
1733 s
= (char *)SMB_MALLOC(len
* 2 + 1);
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];
1745 Just a typesafety wrapper for snprintf into a pstring.
1748 int pstr_sprintf(pstring s
, const char *fmt
, ...)
1754 ret
= vsnprintf(s
, PSTRING_LEN
, fmt
, ap
);
1761 Just a typesafety wrapper for snprintf into a fstring.
1764 int fstr_sprintf(fstring s
, const char *fmt
, ...)
1770 ret
= vsnprintf(s
, FSTRING_LEN
, fmt
, ap
);
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
;
1789 if (!string
|| !*string
)
1792 s
= talloc_strdup(mem_ctx
, string
);
1794 s
= SMB_STRDUP(string
);
1797 DEBUG(0,("str_list_make: Unable to allocate memory"));
1800 if (!sep
) sep
= LIST_SEP
;
1806 while (next_token(&str
, tok
, sep
, sizeof(tok
))) {
1808 lsize
+= S_LIST_ABS
;
1810 rlist
= TALLOC_REALLOC_ARRAY(mem_ctx
, list
, char *, lsize
+1);
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);
1817 DEBUG(0,("str_list_make: Unable to allocate memory"));
1818 str_list_free(&list
);
1828 memset (&list
[num
], 0, ((sizeof(char**)) * (S_LIST_ABS
+1)));
1832 list
[num
] = talloc_strdup(mem_ctx
, tok
);
1834 list
[num
] = SMB_STRDUP(tok
);
1838 DEBUG(0,("str_list_make: Unable to allocate memory"));
1839 str_list_free(&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
;
1884 lsize
+= S_LIST_ABS
;
1885 rlist
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list
, char *, lsize
+1);
1887 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1888 str_list_free(&list
);
1893 memset (&list
[num
], 0, ((sizeof(char **)) * (S_LIST_ABS
+1)));
1896 list
[num
] = SMB_STRDUP(src
[num
]);
1898 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1899 str_list_free(&list
);
1911 * Return true if all the elements of the list match exactly.
1913 BOOL
str_list_compare(char **list1
, char **list2
)
1917 if (!list1
|| !list2
)
1918 return (list1
== list2
);
1920 for (num
= 0; list1
[num
]; num
++) {
1923 if (!strcsequal(list1
[num
], list2
[num
]))
1927 return False
; /* if list2 has more elements than list1 fail */
1932 static void str_list_free_internal(TALLOC_CTX
*mem_ctx
, char ***list
)
1936 if (!list
|| !*list
)
1939 for(; *tlist
; tlist
++) {
1941 TALLOC_FREE(*tlist
);
1947 TALLOC_FREE(*tlist
);
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
)
1973 /* count the number of list members */
1975 for ( i
=0; *list
; i
++, list
++ );
1980 /******************************************************************************
1981 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1983 *****************************************************************************/
1985 BOOL
str_list_sub_basic( char **list
, const char *smb_name
,
1986 const char *domain_name
)
1992 tmpstr
= alloc_sub_basic(smb_name
, domain_name
, s
);
1994 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2007 /******************************************************************************
2008 substritute a specific pattern in a string list
2009 *****************************************************************************/
2011 BOOL
str_list_substitute(char **list
, const char *pattern
, const char *insert
)
2014 ssize_t ls
, lp
, li
, ld
, i
, d
;
2023 lp
= (ssize_t
)strlen(pattern
);
2024 li
= (ssize_t
)strlen(insert
);
2029 ls
= (ssize_t
)strlen(s
);
2031 while ((p
= strstr_m(s
, pattern
))) {
2035 t
= (char *) SMB_MALLOC(ls
+ld
+1);
2037 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2040 memcpy(t
, *list
, d
);
2041 memcpy(t
+d
+li
, p
+lp
, ls
-d
-lp
+1);
2048 for (i
= 0; i
< li
; i
++) {
2049 switch (insert
[i
]) {
2061 t
[d
+i
] = insert
[i
];
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 */
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
);
2103 asprintf(&new_ipstr
, "%s:%d", inet_ntoa(service
->ip
), service
->port
);
2105 *ipstr_list
= new_ipstr
;
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
)
2124 /* arguments checking */
2125 if (!ip_list
|| !ipstr_list
) return 0;
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
)
2154 if (!ipstr_list
|| !ip_list
)
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
));
2164 next_token(&ipstr_list
, token_str
, IPSTR_LIST_SEP
, FSTRING_LEN
) && i
<count
;
2167 struct in_addr addr
;
2169 char *p
= strchr(token_str
, ':');
2176 /* convert single token to ip address */
2177 if ( (addr
.s_addr
= inet_addr(token_str
)) == INADDR_NONE
)
2180 (*ip_list
)[i
].ip
= addr
;
2181 (*ip_list
)[i
].port
= port
;
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
)
2208 while (p
&& *p
&& (p
=strchr_m(p
,'%'))) {
2212 if (c1
>= '0' && c1
<= '9')
2214 else if (c1
>= 'A' && c1
<= 'F')
2216 else if (c1
>= 'a' && c1
<= 'f')
2218 else {p
++; continue;}
2220 if (c2
>= '0' && c2
<= '9')
2222 else if (c2
>= 'A' && c2
<= 'F')
2224 else if (c2
>= 'a' && c2
<= 'f')
2226 else {p
++; continue;}
2230 memmove(p
+1, p
+3, strlen(p
+3)+1);
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
;
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
));
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;
2266 if ((n
> 0) && (*s
== '=')) {
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';
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
)
2303 size_t out_cnt
, len
, output_len
;
2306 if (!data
.length
|| !data
.data
)
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
++);
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];
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
++] = '=';
2337 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
2338 result
[out_cnt
++] = '=';
2341 result
[out_cnt
] = '\0'; /* terminate */
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
;
2359 while (*p
&& isspace(*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 */
2368 while (*p
&& isdigit(*p
))
2376 /* Convert a size specification to a count of bytes. We accept the following
2378 * bytes if there is no suffix
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
)
2392 if (str
== NULL
|| *str
== '\0') {
2396 #ifdef HAVE_STRTOULL
2397 if (sizeof(SMB_OFF_T
) == 8) {
2398 lval
= strtoull(str
, &end
, 10 /* base */);
2400 lval
= strtoul(str
, &end
, 10 /* base */);
2403 lval
= strtoul(str
, &end
, 10 /* base */);
2406 if (end
== NULL
|| end
== str
) {
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 *
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 *
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
) {
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
);
2451 new_len
+= strlen(*left
);
2452 *left
= (char *)SMB_REALLOC(*left
, new_len
);
2455 if (*left
== NULL
) {
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
,
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
)) {
2475 (*strings
)[*num
] = dup_str
;
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
2484 void sprintf_append(TALLOC_CTX
*mem_ctx
, char **string
, ssize_t
*len
,
2485 size_t *bufsize
, const char *fmt
, ...)
2492 /* len<0 is an internal marker that something failed */
2496 if (*string
== NULL
) {
2500 *string
= TALLOC_ARRAY(mem_ctx
, char, *bufsize
);
2501 if (*string
== NULL
)
2506 ret
= vasprintf(&newstr
, fmt
, ap
);
2514 while ((*len
)+ret
>= *bufsize
) {
2517 if (*bufsize
>= (1024*1024*256))
2522 *string
= TALLOC_REALLOC_ARRAY(mem_ctx
, *string
, char,
2524 if (*string
== NULL
) {
2529 StrnCpy((*string
)+(*len
), newstr
, ret
);
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
;
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"));
2561 memcpy(temp3
, temp1
+1, len
-1);
2562 temp3
[len
-1] = '\0';
2566 /********************************************************************
2567 Check a string for any occurrences of a specified list of invalid
2569 ********************************************************************/
2571 BOOL
validate_net_name( const char *name
, const char *invalid_chars
, int max_len
)
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
] ) ) {
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
)
2595 len
= strnlen(src
, n
);
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
)
2611 for (len
= 0; SVAL(buf
,len
); 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
)
2625 for (len
= 0; (len
+2 < n
) && SVAL(src
, len
); len
+= 2) ;
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);
2647 BOOL in_s_quote
= False
;
2648 BOOL in_d_quote
= False
;
2649 BOOL next_escaped
= False
;
2657 codepoint_t c
= next_codepoint(src
, &c_size
);
2659 if (c
== INVALID_CODEPOINT
) {
2665 memcpy(dest
, src
, c_size
);
2668 next_escaped
= False
;
2673 * Deal with backslash escaped state.
2674 * This only lasts for one character.
2679 next_escaped
= False
;
2684 * Deal with single quote state. The
2685 * only thing we care about is exiting
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).
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 \.
2717 c
= next_codepoint(&src
[1], &c_size
);
2718 if (c
== INVALID_CODEPOINT
) {
2724 * Don't escape the next char.
2733 if (nextchar
&& strchr(INSIDE_DQUOTE_LIST
, (int)nextchar
)) {
2734 next_escaped
= True
;
2741 /* Exit double quote state. */
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
)) {
2761 * From here to the end of the loop we're
2762 * not in the single or double quote state.
2766 /* Next character must be escaped. */
2767 next_escaped
= True
;
2773 /* Go into single quote state. */
2780 /* Go into double quote state. */
2786 /* Check if we need to escape the character. */
2788 if (!strchr(INCLUDE_LIST
, (int)*src
)) {