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
397 void string_replace( pstring s
, char oldc
, char newc
)
401 /* this is quite a common operation, so we want it to be
402 fast. We optimise for the ascii case, knowing that all our
403 supported multi-byte character sets are ascii-compatible
404 (ie. they match for the first 128 chars) */
406 for (p
= s
; *p
; p
++) {
407 if (*p
& 0x80) /* mb string - slow path. */
416 /* Slow (mb) path. */
417 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
418 /* With compose characters we must restart from the beginning. JRA. */
421 push_ucs2(NULL
, tmpbuf
, p
, sizeof(tmpbuf
), STR_TERMINATE
);
422 string_replace_w(tmpbuf
, UCS2_CHAR(oldc
), UCS2_CHAR(newc
));
423 pull_ucs2(NULL
, p
, tmpbuf
, -1, sizeof(tmpbuf
), STR_TERMINATE
);
427 * Skip past some strings in a buffer - old version - no checks.
430 char *push_skip_string(char *buf
)
432 buf
+= strlen(buf
) + 1;
437 Skip past a string in a buffer. Buffer may not be
438 null terminated. end_ptr points to the first byte after
439 then end of the buffer.
442 char *skip_string(const char *base
, size_t len
, char *buf
)
444 const char *end_ptr
= base
+ len
;
446 if (end_ptr
< base
|| !base
|| !buf
|| buf
>= end_ptr
) {
450 /* Skip the string */
453 if (buf
>= end_ptr
) {
463 Count the number of characters in a string. Normally this will
464 be the same as the number of bytes in a string for single byte strings,
465 but will be different for multibyte.
468 size_t str_charnum(const char *s
)
470 uint16 tmpbuf2
[sizeof(pstring
)];
471 push_ucs2(NULL
, tmpbuf2
,s
, sizeof(tmpbuf2
), STR_TERMINATE
);
472 return strlen_w(tmpbuf2
);
476 Count the number of characters in a string. Normally this will
477 be the same as the number of bytes in a string for single byte strings,
478 but will be different for multibyte.
481 size_t str_ascii_charnum(const char *s
)
484 push_ascii(tmpbuf2
, s
, sizeof(tmpbuf2
), STR_TERMINATE
);
485 return strlen(tmpbuf2
);
488 BOOL
trim_char(char *s
,char cfront
,char cback
)
494 /* Ignore null or empty strings. */
495 if (!s
|| (s
[0] == '\0'))
499 while (*fp
&& *fp
== cfront
)
502 /* We ate the string. */
510 ep
= fp
+ strlen(fp
) - 1;
512 /* Attempt ascii only. Bail for mb strings. */
513 while ((ep
>= fp
) && (*ep
== cback
)) {
515 if ((ep
> fp
) && (((unsigned char)ep
[-1]) & 0x80)) {
516 /* Could be mb... bail back to tim_string. */
524 return trim_string(s
, cfront
? fs
: NULL
, bs
);
530 /* We ate the string. */
537 memmove(s
, fp
, ep
-fp
+2);
542 Trim the specified elements off the front and back of a string.
545 BOOL
trim_string(char *s
,const char *front
,const char *back
)
552 /* Ignore null or empty strings. */
553 if (!s
|| (s
[0] == '\0'))
556 front_len
= front
? strlen(front
) : 0;
557 back_len
= back
? strlen(back
) : 0;
562 while (len
&& strncmp(s
, front
, front_len
)==0) {
563 /* Must use memmove here as src & dest can
564 * easily overlap. Found by valgrind. JRA. */
565 memmove(s
, s
+front_len
, (len
-front_len
)+1);
572 while ((len
>= back_len
) && strncmp(s
+len
-back_len
,back
,back_len
)==0) {
573 s
[len
-back_len
]='\0';
582 Does a string have any uppercase chars in it?
585 BOOL
strhasupper(const char *s
)
588 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
589 for(ptr
=tmpbuf
;*ptr
;ptr
++)
596 Does a string have any lowercase chars in it?
599 BOOL
strhaslower(const char *s
)
602 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
603 for(ptr
=tmpbuf
;*ptr
;ptr
++)
610 Find the number of 'c' chars in a string
613 size_t count_chars(const char *s
,char c
)
617 smb_ucs2_t
*alloc_tmpbuf
= NULL
;
619 if (push_ucs2_allocate(&alloc_tmpbuf
, s
) == (size_t)-1) {
623 for(count
=0,ptr
=alloc_tmpbuf
;*ptr
;ptr
++)
624 if(*ptr
==UCS2_CHAR(c
))
627 SAFE_FREE(alloc_tmpbuf
);
632 Safe string copy into a known length string. maxlength does not
633 include the terminating zero.
636 char *safe_strcpy_fn(const char *fn
, int line
, char *dest
,const char *src
, size_t maxlength
)
641 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn
, line
));
646 clobber_region(fn
,line
,dest
, maxlength
+1);
654 len
= strnlen(src
, maxlength
+1);
656 if (len
> maxlength
) {
657 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
658 (unsigned long)(len
-maxlength
), (unsigned long)len
,
659 (unsigned long)maxlength
, src
));
663 memmove(dest
, src
, len
);
669 Safe string cat into a string. maxlength does not
670 include the terminating zero.
672 char *safe_strcat_fn(const char *fn
, int line
, char *dest
, const char *src
, size_t maxlength
)
674 size_t src_len
, dest_len
;
677 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn
, line
));
684 src_len
= strnlen(src
, maxlength
+ 1);
685 dest_len
= strnlen(dest
, maxlength
+ 1);
688 clobber_region(fn
, line
, dest
+ dest_len
, maxlength
+ 1 - dest_len
);
691 if (src_len
+ dest_len
> maxlength
) {
692 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
693 (int)(src_len
+ dest_len
- maxlength
), src
));
694 if (maxlength
> dest_len
) {
695 memcpy(&dest
[dest_len
], src
, maxlength
- dest_len
);
701 memcpy(&dest
[dest_len
], src
, src_len
);
702 dest
[dest_len
+ src_len
] = 0;
707 Paranoid strcpy into a buffer of given length (includes terminating
708 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
709 and replaces with '_'. Deliberately does *NOT* check for multibyte
710 characters. Don't change it !
712 char *alpha_strcpy_fn(const char *fn
, int line
, char *dest
, const char *src
, const char *other_safe_chars
, size_t maxlength
)
717 clobber_region(fn
, line
, dest
, maxlength
);
721 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn
, line
));
731 if (len
>= maxlength
)
734 if (!other_safe_chars
)
735 other_safe_chars
= "";
737 for(i
= 0; i
< len
; i
++) {
738 int val
= (src
[i
] & 0xff);
739 if (isupper_ascii(val
) || islower_ascii(val
) || isdigit(val
) || strchr_m(other_safe_chars
, val
))
751 Like strncpy but always null terminates. Make sure there is room!
752 The variable n should always be one less than the available size.
754 char *StrnCpy_fn(const char *fn
, int line
,char *dest
,const char *src
,size_t n
)
759 clobber_region(fn
, line
, dest
, n
+1);
763 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn
, line
));
772 while (n
-- && (*d
= *src
)) {
783 Like strncpy but copies up to the character marker. always null terminates.
784 returns a pointer to the character marker in the source string (src).
787 static char *strncpyn(char *dest
, const char *src
, size_t n
, char c
)
793 clobber_region(dest
, n
+1);
795 p
= strchr_m(src
, c
);
797 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c
));
801 str_len
= PTR_DIFF(p
, src
);
802 strncpy(dest
, src
, MIN(n
, str_len
));
803 dest
[str_len
] = '\0';
810 Routine to get hex characters and turn them into a 16 byte array.
811 the array can be variable length, and any non-hex-numeric
812 characters are skipped. "0xnn" or "0Xnn" is specially catered
815 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
819 size_t strhex_to_str(char *p
, size_t len
, const char *strhex
)
822 size_t num_chars
= 0;
823 unsigned char lonybble
, hinybble
;
824 const char *hexchars
= "0123456789ABCDEF";
825 char *p1
= NULL
, *p2
= NULL
;
827 for (i
= 0; i
< len
&& strhex
[i
] != 0; i
++) {
828 if (strnequal(hexchars
, "0x", 2)) {
829 i
++; /* skip two chars */
833 if (!(p1
= strchr_m(hexchars
, toupper_ascii(strhex
[i
]))))
836 i
++; /* next hex digit */
838 if (!(p2
= strchr_m(hexchars
, toupper_ascii(strhex
[i
]))))
841 /* get the two nybbles */
842 hinybble
= PTR_DIFF(p1
, hexchars
);
843 lonybble
= PTR_DIFF(p2
, hexchars
);
845 p
[num_chars
] = (hinybble
<< 4) | lonybble
;
854 DATA_BLOB
strhex_to_data_blob(TALLOC_CTX
*mem_ctx
, const char *strhex
)
859 ret_blob
= data_blob_talloc(mem_ctx
, NULL
, strlen(strhex
)/2+1);
861 ret_blob
= data_blob(NULL
, strlen(strhex
)/2+1);
863 ret_blob
.length
= strhex_to_str((char*)ret_blob
.data
,
871 * Routine to print a buffer as HEX digits, into an allocated string.
874 char *hex_encode(TALLOC_CTX
*mem_ctx
, const unsigned char *buff_in
, size_t len
)
879 hex_buffer
= TALLOC_ARRAY(mem_ctx
, char, (len
*2)+1);
881 for (i
= 0; i
< len
; i
++)
882 slprintf(&hex_buffer
[i
*2], 3, "%02X", buff_in
[i
]);
888 Check if a string is part of a list.
891 BOOL
in_list(const char *s
, const char *list
, BOOL casesensitive
)
899 while (next_token(&p
,tok
,LIST_SEP
,sizeof(tok
))) {
901 if (strcmp(tok
,s
) == 0)
904 if (StrCaseCmp(tok
,s
) == 0)
911 /* this is used to prevent lots of mallocs of size 1 */
912 static const char *null_string
= "";
915 Set a string value, allocing the space for the string
918 static BOOL
string_init(char **dest
,const char *src
)
928 *dest
= CONST_DISCARD(char*, null_string
);
930 (*dest
) = SMB_STRDUP(src
);
931 if ((*dest
) == NULL
) {
932 DEBUG(0,("Out of memory in string_init\n"));
943 void string_free(char **s
)
947 if (*s
== null_string
)
953 Set a string value, deallocating any existing space, and allocing the space
957 BOOL
string_set(char **dest
,const char *src
)
960 return(string_init(dest
,src
));
964 Substitute a string for a pattern in another string. Make sure there is
967 This routine looks for pattern in s and replaces it with
968 insert. It may do multiple replacements or just one.
970 Any of " ; ' $ or ` in the insert string are replaced with _
971 if len==0 then the string cannot be extended. This is different from the old
972 use of len==0 which was for no length checks to be done.
975 void string_sub2(char *s
,const char *pattern
, const char *insert
, size_t len
,
976 BOOL remove_unsafe_characters
, BOOL replace_once
, BOOL allow_trailing_dollar
)
981 if (!insert
|| !pattern
|| !*pattern
|| !s
)
984 ls
= (ssize_t
)strlen(s
);
985 lp
= (ssize_t
)strlen(pattern
);
986 li
= (ssize_t
)strlen(insert
);
989 len
= ls
+ 1; /* len is number of *bytes* */
991 while (lp
<= ls
&& (p
= strstr_m(s
,pattern
))) {
992 if (ls
+ (li
-lp
) >= len
) {
993 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
994 (int)(ls
+ (li
-lp
) - len
),
999 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1001 for (i
=0;i
<li
;i
++) {
1002 switch (insert
[i
]) {
1008 /* allow a trailing $ (as in machine accounts) */
1009 if (allow_trailing_dollar
&& (i
== li
- 1 )) {
1016 if ( remove_unsafe_characters
) {
1018 /* yes this break should be here since we want to
1019 fall throw if not replacing unsafe chars */
1034 void string_sub_once(char *s
, const char *pattern
, const char *insert
, size_t len
)
1036 string_sub2( s
, pattern
, insert
, len
, True
, True
, False
);
1039 void string_sub(char *s
,const char *pattern
, const char *insert
, size_t len
)
1041 string_sub2( s
, pattern
, insert
, len
, True
, False
, False
);
1044 void fstring_sub(char *s
,const char *pattern
,const char *insert
)
1046 string_sub(s
, pattern
, insert
, sizeof(fstring
));
1049 void pstring_sub(char *s
,const char *pattern
,const char *insert
)
1051 string_sub(s
, pattern
, insert
, sizeof(pstring
));
1055 Similar to string_sub, but it will accept only allocated strings
1056 and may realloc them so pay attention at what you pass on no
1057 pointers inside strings, no pstrings or const may be passed
1061 char *realloc_string_sub(char *string
, const char *pattern
,
1066 ssize_t ls
,lp
,li
,ld
, i
;
1068 if (!insert
|| !pattern
|| !*pattern
|| !string
|| !*string
)
1073 in
= SMB_STRDUP(insert
);
1075 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1078 ls
= (ssize_t
)strlen(s
);
1079 lp
= (ssize_t
)strlen(pattern
);
1080 li
= (ssize_t
)strlen(insert
);
1082 for (i
=0;i
<li
;i
++) {
1099 while ((p
= strstr_m(s
,pattern
))) {
1101 int offset
= PTR_DIFF(s
,string
);
1102 string
= (char *)SMB_REALLOC(string
, ls
+ ld
+ 1);
1104 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1108 p
= string
+ offset
+ (p
- s
);
1111 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1121 /* Same as string_sub, but returns a talloc'ed string */
1123 char *talloc_string_sub(TALLOC_CTX
*mem_ctx
, const char *src
,
1124 const char *pattern
, const char *insert
)
1129 ssize_t ls
,lp
,li
,ld
, i
;
1131 if (!insert
|| !pattern
|| !*pattern
|| !src
|| !*src
)
1134 string
= talloc_strdup(mem_ctx
, src
);
1135 if (string
== NULL
) {
1136 DEBUG(0, ("talloc_strdup failed\n"));
1142 in
= SMB_STRDUP(insert
);
1144 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1147 ls
= (ssize_t
)strlen(s
);
1148 lp
= (ssize_t
)strlen(pattern
);
1149 li
= (ssize_t
)strlen(insert
);
1151 for (i
=0;i
<li
;i
++) {
1168 while ((p
= strstr_m(s
,pattern
))) {
1170 int offset
= PTR_DIFF(s
,string
);
1171 string
= (char *)TALLOC_REALLOC(mem_ctx
, string
,
1174 DEBUG(0, ("talloc_string_sub: out of "
1179 p
= string
+ offset
+ (p
- s
);
1182 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1193 Similar to string_sub() but allows for any character to be substituted.
1195 if len==0 then the string cannot be extended. This is different from the old
1196 use of len==0 which was for no length checks to be done.
1199 void all_string_sub(char *s
,const char *pattern
,const char *insert
, size_t len
)
1204 if (!insert
|| !pattern
|| !s
)
1207 ls
= (ssize_t
)strlen(s
);
1208 lp
= (ssize_t
)strlen(pattern
);
1209 li
= (ssize_t
)strlen(insert
);
1215 len
= ls
+ 1; /* len is number of *bytes* */
1217 while (lp
<= ls
&& (p
= strstr_m(s
,pattern
))) {
1218 if (ls
+ (li
-lp
) >= len
) {
1219 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1220 (int)(ls
+ (li
-lp
) - len
),
1221 pattern
, (int)len
));
1225 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
1227 memcpy(p
, insert
, li
);
1234 Similar to all_string_sub but for unicode strings.
1235 Return a new allocated unicode string.
1236 similar to string_sub() but allows for any character to be substituted.
1240 static smb_ucs2_t
*all_string_sub_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*pattern
,
1241 const smb_ucs2_t
*insert
)
1244 const smb_ucs2_t
*sp
;
1245 size_t lr
, lp
, li
, lt
;
1247 if (!insert
|| !pattern
|| !*pattern
|| !s
)
1250 lt
= (size_t)strlen_w(s
);
1251 lp
= (size_t)strlen_w(pattern
);
1252 li
= (size_t)strlen_w(insert
);
1255 const smb_ucs2_t
*st
= s
;
1257 while ((sp
= strstr_w(st
, pattern
))) {
1263 r
= rp
= SMB_MALLOC_ARRAY(smb_ucs2_t
, lt
+ 1);
1265 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1269 while ((sp
= strstr_w(s
, pattern
))) {
1270 memcpy(rp
, s
, (sp
- s
));
1271 rp
+= ((sp
- s
) / sizeof(smb_ucs2_t
));
1272 memcpy(rp
, insert
, (li
* sizeof(smb_ucs2_t
)));
1276 lr
= ((rp
- r
) / sizeof(smb_ucs2_t
));
1278 memcpy(rp
, s
, ((lt
- lr
) * sizeof(smb_ucs2_t
)));
1286 smb_ucs2_t
*all_string_sub_wa(smb_ucs2_t
*s
, const char *pattern
,
1291 if (!insert
|| !pattern
|| !s
)
1293 push_ucs2(NULL
, p
, pattern
, sizeof(wpstring
) - 1, STR_TERMINATE
);
1294 push_ucs2(NULL
, i
, insert
, sizeof(wpstring
) - 1, STR_TERMINATE
);
1295 return all_string_sub_w(s
, p
, i
);
1300 Splits out the front and back at a separator.
1303 static void split_at_last_component(char *path
, char *front
, char sep
, char *back
)
1305 char *p
= strrchr_m(path
, sep
);
1311 pstrcpy(front
, path
);
1325 Write an octal as a string.
1328 const char *octal_string(int i
)
1330 static char ret
[64];
1333 slprintf(ret
, sizeof(ret
)-1, "0%o", i
);
1339 Truncate a string at a specified length.
1342 char *string_truncate(char *s
, unsigned int length
)
1344 if (s
&& strlen(s
) > length
)
1350 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1351 We convert via ucs2 for now.
1354 char *strchr_m(const char *src
, char c
)
1361 /* characters below 0x3F are guaranteed to not appear in
1362 non-initial position in multi-byte charsets */
1363 if ((c
& 0xC0) == 0) {
1364 return strchr(src
, c
);
1367 /* this is quite a common operation, so we want it to be
1368 fast. We optimise for the ascii case, knowing that all our
1369 supported multi-byte character sets are ascii-compatible
1370 (ie. they match for the first 128 chars) */
1372 for (s
= src
; *s
&& !(((unsigned char)s
[0]) & 0x80); s
++) {
1380 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1381 /* With compose characters we must restart from the beginning. JRA. */
1385 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1386 p
= strchr_w(ws
, UCS2_CHAR(c
));
1390 pull_ucs2_pstring(s2
, ws
);
1391 return (char *)(s
+strlen(s2
));
1394 char *strrchr_m(const char *s
, char c
)
1396 /* characters below 0x3F are guaranteed to not appear in
1397 non-initial position in multi-byte charsets */
1398 if ((c
& 0xC0) == 0) {
1399 return strrchr(s
, c
);
1402 /* this is quite a common operation, so we want it to be
1403 fast. We optimise for the ascii case, knowing that all our
1404 supported multi-byte character sets are ascii-compatible
1405 (ie. they match for the first 128 chars). Also, in Samba
1406 we only search for ascii characters in 'c' and that
1407 in all mb character sets with a compound character
1408 containing c, if 'c' is not a match at position
1409 p, then p[-1] > 0x7f. JRA. */
1412 size_t len
= strlen(s
);
1414 BOOL got_mb
= False
;
1421 /* Could be a match. Part of a multibyte ? */
1422 if ((cp
> s
) && (((unsigned char)cp
[-1]) & 0x80)) {
1423 /* Yep - go slow :-( */
1427 /* No - we have a match ! */
1430 } while (cp
-- != s
);
1435 /* String contained a non-ascii char. Slow path. */
1441 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1442 p
= strrchr_w(ws
, UCS2_CHAR(c
));
1446 pull_ucs2_pstring(s2
, ws
);
1447 return (char *)(s
+strlen(s2
));
1451 /***********************************************************************
1452 Return the equivalent of doing strrchr 'n' times - always going
1454 ***********************************************************************/
1456 char *strnrchr_m(const char *s
, char c
, unsigned int n
)
1462 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1463 p
= strnrchr_w(ws
, UCS2_CHAR(c
), n
);
1467 pull_ucs2_pstring(s2
, ws
);
1468 return (char *)(s
+strlen(s2
));
1471 /***********************************************************************
1472 strstr_m - We convert via ucs2 for now.
1473 ***********************************************************************/
1475 char *strstr_m(const char *src
, const char *findstr
)
1478 smb_ucs2_t
*src_w
, *find_w
;
1483 size_t findstr_len
= 0;
1485 /* for correctness */
1490 /* Samba does single character findstr calls a *lot*. */
1491 if (findstr
[1] == '\0')
1492 return strchr_m(src
, *findstr
);
1494 /* We optimise for the ascii case, knowing that all our
1495 supported multi-byte character sets are ascii-compatible
1496 (ie. they match for the first 128 chars) */
1498 for (s
= src
; *s
&& !(((unsigned char)s
[0]) & 0x80); s
++) {
1499 if (*s
== *findstr
) {
1501 findstr_len
= strlen(findstr
);
1503 if (strncmp(s
, findstr
, findstr_len
) == 0) {
1512 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1513 /* 'make check' fails unless we do this */
1515 /* With compose characters we must restart from the beginning. JRA. */
1519 if (push_ucs2_allocate(&src_w
, src
) == (size_t)-1) {
1520 DEBUG(0,("strstr_m: src malloc fail\n"));
1524 if (push_ucs2_allocate(&find_w
, findstr
) == (size_t)-1) {
1526 DEBUG(0,("strstr_m: find malloc fail\n"));
1530 p
= strstr_w(src_w
, find_w
);
1539 if (pull_ucs2_allocate(&s2
, src_w
) == (size_t)-1) {
1542 DEBUG(0,("strstr_m: dest malloc fail\n"));
1545 retp
= (char *)(s
+strlen(s2
));
1553 Convert a string to lower case.
1556 void strlower_m(char *s
)
1561 /* this is quite a common operation, so we want it to be
1562 fast. We optimise for the ascii case, knowing that all our
1563 supported multi-byte character sets are ascii-compatible
1564 (ie. they match for the first 128 chars) */
1566 while (*s
&& !(((unsigned char)s
[0]) & 0x80)) {
1567 *s
= tolower_ascii((unsigned char)*s
);
1574 /* I assume that lowercased string takes the same number of bytes
1575 * as source string even in UTF-8 encoding. (VIV) */
1576 len
= strlen(s
) + 1;
1579 unix_strlower(s
,len
,s
,len
);
1580 /* Catch mb conversion errors that may not terminate. */
1587 Convert a string to upper case.
1590 void strupper_m(char *s
)
1595 /* this is quite a common operation, so we want it to be
1596 fast. We optimise for the ascii case, knowing that all our
1597 supported multi-byte character sets are ascii-compatible
1598 (ie. they match for the first 128 chars) */
1600 while (*s
&& !(((unsigned char)s
[0]) & 0x80)) {
1601 *s
= toupper_ascii((unsigned char)*s
);
1608 /* I assume that lowercased string takes the same number of bytes
1609 * as source string even in multibyte encoding. (VIV) */
1610 len
= strlen(s
) + 1;
1613 unix_strupper(s
,len
,s
,len
);
1614 /* Catch mb conversion errors that may not terminate. */
1621 Count the number of UCS2 characters in a string. Normally this will
1622 be the same as the number of bytes in a string for single byte strings,
1623 but will be different for multibyte.
1626 size_t strlen_m(const char *s
)
1634 while (*s
&& !(((uint8_t)*s
) & 0x80)) {
1645 codepoint_t c
= next_codepoint(s
, &c_size
);
1647 /* Unicode char fits into 16 bits. */
1650 /* Double-width unicode char - 32 bits. */
1660 Count the number of UCS2 characters in a string including the null
1664 size_t strlen_m_term(const char *s
)
1669 return strlen_m(s
) + 1;
1673 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1674 * if a string is there, include the terminator.
1677 size_t strlen_m_term_null(const char *s
)
1691 Return a RFC2254 binary string representation of a buffer.
1692 Used in LDAP filters.
1696 char *binary_string_rfc2254(char *buf
, int len
)
1700 const char *hex
= "0123456789ABCDEF";
1701 s
= (char *)SMB_MALLOC(len
* 3 + 1);
1704 for (j
=i
=0;i
<len
;i
++) {
1706 s
[j
+1] = hex
[((unsigned char)buf
[i
]) >> 4];
1707 s
[j
+2] = hex
[((unsigned char)buf
[i
]) & 0xF];
1714 char *binary_string(char *buf
, int len
)
1718 const char *hex
= "0123456789ABCDEF";
1719 s
= (char *)SMB_MALLOC(len
* 2 + 1);
1722 for (j
=i
=0;i
<len
;i
++) {
1723 s
[j
] = hex
[((unsigned char)buf
[i
]) >> 4];
1724 s
[j
+1] = hex
[((unsigned char)buf
[i
]) & 0xF];
1731 Just a typesafety wrapper for snprintf into a pstring.
1734 int pstr_sprintf(pstring s
, const char *fmt
, ...)
1740 ret
= vsnprintf(s
, PSTRING_LEN
, fmt
, ap
);
1747 Just a typesafety wrapper for snprintf into a fstring.
1750 int fstr_sprintf(fstring s
, const char *fmt
, ...)
1756 ret
= vsnprintf(s
, FSTRING_LEN
, fmt
, ap
);
1762 List of Strings manipulation functions
1765 #define S_LIST_ABS 16 /* List Allocation Block Size */
1767 static char **str_list_make_internal(TALLOC_CTX
*mem_ctx
, const char *string
, const char *sep
)
1769 char **list
, **rlist
;
1775 if (!string
|| !*string
)
1778 s
= talloc_strdup(mem_ctx
, string
);
1780 s
= SMB_STRDUP(string
);
1783 DEBUG(0,("str_list_make: Unable to allocate memory"));
1786 if (!sep
) sep
= LIST_SEP
;
1792 while (next_token(&str
, tok
, sep
, sizeof(tok
))) {
1794 lsize
+= S_LIST_ABS
;
1796 rlist
= TALLOC_REALLOC_ARRAY(mem_ctx
, list
, char *, lsize
+1);
1798 /* We need to keep the old list on error so we can free the elements
1799 if the realloc fails. */
1800 rlist
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list
, char *, lsize
+1);
1803 DEBUG(0,("str_list_make: Unable to allocate memory"));
1804 str_list_free(&list
);
1814 memset (&list
[num
], 0, ((sizeof(char**)) * (S_LIST_ABS
+1)));
1818 list
[num
] = talloc_strdup(mem_ctx
, tok
);
1820 list
[num
] = SMB_STRDUP(tok
);
1824 DEBUG(0,("str_list_make: Unable to allocate memory"));
1825 str_list_free(&list
);
1846 char **str_list_make_talloc(TALLOC_CTX
*mem_ctx
, const char *string
, const char *sep
)
1848 return str_list_make_internal(mem_ctx
, string
, sep
);
1851 char **str_list_make(const char *string
, const char *sep
)
1853 return str_list_make_internal(NULL
, string
, sep
);
1856 BOOL
str_list_copy(char ***dest
, const char **src
)
1858 char **list
, **rlist
;
1870 lsize
+= S_LIST_ABS
;
1871 rlist
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list
, char *, lsize
+1);
1873 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1874 str_list_free(&list
);
1879 memset (&list
[num
], 0, ((sizeof(char **)) * (S_LIST_ABS
+1)));
1882 list
[num
] = SMB_STRDUP(src
[num
]);
1884 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1885 str_list_free(&list
);
1897 * Return true if all the elements of the list match exactly.
1899 BOOL
str_list_compare(char **list1
, char **list2
)
1903 if (!list1
|| !list2
)
1904 return (list1
== list2
);
1906 for (num
= 0; list1
[num
]; num
++) {
1909 if (!strcsequal(list1
[num
], list2
[num
]))
1913 return False
; /* if list2 has more elements than list1 fail */
1918 static void str_list_free_internal(TALLOC_CTX
*mem_ctx
, char ***list
)
1922 if (!list
|| !*list
)
1925 for(; *tlist
; tlist
++) {
1927 TALLOC_FREE(*tlist
);
1933 TALLOC_FREE(*tlist
);
1939 void str_list_free_talloc(TALLOC_CTX
*mem_ctx
, char ***list
)
1941 str_list_free_internal(mem_ctx
, list
);
1944 void str_list_free(char ***list
)
1946 str_list_free_internal(NULL
, list
);
1949 /******************************************************************************
1950 *****************************************************************************/
1952 int str_list_count( const char **list
)
1959 /* count the number of list members */
1961 for ( i
=0; *list
; i
++, list
++ );
1966 /******************************************************************************
1967 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1969 *****************************************************************************/
1971 BOOL
str_list_sub_basic( char **list
, const char *smb_name
,
1972 const char *domain_name
)
1978 tmpstr
= alloc_sub_basic(smb_name
, domain_name
, s
);
1980 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1993 /******************************************************************************
1994 substritute a specific pattern in a string list
1995 *****************************************************************************/
1997 BOOL
str_list_substitute(char **list
, const char *pattern
, const char *insert
)
2000 ssize_t ls
, lp
, li
, ld
, i
, d
;
2009 lp
= (ssize_t
)strlen(pattern
);
2010 li
= (ssize_t
)strlen(insert
);
2015 ls
= (ssize_t
)strlen(s
);
2017 while ((p
= strstr_m(s
, pattern
))) {
2021 t
= (char *) SMB_MALLOC(ls
+ld
+1);
2023 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2026 memcpy(t
, *list
, d
);
2027 memcpy(t
+d
+li
, p
+lp
, ls
-d
-lp
+1);
2034 for (i
= 0; i
< li
; i
++) {
2035 switch (insert
[i
]) {
2047 t
[d
+i
] = insert
[i
];
2060 #define IPSTR_LIST_SEP ","
2061 #define IPSTR_LIST_CHAR ','
2064 * Add ip string representation to ipstr list. Used also
2065 * as part of @function ipstr_list_make
2067 * @param ipstr_list pointer to string containing ip list;
2068 * MUST BE already allocated and IS reallocated if necessary
2069 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2070 * as a result of reallocation)
2071 * @param ip IP address which is to be added to list
2072 * @return pointer to string appended with new ip and possibly
2073 * reallocated to new length
2076 char* ipstr_list_add(char** ipstr_list
, const struct ip_service
*service
)
2078 char* new_ipstr
= NULL
;
2080 /* arguments checking */
2081 if (!ipstr_list
|| !service
) return NULL
;
2083 /* attempt to convert ip to a string and append colon separator to it */
2085 asprintf(&new_ipstr
, "%s%s%s:%d", *ipstr_list
, IPSTR_LIST_SEP
,
2086 inet_ntoa(service
->ip
), service
->port
);
2087 SAFE_FREE(*ipstr_list
);
2089 asprintf(&new_ipstr
, "%s:%d", inet_ntoa(service
->ip
), service
->port
);
2091 *ipstr_list
= new_ipstr
;
2097 * Allocate and initialise an ipstr list using ip adresses
2098 * passed as arguments.
2100 * @param ipstr_list pointer to string meant to be allocated and set
2101 * @param ip_list array of ip addresses to place in the list
2102 * @param ip_count number of addresses stored in ip_list
2103 * @return pointer to allocated ip string
2106 char* ipstr_list_make(char** ipstr_list
, const struct ip_service
* ip_list
, int ip_count
)
2110 /* arguments checking */
2111 if (!ip_list
|| !ipstr_list
) return 0;
2115 /* process ip addresses given as arguments */
2116 for (i
= 0; i
< ip_count
; i
++)
2117 *ipstr_list
= ipstr_list_add(ipstr_list
, &ip_list
[i
]);
2119 return (*ipstr_list
);
2124 * Parse given ip string list into array of ip addresses
2125 * (as ip_service structures)
2126 * e.g. 192.168.1.100:389,192.168.1.78, ...
2128 * @param ipstr ip string list to be parsed
2129 * @param ip_list pointer to array of ip addresses which is
2130 * allocated by this function and must be freed by caller
2131 * @return number of succesfully parsed addresses
2134 int ipstr_list_parse(const char* ipstr_list
, struct ip_service
**ip_list
)
2140 if (!ipstr_list
|| !ip_list
)
2143 count
= count_chars(ipstr_list
, IPSTR_LIST_CHAR
) + 1;
2144 if ( (*ip_list
= SMB_MALLOC_ARRAY(struct ip_service
, count
)) == NULL
) {
2145 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count
));
2150 next_token(&ipstr_list
, token_str
, IPSTR_LIST_SEP
, FSTRING_LEN
) && i
<count
;
2153 struct in_addr addr
;
2155 char *p
= strchr(token_str
, ':');
2162 /* convert single token to ip address */
2163 if ( (addr
.s_addr
= inet_addr(token_str
)) == INADDR_NONE
)
2166 (*ip_list
)[i
].ip
= addr
;
2167 (*ip_list
)[i
].port
= port
;
2175 * Safely free ip string list
2177 * @param ipstr_list ip string list to be freed
2180 void ipstr_list_free(char* ipstr_list
)
2182 SAFE_FREE(ipstr_list
);
2187 Unescape a URL encoded string, in place.
2190 void rfc1738_unescape(char *buf
)
2194 while (p
&& *p
&& (p
=strchr_m(p
,'%'))) {
2198 if (c1
>= '0' && c1
<= '9')
2200 else if (c1
>= 'A' && c1
<= 'F')
2202 else if (c1
>= 'a' && c1
<= 'f')
2204 else {p
++; continue;}
2206 if (c2
>= '0' && c2
<= '9')
2208 else if (c2
>= 'A' && c2
<= 'F')
2210 else if (c2
>= 'a' && c2
<= 'f')
2212 else {p
++; continue;}
2216 memmove(p
+1, p
+3, strlen(p
+3)+1);
2221 static const char *b64
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2224 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2226 DATA_BLOB
base64_decode_data_blob(const char *s
)
2228 int bit_offset
, byte_offset
, idx
, i
, n
;
2229 DATA_BLOB decoded
= data_blob(s
, strlen(s
)+1);
2230 unsigned char *d
= decoded
.data
;
2235 while (*s
&& (p
=strchr_m(b64
,*s
))) {
2236 idx
= (int)(p
- b64
);
2237 byte_offset
= (i
*6)/8;
2238 bit_offset
= (i
*6)%8;
2239 d
[byte_offset
] &= ~((1<<(8-bit_offset
))-1);
2240 if (bit_offset
< 3) {
2241 d
[byte_offset
] |= (idx
<< (2-bit_offset
));
2244 d
[byte_offset
] |= (idx
>> (bit_offset
-2));
2245 d
[byte_offset
+1] = 0;
2246 d
[byte_offset
+1] |= (idx
<< (8-(bit_offset
-2))) & 0xFF;
2252 if ((n
> 0) && (*s
== '=')) {
2262 * Decode a base64 string in-place - wrapper for the above
2264 void base64_decode_inplace(char *s
)
2266 DATA_BLOB decoded
= base64_decode_data_blob(s
);
2268 if ( decoded
.length
!= 0 ) {
2269 memcpy(s
, decoded
.data
, decoded
.length
);
2271 /* null terminate */
2272 s
[decoded
.length
] = '\0';
2277 data_blob_free(&decoded
);
2281 * Encode a base64 string into a malloc()ed string caller to free.
2283 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2285 char * base64_encode_data_blob(DATA_BLOB data
)
2289 size_t out_cnt
, len
, output_len
;
2292 if (!data
.length
|| !data
.data
)
2297 output_len
= data
.length
* 2;
2298 result
= (char *)SMB_MALLOC(output_len
); /* get us plenty of space */
2300 while (len
-- && out_cnt
< (data
.length
* 2) - 5) {
2301 int c
= (unsigned char) *(data
.data
++);
2304 if (char_count
== 3) {
2305 result
[out_cnt
++] = b64
[bits
>> 18];
2306 result
[out_cnt
++] = b64
[(bits
>> 12) & 0x3f];
2307 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
2308 result
[out_cnt
++] = b64
[bits
& 0x3f];
2315 if (char_count
!= 0) {
2316 bits
<<= 16 - (8 * char_count
);
2317 result
[out_cnt
++] = b64
[bits
>> 18];
2318 result
[out_cnt
++] = b64
[(bits
>> 12) & 0x3f];
2319 if (char_count
== 1) {
2320 result
[out_cnt
++] = '=';
2321 result
[out_cnt
++] = '=';
2323 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
2324 result
[out_cnt
++] = '=';
2327 result
[out_cnt
] = '\0'; /* terminate */
2331 /* read a SMB_BIG_UINT from a string */
2332 SMB_BIG_UINT
STR_TO_SMB_BIG_UINT(const char *nptr
, const char **entptr
)
2335 SMB_BIG_UINT val
= -1;
2336 const char *p
= nptr
;
2345 while (*p
&& isspace(*p
))
2348 #ifdef LARGE_SMB_OFF_T
2349 sscanf(p
,"%llu",&val
);
2350 #else /* LARGE_SMB_OFF_T */
2351 sscanf(p
,"%lu",&val
);
2352 #endif /* LARGE_SMB_OFF_T */
2354 while (*p
&& isdigit(*p
))
2362 /* Convert a size specification to a count of bytes. We accept the following
2364 * bytes if there is no suffix
2369 * pP whatever the ISO name for petabytes is
2371 * Returns 0 if the string can't be converted.
2373 SMB_OFF_T
conv_str_size(const char * str
)
2378 if (str
== NULL
|| *str
== '\0') {
2382 #ifdef HAVE_STRTOULL
2383 if (sizeof(SMB_OFF_T
) == 8) {
2384 lval
= strtoull(str
, &end
, 10 /* base */);
2386 lval
= strtoul(str
, &end
, 10 /* base */);
2389 lval
= strtoul(str
, &end
, 10 /* base */);
2392 if (end
== NULL
|| end
== str
) {
2397 SMB_OFF_T lval_orig
= lval
;
2399 if (strwicmp(end
, "K") == 0) {
2400 lval
*= (SMB_OFF_T
)1024;
2401 } else if (strwicmp(end
, "M") == 0) {
2402 lval
*= ((SMB_OFF_T
)1024 * (SMB_OFF_T
)1024);
2403 } else if (strwicmp(end
, "G") == 0) {
2404 lval
*= ((SMB_OFF_T
)1024 * (SMB_OFF_T
)1024 *
2406 } else if (strwicmp(end
, "T") == 0) {
2407 lval
*= ((SMB_OFF_T
)1024 * (SMB_OFF_T
)1024 *
2408 (SMB_OFF_T
)1024 * (SMB_OFF_T
)1024);
2409 } else if (strwicmp(end
, "P") == 0) {
2410 lval
*= ((SMB_OFF_T
)1024 * (SMB_OFF_T
)1024 *
2411 (SMB_OFF_T
)1024 * (SMB_OFF_T
)1024 *
2417 /* Primitive attempt to detect wrapping on platforms with
2418 * 4-byte SMB_OFF_T. It's better to let the caller handle
2419 * a failure than some random number.
2421 if (lval_orig
<= lval
) {
2429 void string_append(char **left
, const char *right
)
2431 int new_len
= strlen(right
) + 1;
2433 if (*left
== NULL
) {
2434 *left
= (char *)SMB_MALLOC(new_len
);
2437 new_len
+= strlen(*left
);
2438 *left
= (char *)SMB_REALLOC(*left
, new_len
);
2441 if (*left
== NULL
) {
2445 safe_strcat(*left
, right
, new_len
-1);
2448 BOOL
add_string_to_array(TALLOC_CTX
*mem_ctx
,
2449 const char *str
, const char ***strings
,
2452 char *dup_str
= talloc_strdup(mem_ctx
, str
);
2454 *strings
= TALLOC_REALLOC_ARRAY(mem_ctx
, *strings
, const char *, (*num
)+1);
2456 if ((*strings
== NULL
) || (dup_str
== NULL
)) {
2461 (*strings
)[*num
] = dup_str
;
2466 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2467 * error checking in between. The indiation that something weird happened is
2470 void sprintf_append(TALLOC_CTX
*mem_ctx
, char **string
, ssize_t
*len
,
2471 size_t *bufsize
, const char *fmt
, ...)
2478 /* len<0 is an internal marker that something failed */
2482 if (*string
== NULL
) {
2486 *string
= TALLOC_ARRAY(mem_ctx
, char, *bufsize
);
2487 if (*string
== NULL
)
2492 ret
= vasprintf(&newstr
, fmt
, ap
);
2500 while ((*len
)+ret
>= *bufsize
) {
2503 if (*bufsize
>= (1024*1024*256))
2508 *string
= TALLOC_REALLOC_ARRAY(mem_ctx
, *string
, char,
2510 if (*string
== NULL
) {
2515 StrnCpy((*string
)+(*len
), newstr
, ret
);
2526 Returns the substring from src between the first occurrence of
2527 the char "front" and the first occurence of the char "back".
2528 Mallocs the return string which must be freed. Not for use
2529 with wide character strings.
2531 char *sstring_sub(const char *src
, char front
, char back
)
2533 char *temp1
, *temp2
, *temp3
;
2536 temp1
= strchr(src
, front
);
2537 if (temp1
== NULL
) return NULL
;
2538 temp2
= strchr(src
, back
);
2539 if (temp2
== NULL
) return NULL
;
2540 len
= temp2
- temp1
;
2541 if (len
<= 0) return NULL
;
2542 temp3
= (char*)SMB_MALLOC(len
);
2543 if (temp3
== NULL
) {
2544 DEBUG(1,("Malloc failure in sstring_sub\n"));
2547 memcpy(temp3
, temp1
+1, len
-1);
2548 temp3
[len
-1] = '\0';
2552 /********************************************************************
2553 Check a string for any occurrences of a specified list of invalid
2555 ********************************************************************/
2557 BOOL
validate_net_name( const char *name
, const char *invalid_chars
, int max_len
)
2561 for ( i
=0; i
<max_len
&& name
[i
]; i
++ ) {
2562 /* fail if strchr_m() finds one of the invalid characters */
2563 if ( name
[i
] && strchr_m( invalid_chars
, name
[i
] ) ) {
2573 return the number of bytes occupied by a buffer in ASCII format
2574 the result includes the null termination
2575 limited by 'n' bytes
2577 size_t ascii_len_n(const char *src
, size_t n
)
2581 len
= strnlen(src
, n
);
2590 return the number of bytes occupied by a buffer in CH_UTF16 format
2591 the result includes the null termination
2593 size_t utf16_len(const void *buf
)
2597 for (len
= 0; SVAL(buf
,len
); len
+= 2) ;
2603 return the number of bytes occupied by a buffer in CH_UTF16 format
2604 the result includes the null termination
2605 limited by 'n' bytes
2607 size_t utf16_len_n(const void *src
, size_t n
)
2611 for (len
= 0; (len
+2 < n
) && SVAL(src
, len
); len
+= 2) ;
2620 /*******************************************************************
2621 Add a shell escape character '\' to any character not in a known list
2622 of characters. UNIX charset format.
2623 *******************************************************************/
2625 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2626 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2628 char *escape_shell_string(const char *src
)
2630 size_t srclen
= strlen(src
);
2631 char *ret
= SMB_MALLOC((srclen
* 2) + 1);
2633 BOOL in_s_quote
= False
;
2634 BOOL in_d_quote
= False
;
2635 BOOL next_escaped
= False
;
2643 codepoint_t c
= next_codepoint(src
, &c_size
);
2645 if (c
== INVALID_CODEPOINT
) {
2651 memcpy(dest
, src
, c_size
);
2654 next_escaped
= False
;
2659 * Deal with backslash escaped state.
2660 * This only lasts for one character.
2665 next_escaped
= False
;
2670 * Deal with single quote state. The
2671 * only thing we care about is exiting
2684 * Deal with double quote state. The most
2685 * complex state. We must cope with \, meaning
2686 * possibly escape next char (depending what it
2687 * is), ", meaning exit this state, and possibly
2688 * add an \ escape to any unprotected character
2689 * (listed in INSIDE_DQUOTE_LIST).
2695 * Next character might be escaped.
2696 * We have to peek. Inside double
2697 * quotes only INSIDE_DQUOTE_LIST
2698 * characters are escaped by a \.
2703 c
= next_codepoint(&src
[1], &c_size
);
2704 if (c
== INVALID_CODEPOINT
) {
2710 * Don't escape the next char.
2719 if (nextchar
&& strchr(INSIDE_DQUOTE_LIST
, (int)nextchar
)) {
2720 next_escaped
= True
;
2727 /* Exit double quote state. */
2734 * We know the character isn't \ or ",
2735 * so escape it if it's any of the other
2736 * possible unprotected characters.
2739 if (strchr(INSIDE_DQUOTE_LIST
, (int)*src
)) {
2747 * From here to the end of the loop we're
2748 * not in the single or double quote state.
2752 /* Next character must be escaped. */
2753 next_escaped
= True
;
2759 /* Go into single quote state. */
2766 /* Go into double quote state. */
2772 /* Check if we need to escape the character. */
2774 if (!strchr(INCLUDE_LIST
, (int)*src
)) {