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);
799 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
802 Convert a string to lower case.
804 _PUBLIC_ void strlower_m(char *s)
807 struct smb_iconv_handle *iconv_handle;
809 iconv_handle = get_iconv_handle();
814 size_t c_size, c_size2;
815 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
816 c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
817 if (c_size2 > c_size) {
818 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
819 c, tolower_m(c), (int)c_size, (int)c_size2));
820 smb_panic("codepoint expansion in strlower_m\n");
831 Convert a string to lower case.
834 void strlower_m(char *s)
839 /* this is quite a common operation, so we want it to be
840 fast. We optimise for the ascii case, knowing that all our
841 supported multi-byte character sets are ascii-compatible
842 (ie. they match for the first 128 chars) */
844 while (*s && !(((unsigned char)s[0]) & 0x80)) {
845 *s = tolower_ascii((unsigned char)*s);
852 /* I assume that lowercased string takes the same number of bytes
853 * as source string even in UTF-8 encoding. (VIV) */
857 unix_strlower(s,len,s,len);
858 /* Catch mb conversion errors that may not terminate. */
864 static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
870 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
874 if (!strupper_w(buffer) && (dest == src)) {
879 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
884 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
887 Convert a string to UPPER case.
889 _PUBLIC_ void strupper_m(char *s)
892 struct smb_iconv_handle *iconv_handle;
894 iconv_handle = get_iconv_handle();
899 size_t c_size, c_size2;
900 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
901 c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
902 if (c_size2 > c_size) {
903 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
904 c, toupper_m(c), (int)c_size, (int)c_size2));
905 smb_panic("codepoint expansion in strupper_m\n");
916 Convert a string to upper case.
919 void strupper_m(char *s)
924 /* this is quite a common operation, so we want it to be
925 fast. We optimise for the ascii case, knowing that all our
926 supported multi-byte character sets are ascii-compatible
927 (ie. they match for the first 128 chars) */
929 while (*s && !(((unsigned char)s[0]) & 0x80)) {
930 *s = toupper_ascii_fast((unsigned char)*s);
937 /* I assume that lowercased string takes the same number of bytes
938 * as source string even in multibyte encoding. (VIV) */
942 unix_strupper(s,len,s,len);
943 /* Catch mb conversion errors that may not terminate. */
950 Just a typesafety wrapper for snprintf into a fstring.
953 int fstr_sprintf(fstring s, const char *fmt, ...)
959 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
965 List of Strings manipulation functions
968 #define S_LIST_ABS 16 /* List Allocation Block Size */
970 /******************************************************************************
971 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
973 *****************************************************************************/
975 bool str_list_sub_basic( char **list, const char *smb_name,
976 const char *domain_name )
978 TALLOC_CTX *ctx = list;
983 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
985 DEBUG(0,("str_list_sub_basic: "
986 "alloc_sub_basic() return NULL!\n"));
999 /******************************************************************************
1000 substitute a specific pattern in a string list
1001 *****************************************************************************/
1003 bool str_list_substitute(char **list, const char *pattern, const char *insert)
1005 TALLOC_CTX *ctx = list;
1007 ssize_t ls, lp, li, ld, i, d;
1016 lp = (ssize_t)strlen(pattern);
1017 li = (ssize_t)strlen(insert);
1022 ls = (ssize_t)strlen(s);
1024 while ((p = strstr_m(s, pattern))) {
1028 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
1030 DEBUG(0,("str_list_substitute: "
1031 "Unable to allocate memory"));
1034 memcpy(t, *list, d);
1035 memcpy(t +d +li, p +lp, ls -d -lp +1);
1042 for (i = 0; i < li; i++) {
1043 switch (insert[i]) {
1055 t[d +i] = insert[i];
1067 #define IPSTR_LIST_SEP ","
1068 #define IPSTR_LIST_CHAR ','
1071 * Add ip string representation to ipstr list. Used also
1072 * as part of @function ipstr_list_make
1074 * @param ipstr_list pointer to string containing ip list;
1075 * MUST BE already allocated and IS reallocated if necessary
1076 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1077 * as a result of reallocation)
1078 * @param ip IP address which is to be added to list
1079 * @return pointer to string appended with new ip and possibly
1080 * reallocated to new length
1083 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1085 char *new_ipstr = NULL;
1086 char addr_buf[INET6_ADDRSTRLEN];
1089 /* arguments checking */
1090 if (!ipstr_list || !service) {
1094 print_sockaddr(addr_buf,
1098 /* attempt to convert ip to a string and append colon separator to it */
1100 if (service->ss.ss_family == AF_INET) {
1102 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1103 IPSTR_LIST_SEP, addr_buf,
1107 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1108 IPSTR_LIST_SEP, addr_buf,
1111 SAFE_FREE(*ipstr_list);
1113 if (service->ss.ss_family == AF_INET) {
1115 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1119 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1126 *ipstr_list = new_ipstr;
1131 * Allocate and initialise an ipstr list using ip adresses
1132 * passed as arguments.
1134 * @param ipstr_list pointer to string meant to be allocated and set
1135 * @param ip_list array of ip addresses to place in the list
1136 * @param ip_count number of addresses stored in ip_list
1137 * @return pointer to allocated ip string
1140 char *ipstr_list_make(char **ipstr_list,
1141 const struct ip_service *ip_list,
1146 /* arguments checking */
1147 if (!ip_list || !ipstr_list) {
1153 /* process ip addresses given as arguments */
1154 for (i = 0; i < ip_count; i++) {
1155 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1158 return (*ipstr_list);
1163 * Parse given ip string list into array of ip addresses
1164 * (as ip_service structures)
1165 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1167 * @param ipstr ip string list to be parsed
1168 * @param ip_list pointer to array of ip addresses which is
1169 * allocated by this function and must be freed by caller
1170 * @return number of successfully parsed addresses
1173 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1176 char *token_str = NULL;
1180 if (!ipstr_list || !ip_list)
1183 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1184 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1185 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1186 (unsigned long)count));
1190 frame = talloc_stackframe();
1191 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1192 IPSTR_LIST_SEP) && i<count; i++ ) {
1193 char *s = token_str;
1194 char *p = strrchr(token_str, ':');
1198 (*ip_list)[i].port = atoi(p+1);
1201 /* convert single token to ip address */
1202 if (token_str[0] == '[') {
1205 p = strchr(token_str, ']');
1211 if (!interpret_string_addr(&(*ip_list)[i].ss,
1222 * Safely free ip string list
1224 * @param ipstr_list ip string list to be freed
1227 void ipstr_list_free(char* ipstr_list)
1229 SAFE_FREE(ipstr_list);
1232 /* read a SMB_BIG_UINT from a string */
1233 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1236 uint64_t val = (uint64_t)-1;
1237 const char *p = nptr;
1246 while (*p && isspace(*p))
1249 sscanf(p,"%"PRIu64,&val);
1251 while (*p && isdigit(*p))
1259 /* Convert a size specification to a count of bytes. We accept the following
1261 * bytes if there is no suffix
1266 * pP whatever the ISO name for petabytes is
1268 * Returns 0 if the string can't be converted.
1270 uint64_t conv_str_size(const char * str)
1276 if (str == NULL || *str == '\0') {
1280 lval = strtoull(str, &end, 10 /* base */);
1282 if (end == NULL || end == str) {
1292 if (strwicmp(end, "K") == 0) {
1294 } else if (strwicmp(end, "M") == 0) {
1295 lval *= (1024ULL * 1024ULL);
1296 } else if (strwicmp(end, "G") == 0) {
1297 lval *= (1024ULL * 1024ULL *
1299 } else if (strwicmp(end, "T") == 0) {
1300 lval *= (1024ULL * 1024ULL *
1302 } else if (strwicmp(end, "P") == 0) {
1303 lval *= (1024ULL * 1024ULL *
1313 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1314 * error checking in between. The indiation that something weird happened is
1317 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
1318 size_t *bufsize, const char *fmt, ...)
1325 /* len<0 is an internal marker that something failed */
1329 if (*string == NULL) {
1333 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
1334 if (*string == NULL)
1339 ret = vasprintf(&newstr, fmt, ap);
1347 while ((*len)+ret >= *bufsize) {
1350 if (*bufsize >= (1024*1024*256))
1355 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
1357 if (*string == NULL) {
1362 StrnCpy((*string)+(*len), newstr, ret);
1373 * asprintf into a string and strupper_m it after that.
1376 int asprintf_strupper_m(char **strp, const char *fmt, ...)
1383 ret = vasprintf(&result, fmt, ap);
1394 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
1400 ret = talloc_vasprintf(t, fmt, ap);
1410 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
1416 ret = talloc_vasprintf(t, fmt, ap);
1428 Returns the substring from src between the first occurrence of
1429 the char "front" and the first occurence of the char "back".
1430 Mallocs the return string which must be freed. Not for use
1431 with wide character strings.
1433 char *sstring_sub(const char *src, char front, char back)
1435 char *temp1, *temp2, *temp3;
1438 temp1 = strchr(src, front);
1439 if (temp1 == NULL) return NULL;
1440 temp2 = strchr(src, back);
1441 if (temp2 == NULL) return NULL;
1442 len = temp2 - temp1;
1443 if (len <= 0) return NULL;
1444 temp3 = (char*)SMB_MALLOC(len);
1445 if (temp3 == NULL) {
1446 DEBUG(1,("Malloc failure in sstring_sub\n"));
1449 memcpy(temp3, temp1+1, len-1);
1450 temp3[len-1] = '\0';
1454 /********************************************************************
1455 Check a string for any occurrences of a specified list of invalid
1457 ********************************************************************/
1459 bool validate_net_name( const char *name,
1460 const char *invalid_chars,
1469 for ( i=0; i<max_len && name[i]; i++ ) {
1470 /* fail if strchr_m() finds one of the invalid characters */
1471 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
1480 /*******************************************************************
1481 Add a shell escape character '\' to any character not in a known list
1482 of characters. UNIX charset format.
1483 *******************************************************************/
1485 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1486 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1488 char *escape_shell_string(const char *src)
1490 size_t srclen = strlen(src);
1491 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
1493 bool in_s_quote = false;
1494 bool in_d_quote = false;
1495 bool next_escaped = false;
1503 codepoint_t c = next_codepoint(src, &c_size);
1505 if (c == INVALID_CODEPOINT) {
1511 memcpy(dest, src, c_size);
1514 next_escaped = false;
1519 * Deal with backslash escaped state.
1520 * This only lasts for one character.
1525 next_escaped = false;
1530 * Deal with single quote state. The
1531 * only thing we care about is exiting
1544 * Deal with double quote state. The most
1545 * complex state. We must cope with \, meaning
1546 * possibly escape next char (depending what it
1547 * is), ", meaning exit this state, and possibly
1548 * add an \ escape to any unprotected character
1549 * (listed in INSIDE_DQUOTE_LIST).
1555 * Next character might be escaped.
1556 * We have to peek. Inside double
1557 * quotes only INSIDE_DQUOTE_LIST
1558 * characters are escaped by a \.
1563 c = next_codepoint(&src[1], &c_size);
1564 if (c == INVALID_CODEPOINT) {
1570 * Don't escape the next char.
1579 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
1581 next_escaped = true;
1588 /* Exit double quote state. */
1595 * We know the character isn't \ or ",
1596 * so escape it if it's any of the other
1597 * possible unprotected characters.
1600 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
1608 * From here to the end of the loop we're
1609 * not in the single or double quote state.
1613 /* Next character must be escaped. */
1614 next_escaped = true;
1620 /* Go into single quote state. */
1627 /* Go into double quote state. */
1633 /* Check if we need to escape the character. */
1635 if (!strchr(INCLUDE_LIST, (int)*src)) {
1644 /***************************************************
1645 str_list_make, v3 version. The v4 version does not
1646 look at quoted strings with embedded blanks, so
1647 do NOT merge this function please!
1648 ***************************************************/
1650 #define S_LIST_ABS 16 /* List Allocation Block Size */
1652 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
1660 if (!string || !*string)
1663 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1669 s = talloc_strdup(list, string);
1671 DEBUG(0,("str_list_make: Unable to allocate memory"));
1675 if (!sep) sep = LIST_SEP;
1680 while (next_token_talloc(list, &str, &tok, sep)) {
1685 lsize += S_LIST_ABS;
1687 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1690 DEBUG(0,("str_list_make: "
1691 "Unable to allocate memory"));
1698 memset (&list[num], 0,
1699 ((sizeof(char**)) * (S_LIST_ABS +1)));
1712 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
1716 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
1717 return talloc_strdup(mem_ctx, tmp);