2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) Simo Sorce 2001-2002
7 Copyright (C) Martin Pool 2003
8 Copyright (C) James Peach 2006
9 Copyright (C) Jeremy Allison 1992-2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 const char toupper_ascii_fast_table
[128] = {
28 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
39 * Case insensitive string compararison.
41 * iconv does not directly give us a way to compare strings in
42 * arbitrary unix character sets -- all we can is convert and then
43 * compare. This is expensive.
45 * As an optimization, we do a first pass that considers only the
46 * prefix of the strings that is entirely 7-bit. Within this, we
47 * check whether they have the same value.
49 * Hopefully this will often give the answer without needing to copy.
50 * In particular it should speed comparisons to literal ascii strings
51 * or comparisons of strings that are "obviously" different.
53 * If we find a non-ascii character we fall back to converting via
56 * This should never be slower than convering the whole thing, and
59 * A different optimization would be to compare for bitwise equality
60 * in the binary encoding. (It would be possible thought hairy to do
61 * both simultaneously.) But in that case if they turn out to be
62 * different, we'd need to restart the whole thing.
64 * Even better is to implement strcasecmp for each encoding and use a
67 int StrCaseCmp(const char *s
, const char *t
)
72 smb_ucs2_t
*buffer_s
, *buffer_t
;
75 for (ps
= s
, pt
= t
; ; ps
++, pt
++) {
79 return 0; /* both ended */
81 return -1; /* s is a prefix */
83 return +1; /* t is a prefix */
84 else if ((*ps
& 0x80) || (*pt
& 0x80))
85 /* not ascii anymore, do it the hard way
89 us
= toupper_ascii_fast(*ps
);
90 ut
= toupper_ascii_fast(*pt
);
99 if (!push_ucs2_talloc(talloc_tos(), &buffer_s
, ps
, &size
)) {
100 return strcmp(ps
, pt
);
101 /* Not quite the right answer, but finding the right one
102 under this failure case is expensive, and it's pretty
106 if (!push_ucs2_talloc(talloc_tos(), &buffer_t
, pt
, &size
)) {
107 TALLOC_FREE(buffer_s
);
108 return strcmp(ps
, pt
);
109 /* Not quite the right answer, but finding the right one
110 under this failure case is expensive, and it's pretty
114 ret
= strcasecmp_w(buffer_s
, buffer_t
);
115 TALLOC_FREE(buffer_s
);
116 TALLOC_FREE(buffer_t
);
122 Case insensitive string compararison, length limited.
124 int StrnCaseCmp(const char *s
, const char *t
, size_t len
)
129 smb_ucs2_t
*buffer_s
, *buffer_t
;
132 for (ps
= s
, pt
= t
; n
< len
; ps
++, pt
++, n
++) {
136 return 0; /* both ended */
138 return -1; /* s is a prefix */
140 return +1; /* t is a prefix */
141 else if ((*ps
& 0x80) || (*pt
& 0x80))
142 /* not ascii anymore, do it the
143 * hard way from here on in */
146 us
= toupper_ascii_fast(*ps
);
147 ut
= toupper_ascii_fast(*pt
);
160 if (!push_ucs2_talloc(talloc_tos(), &buffer_s
, ps
, &size
)) {
161 return strncmp(ps
, pt
, len
-n
);
162 /* Not quite the right answer, but finding the right one
163 under this failure case is expensive,
164 and it's pretty close */
167 if (!push_ucs2_talloc(talloc_tos(), &buffer_t
, pt
, &size
)) {
168 TALLOC_FREE(buffer_s
);
169 return strncmp(ps
, pt
, len
-n
);
170 /* Not quite the right answer, but finding the right one
171 under this failure case is expensive,
172 and it's pretty close */
175 ret
= strncasecmp_w(buffer_s
, buffer_t
, len
-n
);
176 TALLOC_FREE(buffer_s
);
177 TALLOC_FREE(buffer_t
);
184 * @note The comparison is case-insensitive.
186 bool strequal(const char *s1
, const char *s2
)
193 return(StrCaseCmp(s1
,s2
)==0);
197 * Compare 2 strings up to and including the nth char.
199 * @note The comparison is case-insensitive.
201 bool strnequal(const char *s1
,const char *s2
,size_t n
)
205 if (!s1
|| !s2
|| !n
)
208 return(StrnCaseCmp(s1
,s2
,n
)==0);
212 Convert a string to "normal" form.
215 void strnorm(char *s
, int case_default
)
217 if (case_default
== CASE_UPPER
)
224 * Skip past some strings in a buffer - old version - no checks.
227 char *push_skip_string(char *buf
)
229 buf
+= strlen(buf
) + 1;
234 Skip past a string in a buffer. Buffer may not be
235 null terminated. end_ptr points to the first byte after
236 then end of the buffer.
239 char *skip_string(const char *base
, size_t len
, char *buf
)
241 const char *end_ptr
= base
+ len
;
243 if (end_ptr
< base
|| !base
|| !buf
|| buf
>= end_ptr
) {
247 /* Skip the string */
250 if (buf
>= end_ptr
) {
260 Count the number of characters in a string. Normally this will
261 be the same as the number of bytes in a string for single byte strings,
262 but will be different for multibyte.
265 size_t str_charnum(const char *s
)
267 size_t ret
, converted_size
;
268 smb_ucs2_t
*tmpbuf2
= NULL
;
269 if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2
, s
, &converted_size
)) {
272 ret
= strlen_w(tmpbuf2
);
273 TALLOC_FREE(tmpbuf2
);
277 bool trim_char(char *s
,char cfront
,char cback
)
283 /* Ignore null or empty strings. */
284 if (!s
|| (s
[0] == '\0'))
288 while (*fp
&& *fp
== cfront
)
291 /* We ate the string. */
299 ep
= fp
+ strlen(fp
) - 1;
301 /* Attempt ascii only. Bail for mb strings. */
302 while ((ep
>= fp
) && (*ep
== cback
)) {
304 if ((ep
> fp
) && (((unsigned char)ep
[-1]) & 0x80)) {
305 /* Could be mb... bail back to tim_string. */
313 return trim_string(s
, cfront
? fs
: NULL
, bs
);
319 /* We ate the string. */
326 memmove(s
, fp
, ep
-fp
+2);
331 Safe string copy into a known length string. maxlength does not
332 include the terminating zero.
335 char *safe_strcpy_fn(char *dest
,
342 smb_panic("ERROR: NULL dest in safe_strcpy");
350 len
= strnlen(src
, maxlength
+1);
352 if (len
> maxlength
) {
353 DEBUG(0,("ERROR: string overflow by "
354 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
355 (unsigned long)(len
-maxlength
), (unsigned long)len
,
356 (unsigned long)maxlength
, src
));
360 memmove(dest
, src
, len
);
366 Safe string cat into a string. maxlength does not
367 include the terminating zero.
369 char *safe_strcat_fn(char *dest
,
373 size_t src_len
, dest_len
;
376 smb_panic("ERROR: NULL dest in safe_strcat");
382 src_len
= strnlen(src
, maxlength
+ 1);
383 dest_len
= strnlen(dest
, maxlength
+ 1);
385 if (src_len
+ dest_len
> maxlength
) {
386 DEBUG(0,("ERROR: string overflow by %d "
387 "in safe_strcat [%.50s]\n",
388 (int)(src_len
+ dest_len
- maxlength
), src
));
389 if (maxlength
> dest_len
) {
390 memcpy(&dest
[dest_len
], src
, maxlength
- dest_len
);
396 memcpy(&dest
[dest_len
], src
, src_len
);
397 dest
[dest_len
+ src_len
] = 0;
402 Like strncpy but always null terminates. Make sure there is room!
403 The variable n should always be one less than the available size.
405 char *StrnCpy(char *dest
,const char *src
,size_t n
)
410 smb_panic("ERROR: NULL dest in StrnCpy");
418 while (n
-- && (*d
= *src
)) {
428 Check if a string is part of a list.
431 bool in_list(const char *s
, const char *list
, bool casesensitive
)
441 frame
= talloc_stackframe();
442 while (next_token_talloc(frame
, &list
, &tok
,LIST_SEP
)) {
444 if (strcmp(tok
,s
) == 0) {
449 if (StrCaseCmp(tok
,s
) == 0) {
459 /* this is used to prevent lots of mallocs of size 1 */
460 static const char null_string
[] = "";
463 Set a string value, allocing the space for the string
466 static bool string_init(char **dest
,const char *src
)
476 *dest
= CONST_DISCARD(char*, null_string
);
478 (*dest
) = SMB_STRDUP(src
);
479 if ((*dest
) == NULL
) {
480 DEBUG(0,("Out of memory in string_init\n"));
491 void string_free(char **s
)
495 if (*s
== null_string
)
501 Set a string value, deallocating any existing space, and allocing the space
505 bool string_set(char **dest
,const char *src
)
508 return(string_init(dest
,src
));
511 void fstring_sub(char *s
,const char *pattern
,const char *insert
)
513 string_sub(s
, pattern
, insert
, sizeof(fstring
));
517 Similar to string_sub2, but it will accept only allocated strings
518 and may realloc them so pay attention at what you pass on no
519 pointers inside strings, no const may be passed
523 char *realloc_string_sub2(char *string
,
526 bool remove_unsafe_characters
,
527 bool allow_trailing_dollar
)
531 ssize_t ls
,lp
,li
,ld
, i
;
533 if (!insert
|| !pattern
|| !*pattern
|| !string
|| !*string
)
538 in
= SMB_STRDUP(insert
);
540 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
543 ls
= (ssize_t
)strlen(s
);
544 lp
= (ssize_t
)strlen(pattern
);
545 li
= (ssize_t
)strlen(insert
);
550 /* allow a trailing $
551 * (as in machine accounts) */
552 if (allow_trailing_dollar
&& (i
== li
- 1 )) {
562 if ( remove_unsafe_characters
) {
572 while ((p
= strstr_m(s
,pattern
))) {
574 int offset
= PTR_DIFF(s
,string
);
575 string
= (char *)SMB_REALLOC(string
, ls
+ ld
+ 1);
577 DEBUG(0, ("realloc_string_sub: "
578 "out of memory!\n"));
582 p
= string
+ offset
+ (p
- s
);
585 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
595 char *realloc_string_sub(char *string
,
599 return realloc_string_sub2(string
, pattern
, insert
, true, false);
603 * Internal guts of talloc_string_sub and talloc_all_string_sub.
604 * talloc version of string_sub2.
607 char *talloc_string_sub2(TALLOC_CTX
*mem_ctx
, const char *src
,
610 bool remove_unsafe_characters
,
612 bool allow_trailing_dollar
)
617 ssize_t ls
,lp
,li
,ld
, i
;
619 if (!insert
|| !pattern
|| !*pattern
|| !src
) {
623 string
= talloc_strdup(mem_ctx
, src
);
624 if (string
== NULL
) {
625 DEBUG(0, ("talloc_string_sub2: "
626 "talloc_strdup failed\n"));
632 in
= SMB_STRDUP(insert
);
634 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
637 ls
= (ssize_t
)strlen(s
);
638 lp
= (ssize_t
)strlen(pattern
);
639 li
= (ssize_t
)strlen(insert
);
645 /* allow a trailing $
646 * (as in machine accounts) */
647 if (allow_trailing_dollar
&& (i
== li
- 1 )) {
657 if (remove_unsafe_characters
) {
667 while ((p
= strstr_m(s
,pattern
))) {
669 int offset
= PTR_DIFF(s
,string
);
670 string
= (char *)TALLOC_REALLOC(mem_ctx
, string
,
673 DEBUG(0, ("talloc_string_sub: out of "
678 p
= string
+ offset
+ (p
- s
);
681 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
695 /* Same as string_sub, but returns a talloc'ed string */
697 char *talloc_string_sub(TALLOC_CTX
*mem_ctx
,
702 return talloc_string_sub2(mem_ctx
, src
, pattern
, insert
,
706 char *talloc_all_string_sub(TALLOC_CTX
*ctx
,
711 return talloc_string_sub2(ctx
, src
, pattern
, insert
,
712 false, false, false);
716 Write an octal as a string.
719 char *octal_string(int i
)
723 result
= talloc_strdup(talloc_tos(), "-1");
726 result
= talloc_asprintf(talloc_tos(), "0%o", i
);
728 SMB_ASSERT(result
!= NULL
);
734 Truncate a string at a specified length.
737 char *string_truncate(char *s
, unsigned int length
)
739 if (s
&& strlen(s
) > length
)
745 /***********************************************************************
746 Return the equivalent of doing strrchr 'n' times - always going
748 ***********************************************************************/
750 char *strnrchr_m(const char *s
, char c
, unsigned int n
)
752 smb_ucs2_t
*ws
= NULL
;
756 size_t converted_size
;
758 if (!push_ucs2_talloc(talloc_tos(), &ws
, s
, &converted_size
)) {
759 /* Too hard to try and get right. */
762 p
= strnrchr_w(ws
, UCS2_CHAR(c
), n
);
768 if (!pull_ucs2_talloc(talloc_tos(), &s2
, ws
, &converted_size
)) {
770 /* Too hard to try and get right. */
773 ret
= (char *)(s
+strlen(s2
));
779 static bool unix_strlower(const char *src
, size_t srclen
, char *dest
, size_t destlen
)
782 smb_ucs2_t
*buffer
= NULL
;
785 if (!convert_string_talloc(talloc_tos(), CH_UNIX
, CH_UTF16LE
, src
, srclen
,
786 (void **)(void *)&buffer
, &size
))
788 smb_panic("failed to create UCS2 buffer");
790 if (!strlower_w(buffer
) && (dest
== src
)) {
794 ret
= convert_string(CH_UTF16LE
, CH_UNIX
, buffer
, size
, dest
, destlen
, &size
);
801 Convert a string to lower case.
804 void strlower_m(char *s
)
809 /* this is quite a common operation, so we want it to be
810 fast. We optimise for the ascii case, knowing that all our
811 supported multi-byte character sets are ascii-compatible
812 (ie. they match for the first 128 chars) */
814 while (*s
&& !(((unsigned char)s
[0]) & 0x80)) {
815 *s
= tolower_ascii((unsigned char)*s
);
822 /* I assume that lowercased string takes the same number of bytes
823 * as source string even in UTF-8 encoding. (VIV) */
827 unix_strlower(s
,len
,s
,len
);
828 /* Catch mb conversion errors that may not terminate. */
834 static bool unix_strupper(const char *src
, size_t srclen
, char *dest
, size_t destlen
)
840 if (!push_ucs2_talloc(talloc_tos(), &buffer
, src
, &size
)) {
844 if (!strupper_w(buffer
) && (dest
== src
)) {
849 ret
= convert_string(CH_UTF16LE
, CH_UNIX
, buffer
, size
, dest
, destlen
, &size
);
855 Convert a string to upper case.
858 void strupper_m(char *s
)
863 /* this is quite a common operation, so we want it to be
864 fast. We optimise for the ascii case, knowing that all our
865 supported multi-byte character sets are ascii-compatible
866 (ie. they match for the first 128 chars) */
868 while (*s
&& !(((unsigned char)s
[0]) & 0x80)) {
869 *s
= toupper_ascii_fast((unsigned char)*s
);
876 /* I assume that lowercased string takes the same number of bytes
877 * as source string even in multibyte encoding. (VIV) */
881 unix_strupper(s
,len
,s
,len
);
882 /* Catch mb conversion errors that may not terminate. */
889 Just a typesafety wrapper for snprintf into a fstring.
892 int fstr_sprintf(fstring s
, const char *fmt
, ...)
898 ret
= vsnprintf(s
, FSTRING_LEN
, fmt
, ap
);
904 List of Strings manipulation functions
907 #define S_LIST_ABS 16 /* List Allocation Block Size */
909 /******************************************************************************
910 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
912 *****************************************************************************/
914 bool str_list_sub_basic( char **list
, const char *smb_name
,
915 const char *domain_name
)
917 TALLOC_CTX
*ctx
= list
;
922 tmpstr
= talloc_sub_basic(ctx
, smb_name
, domain_name
, s
);
924 DEBUG(0,("str_list_sub_basic: "
925 "alloc_sub_basic() return NULL!\n"));
938 /******************************************************************************
939 substitute a specific pattern in a string list
940 *****************************************************************************/
942 bool str_list_substitute(char **list
, const char *pattern
, const char *insert
)
944 TALLOC_CTX
*ctx
= list
;
946 ssize_t ls
, lp
, li
, ld
, i
, d
;
955 lp
= (ssize_t
)strlen(pattern
);
956 li
= (ssize_t
)strlen(insert
);
961 ls
= (ssize_t
)strlen(s
);
963 while ((p
= strstr_m(s
, pattern
))) {
967 t
= TALLOC_ARRAY(ctx
, char, ls
+ld
+1);
969 DEBUG(0,("str_list_substitute: "
970 "Unable to allocate memory"));
974 memcpy(t
+d
+li
, p
+lp
, ls
-d
-lp
+1);
981 for (i
= 0; i
< li
; i
++) {
1006 #define IPSTR_LIST_SEP ","
1007 #define IPSTR_LIST_CHAR ','
1010 * Add ip string representation to ipstr list. Used also
1011 * as part of @function ipstr_list_make
1013 * @param ipstr_list pointer to string containing ip list;
1014 * MUST BE already allocated and IS reallocated if necessary
1015 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1016 * as a result of reallocation)
1017 * @param ip IP address which is to be added to list
1018 * @return pointer to string appended with new ip and possibly
1019 * reallocated to new length
1022 static char *ipstr_list_add(char **ipstr_list
, const struct ip_service
*service
)
1024 char *new_ipstr
= NULL
;
1025 char addr_buf
[INET6_ADDRSTRLEN
];
1028 /* arguments checking */
1029 if (!ipstr_list
|| !service
) {
1033 print_sockaddr(addr_buf
,
1037 /* attempt to convert ip to a string and append colon separator to it */
1039 if (service
->ss
.ss_family
== AF_INET
) {
1041 ret
= asprintf(&new_ipstr
, "%s%s%s:%d", *ipstr_list
,
1042 IPSTR_LIST_SEP
, addr_buf
,
1046 ret
= asprintf(&new_ipstr
, "%s%s[%s]:%d", *ipstr_list
,
1047 IPSTR_LIST_SEP
, addr_buf
,
1050 SAFE_FREE(*ipstr_list
);
1052 if (service
->ss
.ss_family
== AF_INET
) {
1054 ret
= asprintf(&new_ipstr
, "%s:%d", addr_buf
,
1058 ret
= asprintf(&new_ipstr
, "[%s]:%d", addr_buf
,
1065 *ipstr_list
= new_ipstr
;
1070 * Allocate and initialise an ipstr list using ip adresses
1071 * passed as arguments.
1073 * @param ipstr_list pointer to string meant to be allocated and set
1074 * @param ip_list array of ip addresses to place in the list
1075 * @param ip_count number of addresses stored in ip_list
1076 * @return pointer to allocated ip string
1079 char *ipstr_list_make(char **ipstr_list
,
1080 const struct ip_service
*ip_list
,
1085 /* arguments checking */
1086 if (!ip_list
|| !ipstr_list
) {
1092 /* process ip addresses given as arguments */
1093 for (i
= 0; i
< ip_count
; i
++) {
1094 *ipstr_list
= ipstr_list_add(ipstr_list
, &ip_list
[i
]);
1097 return (*ipstr_list
);
1102 * Parse given ip string list into array of ip addresses
1103 * (as ip_service structures)
1104 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1106 * @param ipstr ip string list to be parsed
1107 * @param ip_list pointer to array of ip addresses which is
1108 * allocated by this function and must be freed by caller
1109 * @return number of successfully parsed addresses
1112 int ipstr_list_parse(const char *ipstr_list
, struct ip_service
**ip_list
)
1115 char *token_str
= NULL
;
1119 if (!ipstr_list
|| !ip_list
)
1122 count
= count_chars(ipstr_list
, IPSTR_LIST_CHAR
) + 1;
1123 if ( (*ip_list
= SMB_MALLOC_ARRAY(struct ip_service
, count
)) == NULL
) {
1124 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1125 (unsigned long)count
));
1129 frame
= talloc_stackframe();
1130 for ( i
=0; next_token_talloc(frame
, &ipstr_list
, &token_str
,
1131 IPSTR_LIST_SEP
) && i
<count
; i
++ ) {
1132 char *s
= token_str
;
1133 char *p
= strrchr(token_str
, ':');
1137 (*ip_list
)[i
].port
= atoi(p
+1);
1140 /* convert single token to ip address */
1141 if (token_str
[0] == '[') {
1144 p
= strchr(token_str
, ']');
1150 if (!interpret_string_addr(&(*ip_list
)[i
].ss
,
1161 * Safely free ip string list
1163 * @param ipstr_list ip string list to be freed
1166 void ipstr_list_free(char* ipstr_list
)
1168 SAFE_FREE(ipstr_list
);
1171 /* read a SMB_BIG_UINT from a string */
1172 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr
, const char **entptr
)
1175 uint64_t val
= (uint64_t)-1;
1176 const char *p
= nptr
;
1185 while (*p
&& isspace(*p
))
1188 sscanf(p
,"%"PRIu64
,&val
);
1190 while (*p
&& isdigit(*p
))
1198 /* Convert a size specification to a count of bytes. We accept the following
1200 * bytes if there is no suffix
1205 * pP whatever the ISO name for petabytes is
1207 * Returns 0 if the string can't be converted.
1209 uint64_t conv_str_size(const char * str
)
1215 if (str
== NULL
|| *str
== '\0') {
1219 lval
= strtoull(str
, &end
, 10 /* base */);
1221 if (end
== NULL
|| end
== str
) {
1231 if (strwicmp(end
, "K") == 0) {
1233 } else if (strwicmp(end
, "M") == 0) {
1234 lval
*= (1024ULL * 1024ULL);
1235 } else if (strwicmp(end
, "G") == 0) {
1236 lval
*= (1024ULL * 1024ULL *
1238 } else if (strwicmp(end
, "T") == 0) {
1239 lval
*= (1024ULL * 1024ULL *
1241 } else if (strwicmp(end
, "P") == 0) {
1242 lval
*= (1024ULL * 1024ULL *
1252 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1253 * error checking in between. The indiation that something weird happened is
1256 void sprintf_append(TALLOC_CTX
*mem_ctx
, char **string
, ssize_t
*len
,
1257 size_t *bufsize
, const char *fmt
, ...)
1264 /* len<0 is an internal marker that something failed */
1268 if (*string
== NULL
) {
1272 *string
= TALLOC_ARRAY(mem_ctx
, char, *bufsize
);
1273 if (*string
== NULL
)
1278 ret
= vasprintf(&newstr
, fmt
, ap
);
1286 while ((*len
)+ret
>= *bufsize
) {
1289 if (*bufsize
>= (1024*1024*256))
1294 *string
= TALLOC_REALLOC_ARRAY(mem_ctx
, *string
, char,
1296 if (*string
== NULL
) {
1301 StrnCpy((*string
)+(*len
), newstr
, ret
);
1312 * asprintf into a string and strupper_m it after that.
1315 int asprintf_strupper_m(char **strp
, const char *fmt
, ...)
1322 ret
= vasprintf(&result
, fmt
, ap
);
1333 char *talloc_asprintf_strupper_m(TALLOC_CTX
*t
, const char *fmt
, ...)
1339 ret
= talloc_vasprintf(t
, fmt
, ap
);
1349 char *talloc_asprintf_strlower_m(TALLOC_CTX
*t
, const char *fmt
, ...)
1355 ret
= talloc_vasprintf(t
, fmt
, ap
);
1367 Returns the substring from src between the first occurrence of
1368 the char "front" and the first occurence of the char "back".
1369 Mallocs the return string which must be freed. Not for use
1370 with wide character strings.
1372 char *sstring_sub(const char *src
, char front
, char back
)
1374 char *temp1
, *temp2
, *temp3
;
1377 temp1
= strchr(src
, front
);
1378 if (temp1
== NULL
) return NULL
;
1379 temp2
= strchr(src
, back
);
1380 if (temp2
== NULL
) return NULL
;
1381 len
= temp2
- temp1
;
1382 if (len
<= 0) return NULL
;
1383 temp3
= (char*)SMB_MALLOC(len
);
1384 if (temp3
== NULL
) {
1385 DEBUG(1,("Malloc failure in sstring_sub\n"));
1388 memcpy(temp3
, temp1
+1, len
-1);
1389 temp3
[len
-1] = '\0';
1393 /********************************************************************
1394 Check a string for any occurrences of a specified list of invalid
1396 ********************************************************************/
1398 bool validate_net_name( const char *name
,
1399 const char *invalid_chars
,
1408 for ( i
=0; i
<max_len
&& name
[i
]; i
++ ) {
1409 /* fail if strchr_m() finds one of the invalid characters */
1410 if ( name
[i
] && strchr_m( invalid_chars
, name
[i
] ) ) {
1419 /*******************************************************************
1420 Add a shell escape character '\' to any character not in a known list
1421 of characters. UNIX charset format.
1422 *******************************************************************/
1424 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1425 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1427 char *escape_shell_string(const char *src
)
1429 size_t srclen
= strlen(src
);
1430 char *ret
= SMB_MALLOC_ARRAY(char, (srclen
* 2) + 1);
1432 bool in_s_quote
= false;
1433 bool in_d_quote
= false;
1434 bool next_escaped
= false;
1442 codepoint_t c
= next_codepoint(src
, &c_size
);
1444 if (c
== INVALID_CODEPOINT
) {
1450 memcpy(dest
, src
, c_size
);
1453 next_escaped
= false;
1458 * Deal with backslash escaped state.
1459 * This only lasts for one character.
1464 next_escaped
= false;
1469 * Deal with single quote state. The
1470 * only thing we care about is exiting
1483 * Deal with double quote state. The most
1484 * complex state. We must cope with \, meaning
1485 * possibly escape next char (depending what it
1486 * is), ", meaning exit this state, and possibly
1487 * add an \ escape to any unprotected character
1488 * (listed in INSIDE_DQUOTE_LIST).
1494 * Next character might be escaped.
1495 * We have to peek. Inside double
1496 * quotes only INSIDE_DQUOTE_LIST
1497 * characters are escaped by a \.
1502 c
= next_codepoint(&src
[1], &c_size
);
1503 if (c
== INVALID_CODEPOINT
) {
1509 * Don't escape the next char.
1518 if (nextchar
&& strchr(INSIDE_DQUOTE_LIST
,
1520 next_escaped
= true;
1527 /* Exit double quote state. */
1534 * We know the character isn't \ or ",
1535 * so escape it if it's any of the other
1536 * possible unprotected characters.
1539 if (strchr(INSIDE_DQUOTE_LIST
, (int)*src
)) {
1547 * From here to the end of the loop we're
1548 * not in the single or double quote state.
1552 /* Next character must be escaped. */
1553 next_escaped
= true;
1559 /* Go into single quote state. */
1566 /* Go into double quote state. */
1572 /* Check if we need to escape the character. */
1574 if (!strchr(INCLUDE_LIST
, (int)*src
)) {
1583 /***************************************************
1584 str_list_make, v3 version. The v4 version does not
1585 look at quoted strings with embedded blanks, so
1586 do NOT merge this function please!
1587 ***************************************************/
1589 #define S_LIST_ABS 16 /* List Allocation Block Size */
1591 char **str_list_make_v3(TALLOC_CTX
*mem_ctx
, const char *string
,
1599 if (!string
|| !*string
)
1602 list
= TALLOC_ARRAY(mem_ctx
, char *, S_LIST_ABS
+1);
1608 s
= talloc_strdup(list
, string
);
1610 DEBUG(0,("str_list_make: Unable to allocate memory"));
1614 if (!sep
) sep
= LIST_SEP
;
1619 while (next_token_talloc(list
, &str
, &tok
, sep
)) {
1624 lsize
+= S_LIST_ABS
;
1626 tmp
= TALLOC_REALLOC_ARRAY(mem_ctx
, list
, char *,
1629 DEBUG(0,("str_list_make: "
1630 "Unable to allocate memory"));
1637 memset (&list
[num
], 0,
1638 ((sizeof(char**)) * (S_LIST_ABS
+1)));
1651 char *sanitize_username(TALLOC_CTX
*mem_ctx
, const char *username
)
1655 alpha_strcpy(tmp
, username
, ". _-$", sizeof(tmp
));
1656 return talloc_strdup(mem_ctx
, tmp
);