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 2005
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.
26 #include "system/iconv.h"
29 #include "lib/ldb/include/ldb.h"
33 * @brief String utilities.
37 * Get the next token from a string, return False if none found.
38 * Handles double-quotes.
40 * Based on a routine by GJC@VILLAGE.COM.
41 * Extensively modified by Andrew.Tridgell@anu.edu.au
43 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
54 /* default to simple separators */
58 /* find the first non sep char */
59 while (*s && strchr_m(sep,*s))
66 /* copy over the token */
67 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
76 *ptr = (*s) ? s+1 : s;
83 Case insensitive string compararison
85 int strcasecmp_m(const char *s1, const char *s2)
87 codepoint_t c1=0, c2=0;
91 c1 = next_codepoint(s1, &size1);
92 c2 = next_codepoint(s2, &size2);
101 if (c1 == INVALID_CODEPOINT ||
102 c2 == INVALID_CODEPOINT) {
103 /* what else can we do?? */
107 if (toupper_w(c1) != toupper_w(c2)) {
118 * @note The comparison is case-insensitive.
120 BOOL strequal(const char *s1, const char *s2)
127 return strcasecmp_m(s1,s2) == 0;
131 Compare 2 strings (case sensitive).
133 BOOL strcsequal(const char *s1,const char *s2)
140 return strcmp(s1,s2) == 0;
145 Do a case-insensitive, whitespace-ignoring string compare.
147 int strwicmp(const char *psz1, const char *psz2)
149 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
150 /* appropriate value. */
153 else if (psz1 == NULL)
155 else if (psz2 == NULL)
158 /* sync the strings on first non-whitespace */
160 while (isspace((int)*psz1))
162 while (isspace((int)*psz2))
164 if (toupper((unsigned char)*psz1) != toupper((unsigned char)*psz2)
171 return (*psz1 - *psz2);
176 NOTE: oldc and newc must be 7 bit characters
178 void string_replace(char *s, char oldc, char newc)
182 codepoint_t c = next_codepoint(s, &size);
191 Trim the specified elements off the front and back of a string.
193 BOOL trim_string(char *s,const char *front,const char *back)
200 /* Ignore null or empty strings. */
201 if (!s || (s[0] == '\0'))
204 front_len = front? strlen(front) : 0;
205 back_len = back? strlen(back) : 0;
210 while (len && strncmp(s, front, front_len)==0) {
211 /* Must use memmove here as src & dest can
212 * easily overlap. Found by valgrind. JRA. */
213 memmove(s, s+front_len, (len-front_len)+1);
220 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
221 s[len-back_len]='\0';
230 Find the number of 'c' chars in a string
232 size_t count_chars(const char *s, char c)
238 codepoint_t c2 = next_codepoint(s, &size);
239 if (c2 == c) count++;
247 Safe string copy into a known length string. maxlength does not
248 include the terminating zero.
250 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
255 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
260 /* We intentionally write out at the extremity of the destination
261 * string. If the destination is too short (e.g. pstrcpy into mallocd
262 * or fstring) then this should cause an error under a memory
264 dest[maxlength] = '\0';
265 if (PTR_DIFF(&len, dest) > 0) { /* check if destination is on the stack, ok if so */
266 log_suspicious_usage("safe_strcpy", src);
277 if (len > maxlength) {
278 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
279 (uint_t)(len-maxlength), (unsigned)len, (unsigned)maxlength, src));
283 memmove(dest, src, len);
289 Safe string cat into a string. maxlength does not
290 include the terminating zero.
292 char *safe_strcat(char *dest, const char *src, size_t maxlength)
294 size_t src_len, dest_len;
297 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
305 if (PTR_DIFF(&src_len, dest) > 0) { /* check if destination is on the stack, ok if so */
306 log_suspicious_usage("safe_strcat", src);
309 src_len = strlen(src);
310 dest_len = strlen(dest);
312 if (src_len + dest_len > maxlength) {
313 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
314 (int)(src_len + dest_len - maxlength), src));
315 if (maxlength > dest_len) {
316 memcpy(&dest[dest_len], src, maxlength - dest_len);
322 memcpy(&dest[dest_len], src, src_len);
323 dest[dest_len + src_len] = 0;
328 Paranoid strcpy into a buffer of given length (includes terminating
329 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
330 and replaces with '_'. Deliberately does *NOT* check for multibyte
331 characters. Don't change it !
334 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
338 if (maxlength == 0) {
339 /* can't fit any bytes at all! */
344 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
354 if (len >= maxlength)
357 if (!other_safe_chars)
358 other_safe_chars = "";
360 for(i = 0; i < len; i++) {
361 int val = (src[i] & 0xff);
362 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
374 Like strncpy but always null terminates. Make sure there is room!
375 The variable n should always be one less than the available size.
378 char *StrnCpy(char *dest,const char *src,size_t n)
387 while (n-- && (*d++ = *src++))
395 Routine to get hex characters and turn them into a 16 byte array.
396 the array can be variable length, and any non-hex-numeric
397 characters are skipped. "0xnn" or "0Xnn" is specially catered
400 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
404 size_t strhex_to_str(char *p, size_t len, const char *strhex)
407 size_t num_chars = 0;
408 uint8_t lonybble, hinybble;
409 const char *hexchars = "0123456789ABCDEF";
410 char *p1 = NULL, *p2 = NULL;
412 for (i = 0; i < len && strhex[i] != 0; i++) {
413 if (strncasecmp(hexchars, "0x", 2) == 0) {
414 i++; /* skip two chars */
418 if (!(p1 = strchr_m(hexchars, toupper((unsigned char)strhex[i]))))
421 i++; /* next hex digit */
423 if (!(p2 = strchr_m(hexchars, toupper((unsigned char)strhex[i]))))
426 /* get the two nybbles */
427 hinybble = PTR_DIFF(p1, hexchars);
428 lonybble = PTR_DIFF(p2, hexchars);
430 p[num_chars] = (hinybble << 4) | lonybble;
439 DATA_BLOB strhex_to_data_blob(const char *strhex)
441 DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
443 ret_blob.length = strhex_to_str((char *)ret_blob.data,
452 * Routine to print a buffer as HEX digits, into an allocated string.
454 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
459 *out_hex_buffer = smb_xmalloc((len*2)+1);
460 hex_buffer = *out_hex_buffer;
462 for (i = 0; i < len; i++)
463 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
467 Check if a string is part of a list.
469 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
477 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
479 if (strcmp(tok,s) == 0)
482 if (strcasecmp_m(tok,s) == 0)
490 Set a string value, allocing the space for the string
492 static BOOL string_init(char **dest,const char *src)
496 (*dest) = strdup(src);
497 if ((*dest) == NULL) {
498 DEBUG(0,("Out of memory in string_init\n"));
507 void string_free(char **s)
509 if (s) SAFE_FREE(*s);
513 Set a string value, deallocating any existing space, and allocing the space
516 BOOL string_set(char **dest, const char *src)
519 return string_init(dest,src);
523 Substitute a string for a pattern in another string. Make sure there is
526 This routine looks for pattern in s and replaces it with
527 insert. It may do multiple replacements.
529 Any of " ; ' $ or ` in the insert string are replaced with _
530 if len==0 then the string cannot be extended. This is different from the old
531 use of len==0 which was for no length checks to be done.
534 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
539 if (!insert || !pattern || !*pattern || !s)
542 ls = (ssize_t)strlen(s);
543 lp = (ssize_t)strlen(pattern);
544 li = (ssize_t)strlen(insert);
547 len = ls + 1; /* len is number of *bytes* */
549 while (lp <= ls && (p = strstr(s,pattern))) {
550 if (ls + (li-lp) >= len) {
551 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
552 (int)(ls + (li-lp) - len),
557 memmove(p+li,p+lp,strlen(p+lp)+1);
582 Similar to string_sub() but allows for any character to be substituted.
584 if len==0 then the string cannot be extended. This is different from the old
585 use of len==0 which was for no length checks to be done.
588 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
593 if (!insert || !pattern || !s)
596 ls = (ssize_t)strlen(s);
597 lp = (ssize_t)strlen(pattern);
598 li = (ssize_t)strlen(insert);
604 len = ls + 1; /* len is number of *bytes* */
606 while (lp <= ls && (p = strstr(s,pattern))) {
607 if (ls + (li-lp) >= len) {
608 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
609 (int)(ls + (li-lp) - len),
614 memmove(p+li,p+lp,strlen(p+lp)+1);
616 memcpy(p, insert, li);
624 Strchr and strrchr_m are a bit complex on general multi-byte strings.
626 char *strchr_m(const char *s, char c)
628 /* characters below 0x3F are guaranteed to not appear in
629 non-initial position in multi-byte charsets */
630 if ((c & 0xC0) == 0) {
636 codepoint_t c2 = next_codepoint(s, &size);
638 return discard_const(s);
646 char *strrchr_m(const char *s, char c)
650 /* characters below 0x3F are guaranteed to not appear in
651 non-initial position in multi-byte charsets */
652 if ((c & 0xC0) == 0) {
653 return strrchr(s, c);
658 codepoint_t c2 = next_codepoint(s, &size);
660 ret = discard_const(s);
669 return True if any (multi-byte) character is lower case
671 BOOL strhaslower(const char *string)
678 s = next_codepoint(string, &c_size);
684 return True; /* that means it has lower case chars */
692 return True if any (multi-byte) character is upper case
694 BOOL strhasupper(const char *string)
701 s = next_codepoint(string, &c_size);
707 return True; /* that means it has upper case chars */
715 Convert a string to lower case, allocated with talloc
717 char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
722 /* this takes advantage of the fact that upper/lower can't
723 change the length of a character by more than 1 byte */
724 dest = talloc_size(ctx, 2*(strlen(src))+1);
731 codepoint_t c = next_codepoint(src, &c_size);
736 c_size = push_codepoint(dest+size, c);
750 Convert a string to UPPER case, allocated with talloc
752 char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
761 /* this takes advantage of the fact that upper/lower can't
762 change the length of a character by more than 1 byte */
763 dest = talloc_size(ctx, 2*(strlen(src))+1);
770 codepoint_t c = next_codepoint(src, &c_size);
775 c_size = push_codepoint(dest+size, c);
789 Convert a string to lower case.
791 void strlower_m(char *s)
795 /* this is quite a common operation, so we want it to be
796 fast. We optimise for the ascii case, knowing that all our
797 supported multi-byte character sets are ascii-compatible
798 (ie. they match for the first 128 chars) */
799 while (*s && !(((uint8_t)*s) & 0x80)) {
800 *s = tolower((uint8_t)*s);
810 size_t c_size, c_size2;
811 codepoint_t c = next_codepoint(s, &c_size);
812 c_size2 = push_codepoint(d, tolower_w(c));
813 if (c_size2 > c_size) {
814 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
815 c, tolower_w(c), (int)c_size, (int)c_size2));
816 smb_panic("codepoint expansion in strlower_m\n");
825 Convert a string to UPPER case.
827 void strupper_m(char *s)
831 /* this is quite a common operation, so we want it to be
832 fast. We optimise for the ascii case, knowing that all our
833 supported multi-byte character sets are ascii-compatible
834 (ie. they match for the first 128 chars) */
835 while (*s && !(((uint8_t)*s) & 0x80)) {
836 *s = toupper((uint8_t)*s);
846 size_t c_size, c_size2;
847 codepoint_t c = next_codepoint(s, &c_size);
848 c_size2 = push_codepoint(d, toupper_w(c));
849 if (c_size2 > c_size) {
850 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
851 c, toupper_w(c), (int)c_size, (int)c_size2));
852 smb_panic("codepoint expansion in strupper_m\n");
861 Count the number of UCS2 characters in a string. Normally this will
862 be the same as the number of bytes in a string for single byte strings,
863 but will be different for multibyte.
865 size_t strlen_m(const char *s)
873 while (*s && !(((uint8_t)*s) & 0x80)) {
884 codepoint_t c = next_codepoint(s, &c_size);
897 Work out the number of multibyte chars in a string, including the NULL
900 size_t strlen_m_term(const char *s)
906 return strlen_m(s) + 1;
910 Unescape a URL encoded string, in place.
913 void rfc1738_unescape(char *buf)
917 while ((p=strchr_m(p,'+')))
922 while (p && *p && (p=strchr_m(p,'%'))) {
926 if (c1 >= '0' && c1 <= '9')
928 else if (c1 >= 'A' && c1 <= 'F')
930 else if (c1 >= 'a' && c1 <= 'f')
932 else {p++; continue;}
934 if (c2 >= '0' && c2 <= '9')
936 else if (c2 >= 'A' && c2 <= 'F')
938 else if (c2 >= 'a' && c2 <= 'f')
940 else {p++; continue;}
944 memmove(p+1, p+3, strlen(p+3)+1);
950 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
952 DATA_BLOB base64_decode_data_blob(TALLOC_CTX *mem_ctx, const char *s)
954 DATA_BLOB ret = data_blob_talloc(mem_ctx, s, strlen(s)+1);
955 ret.length = ldb_base64_decode((char *)ret.data);
960 * Decode a base64 string in-place - wrapper for the above
962 void base64_decode_inplace(char *s)
964 ldb_base64_decode(s);
968 * Encode a base64 string into a talloc()ed string caller to free.
970 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
972 return ldb_base64_encode(mem_ctx, (const char *)data.data, data.length);
976 size_t valgrind_strlen(const char *s)
979 for(count = 0; *s++; count++)
987 format a string into length-prefixed dotted domain format, as used in NBT
988 and in some ADS structures
990 const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s)
995 return talloc_strdup(mem_ctx, "");
997 ret = talloc_size(mem_ctx, strlen(s)+2);
1002 memcpy(ret+1, s, strlen(s)+1);
1005 for (i=0;ret[i];i++) {
1006 if (ret[i] == '.') {
1007 char *p = strchr(ret+i+1, '.');
1009 ret[i] = p-(ret+i+1);
1011 ret[i] = strlen(ret+i+1);
1019 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
1020 const char *str, const char ***strings, int *num)
1022 char *dup_str = talloc_strdup(mem_ctx, str);
1024 *strings = talloc_realloc(mem_ctx,
1026 const char *, ((*num)+1));
1028 if ((*strings == NULL) || (dup_str == NULL))
1031 (*strings)[*num] = dup_str;
1040 varient of strcmp() that handles NULL ptrs
1042 int strcmp_safe(const char *s1, const char *s2)
1047 if (s1 == NULL || s2 == NULL) {
1050 return strcmp(s1, s2);
1054 /*******************************************************************
1055 return the number of bytes occupied by a buffer in ASCII format
1056 the result includes the null termination
1057 limited by 'n' bytes
1058 ********************************************************************/
1059 size_t ascii_len_n(const char *src, size_t n)
1063 len = strnlen(src, n);
1072 /*******************************************************************
1073 Return a string representing a CIFS attribute for a file.
1074 ********************************************************************/
1075 char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
1082 {'V', FILE_ATTRIBUTE_VOLUME},
1083 {'D', FILE_ATTRIBUTE_DIRECTORY},
1084 {'A', FILE_ATTRIBUTE_ARCHIVE},
1085 {'H', FILE_ATTRIBUTE_HIDDEN},
1086 {'S', FILE_ATTRIBUTE_SYSTEM},
1087 {'N', FILE_ATTRIBUTE_NORMAL},
1088 {'R', FILE_ATTRIBUTE_READONLY},
1089 {'d', FILE_ATTRIBUTE_DEVICE},
1090 {'t', FILE_ATTRIBUTE_TEMPORARY},
1091 {'s', FILE_ATTRIBUTE_SPARSE},
1092 {'r', FILE_ATTRIBUTE_REPARSE_POINT},
1093 {'c', FILE_ATTRIBUTE_COMPRESSED},
1094 {'o', FILE_ATTRIBUTE_OFFLINE},
1095 {'n', FILE_ATTRIBUTE_NONINDEXED},
1096 {'e', FILE_ATTRIBUTE_ENCRYPTED}
1100 ret = talloc_size(mem_ctx, ARRAY_SIZE(attr_strs)+1);
1105 for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {
1106 if (attrib & attr_strs[i].attr) {
1107 ret[len++] = attr_strs[i].c;
1116 /***************************************************************************
1117 Set a boolean variable from the text value stored in the passed string.
1118 Returns True in success, False if the passed string does not correctly
1119 represent a boolean.
1120 ***************************************************************************/
1122 BOOL set_boolean(const char *boolean_string, BOOL *boolean)
1124 if (strwicmp(boolean_string, "yes") == 0 ||
1125 strwicmp(boolean_string, "true") == 0 ||
1126 strwicmp(boolean_string, "on") == 0 ||
1127 strwicmp(boolean_string, "1") == 0) {
1130 } else if (strwicmp(boolean_string, "no") == 0 ||
1131 strwicmp(boolean_string, "false") == 0 ||
1132 strwicmp(boolean_string, "off") == 0 ||
1133 strwicmp(boolean_string, "0") == 0) {
1140 BOOL conv_str_bool(const char * str, BOOL * val)
1145 if (str == NULL || *str == '\0') {
1149 lval = strtol(str, &end, 10 /* base */);
1150 if (end == NULL || *end != '\0' || end == str) {
1151 return set_boolean(str, val);
1154 *val = (lval) ? True : False;
1158 /* Convert a size specification like 16K into an integral number of bytes. */
1159 BOOL conv_str_size(const char * str, uint64_t * val)
1162 unsigned long long lval;
1164 if (str == NULL || *str == '\0') {
1168 lval = strtoull(str, &end, 10 /* base */);
1169 if (end == NULL || end == str) {
1174 if (strwicmp(end, "K") == 0) {
1176 } else if (strwicmp(end, "M") == 0) {
1177 lval *= (1024ULL * 1024ULL);
1178 } else if (strwicmp(end, "G") == 0) {
1179 lval *= (1024ULL * 1024ULL * 1024ULL);
1180 } else if (strwicmp(end, "T") == 0) {
1181 lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
1182 } else if (strwicmp(end, "P") == 0) {
1183 lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
1189 *val = (uint64_t)lval;
1193 BOOL conv_str_u64(const char * str, uint64_t * val)
1196 unsigned long long lval;
1198 if (str == NULL || *str == '\0') {
1202 lval = strtoull(str, &end, 10 /* base */);
1203 if (end == NULL || *end != '\0' || end == str) {
1207 *val = (uint64_t)lval;