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/>.
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 &&
73 (quoted || !strchr_m(sep,*s)); s++) {
82 *ptr = (*s) ? s+1 : s;
89 * Get the next token from a string, return false if none found. Handles
90 * double-quotes. This version trims leading separator characters before
91 * looking for a token.
93 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
95 return next_token_internal(ptr, buff, sep, bufsize, true);
99 * Get the next token from a string, return false if none found. Handles
100 * double-quotes. This version does not trim leading separator characters
101 * before looking for a token.
103 bool next_token_no_ltrim(const char **ptr,
108 return next_token_internal(ptr, buff, sep, bufsize, false);
112 This is like next_token but is not re-entrant and "remembers" the first
113 parameter so you can pass NULL. This is useful for user interface code
114 but beware the fact that it is not re-entrant!
117 static const char *last_ptr=NULL;
119 bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
125 ret = next_token(ptr, buff, sep, bufsize);
130 void set_first_token(char *ptr)
136 Convert list of tokens to array; dependent on above routine.
137 Uses last_ptr from above - bit of a hack.
140 char **toktocliplist(int *ctok, const char *sep)
142 char *s=(char *)last_ptr;
149 while(*s && strchr_m(sep,*s))
158 while(*s && (!strchr_m(sep,*s)))
160 while(*s && strchr_m(sep,*s))
167 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
185 * Case insensitive string compararison.
187 * iconv does not directly give us a way to compare strings in
188 * arbitrary unix character sets -- all we can is convert and then
189 * compare. This is expensive.
191 * As an optimization, we do a first pass that considers only the
192 * prefix of the strings that is entirely 7-bit. Within this, we
193 * check whether they have the same value.
195 * Hopefully this will often give the answer without needing to copy.
196 * In particular it should speed comparisons to literal ascii strings
197 * or comparisons of strings that are "obviously" different.
199 * If we find a non-ascii character we fall back to converting via
202 * This should never be slower than convering the whole thing, and
205 * A different optimization would be to compare for bitwise equality
206 * in the binary encoding. (It would be possible thought hairy to do
207 * both simultaneously.) But in that case if they turn out to be
208 * different, we'd need to restart the whole thing.
210 * Even better is to implement strcasecmp for each encoding and use a
213 int StrCaseCmp(const char *s, const char *t)
218 smb_ucs2_t *buffer_s, *buffer_t;
221 for (ps = s, pt = t; ; ps++, pt++) {
225 return 0; /* both ended */
227 return -1; /* s is a prefix */
229 return +1; /* t is a prefix */
230 else if ((*ps & 0x80) || (*pt & 0x80))
231 /* not ascii anymore, do it the hard way
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
253 size = push_ucs2_allocate(&buffer_t, pt);
254 if (size == (size_t)-1) {
256 return strcmp(ps, pt);
257 /* Not quite the right answer, but finding the right one
258 under this failure case is expensive, and it's pretty
262 ret = strcasecmp_w(buffer_s, buffer_t);
270 Case insensitive string compararison, length limited.
272 int StrnCaseCmp(const char *s, const char *t, size_t len)
277 smb_ucs2_t *buffer_s, *buffer_t;
280 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
284 return 0; /* both ended */
286 return -1; /* s is a prefix */
288 return +1; /* t is a prefix */
289 else if ((*ps & 0x80) || (*pt & 0x80))
290 /* not ascii anymore, do it the
291 * hard way from here on in */
294 us = toupper_ascii(*ps);
295 ut = toupper_ascii(*pt);
308 size = push_ucs2_allocate(&buffer_s, ps);
309 if (size == (size_t)-1) {
310 return strncmp(ps, pt, len-n);
311 /* Not quite the right answer, but finding the right one
312 under this failure case is expensive,
313 and it's pretty close */
316 size = push_ucs2_allocate(&buffer_t, pt);
317 if (size == (size_t)-1) {
319 return strncmp(ps, pt, len-n);
320 /* Not quite the right answer, but finding the right one
321 under this failure case is expensive,
322 and it's pretty close */
325 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
334 * @note The comparison is case-insensitive.
336 bool strequal(const char *s1, const char *s2)
343 return(StrCaseCmp(s1,s2)==0);
347 * Compare 2 strings up to and including the nth char.
349 * @note The comparison is case-insensitive.
351 bool strnequal(const char *s1,const char *s2,size_t n)
355 if (!s1 || !s2 || !n)
358 return(StrnCaseCmp(s1,s2,n)==0);
362 Compare 2 strings (case sensitive).
365 bool strcsequal(const char *s1,const char *s2)
372 return(strcmp(s1,s2)==0);
376 Do a case-insensitive, whitespace-ignoring string compare.
379 int strwicmp(const char *psz1, const char *psz2)
381 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
382 /* appropriate value. */
385 else if (psz1 == NULL)
387 else if (psz2 == NULL)
390 /* sync the strings on first non-whitespace */
392 while (isspace((int)*psz1))
394 while (isspace((int)*psz2))
396 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
397 *psz1 == '\0' || *psz2 == '\0')
402 return (*psz1 - *psz2);
407 Convert a string to upper case, but don't modify it.
410 char *strupper_static(const char *s)
412 static char *str = NULL;
421 Convert a string to "normal" form.
424 void strnorm(char *s, int case_default)
426 if (case_default == CASE_UPPER)
433 Check if a string is in "normal" case.
436 bool strisnormal(const char *s, int case_default)
438 if (case_default == CASE_UPPER)
439 return(!strhaslower(s));
441 return(!strhasupper(s));
447 NOTE: oldc and newc must be 7 bit characters
449 void string_replace( char *s, char oldc, char newc )
453 /* this is quite a common operation, so we want it to be
454 fast. We optimise for the ascii case, knowing that all our
455 supported multi-byte character sets are ascii-compatible
456 (ie. they match for the first 128 chars) */
458 for (p = s; *p; p++) {
459 if (*p & 0x80) /* mb string - slow path. */
469 /* Slow (mb) path. */
470 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
471 /* With compose characters we must restart from the beginning. JRA. */
477 next_codepoint(p, &c_size);
489 * Skip past some strings in a buffer - old version - no checks.
492 char *push_skip_string(char *buf)
494 buf += strlen(buf) + 1;
499 Skip past a string in a buffer. Buffer may not be
500 null terminated. end_ptr points to the first byte after
501 then end of the buffer.
504 char *skip_string(const char *base, size_t len, char *buf)
506 const char *end_ptr = base + len;
508 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
512 /* Skip the string */
515 if (buf >= end_ptr) {
525 Count the number of characters in a string. Normally this will
526 be the same as the number of bytes in a string for single byte strings,
527 but will be different for multibyte.
530 size_t str_charnum(const char *s)
533 smb_ucs2_t *tmpbuf2 = NULL;
534 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
537 ret = strlen_w(tmpbuf2);
543 Count the number of characters in a string. Normally this will
544 be the same as the number of bytes in a string for single byte strings,
545 but will be different for multibyte.
548 size_t str_ascii_charnum(const char *s)
551 char *tmpbuf2 = NULL;
552 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
555 ret = strlen(tmpbuf2);
560 bool trim_char(char *s,char cfront,char cback)
566 /* Ignore null or empty strings. */
567 if (!s || (s[0] == '\0'))
571 while (*fp && *fp == cfront)
574 /* We ate the string. */
582 ep = fp + strlen(fp) - 1;
584 /* Attempt ascii only. Bail for mb strings. */
585 while ((ep >= fp) && (*ep == cback)) {
587 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
588 /* Could be mb... bail back to tim_string. */
596 return trim_string(s, cfront ? fs : NULL, bs);
602 /* We ate the string. */
609 memmove(s, fp, ep-fp+2);
614 Trim the specified elements off the front and back of a string.
617 bool trim_string(char *s,const char *front,const char *back)
624 /* Ignore null or empty strings. */
625 if (!s || (s[0] == '\0'))
628 front_len = front? strlen(front) : 0;
629 back_len = back? strlen(back) : 0;
634 while (len && strncmp(s, front, front_len)==0) {
635 /* Must use memmove here as src & dest can
636 * easily overlap. Found by valgrind. JRA. */
637 memmove(s, s+front_len, (len-front_len)+1);
644 while ((len >= back_len) &&
645 strncmp(s+len-back_len,back,back_len)==0) {
646 s[len-back_len]='\0';
655 Does a string have any uppercase chars in it?
658 bool strhasupper(const char *s)
663 if (push_ucs2_allocate(&tmp, s) == -1) {
667 for(p = tmp; *p != 0; p++) {
679 Does a string have any lowercase chars in it?
682 bool strhaslower(const char *s)
687 if (push_ucs2_allocate(&tmp, s) == -1) {
691 for(p = tmp; *p != 0; p++) {
703 Find the number of 'c' chars in a string
706 size_t count_chars(const char *s,char c)
710 smb_ucs2_t *alloc_tmpbuf = NULL;
712 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
716 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
717 if(*ptr==UCS2_CHAR(c))
720 SAFE_FREE(alloc_tmpbuf);
725 Safe string copy into a known length string. maxlength does not
726 include the terminating zero.
729 char *safe_strcpy_fn(const char *fn,
738 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
739 "called from [%s][%d]\n", fn, line));
744 clobber_region(fn,line,dest, maxlength+1);
752 len = strnlen(src, maxlength+1);
754 if (len > maxlength) {
755 DEBUG(0,("ERROR: string overflow by "
756 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
757 (unsigned long)(len-maxlength), (unsigned long)len,
758 (unsigned long)maxlength, src));
762 memmove(dest, src, len);
768 Safe string cat into a string. maxlength does not
769 include the terminating zero.
771 char *safe_strcat_fn(const char *fn,
777 size_t src_len, dest_len;
780 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
781 "called from [%s][%d]\n", fn, line));
788 src_len = strnlen(src, maxlength + 1);
789 dest_len = strnlen(dest, maxlength + 1);
792 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
795 if (src_len + dest_len > maxlength) {
796 DEBUG(0,("ERROR: string overflow by %d "
797 "in safe_strcat [%.50s]\n",
798 (int)(src_len + dest_len - maxlength), src));
799 if (maxlength > dest_len) {
800 memcpy(&dest[dest_len], src, maxlength - dest_len);
806 memcpy(&dest[dest_len], src, src_len);
807 dest[dest_len + src_len] = 0;
812 Paranoid strcpy into a buffer of given length (includes terminating
813 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
814 and replaces with '_'. Deliberately does *NOT* check for multibyte
815 characters. Don't change it !
818 char *alpha_strcpy_fn(const char *fn,
822 const char *other_safe_chars,
828 clobber_region(fn, line, dest, maxlength);
832 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
833 "called from [%s][%d]\n", fn, line));
843 if (len >= maxlength)
846 if (!other_safe_chars)
847 other_safe_chars = "";
849 for(i = 0; i < len; i++) {
850 int val = (src[i] & 0xff);
851 if (isupper_ascii(val) || islower_ascii(val) ||
852 isdigit(val) || strchr_m(other_safe_chars, val))
864 Like strncpy but always null terminates. Make sure there is room!
865 The variable n should always be one less than the available size.
867 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
872 clobber_region(fn, line, dest, n+1);
876 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
877 "called from [%s][%d]\n", fn, line));
886 while (n-- && (*d = *src)) {
897 Like strncpy but copies up to the character marker. always null terminates.
898 returns a pointer to the character marker in the source string (src).
901 static char *strncpyn(char *dest, const char *src, size_t n, char c)
907 clobber_region(dest, n+1);
909 p = strchr_m(src, c);
911 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
915 str_len = PTR_DIFF(p, src);
916 strncpy(dest, src, MIN(n, str_len));
917 dest[str_len] = '\0';
924 Routine to get hex characters and turn them into a 16 byte array.
925 the array can be variable length, and any non-hex-numeric
926 characters are skipped. "0xnn" or "0Xnn" is specially catered
929 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
933 size_t strhex_to_str(char *p, size_t len, const char *strhex)
936 size_t num_chars = 0;
937 unsigned char lonybble, hinybble;
938 const char *hexchars = "0123456789ABCDEF";
939 char *p1 = NULL, *p2 = NULL;
941 for (i = 0; i < len && strhex[i] != 0; i++) {
942 if (strnequal(hexchars, "0x", 2)) {
943 i++; /* skip two chars */
947 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
950 i++; /* next hex digit */
952 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
955 /* get the two nybbles */
956 hinybble = PTR_DIFF(p1, hexchars);
957 lonybble = PTR_DIFF(p2, hexchars);
959 p[num_chars] = (hinybble << 4) | lonybble;
968 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
973 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
975 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
977 ret_blob.length = strhex_to_str((char*)ret_blob.data,
985 * Routine to print a buffer as HEX digits, into an allocated string.
988 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
993 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
995 for (i = 0; i < len; i++)
996 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
1002 Check if a string is part of a list.
1005 bool in_list(const char *s, const char *list, bool casesensitive)
1009 size_t bufsize = strlen(list);
1015 /* We know a token can't be larger
1016 * than the entire list. */
1018 tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1023 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1024 if (casesensitive) {
1025 if (strcmp(tok,s) == 0) {
1030 if (StrCaseCmp(tok,s) == 0) {
1041 /* this is used to prevent lots of mallocs of size 1 */
1042 static const char *null_string = "";
1045 Set a string value, allocing the space for the string
1048 static bool string_init(char **dest,const char *src)
1058 *dest = CONST_DISCARD(char*, null_string);
1060 (*dest) = SMB_STRDUP(src);
1061 if ((*dest) == NULL) {
1062 DEBUG(0,("Out of memory in string_init\n"));
1070 Free a string value.
1073 void string_free(char **s)
1077 if (*s == null_string)
1083 Set a string value, deallocating any existing space, and allocing the space
1087 bool string_set(char **dest,const char *src)
1090 return(string_init(dest,src));
1094 Substitute a string for a pattern in another string. Make sure there is
1097 This routine looks for pattern in s and replaces it with
1098 insert. It may do multiple replacements or just one.
1100 Any of " ; ' $ or ` in the insert string are replaced with _
1101 if len==0 then the string cannot be extended. This is different from the old
1102 use of len==0 which was for no length checks to be done.
1105 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1106 bool remove_unsafe_characters, bool replace_once,
1107 bool allow_trailing_dollar)
1110 ssize_t ls,lp,li, i;
1112 if (!insert || !pattern || !*pattern || !s)
1115 ls = (ssize_t)strlen(s);
1116 lp = (ssize_t)strlen(pattern);
1117 li = (ssize_t)strlen(insert);
1120 len = ls + 1; /* len is number of *bytes* */
1122 while (lp <= ls && (p = strstr_m(s,pattern))) {
1123 if (ls + (li-lp) >= len) {
1124 DEBUG(0,("ERROR: string overflow by "
1125 "%d in string_sub(%.50s, %d)\n",
1126 (int)(ls + (li-lp) - len),
1127 pattern, (int)len));
1131 memmove(p+li,p+lp,strlen(p+lp)+1);
1133 for (i=0;i<li;i++) {
1134 switch (insert[i]) {
1140 /* allow a trailing $
1141 * (as in machine accounts) */
1142 if (allow_trailing_dollar && (i == li - 1 )) {
1149 if ( remove_unsafe_characters ) {
1151 /* yes this break should be here
1152 * since we want to fall throw if
1153 * not replacing unsafe chars */
1168 void string_sub_once(char *s, const char *pattern,
1169 const char *insert, size_t len)
1171 string_sub2( s, pattern, insert, len, true, true, false );
1174 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1176 string_sub2( s, pattern, insert, len, true, false, false );
1179 void fstring_sub(char *s,const char *pattern,const char *insert)
1181 string_sub(s, pattern, insert, sizeof(fstring));
1184 void pstring_sub(char *s,const char *pattern,const char *insert)
1186 string_sub(s, pattern, insert, sizeof(pstring));
1190 Similar to string_sub2, but it will accept only allocated strings
1191 and may realloc them so pay attention at what you pass on no
1192 pointers inside strings, no pstrings or const may be passed
1196 char *realloc_string_sub2(char *string,
1197 const char *pattern,
1199 bool remove_unsafe_characters,
1200 bool allow_trailing_dollar)
1204 ssize_t ls,lp,li,ld, i;
1206 if (!insert || !pattern || !*pattern || !string || !*string)
1211 in = SMB_STRDUP(insert);
1213 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1216 ls = (ssize_t)strlen(s);
1217 lp = (ssize_t)strlen(pattern);
1218 li = (ssize_t)strlen(insert);
1220 for (i=0;i<li;i++) {
1227 /* allow a trailing $
1228 * (as in machine accounts) */
1229 if (allow_trailing_dollar && (i == li - 1 )) {
1235 if ( remove_unsafe_characters ) {
1245 while ((p = strstr_m(s,pattern))) {
1247 int offset = PTR_DIFF(s,string);
1248 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1250 DEBUG(0, ("realloc_string_sub: "
1251 "out of memory!\n"));
1255 p = string + offset + (p - s);
1258 memmove(p+li,p+lp,strlen(p+lp)+1);
1268 char *realloc_string_sub(char *string,
1269 const char *pattern,
1272 return realloc_string_sub2(string, pattern, insert, true, false);
1276 * Internal guts of talloc_string_sub and talloc_all_string_sub.
1277 * talloc version of string_sub2.
1280 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
1281 const char *pattern,
1283 bool remove_unsafe_characters,
1285 bool allow_trailing_dollar)
1290 ssize_t ls,lp,li,ld, i;
1292 if (!insert || !pattern || !*pattern || !src || !*src) {
1296 string = talloc_strdup(mem_ctx, src);
1297 if (string == NULL) {
1298 DEBUG(0, ("talloc_string_sub2: "
1299 "talloc_strdup failed\n"));
1305 in = SMB_STRDUP(insert);
1307 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
1310 ls = (ssize_t)strlen(s);
1311 lp = (ssize_t)strlen(pattern);
1312 li = (ssize_t)strlen(insert);
1315 for (i=0;i<li;i++) {
1322 /* allow a trailing $
1323 * (as in machine accounts) */
1324 if (allow_trailing_dollar && (i == li - 1 )) {
1330 if (remove_unsafe_characters) {
1340 while ((p = strstr_m(s,pattern))) {
1342 int offset = PTR_DIFF(s,string);
1343 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1346 DEBUG(0, ("talloc_string_sub: out of "
1351 p = string + offset + (p - s);
1354 memmove(p+li,p+lp,strlen(p+lp)+1);
1368 /* Same as string_sub, but returns a talloc'ed string */
1370 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1372 const char *pattern,
1375 return talloc_string_sub2(mem_ctx, src, pattern, insert,
1376 true, false, false);
1380 Similar to string_sub() but allows for any character to be substituted.
1382 if len==0 then the string cannot be extended. This is different from the old
1383 use of len==0 which was for no length checks to be done.
1386 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1391 if (!insert || !pattern || !s)
1394 ls = (ssize_t)strlen(s);
1395 lp = (ssize_t)strlen(pattern);
1396 li = (ssize_t)strlen(insert);
1402 len = ls + 1; /* len is number of *bytes* */
1404 while (lp <= ls && (p = strstr_m(s,pattern))) {
1405 if (ls + (li-lp) >= len) {
1406 DEBUG(0,("ERROR: string overflow by "
1407 "%d in all_string_sub(%.50s, %d)\n",
1408 (int)(ls + (li-lp) - len),
1409 pattern, (int)len));
1413 memmove(p+li,p+lp,strlen(p+lp)+1);
1415 memcpy(p, insert, li);
1421 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1423 const char *pattern,
1426 return talloc_string_sub2(ctx, src, pattern, insert,
1427 false, false, false);
1432 Splits out the front and back at a separator.
1435 static void split_at_last_component(char *path, char *front, char sep,
1438 char *p = strrchr_m(path, sep);
1444 pstrcpy(front, path);
1458 Write an octal as a string.
1461 const char *octal_string(int i)
1463 static char ret[64];
1466 slprintf(ret, sizeof(ret)-1, "0%o", i);
1472 Truncate a string at a specified length.
1475 char *string_truncate(char *s, unsigned int length)
1477 if (s && strlen(s) > length)
1483 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1484 We convert via ucs2 for now.
1487 char *strchr_m(const char *src, char c)
1489 smb_ucs2_t *ws = NULL;
1495 /* characters below 0x3F are guaranteed to not appear in
1496 non-initial position in multi-byte charsets */
1497 if ((c & 0xC0) == 0) {
1498 return strchr(src, c);
1501 /* this is quite a common operation, so we want it to be
1502 fast. We optimise for the ascii case, knowing that all our
1503 supported multi-byte character sets are ascii-compatible
1504 (ie. they match for the first 128 chars) */
1506 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1514 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1515 /* With compose characters we must restart from the beginning. JRA. */
1519 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1520 /* Wrong answer, but what can we do... */
1521 return strchr(src, c);
1523 p = strchr_w(ws, UCS2_CHAR(c));
1529 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1531 /* Wrong answer, but what can we do... */
1532 return strchr(src, c);
1534 ret = (char *)(s+strlen(s2));
1540 char *strrchr_m(const char *s, char c)
1542 /* characters below 0x3F are guaranteed to not appear in
1543 non-initial position in multi-byte charsets */
1544 if ((c & 0xC0) == 0) {
1545 return strrchr(s, c);
1548 /* this is quite a common operation, so we want it to be
1549 fast. We optimise for the ascii case, knowing that all our
1550 supported multi-byte character sets are ascii-compatible
1551 (ie. they match for the first 128 chars). Also, in Samba
1552 we only search for ascii characters in 'c' and that
1553 in all mb character sets with a compound character
1554 containing c, if 'c' is not a match at position
1555 p, then p[-1] > 0x7f. JRA. */
1558 size_t len = strlen(s);
1560 bool got_mb = false;
1567 /* Could be a match. Part of a multibyte ? */
1569 (((unsigned char)cp[-1]) & 0x80)) {
1570 /* Yep - go slow :-( */
1574 /* No - we have a match ! */
1577 } while (cp-- != s);
1582 /* String contained a non-ascii char. Slow path. */
1584 smb_ucs2_t *ws = NULL;
1589 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1590 /* Wrong answer, but what can we do. */
1591 return strrchr(s, c);
1593 p = strrchr_w(ws, UCS2_CHAR(c));
1599 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1601 /* Wrong answer, but what can we do. */
1602 return strrchr(s, c);
1604 ret = (char *)(s+strlen(s2));
1611 /***********************************************************************
1612 Return the equivalent of doing strrchr 'n' times - always going
1614 ***********************************************************************/
1616 char *strnrchr_m(const char *s, char c, unsigned int n)
1618 smb_ucs2_t *ws = NULL;
1623 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1624 /* Too hard to try and get right. */
1627 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1633 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1635 /* Too hard to try and get right. */
1638 ret = (char *)(s+strlen(s2));
1644 /***********************************************************************
1645 strstr_m - We convert via ucs2 for now.
1646 ***********************************************************************/
1648 char *strstr_m(const char *src, const char *findstr)
1651 smb_ucs2_t *src_w, *find_w;
1656 size_t findstr_len = 0;
1658 /* for correctness */
1663 /* Samba does single character findstr calls a *lot*. */
1664 if (findstr[1] == '\0')
1665 return strchr_m(src, *findstr);
1667 /* We optimise for the ascii case, knowing that all our
1668 supported multi-byte character sets are ascii-compatible
1669 (ie. they match for the first 128 chars) */
1671 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1672 if (*s == *findstr) {
1674 findstr_len = strlen(findstr);
1676 if (strncmp(s, findstr, findstr_len) == 0) {
1685 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1686 /* 'make check' fails unless we do this */
1688 /* With compose characters we must restart from the beginning. JRA. */
1692 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1693 DEBUG(0,("strstr_m: src malloc fail\n"));
1697 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1699 DEBUG(0,("strstr_m: find malloc fail\n"));
1703 p = strstr_w(src_w, find_w);
1712 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1715 DEBUG(0,("strstr_m: dest malloc fail\n"));
1718 retp = (char *)(s+strlen(s2));
1726 Convert a string to lower case.
1729 void strlower_m(char *s)
1734 /* this is quite a common operation, so we want it to be
1735 fast. We optimise for the ascii case, knowing that all our
1736 supported multi-byte character sets are ascii-compatible
1737 (ie. they match for the first 128 chars) */
1739 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1740 *s = tolower_ascii((unsigned char)*s);
1747 /* I assume that lowercased string takes the same number of bytes
1748 * as source string even in UTF-8 encoding. (VIV) */
1749 len = strlen(s) + 1;
1752 unix_strlower(s,len,s,len);
1753 /* Catch mb conversion errors that may not terminate. */
1760 Convert a string to upper case.
1763 void strupper_m(char *s)
1768 /* this is quite a common operation, so we want it to be
1769 fast. We optimise for the ascii case, knowing that all our
1770 supported multi-byte character sets are ascii-compatible
1771 (ie. they match for the first 128 chars) */
1773 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1774 *s = toupper_ascii((unsigned char)*s);
1781 /* I assume that lowercased string takes the same number of bytes
1782 * as source string even in multibyte encoding. (VIV) */
1783 len = strlen(s) + 1;
1786 unix_strupper(s,len,s,len);
1787 /* Catch mb conversion errors that may not terminate. */
1794 Count the number of UCS2 characters in a string. Normally this will
1795 be the same as the number of bytes in a string for single byte strings,
1796 but will be different for multibyte.
1799 size_t strlen_m(const char *s)
1807 while (*s && !(((uint8_t)*s) & 0x80)) {
1818 codepoint_t c = next_codepoint(s, &c_size);
1820 /* Unicode char fits into 16 bits. */
1823 /* Double-width unicode char - 32 bits. */
1833 Count the number of UCS2 characters in a string including the null
1837 size_t strlen_m_term(const char *s)
1842 return strlen_m(s) + 1;
1846 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1847 * if a string is there, include the terminator.
1850 size_t strlen_m_term_null(const char *s)
1864 Return a RFC2254 binary string representation of a buffer.
1865 Used in LDAP filters.
1869 char *binary_string_rfc2254(char *buf, int len)
1873 const char *hex = "0123456789ABCDEF";
1874 s = (char *)SMB_MALLOC(len * 3 + 1);
1877 for (j=i=0;i<len;i++) {
1879 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1880 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1887 char *binary_string(char *buf, int len)
1891 const char *hex = "0123456789ABCDEF";
1892 s = (char *)SMB_MALLOC(len * 2 + 1);
1895 for (j=i=0;i<len;i++) {
1896 s[j] = hex[((unsigned char)buf[i]) >> 4];
1897 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1904 Just a typesafety wrapper for snprintf into a pstring.
1907 int pstr_sprintf(pstring s, const char *fmt, ...)
1913 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1920 Just a typesafety wrapper for snprintf into a fstring.
1923 int fstr_sprintf(fstring s, const char *fmt, ...)
1929 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1935 List of Strings manipulation functions
1938 #define S_LIST_ABS 16 /* List Allocation Block Size */
1940 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
1944 char **list, **rlist;
1950 if (!string || !*string)
1953 s = talloc_strdup(mem_ctx, string);
1955 s = SMB_STRDUP(string);
1958 DEBUG(0,("str_list_make: Unable to allocate memory"));
1961 if (!sep) sep = LIST_SEP;
1967 while (next_token(&str, tok, sep, sizeof(tok))) {
1969 lsize += S_LIST_ABS;
1971 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
1974 /* We need to keep the old list on
1975 * error so we can free the elements
1976 if the realloc fails. */
1977 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
1981 DEBUG(0,("str_list_make: "
1982 "Unable to allocate memory"));
1983 str_list_free(&list);
1993 memset (&list[num], 0,
1994 ((sizeof(char**)) * (S_LIST_ABS +1)));
1998 list[num] = talloc_strdup(mem_ctx, tok);
2000 list[num] = SMB_STRDUP(tok);
2004 DEBUG(0,("str_list_make: Unable to allocate memory"));
2005 str_list_free(&list);
2026 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
2030 return str_list_make_internal(mem_ctx, string, sep);
2033 char **str_list_make(const char *string, const char *sep)
2035 return str_list_make_internal(NULL, string, sep);
2038 bool str_list_copy(char ***dest, const char **src)
2040 char **list, **rlist;
2052 lsize += S_LIST_ABS;
2053 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2056 DEBUG(0,("str_list_copy: "
2057 "Unable to re-allocate memory"));
2058 str_list_free(&list);
2063 memset (&list[num], 0,
2064 ((sizeof(char **)) * (S_LIST_ABS +1)));
2067 list[num] = SMB_STRDUP(src[num]);
2069 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2070 str_list_free(&list);
2082 * Return true if all the elements of the list match exactly.
2084 bool str_list_compare(char **list1, char **list2)
2088 if (!list1 || !list2)
2089 return (list1 == list2);
2091 for (num = 0; list1[num]; num++) {
2094 if (!strcsequal(list1[num], list2[num]))
2098 return false; /* if list2 has more elements than list1 fail */
2103 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2107 if (!list || !*list)
2110 for(; *tlist; tlist++) {
2112 TALLOC_FREE(*tlist);
2118 TALLOC_FREE(*tlist);
2124 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2126 str_list_free_internal(mem_ctx, list);
2129 void str_list_free(char ***list)
2131 str_list_free_internal(NULL, list);
2134 /******************************************************************************
2135 *****************************************************************************/
2137 int str_list_count( const char **list )
2144 /* count the number of list members */
2146 for ( i=0; *list; i++, list++ );
2151 /******************************************************************************
2152 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2154 *****************************************************************************/
2156 bool str_list_sub_basic( char **list, const char *smb_name,
2157 const char *domain_name )
2163 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2165 DEBUG(0,("str_list_sub_basic: "
2166 "alloc_sub_basic() return NULL!\n"));
2179 /******************************************************************************
2180 substritute a specific pattern in a string list
2181 *****************************************************************************/
2183 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2186 ssize_t ls, lp, li, ld, i, d;
2195 lp = (ssize_t)strlen(pattern);
2196 li = (ssize_t)strlen(insert);
2201 ls = (ssize_t)strlen(s);
2203 while ((p = strstr_m(s, pattern))) {
2207 t = (char *) SMB_MALLOC(ls +ld +1);
2209 DEBUG(0,("str_list_substitute: "
2210 "Unable to allocate memory"));
2213 memcpy(t, *list, d);
2214 memcpy(t +d +li, p +lp, ls -d -lp +1);
2221 for (i = 0; i < li; i++) {
2222 switch (insert[i]) {
2234 t[d +i] = insert[i];
2246 #define IPSTR_LIST_SEP ","
2247 #define IPSTR_LIST_CHAR ','
2250 * Add ip string representation to ipstr list. Used also
2251 * as part of @function ipstr_list_make
2253 * @param ipstr_list pointer to string containing ip list;
2254 * MUST BE already allocated and IS reallocated if necessary
2255 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2256 * as a result of reallocation)
2257 * @param ip IP address which is to be added to list
2258 * @return pointer to string appended with new ip and possibly
2259 * reallocated to new length
2262 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2264 char *new_ipstr = NULL;
2265 char addr_buf[INET6_ADDRSTRLEN];
2267 /* arguments checking */
2268 if (!ipstr_list || !service) {
2272 print_sockaddr(addr_buf,
2276 /* attempt to convert ip to a string and append colon separator to it */
2278 if (service->ss.ss_family == AF_INET) {
2280 asprintf(&new_ipstr, "%s%s%s:%d",
2287 asprintf(&new_ipstr, "%s%s[%s]:%d",
2293 SAFE_FREE(*ipstr_list);
2295 if (service->ss.ss_family == AF_INET) {
2297 asprintf(&new_ipstr, "%s:%d",
2302 asprintf(&new_ipstr, "[%s]:%d",
2307 *ipstr_list = new_ipstr;
2312 * Allocate and initialise an ipstr list using ip adresses
2313 * passed as arguments.
2315 * @param ipstr_list pointer to string meant to be allocated and set
2316 * @param ip_list array of ip addresses to place in the list
2317 * @param ip_count number of addresses stored in ip_list
2318 * @return pointer to allocated ip string
2321 char *ipstr_list_make(char **ipstr_list,
2322 const struct ip_service *ip_list,
2327 /* arguments checking */
2328 if (!ip_list || !ipstr_list) {
2334 /* process ip addresses given as arguments */
2335 for (i = 0; i < ip_count; i++) {
2336 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2339 return (*ipstr_list);
2344 * Parse given ip string list into array of ip addresses
2345 * (as ip_service structures)
2346 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2348 * @param ipstr ip string list to be parsed
2349 * @param ip_list pointer to array of ip addresses which is
2350 * allocated by this function and must be freed by caller
2351 * @return number of succesfully parsed addresses
2354 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2360 if (!ipstr_list || !ip_list)
2363 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2364 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2365 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2366 (unsigned long)count));
2370 for ( i=0; next_token(&ipstr_list, token_str,
2371 IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
2372 char *s = token_str;
2373 char *p = strrchr(token_str, ':');
2377 (*ip_list)[i].port = atoi(p+1);
2380 /* convert single token to ip address */
2381 if (token_str[0] == '[') {
2384 p = strchr(token_str, ']');
2390 if (!interpret_string_addr(&(*ip_list)[i].ss,
2401 * Safely free ip string list
2403 * @param ipstr_list ip string list to be freed
2406 void ipstr_list_free(char* ipstr_list)
2408 SAFE_FREE(ipstr_list);
2412 Unescape a URL encoded string, in place.
2415 void rfc1738_unescape(char *buf)
2419 while (p && *p && (p=strchr_m(p,'%'))) {
2423 if (c1 >= '0' && c1 <= '9')
2425 else if (c1 >= 'A' && c1 <= 'F')
2427 else if (c1 >= 'a' && c1 <= 'f')
2429 else {p++; continue;}
2431 if (c2 >= '0' && c2 <= '9')
2433 else if (c2 >= 'A' && c2 <= 'F')
2435 else if (c2 >= 'a' && c2 <= 'f')
2437 else {p++; continue;}
2441 memmove(p+1, p+3, strlen(p+3)+1);
2446 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2449 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2451 DATA_BLOB base64_decode_data_blob(const char *s)
2453 int bit_offset, byte_offset, idx, i, n;
2454 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2455 unsigned char *d = decoded.data;
2460 while (*s && (p=strchr_m(b64,*s))) {
2461 idx = (int)(p - b64);
2462 byte_offset = (i*6)/8;
2463 bit_offset = (i*6)%8;
2464 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2465 if (bit_offset < 3) {
2466 d[byte_offset] |= (idx << (2-bit_offset));
2469 d[byte_offset] |= (idx >> (bit_offset-2));
2470 d[byte_offset+1] = 0;
2471 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2477 if ((n > 0) && (*s == '=')) {
2487 * Decode a base64 string in-place - wrapper for the above
2489 void base64_decode_inplace(char *s)
2491 DATA_BLOB decoded = base64_decode_data_blob(s);
2493 if ( decoded.length != 0 ) {
2494 memcpy(s, decoded.data, decoded.length);
2496 /* null terminate */
2497 s[decoded.length] = '\0';
2502 data_blob_free(&decoded);
2506 * Encode a base64 string into a malloc()ed string caller to free.
2508 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2512 char *base64_encode_data_blob(DATA_BLOB data)
2516 size_t out_cnt, len, output_len;
2519 if (!data.length || !data.data)
2524 output_len = data.length * 2;
2525 result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */
2526 SMB_ASSERT(result != NULL);
2528 while (len-- && out_cnt < (data.length * 2) - 5) {
2529 int c = (unsigned char) *(data.data++);
2532 if (char_count == 3) {
2533 result[out_cnt++] = b64[bits >> 18];
2534 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2535 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2536 result[out_cnt++] = b64[bits & 0x3f];
2543 if (char_count != 0) {
2544 bits <<= 16 - (8 * char_count);
2545 result[out_cnt++] = b64[bits >> 18];
2546 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2547 if (char_count == 1) {
2548 result[out_cnt++] = '=';
2549 result[out_cnt++] = '=';
2551 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2552 result[out_cnt++] = '=';
2555 result[out_cnt] = '\0'; /* terminate */
2559 /* read a SMB_BIG_UINT from a string */
2560 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2563 SMB_BIG_UINT val = -1;
2564 const char *p = nptr;
2573 while (*p && isspace(*p))
2576 #ifdef LARGE_SMB_OFF_T
2577 sscanf(p,"%llu",&val);
2578 #else /* LARGE_SMB_OFF_T */
2579 sscanf(p,"%lu",&val);
2580 #endif /* LARGE_SMB_OFF_T */
2582 while (*p && isdigit(*p))
2590 /* Convert a size specification to a count of bytes. We accept the following
2592 * bytes if there is no suffix
2597 * pP whatever the ISO name for petabytes is
2599 * Returns 0 if the string can't be converted.
2601 SMB_OFF_T conv_str_size(const char * str)
2606 if (str == NULL || *str == '\0') {
2610 #ifdef HAVE_STRTOULL
2611 if (sizeof(SMB_OFF_T) == 8) {
2612 lval = strtoull(str, &end, 10 /* base */);
2614 lval = strtoul(str, &end, 10 /* base */);
2617 lval = strtoul(str, &end, 10 /* base */);
2620 if (end == NULL || end == str) {
2625 SMB_OFF_T lval_orig = lval;
2627 if (strwicmp(end, "K") == 0) {
2628 lval *= (SMB_OFF_T)1024;
2629 } else if (strwicmp(end, "M") == 0) {
2630 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2631 } else if (strwicmp(end, "G") == 0) {
2632 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2634 } else if (strwicmp(end, "T") == 0) {
2635 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2636 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2637 } else if (strwicmp(end, "P") == 0) {
2638 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2639 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2645 /* Primitive attempt to detect wrapping on platforms with
2646 * 4-byte SMB_OFF_T. It's better to let the caller handle
2647 * a failure than some random number.
2649 if (lval_orig <= lval) {
2657 void string_append(char **left, const char *right)
2659 int new_len = strlen(right) + 1;
2661 if (*left == NULL) {
2662 *left = (char *)SMB_MALLOC(new_len);
2665 new_len += strlen(*left);
2666 *left = (char *)SMB_REALLOC(*left, new_len);
2669 if (*left == NULL) {
2673 safe_strcat(*left, right, new_len-1);
2676 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2677 const char *str, const char ***strings,
2680 char *dup_str = talloc_strdup(mem_ctx, str);
2682 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2683 const char *, (*num)+1);
2685 if ((*strings == NULL) || (dup_str == NULL)) {
2690 (*strings)[*num] = dup_str;
2695 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2696 * error checking in between. The indiation that something weird happened is
2699 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2700 size_t *bufsize, const char *fmt, ...)
2707 /* len<0 is an internal marker that something failed */
2711 if (*string == NULL) {
2715 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2716 if (*string == NULL)
2721 ret = vasprintf(&newstr, fmt, ap);
2729 while ((*len)+ret >= *bufsize) {
2732 if (*bufsize >= (1024*1024*256))
2737 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2739 if (*string == NULL) {
2744 StrnCpy((*string)+(*len), newstr, ret);
2755 Returns the substring from src between the first occurrence of
2756 the char "front" and the first occurence of the char "back".
2757 Mallocs the return string which must be freed. Not for use
2758 with wide character strings.
2760 char *sstring_sub(const char *src, char front, char back)
2762 char *temp1, *temp2, *temp3;
2765 temp1 = strchr(src, front);
2766 if (temp1 == NULL) return NULL;
2767 temp2 = strchr(src, back);
2768 if (temp2 == NULL) return NULL;
2769 len = temp2 - temp1;
2770 if (len <= 0) return NULL;
2771 temp3 = (char*)SMB_MALLOC(len);
2772 if (temp3 == NULL) {
2773 DEBUG(1,("Malloc failure in sstring_sub\n"));
2776 memcpy(temp3, temp1+1, len-1);
2777 temp3[len-1] = '\0';
2781 /********************************************************************
2782 Check a string for any occurrences of a specified list of invalid
2784 ********************************************************************/
2786 bool validate_net_name( const char *name,
2787 const char *invalid_chars,
2792 for ( i=0; i<max_len && name[i]; i++ ) {
2793 /* fail if strchr_m() finds one of the invalid characters */
2794 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2804 return the number of bytes occupied by a buffer in ASCII format
2805 the result includes the null termination
2806 limited by 'n' bytes
2808 size_t ascii_len_n(const char *src, size_t n)
2812 len = strnlen(src, n);
2821 return the number of bytes occupied by a buffer in CH_UTF16 format
2822 the result includes the null termination
2824 size_t utf16_len(const void *buf)
2828 for (len = 0; SVAL(buf,len); len += 2) ;
2834 return the number of bytes occupied by a buffer in CH_UTF16 format
2835 the result includes the null termination
2836 limited by 'n' bytes
2838 size_t utf16_len_n(const void *src, size_t n)
2842 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2851 /*******************************************************************
2852 Add a shell escape character '\' to any character not in a known list
2853 of characters. UNIX charset format.
2854 *******************************************************************/
2856 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2857 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2859 char *escape_shell_string(const char *src)
2861 size_t srclen = strlen(src);
2862 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2864 bool in_s_quote = false;
2865 bool in_d_quote = false;
2866 bool next_escaped = false;
2874 codepoint_t c = next_codepoint(src, &c_size);
2876 if (c == INVALID_CODEPOINT) {
2882 memcpy(dest, src, c_size);
2885 next_escaped = false;
2890 * Deal with backslash escaped state.
2891 * This only lasts for one character.
2896 next_escaped = false;
2901 * Deal with single quote state. The
2902 * only thing we care about is exiting
2915 * Deal with double quote state. The most
2916 * complex state. We must cope with \, meaning
2917 * possibly escape next char (depending what it
2918 * is), ", meaning exit this state, and possibly
2919 * add an \ escape to any unprotected character
2920 * (listed in INSIDE_DQUOTE_LIST).
2926 * Next character might be escaped.
2927 * We have to peek. Inside double
2928 * quotes only INSIDE_DQUOTE_LIST
2929 * characters are escaped by a \.
2934 c = next_codepoint(&src[1], &c_size);
2935 if (c == INVALID_CODEPOINT) {
2941 * Don't escape the next char.
2950 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2952 next_escaped = true;
2959 /* Exit double quote state. */
2966 * We know the character isn't \ or ",
2967 * so escape it if it's any of the other
2968 * possible unprotected characters.
2971 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2979 * From here to the end of the loop we're
2980 * not in the single or double quote state.
2984 /* Next character must be escaped. */
2985 next_escaped = true;
2991 /* Go into single quote state. */
2998 /* Go into double quote state. */
3004 /* Check if we need to escape the character. */
3006 if (!strchr(INCLUDE_LIST, (int)*src)) {