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;
419 return CONST_DISCARD(char *,s);
426 Convert a string to "normal" form.
429 void strnorm(char *s, int case_default)
431 if (case_default == CASE_UPPER)
438 Check if a string is in "normal" case.
441 bool strisnormal(const char *s, int case_default)
443 if (case_default == CASE_UPPER)
444 return(!strhaslower(s));
446 return(!strhasupper(s));
452 NOTE: oldc and newc must be 7 bit characters
454 void string_replace( char *s, char oldc, char newc )
458 /* this is quite a common operation, so we want it to be
459 fast. We optimise for the ascii case, knowing that all our
460 supported multi-byte character sets are ascii-compatible
461 (ie. they match for the first 128 chars) */
463 for (p = s; *p; p++) {
464 if (*p & 0x80) /* mb string - slow path. */
474 /* Slow (mb) path. */
475 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
476 /* With compose characters we must restart from the beginning. JRA. */
482 next_codepoint(p, &c_size);
494 * Skip past some strings in a buffer - old version - no checks.
497 char *push_skip_string(char *buf)
499 buf += strlen(buf) + 1;
504 Skip past a string in a buffer. Buffer may not be
505 null terminated. end_ptr points to the first byte after
506 then end of the buffer.
509 char *skip_string(const char *base, size_t len, char *buf)
511 const char *end_ptr = base + len;
513 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
517 /* Skip the string */
520 if (buf >= end_ptr) {
530 Count the number of characters in a string. Normally this will
531 be the same as the number of bytes in a string for single byte strings,
532 but will be different for multibyte.
535 size_t str_charnum(const char *s)
538 smb_ucs2_t *tmpbuf2 = NULL;
539 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
542 ret = strlen_w(tmpbuf2);
548 Count the number of characters in a string. Normally this will
549 be the same as the number of bytes in a string for single byte strings,
550 but will be different for multibyte.
553 size_t str_ascii_charnum(const char *s)
556 char *tmpbuf2 = NULL;
557 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
560 ret = strlen(tmpbuf2);
565 bool trim_char(char *s,char cfront,char cback)
571 /* Ignore null or empty strings. */
572 if (!s || (s[0] == '\0'))
576 while (*fp && *fp == cfront)
579 /* We ate the string. */
587 ep = fp + strlen(fp) - 1;
589 /* Attempt ascii only. Bail for mb strings. */
590 while ((ep >= fp) && (*ep == cback)) {
592 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
593 /* Could be mb... bail back to tim_string. */
601 return trim_string(s, cfront ? fs : NULL, bs);
607 /* We ate the string. */
614 memmove(s, fp, ep-fp+2);
619 Trim the specified elements off the front and back of a string.
622 bool trim_string(char *s,const char *front,const char *back)
629 /* Ignore null or empty strings. */
630 if (!s || (s[0] == '\0'))
633 front_len = front? strlen(front) : 0;
634 back_len = back? strlen(back) : 0;
639 while (len && strncmp(s, front, front_len)==0) {
640 /* Must use memmove here as src & dest can
641 * easily overlap. Found by valgrind. JRA. */
642 memmove(s, s+front_len, (len-front_len)+1);
649 while ((len >= back_len) &&
650 strncmp(s+len-back_len,back,back_len)==0) {
651 s[len-back_len]='\0';
660 Does a string have any uppercase chars in it?
663 bool strhasupper(const char *s)
668 if (push_ucs2_allocate(&tmp, s) == -1) {
672 for(p = tmp; *p != 0; p++) {
684 Does a string have any lowercase chars in it?
687 bool strhaslower(const char *s)
692 if (push_ucs2_allocate(&tmp, s) == -1) {
696 for(p = tmp; *p != 0; p++) {
708 Find the number of 'c' chars in a string
711 size_t count_chars(const char *s,char c)
715 smb_ucs2_t *alloc_tmpbuf = NULL;
717 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
721 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
722 if(*ptr==UCS2_CHAR(c))
725 SAFE_FREE(alloc_tmpbuf);
730 Safe string copy into a known length string. maxlength does not
731 include the terminating zero.
734 char *safe_strcpy_fn(const char *fn,
743 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
744 "called from [%s][%d]\n", fn, line));
749 clobber_region(fn,line,dest, maxlength+1);
757 len = strnlen(src, maxlength+1);
759 if (len > maxlength) {
760 DEBUG(0,("ERROR: string overflow by "
761 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
762 (unsigned long)(len-maxlength), (unsigned long)len,
763 (unsigned long)maxlength, src));
767 memmove(dest, src, len);
773 Safe string cat into a string. maxlength does not
774 include the terminating zero.
776 char *safe_strcat_fn(const char *fn,
782 size_t src_len, dest_len;
785 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
786 "called from [%s][%d]\n", fn, line));
793 src_len = strnlen(src, maxlength + 1);
794 dest_len = strnlen(dest, maxlength + 1);
797 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
800 if (src_len + dest_len > maxlength) {
801 DEBUG(0,("ERROR: string overflow by %d "
802 "in safe_strcat [%.50s]\n",
803 (int)(src_len + dest_len - maxlength), src));
804 if (maxlength > dest_len) {
805 memcpy(&dest[dest_len], src, maxlength - dest_len);
811 memcpy(&dest[dest_len], src, src_len);
812 dest[dest_len + src_len] = 0;
817 Paranoid strcpy into a buffer of given length (includes terminating
818 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
819 and replaces with '_'. Deliberately does *NOT* check for multibyte
820 characters. Don't change it !
823 char *alpha_strcpy_fn(const char *fn,
827 const char *other_safe_chars,
833 clobber_region(fn, line, dest, maxlength);
837 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
838 "called from [%s][%d]\n", fn, line));
848 if (len >= maxlength)
851 if (!other_safe_chars)
852 other_safe_chars = "";
854 for(i = 0; i < len; i++) {
855 int val = (src[i] & 0xff);
856 if (isupper_ascii(val) || islower_ascii(val) ||
857 isdigit(val) || strchr_m(other_safe_chars, val))
869 Like strncpy but always null terminates. Make sure there is room!
870 The variable n should always be one less than the available size.
872 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
877 clobber_region(fn, line, dest, n+1);
881 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
882 "called from [%s][%d]\n", fn, line));
891 while (n-- && (*d = *src)) {
902 Like strncpy but copies up to the character marker. always null terminates.
903 returns a pointer to the character marker in the source string (src).
906 static char *strncpyn(char *dest, const char *src, size_t n, char c)
912 clobber_region(dest, n+1);
914 p = strchr_m(src, c);
916 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
920 str_len = PTR_DIFF(p, src);
921 strncpy(dest, src, MIN(n, str_len));
922 dest[str_len] = '\0';
929 Routine to get hex characters and turn them into a 16 byte array.
930 the array can be variable length, and any non-hex-numeric
931 characters are skipped. "0xnn" or "0Xnn" is specially catered
934 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
938 size_t strhex_to_str(char *p, size_t len, const char *strhex)
941 size_t num_chars = 0;
942 unsigned char lonybble, hinybble;
943 const char *hexchars = "0123456789ABCDEF";
944 char *p1 = NULL, *p2 = NULL;
946 for (i = 0; i < len && strhex[i] != 0; i++) {
947 if (strnequal(hexchars, "0x", 2)) {
948 i++; /* skip two chars */
952 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
955 i++; /* next hex digit */
957 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
960 /* get the two nybbles */
961 hinybble = PTR_DIFF(p1, hexchars);
962 lonybble = PTR_DIFF(p2, hexchars);
964 p[num_chars] = (hinybble << 4) | lonybble;
973 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
978 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
980 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
982 ret_blob.length = strhex_to_str((char*)ret_blob.data,
990 * Routine to print a buffer as HEX digits, into an allocated string.
993 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
998 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
1000 for (i = 0; i < len; i++)
1001 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
1007 Check if a string is part of a list.
1010 bool in_list(const char *s, const char *list, bool casesensitive)
1014 size_t bufsize = strlen(list);
1020 /* We know a token can't be larger
1021 * than the entire list. */
1023 tok = SMB_MALLOC_ARRAY(char, bufsize+1);
1028 while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
1029 if (casesensitive) {
1030 if (strcmp(tok,s) == 0) {
1035 if (StrCaseCmp(tok,s) == 0) {
1046 /* this is used to prevent lots of mallocs of size 1 */
1047 static const char *null_string = "";
1050 Set a string value, allocing the space for the string
1053 static bool string_init(char **dest,const char *src)
1063 *dest = CONST_DISCARD(char*, null_string);
1065 (*dest) = SMB_STRDUP(src);
1066 if ((*dest) == NULL) {
1067 DEBUG(0,("Out of memory in string_init\n"));
1075 Free a string value.
1078 void string_free(char **s)
1082 if (*s == null_string)
1088 Set a string value, deallocating any existing space, and allocing the space
1092 bool string_set(char **dest,const char *src)
1095 return(string_init(dest,src));
1099 Substitute a string for a pattern in another string. Make sure there is
1102 This routine looks for pattern in s and replaces it with
1103 insert. It may do multiple replacements or just one.
1105 Any of " ; ' $ or ` in the insert string are replaced with _
1106 if len==0 then the string cannot be extended. This is different from the old
1107 use of len==0 which was for no length checks to be done.
1110 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1111 bool remove_unsafe_characters, bool replace_once,
1112 bool allow_trailing_dollar)
1115 ssize_t ls,lp,li, i;
1117 if (!insert || !pattern || !*pattern || !s)
1120 ls = (ssize_t)strlen(s);
1121 lp = (ssize_t)strlen(pattern);
1122 li = (ssize_t)strlen(insert);
1125 len = ls + 1; /* len is number of *bytes* */
1127 while (lp <= ls && (p = strstr_m(s,pattern))) {
1128 if (ls + (li-lp) >= len) {
1129 DEBUG(0,("ERROR: string overflow by "
1130 "%d in string_sub(%.50s, %d)\n",
1131 (int)(ls + (li-lp) - len),
1132 pattern, (int)len));
1136 memmove(p+li,p+lp,strlen(p+lp)+1);
1138 for (i=0;i<li;i++) {
1139 switch (insert[i]) {
1145 /* allow a trailing $
1146 * (as in machine accounts) */
1147 if (allow_trailing_dollar && (i == li - 1 )) {
1154 if ( remove_unsafe_characters ) {
1156 /* yes this break should be here
1157 * since we want to fall throw if
1158 * not replacing unsafe chars */
1173 void string_sub_once(char *s, const char *pattern,
1174 const char *insert, size_t len)
1176 string_sub2( s, pattern, insert, len, true, true, false );
1179 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1181 string_sub2( s, pattern, insert, len, true, false, false );
1184 void fstring_sub(char *s,const char *pattern,const char *insert)
1186 string_sub(s, pattern, insert, sizeof(fstring));
1189 void pstring_sub(char *s,const char *pattern,const char *insert)
1191 string_sub(s, pattern, insert, sizeof(pstring));
1195 Similar to string_sub, but it will accept only allocated strings
1196 and may realloc them so pay attention at what you pass on no
1197 pointers inside strings, no pstrings or const may be passed
1201 char *realloc_string_sub(char *string, const char *pattern,
1206 ssize_t ls,lp,li,ld, i;
1208 if (!insert || !pattern || !*pattern || !string || !*string)
1213 in = SMB_STRDUP(insert);
1215 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1218 ls = (ssize_t)strlen(s);
1219 lp = (ssize_t)strlen(pattern);
1220 li = (ssize_t)strlen(insert);
1222 for (i=0;i<li;i++) {
1239 while ((p = strstr_m(s,pattern))) {
1241 int offset = PTR_DIFF(s,string);
1242 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1244 DEBUG(0, ("realloc_string_sub: "
1245 "out of memory!\n"));
1249 p = string + offset + (p - s);
1252 memmove(p+li,p+lp,strlen(p+lp)+1);
1262 /* Same as string_sub, but returns a talloc'ed string */
1264 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1265 const char *pattern, const char *insert)
1270 ssize_t ls,lp,li,ld, i;
1272 if (!insert || !pattern || !*pattern || !src || !*src)
1275 string = talloc_strdup(mem_ctx, src);
1276 if (string == NULL) {
1277 DEBUG(0, ("talloc_strdup failed\n"));
1283 in = SMB_STRDUP(insert);
1285 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1288 ls = (ssize_t)strlen(s);
1289 lp = (ssize_t)strlen(pattern);
1290 li = (ssize_t)strlen(insert);
1292 for (i=0;i<li;i++) {
1309 while ((p = strstr_m(s,pattern))) {
1311 int offset = PTR_DIFF(s,string);
1312 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1315 DEBUG(0, ("talloc_string_sub: out of "
1320 p = string + offset + (p - s);
1323 memmove(p+li,p+lp,strlen(p+lp)+1);
1334 Similar to string_sub() but allows for any character to be substituted.
1336 if len==0 then the string cannot be extended. This is different from the old
1337 use of len==0 which was for no length checks to be done.
1340 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1345 if (!insert || !pattern || !s)
1348 ls = (ssize_t)strlen(s);
1349 lp = (ssize_t)strlen(pattern);
1350 li = (ssize_t)strlen(insert);
1356 len = ls + 1; /* len is number of *bytes* */
1358 while (lp <= ls && (p = strstr_m(s,pattern))) {
1359 if (ls + (li-lp) >= len) {
1360 DEBUG(0,("ERROR: string overflow by "
1361 "%d in all_string_sub(%.50s, %d)\n",
1362 (int)(ls + (li-lp) - len),
1363 pattern, (int)len));
1367 memmove(p+li,p+lp,strlen(p+lp)+1);
1369 memcpy(p, insert, li);
1376 Similar to all_string_sub but for unicode strings.
1377 Return a new allocated unicode string.
1378 similar to string_sub() but allows for any character to be substituted.
1382 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s,
1383 const smb_ucs2_t *pattern,
1384 const smb_ucs2_t *insert)
1387 const smb_ucs2_t *sp;
1388 size_t lr, lp, li, lt;
1390 if (!insert || !pattern || !*pattern || !s)
1393 lt = (size_t)strlen_w(s);
1394 lp = (size_t)strlen_w(pattern);
1395 li = (size_t)strlen_w(insert);
1398 const smb_ucs2_t *st = s;
1400 while ((sp = strstr_w(st, pattern))) {
1406 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1408 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1412 while ((sp = strstr_w(s, pattern))) {
1413 memcpy(rp, s, (sp - s));
1414 rp += ((sp - s) / sizeof(smb_ucs2_t));
1415 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1419 lr = ((rp - r) / sizeof(smb_ucs2_t));
1421 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1429 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1434 if (!insert || !pattern || !s)
1436 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1437 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1438 return all_string_sub_w(s, p, i);
1443 Splits out the front and back at a separator.
1446 static void split_at_last_component(char *path, char *front, char sep,
1449 char *p = strrchr_m(path, sep);
1455 pstrcpy(front, path);
1469 Write an octal as a string.
1472 const char *octal_string(int i)
1474 static char ret[64];
1477 slprintf(ret, sizeof(ret)-1, "0%o", i);
1483 Truncate a string at a specified length.
1486 char *string_truncate(char *s, unsigned int length)
1488 if (s && strlen(s) > length)
1494 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1495 We convert via ucs2 for now.
1498 char *strchr_m(const char *src, char c)
1500 smb_ucs2_t *ws = NULL;
1506 /* characters below 0x3F are guaranteed to not appear in
1507 non-initial position in multi-byte charsets */
1508 if ((c & 0xC0) == 0) {
1509 return strchr(src, c);
1512 /* this is quite a common operation, so we want it to be
1513 fast. We optimise for the ascii case, knowing that all our
1514 supported multi-byte character sets are ascii-compatible
1515 (ie. they match for the first 128 chars) */
1517 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1525 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1526 /* With compose characters we must restart from the beginning. JRA. */
1530 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1531 /* Wrong answer, but what can we do... */
1532 return strchr(src, c);
1534 p = strchr_w(ws, UCS2_CHAR(c));
1540 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1542 /* Wrong answer, but what can we do... */
1543 return strchr(src, c);
1545 ret = (char *)(s+strlen(s2));
1551 char *strrchr_m(const char *s, char c)
1553 /* characters below 0x3F are guaranteed to not appear in
1554 non-initial position in multi-byte charsets */
1555 if ((c & 0xC0) == 0) {
1556 return strrchr(s, c);
1559 /* this is quite a common operation, so we want it to be
1560 fast. We optimise for the ascii case, knowing that all our
1561 supported multi-byte character sets are ascii-compatible
1562 (ie. they match for the first 128 chars). Also, in Samba
1563 we only search for ascii characters in 'c' and that
1564 in all mb character sets with a compound character
1565 containing c, if 'c' is not a match at position
1566 p, then p[-1] > 0x7f. JRA. */
1569 size_t len = strlen(s);
1571 bool got_mb = false;
1578 /* Could be a match. Part of a multibyte ? */
1580 (((unsigned char)cp[-1]) & 0x80)) {
1581 /* Yep - go slow :-( */
1585 /* No - we have a match ! */
1588 } while (cp-- != s);
1593 /* String contained a non-ascii char. Slow path. */
1595 smb_ucs2_t *ws = NULL;
1600 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1601 /* Wrong answer, but what can we do. */
1602 return strrchr(s, c);
1604 p = strrchr_w(ws, UCS2_CHAR(c));
1610 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1612 /* Wrong answer, but what can we do. */
1613 return strrchr(s, c);
1615 ret = (char *)(s+strlen(s2));
1622 /***********************************************************************
1623 Return the equivalent of doing strrchr 'n' times - always going
1625 ***********************************************************************/
1627 char *strnrchr_m(const char *s, char c, unsigned int n)
1629 smb_ucs2_t *ws = NULL;
1634 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1635 /* Too hard to try and get right. */
1638 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1644 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1646 /* Too hard to try and get right. */
1649 ret = (char *)(s+strlen(s2));
1655 /***********************************************************************
1656 strstr_m - We convert via ucs2 for now.
1657 ***********************************************************************/
1659 char *strstr_m(const char *src, const char *findstr)
1662 smb_ucs2_t *src_w, *find_w;
1667 size_t findstr_len = 0;
1669 /* for correctness */
1674 /* Samba does single character findstr calls a *lot*. */
1675 if (findstr[1] == '\0')
1676 return strchr_m(src, *findstr);
1678 /* We optimise for the ascii case, knowing that all our
1679 supported multi-byte character sets are ascii-compatible
1680 (ie. they match for the first 128 chars) */
1682 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1683 if (*s == *findstr) {
1685 findstr_len = strlen(findstr);
1687 if (strncmp(s, findstr, findstr_len) == 0) {
1696 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1697 /* 'make check' fails unless we do this */
1699 /* With compose characters we must restart from the beginning. JRA. */
1703 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1704 DEBUG(0,("strstr_m: src malloc fail\n"));
1708 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1710 DEBUG(0,("strstr_m: find malloc fail\n"));
1714 p = strstr_w(src_w, find_w);
1723 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1726 DEBUG(0,("strstr_m: dest malloc fail\n"));
1729 retp = (char *)(s+strlen(s2));
1737 Convert a string to lower case.
1740 void strlower_m(char *s)
1745 /* this is quite a common operation, so we want it to be
1746 fast. We optimise for the ascii case, knowing that all our
1747 supported multi-byte character sets are ascii-compatible
1748 (ie. they match for the first 128 chars) */
1750 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1751 *s = tolower_ascii((unsigned char)*s);
1758 /* I assume that lowercased string takes the same number of bytes
1759 * as source string even in UTF-8 encoding. (VIV) */
1760 len = strlen(s) + 1;
1763 unix_strlower(s,len,s,len);
1764 /* Catch mb conversion errors that may not terminate. */
1771 Convert a string to upper case.
1774 void strupper_m(char *s)
1779 /* this is quite a common operation, so we want it to be
1780 fast. We optimise for the ascii case, knowing that all our
1781 supported multi-byte character sets are ascii-compatible
1782 (ie. they match for the first 128 chars) */
1784 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1785 *s = toupper_ascii((unsigned char)*s);
1792 /* I assume that lowercased string takes the same number of bytes
1793 * as source string even in multibyte encoding. (VIV) */
1794 len = strlen(s) + 1;
1797 unix_strupper(s,len,s,len);
1798 /* Catch mb conversion errors that may not terminate. */
1805 Count the number of UCS2 characters in a string. Normally this will
1806 be the same as the number of bytes in a string for single byte strings,
1807 but will be different for multibyte.
1810 size_t strlen_m(const char *s)
1818 while (*s && !(((uint8_t)*s) & 0x80)) {
1829 codepoint_t c = next_codepoint(s, &c_size);
1831 /* Unicode char fits into 16 bits. */
1834 /* Double-width unicode char - 32 bits. */
1844 Count the number of UCS2 characters in a string including the null
1848 size_t strlen_m_term(const char *s)
1853 return strlen_m(s) + 1;
1857 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1858 * if a string is there, include the terminator.
1861 size_t strlen_m_term_null(const char *s)
1875 Return a RFC2254 binary string representation of a buffer.
1876 Used in LDAP filters.
1880 char *binary_string_rfc2254(char *buf, int len)
1884 const char *hex = "0123456789ABCDEF";
1885 s = (char *)SMB_MALLOC(len * 3 + 1);
1888 for (j=i=0;i<len;i++) {
1890 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1891 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1898 char *binary_string(char *buf, int len)
1902 const char *hex = "0123456789ABCDEF";
1903 s = (char *)SMB_MALLOC(len * 2 + 1);
1906 for (j=i=0;i<len;i++) {
1907 s[j] = hex[((unsigned char)buf[i]) >> 4];
1908 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1915 Just a typesafety wrapper for snprintf into a pstring.
1918 int pstr_sprintf(pstring s, const char *fmt, ...)
1924 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1931 Just a typesafety wrapper for snprintf into a fstring.
1934 int fstr_sprintf(fstring s, const char *fmt, ...)
1940 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1946 List of Strings manipulation functions
1949 #define S_LIST_ABS 16 /* List Allocation Block Size */
1951 static char **str_list_make_internal(TALLOC_CTX *mem_ctx,
1955 char **list, **rlist;
1961 if (!string || !*string)
1964 s = talloc_strdup(mem_ctx, string);
1966 s = SMB_STRDUP(string);
1969 DEBUG(0,("str_list_make: Unable to allocate memory"));
1972 if (!sep) sep = LIST_SEP;
1978 while (next_token(&str, tok, sep, sizeof(tok))) {
1980 lsize += S_LIST_ABS;
1982 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list,
1985 /* We need to keep the old list on
1986 * error so we can free the elements
1987 if the realloc fails. */
1988 rlist =SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
1992 DEBUG(0,("str_list_make: "
1993 "Unable to allocate memory"));
1994 str_list_free(&list);
2004 memset (&list[num], 0,
2005 ((sizeof(char**)) * (S_LIST_ABS +1)));
2009 list[num] = talloc_strdup(mem_ctx, tok);
2011 list[num] = SMB_STRDUP(tok);
2015 DEBUG(0,("str_list_make: Unable to allocate memory"));
2016 str_list_free(&list);
2037 char **str_list_make_talloc(TALLOC_CTX *mem_ctx,
2041 return str_list_make_internal(mem_ctx, string, sep);
2044 char **str_list_make(const char *string, const char *sep)
2046 return str_list_make_internal(NULL, string, sep);
2049 bool str_list_copy(char ***dest, const char **src)
2051 char **list, **rlist;
2063 lsize += S_LIST_ABS;
2064 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list,
2067 DEBUG(0,("str_list_copy: "
2068 "Unable to re-allocate memory"));
2069 str_list_free(&list);
2074 memset (&list[num], 0,
2075 ((sizeof(char **)) * (S_LIST_ABS +1)));
2078 list[num] = SMB_STRDUP(src[num]);
2080 DEBUG(0,("str_list_copy: Unable to allocate memory"));
2081 str_list_free(&list);
2093 * Return true if all the elements of the list match exactly.
2095 bool str_list_compare(char **list1, char **list2)
2099 if (!list1 || !list2)
2100 return (list1 == list2);
2102 for (num = 0; list1[num]; num++) {
2105 if (!strcsequal(list1[num], list2[num]))
2109 return false; /* if list2 has more elements than list1 fail */
2114 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
2118 if (!list || !*list)
2121 for(; *tlist; tlist++) {
2123 TALLOC_FREE(*tlist);
2129 TALLOC_FREE(*tlist);
2135 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
2137 str_list_free_internal(mem_ctx, list);
2140 void str_list_free(char ***list)
2142 str_list_free_internal(NULL, list);
2145 /******************************************************************************
2146 *****************************************************************************/
2148 int str_list_count( const char **list )
2155 /* count the number of list members */
2157 for ( i=0; *list; i++, list++ );
2162 /******************************************************************************
2163 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
2165 *****************************************************************************/
2167 bool str_list_sub_basic( char **list, const char *smb_name,
2168 const char *domain_name )
2174 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2176 DEBUG(0,("str_list_sub_basic: "
2177 "alloc_sub_basic() return NULL!\n"));
2190 /******************************************************************************
2191 substritute a specific pattern in a string list
2192 *****************************************************************************/
2194 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2197 ssize_t ls, lp, li, ld, i, d;
2206 lp = (ssize_t)strlen(pattern);
2207 li = (ssize_t)strlen(insert);
2212 ls = (ssize_t)strlen(s);
2214 while ((p = strstr_m(s, pattern))) {
2218 t = (char *) SMB_MALLOC(ls +ld +1);
2220 DEBUG(0,("str_list_substitute: "
2221 "Unable to allocate memory"));
2224 memcpy(t, *list, d);
2225 memcpy(t +d +li, p +lp, ls -d -lp +1);
2232 for (i = 0; i < li; i++) {
2233 switch (insert[i]) {
2245 t[d +i] = insert[i];
2257 #define IPSTR_LIST_SEP ","
2258 #define IPSTR_LIST_CHAR ','
2261 * Add ip string representation to ipstr list. Used also
2262 * as part of @function ipstr_list_make
2264 * @param ipstr_list pointer to string containing ip list;
2265 * MUST BE already allocated and IS reallocated if necessary
2266 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2267 * as a result of reallocation)
2268 * @param ip IP address which is to be added to list
2269 * @return pointer to string appended with new ip and possibly
2270 * reallocated to new length
2273 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2275 char *new_ipstr = NULL;
2276 char addr_buf[INET6_ADDRSTRLEN];
2278 /* arguments checking */
2279 if (!ipstr_list || !service) {
2283 print_sockaddr(addr_buf,
2287 /* attempt to convert ip to a string and append colon separator to it */
2289 if (service->ss.ss_family == AF_INET) {
2291 asprintf(&new_ipstr, "%s%s%s:%d",
2298 asprintf(&new_ipstr, "%s%s[%s]:%d",
2304 SAFE_FREE(*ipstr_list);
2306 if (service->ss.ss_family == AF_INET) {
2308 asprintf(&new_ipstr, "%s:%d",
2313 asprintf(&new_ipstr, "[%s]:%d",
2318 *ipstr_list = new_ipstr;
2323 * Allocate and initialise an ipstr list using ip adresses
2324 * passed as arguments.
2326 * @param ipstr_list pointer to string meant to be allocated and set
2327 * @param ip_list array of ip addresses to place in the list
2328 * @param ip_count number of addresses stored in ip_list
2329 * @return pointer to allocated ip string
2332 char *ipstr_list_make(char **ipstr_list,
2333 const struct ip_service *ip_list,
2338 /* arguments checking */
2339 if (!ip_list || !ipstr_list) {
2345 /* process ip addresses given as arguments */
2346 for (i = 0; i < ip_count; i++) {
2347 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2350 return (*ipstr_list);
2355 * Parse given ip string list into array of ip addresses
2356 * (as ip_service structures)
2357 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2359 * @param ipstr ip string list to be parsed
2360 * @param ip_list pointer to array of ip addresses which is
2361 * allocated by this function and must be freed by caller
2362 * @return number of succesfully parsed addresses
2365 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2371 if (!ipstr_list || !ip_list)
2374 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2375 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2376 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2377 (unsigned long)count));
2381 for ( i=0; next_token(&ipstr_list, token_str,
2382 IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
2383 char *s = token_str;
2384 char *p = strrchr(token_str, ':');
2388 (*ip_list)[i].port = atoi(p+1);
2391 /* convert single token to ip address */
2392 if (token_str[0] == '[') {
2395 p = strchr(token_str, ']');
2401 if (!interpret_string_addr(&(*ip_list)[i].ss,
2412 * Safely free ip string list
2414 * @param ipstr_list ip string list to be freed
2417 void ipstr_list_free(char* ipstr_list)
2419 SAFE_FREE(ipstr_list);
2423 Unescape a URL encoded string, in place.
2426 void rfc1738_unescape(char *buf)
2430 while (p && *p && (p=strchr_m(p,'%'))) {
2434 if (c1 >= '0' && c1 <= '9')
2436 else if (c1 >= 'A' && c1 <= 'F')
2438 else if (c1 >= 'a' && c1 <= 'f')
2440 else {p++; continue;}
2442 if (c2 >= '0' && c2 <= '9')
2444 else if (c2 >= 'A' && c2 <= 'F')
2446 else if (c2 >= 'a' && c2 <= 'f')
2448 else {p++; continue;}
2452 memmove(p+1, p+3, strlen(p+3)+1);
2457 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2460 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2462 DATA_BLOB base64_decode_data_blob(const char *s)
2464 int bit_offset, byte_offset, idx, i, n;
2465 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2466 unsigned char *d = decoded.data;
2471 while (*s && (p=strchr_m(b64,*s))) {
2472 idx = (int)(p - b64);
2473 byte_offset = (i*6)/8;
2474 bit_offset = (i*6)%8;
2475 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2476 if (bit_offset < 3) {
2477 d[byte_offset] |= (idx << (2-bit_offset));
2480 d[byte_offset] |= (idx >> (bit_offset-2));
2481 d[byte_offset+1] = 0;
2482 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2488 if ((n > 0) && (*s == '=')) {
2498 * Decode a base64 string in-place - wrapper for the above
2500 void base64_decode_inplace(char *s)
2502 DATA_BLOB decoded = base64_decode_data_blob(s);
2504 if ( decoded.length != 0 ) {
2505 memcpy(s, decoded.data, decoded.length);
2507 /* null terminate */
2508 s[decoded.length] = '\0';
2513 data_blob_free(&decoded);
2517 * Encode a base64 string into a malloc()ed string caller to free.
2519 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2523 char *base64_encode_data_blob(DATA_BLOB data)
2527 size_t out_cnt, len, output_len;
2530 if (!data.length || !data.data)
2535 output_len = data.length * 2;
2536 result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2538 while (len-- && out_cnt < (data.length * 2) - 5) {
2539 int c = (unsigned char) *(data.data++);
2542 if (char_count == 3) {
2543 result[out_cnt++] = b64[bits >> 18];
2544 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2545 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2546 result[out_cnt++] = b64[bits & 0x3f];
2553 if (char_count != 0) {
2554 bits <<= 16 - (8 * char_count);
2555 result[out_cnt++] = b64[bits >> 18];
2556 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2557 if (char_count == 1) {
2558 result[out_cnt++] = '=';
2559 result[out_cnt++] = '=';
2561 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2562 result[out_cnt++] = '=';
2565 result[out_cnt] = '\0'; /* terminate */
2569 /* read a SMB_BIG_UINT from a string */
2570 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2573 SMB_BIG_UINT val = -1;
2574 const char *p = nptr;
2583 while (*p && isspace(*p))
2586 #ifdef LARGE_SMB_OFF_T
2587 sscanf(p,"%llu",&val);
2588 #else /* LARGE_SMB_OFF_T */
2589 sscanf(p,"%lu",&val);
2590 #endif /* LARGE_SMB_OFF_T */
2592 while (*p && isdigit(*p))
2600 /* Convert a size specification to a count of bytes. We accept the following
2602 * bytes if there is no suffix
2607 * pP whatever the ISO name for petabytes is
2609 * Returns 0 if the string can't be converted.
2611 SMB_OFF_T conv_str_size(const char * str)
2616 if (str == NULL || *str == '\0') {
2620 #ifdef HAVE_STRTOULL
2621 if (sizeof(SMB_OFF_T) == 8) {
2622 lval = strtoull(str, &end, 10 /* base */);
2624 lval = strtoul(str, &end, 10 /* base */);
2627 lval = strtoul(str, &end, 10 /* base */);
2630 if (end == NULL || end == str) {
2635 SMB_OFF_T lval_orig = lval;
2637 if (strwicmp(end, "K") == 0) {
2638 lval *= (SMB_OFF_T)1024;
2639 } else if (strwicmp(end, "M") == 0) {
2640 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2641 } else if (strwicmp(end, "G") == 0) {
2642 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2644 } else if (strwicmp(end, "T") == 0) {
2645 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2646 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2647 } else if (strwicmp(end, "P") == 0) {
2648 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2649 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2655 /* Primitive attempt to detect wrapping on platforms with
2656 * 4-byte SMB_OFF_T. It's better to let the caller handle
2657 * a failure than some random number.
2659 if (lval_orig <= lval) {
2667 void string_append(char **left, const char *right)
2669 int new_len = strlen(right) + 1;
2671 if (*left == NULL) {
2672 *left = (char *)SMB_MALLOC(new_len);
2675 new_len += strlen(*left);
2676 *left = (char *)SMB_REALLOC(*left, new_len);
2679 if (*left == NULL) {
2683 safe_strcat(*left, right, new_len-1);
2686 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2687 const char *str, const char ***strings,
2690 char *dup_str = talloc_strdup(mem_ctx, str);
2692 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2693 const char *, (*num)+1);
2695 if ((*strings == NULL) || (dup_str == NULL)) {
2700 (*strings)[*num] = dup_str;
2705 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2706 * error checking in between. The indiation that something weird happened is
2709 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2710 size_t *bufsize, const char *fmt, ...)
2717 /* len<0 is an internal marker that something failed */
2721 if (*string == NULL) {
2725 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2726 if (*string == NULL)
2731 ret = vasprintf(&newstr, fmt, ap);
2739 while ((*len)+ret >= *bufsize) {
2742 if (*bufsize >= (1024*1024*256))
2747 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2749 if (*string == NULL) {
2754 StrnCpy((*string)+(*len), newstr, ret);
2765 Returns the substring from src between the first occurrence of
2766 the char "front" and the first occurence of the char "back".
2767 Mallocs the return string which must be freed. Not for use
2768 with wide character strings.
2770 char *sstring_sub(const char *src, char front, char back)
2772 char *temp1, *temp2, *temp3;
2775 temp1 = strchr(src, front);
2776 if (temp1 == NULL) return NULL;
2777 temp2 = strchr(src, back);
2778 if (temp2 == NULL) return NULL;
2779 len = temp2 - temp1;
2780 if (len <= 0) return NULL;
2781 temp3 = (char*)SMB_MALLOC(len);
2782 if (temp3 == NULL) {
2783 DEBUG(1,("Malloc failure in sstring_sub\n"));
2786 memcpy(temp3, temp1+1, len-1);
2787 temp3[len-1] = '\0';
2791 /********************************************************************
2792 Check a string for any occurrences of a specified list of invalid
2794 ********************************************************************/
2796 bool validate_net_name( const char *name,
2797 const char *invalid_chars,
2802 for ( i=0; i<max_len && name[i]; i++ ) {
2803 /* fail if strchr_m() finds one of the invalid characters */
2804 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2814 return the number of bytes occupied by a buffer in ASCII format
2815 the result includes the null termination
2816 limited by 'n' bytes
2818 size_t ascii_len_n(const char *src, size_t n)
2822 len = strnlen(src, n);
2831 return the number of bytes occupied by a buffer in CH_UTF16 format
2832 the result includes the null termination
2834 size_t utf16_len(const void *buf)
2838 for (len = 0; SVAL(buf,len); len += 2) ;
2844 return the number of bytes occupied by a buffer in CH_UTF16 format
2845 the result includes the null termination
2846 limited by 'n' bytes
2848 size_t utf16_len_n(const void *src, size_t n)
2852 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2861 /*******************************************************************
2862 Add a shell escape character '\' to any character not in a known list
2863 of characters. UNIX charset format.
2864 *******************************************************************/
2866 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2867 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2869 char *escape_shell_string(const char *src)
2871 size_t srclen = strlen(src);
2872 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2874 bool in_s_quote = false;
2875 bool in_d_quote = false;
2876 bool next_escaped = false;
2884 codepoint_t c = next_codepoint(src, &c_size);
2886 if (c == INVALID_CODEPOINT) {
2892 memcpy(dest, src, c_size);
2895 next_escaped = false;
2900 * Deal with backslash escaped state.
2901 * This only lasts for one character.
2906 next_escaped = false;
2911 * Deal with single quote state. The
2912 * only thing we care about is exiting
2925 * Deal with double quote state. The most
2926 * complex state. We must cope with \, meaning
2927 * possibly escape next char (depending what it
2928 * is), ", meaning exit this state, and possibly
2929 * add an \ escape to any unprotected character
2930 * (listed in INSIDE_DQUOTE_LIST).
2936 * Next character might be escaped.
2937 * We have to peek. Inside double
2938 * quotes only INSIDE_DQUOTE_LIST
2939 * characters are escaped by a \.
2944 c = next_codepoint(&src[1], &c_size);
2945 if (c == INVALID_CODEPOINT) {
2951 * Don't escape the next char.
2960 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2962 next_escaped = true;
2969 /* Exit double quote state. */
2976 * We know the character isn't \ or ",
2977 * so escape it if it's any of the other
2978 * possible unprotected characters.
2981 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2989 * From here to the end of the loop we're
2990 * not in the single or double quote state.
2994 /* Next character must be escaped. */
2995 next_escaped = true;
3001 /* Go into single quote state. */
3008 /* Go into double quote state. */
3014 /* Check if we need to escape the character. */
3016 if (!strchr(INCLUDE_LIST, (int)*src)) {