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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * @brief String utilities.
32 * Get the next token from a string, return False if none found.
33 * Handles double-quotes.
35 * Based on a routine by GJC@VILLAGE.COM.
36 * Extensively modified by Andrew.Tridgell@anu.edu.au
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
50 /* default to simple separators */
54 /* find the first non sep char */
55 while (*s && strchr_m(sep,*s))
62 /* copy over the token */
64 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65 if (*s == '\"' || *s == '\'') {
73 *ptr = (*s) ? s+1 : s;
80 This is like next_token but is not re-entrant and "remembers" the first
81 parameter so you can pass NULL. This is useful for user interface code
82 but beware the fact that it is not re-entrant!
85 static const char *last_ptr=NULL;
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
93 ret = next_token(ptr, buff, sep, bufsize);
98 static uint16 tmpbuf[sizeof(pstring)];
100 void set_first_token(char *ptr)
106 Convert list of tokens to array; dependent on above routine.
107 Uses last_ptr from above - bit of a hack.
110 char **toktocliplist(int *ctok, const char *sep)
112 char *s=(char *)last_ptr;
119 while(*s && strchr_m(sep,*s))
128 while(*s && (!strchr_m(sep,*s)))
130 while(*s && strchr_m(sep,*s))
137 if (!(ret=iret=malloc(ictok*sizeof(char *))))
152 * Case insensitive string compararison.
154 * iconv does not directly give us a way to compare strings in
155 * arbitrary unix character sets -- all we can is convert and then
156 * compare. This is expensive.
158 * As an optimization, we do a first pass that considers only the
159 * prefix of the strings that is entirely 7-bit. Within this, we
160 * check whether they have the same value.
162 * Hopefully this will often give the answer without needing to copy.
163 * In particular it should speed comparisons to literal ascii strings
164 * or comparisons of strings that are "obviously" different.
166 * If we find a non-ascii character we fall back to converting via
169 * This should never be slower than convering the whole thing, and
172 * A different optimization would be to compare for bitwise equality
173 * in the binary encoding. (It would be possible thought hairy to do
174 * both simultaneously.) But in that case if they turn out to be
175 * different, we'd need to restart the whole thing.
177 * Even better is to implement strcasecmp for each encoding and use a
180 int StrCaseCmp(const char *s, const char *t)
183 const char * ps, * pt;
185 smb_ucs2_t *buffer_s, *buffer_t;
188 for (ps = s, pt = t; ; ps++, pt++) {
192 return 0; /* both ended */
194 return -1; /* s is a prefix */
196 return +1; /* t is a prefix */
197 else if ((*ps & 0x80) || (*pt & 0x80))
198 /* not ascii anymore, do it the hard way from here on in */
211 size = push_ucs2_allocate(&buffer_s, s);
212 if (size == (size_t)-1) {
214 /* Not quite the right answer, but finding the right one
215 under this failure case is expensive, and it's pretty close */
218 size = push_ucs2_allocate(&buffer_t, t);
219 if (size == (size_t)-1) {
222 /* Not quite the right answer, but finding the right one
223 under this failure case is expensive, and it's pretty close */
226 ret = strcasecmp_w(buffer_s, buffer_t);
234 Case insensitive string compararison, length limited.
236 int StrnCaseCmp(const char *s, const char *t, size_t n)
239 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
240 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
241 return strncmp(buf1,buf2,n);
247 * @note The comparison is case-insensitive.
249 BOOL strequal(const char *s1, const char *s2)
256 return(StrCaseCmp(s1,s2)==0);
260 * Compare 2 strings up to and including the nth char.
262 * @note The comparison is case-insensitive.
264 BOOL strnequal(const char *s1,const char *s2,size_t n)
268 if (!s1 || !s2 || !n)
271 return(StrnCaseCmp(s1,s2,n)==0);
275 Compare 2 strings (case sensitive).
278 BOOL strcsequal(const char *s1,const char *s2)
285 return(strcmp(s1,s2)==0);
289 Do a case-insensitive, whitespace-ignoring string compare.
292 int strwicmp(const char *psz1, const char *psz2)
294 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
295 /* appropriate value. */
298 else if (psz1 == NULL)
300 else if (psz2 == NULL)
303 /* sync the strings on first non-whitespace */
305 while (isspace((int)*psz1))
307 while (isspace((int)*psz2))
309 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
315 return (*psz1 - *psz2);
320 Convert a string to upper case, but don't modify it.
323 char *strupper_static(const char *s)
334 Convert a string to "normal" form.
337 void strnorm(char *s)
339 extern int case_default;
340 if (case_default == CASE_UPPER)
347 Check if a string is in "normal" case.
350 BOOL strisnormal(const char *s)
352 extern int case_default;
353 if (case_default == CASE_UPPER)
354 return(!strhaslower(s));
356 return(!strhasupper(s));
362 NOTE: oldc and newc must be 7 bit characters
365 void string_replace(pstring s,char oldc,char newc)
369 /* this is quite a common operation, so we want it to be
370 fast. We optimise for the ascii case, knowing that all our
371 supported multi-byte character sets are ascii-compatible
372 (ie. they match for the first 128 chars) */
374 for (p = (unsigned char *)s; *p; p++) {
375 if (*p & 0x80) /* mb string - slow path. */
384 /* Slow (mb) path. */
385 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
386 /* With compose characters we must restart from the beginning. JRA. */
389 push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
390 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
391 pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
395 Skip past some strings in a buffer.
398 char *skip_string(char *buf,size_t n)
401 buf += strlen(buf) + 1;
406 Count the number of characters in a string. Normally this will
407 be the same as the number of bytes in a string for single byte strings,
408 but will be different for multibyte.
411 size_t str_charnum(const char *s)
413 uint16 tmpbuf2[sizeof(pstring)];
414 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
415 return strlen_w(tmpbuf2);
419 Count the number of characters in a string. Normally this will
420 be the same as the number of bytes in a string for single byte strings,
421 but will be different for multibyte.
424 size_t str_ascii_charnum(const char *s)
427 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
428 return strlen(tmpbuf2);
431 BOOL trim_char(char *s,char cfront,char cback)
437 /* Ignore null or empty strings. */
438 if (!s || (s[0] == '\0'))
442 while (*fp && *fp == cfront)
445 /* We ate the string. */
453 ep = fp + strlen(fp) - 1;
455 /* Attempt ascii only. Bail for mb strings. */
456 while ((ep >= fp) && (*ep == cback)) {
458 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
459 /* Could be mb... bail back to tim_string. */
467 return trim_string(s, cfront ? fs : NULL, bs);
473 /* We ate the string. */
480 memmove(s, fp, ep-fp+2);
485 Trim the specified elements off the front and back of a string.
488 BOOL trim_string(char *s,const char *front,const char *back)
495 /* Ignore null or empty strings. */
496 if (!s || (s[0] == '\0'))
499 front_len = front? strlen(front) : 0;
500 back_len = back? strlen(back) : 0;
505 while (len && strncmp(s, front, front_len)==0) {
506 /* Must use memmove here as src & dest can
507 * easily overlap. Found by valgrind. JRA. */
508 memmove(s, s+front_len, (len-front_len)+1);
515 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
516 s[len-back_len]='\0';
525 Does a string have any uppercase chars in it?
528 BOOL strhasupper(const char *s)
531 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
532 for(ptr=tmpbuf;*ptr;ptr++)
539 Does a string have any lowercase chars in it?
542 BOOL strhaslower(const char *s)
545 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
546 for(ptr=tmpbuf;*ptr;ptr++)
553 Find the number of 'c' chars in a string
556 size_t count_chars(const char *s,char c)
560 smb_ucs2_t *alloc_tmpbuf = NULL;
562 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
566 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
567 if(*ptr==UCS2_CHAR(c))
570 SAFE_FREE(alloc_tmpbuf);
575 Safe string copy into a known length string. maxlength does not
576 include the terminating zero.
579 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
584 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
589 clobber_region(fn,line,dest, maxlength+1);
597 len = strnlen(src, maxlength+1);
599 if (len > maxlength) {
600 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
601 (unsigned long)(len-maxlength), (unsigned long)len,
602 (unsigned long)maxlength, src));
606 memmove(dest, src, len);
612 Safe string cat into a string. maxlength does not
613 include the terminating zero.
615 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
617 size_t src_len, dest_len;
620 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
627 src_len = strnlen(src, maxlength + 1);
628 dest_len = strnlen(dest, maxlength + 1);
631 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
634 if (src_len + dest_len > maxlength) {
635 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
636 (int)(src_len + dest_len - maxlength), src));
637 if (maxlength > dest_len) {
638 memcpy(&dest[dest_len], src, maxlength - dest_len);
644 memcpy(&dest[dest_len], src, src_len);
645 dest[dest_len + src_len] = 0;
650 Paranoid strcpy into a buffer of given length (includes terminating
651 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
652 and replaces with '_'. Deliberately does *NOT* check for multibyte
653 characters. Don't change it !
655 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
660 clobber_region(fn, line, dest, maxlength);
664 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
674 if (len >= maxlength)
677 if (!other_safe_chars)
678 other_safe_chars = "";
680 for(i = 0; i < len; i++) {
681 int val = (src[i] & 0xff);
682 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
694 Like strncpy but always null terminates. Make sure there is room!
695 The variable n should always be one less than the available size.
697 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
702 clobber_region(fn, line, dest, n+1);
706 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
715 while (n-- && (*d = *src)) {
726 Like strncpy but copies up to the character marker. always null terminates.
727 returns a pointer to the character marker in the source string (src).
730 static char *strncpyn(char *dest, const char *src, size_t n, char c)
736 clobber_region(dest, n+1);
738 p = strchr_m(src, c);
740 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
744 str_len = PTR_DIFF(p, src);
745 strncpy(dest, src, MIN(n, str_len));
746 dest[str_len] = '\0';
753 Routine to get hex characters and turn them into a 16 byte array.
754 the array can be variable length, and any non-hex-numeric
755 characters are skipped. "0xnn" or "0Xnn" is specially catered
758 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
762 size_t strhex_to_str(char *p, size_t len, const char *strhex)
765 size_t num_chars = 0;
766 unsigned char lonybble, hinybble;
767 const char *hexchars = "0123456789ABCDEF";
768 char *p1 = NULL, *p2 = NULL;
770 for (i = 0; i < len && strhex[i] != 0; i++) {
771 if (strnequal(hexchars, "0x", 2)) {
772 i++; /* skip two chars */
776 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
779 i++; /* next hex digit */
781 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
784 /* get the two nybbles */
785 hinybble = PTR_DIFF(p1, hexchars);
786 lonybble = PTR_DIFF(p2, hexchars);
788 p[num_chars] = (hinybble << 4) | lonybble;
798 * Routine to print a buffer as HEX digits, into an allocated string.
801 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
806 *out_hex_buffer = smb_xmalloc((len*2)+1);
807 hex_buffer = *out_hex_buffer;
809 for (i = 0; i < len; i++)
810 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
814 Check if a string is part of a list.
817 BOOL in_list(char *s,char *list,BOOL casesensitive)
825 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
827 if (strcmp(tok,s) == 0)
830 if (StrCaseCmp(tok,s) == 0)
837 /* this is used to prevent lots of mallocs of size 1 */
838 static char *null_string = NULL;
841 Set a string value, allocing the space for the string
844 static BOOL string_init(char **dest,const char *src)
854 if((null_string = (char *)malloc(1)) == NULL) {
855 DEBUG(0,("string_init: malloc fail for null_string.\n"));
862 (*dest) = strdup(src);
863 if ((*dest) == NULL) {
864 DEBUG(0,("Out of memory in string_init\n"));
875 void string_free(char **s)
879 if (*s == null_string)
885 Set a string value, deallocating any existing space, and allocing the space
889 BOOL string_set(char **dest,const char *src)
892 return(string_init(dest,src));
896 Substitute a string for a pattern in another string. Make sure there is
899 This routine looks for pattern in s and replaces it with
900 insert. It may do multiple replacements.
902 Any of " ; ' $ or ` in the insert string are replaced with _
903 if len==0 then the string cannot be extended. This is different from the old
904 use of len==0 which was for no length checks to be done.
907 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
912 if (!insert || !pattern || !*pattern || !s)
915 ls = (ssize_t)strlen(s);
916 lp = (ssize_t)strlen(pattern);
917 li = (ssize_t)strlen(insert);
920 len = ls + 1; /* len is number of *bytes* */
922 while (lp <= ls && (p = strstr_m(s,pattern))) {
923 if (ls + (li-lp) >= len) {
924 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
925 (int)(ls + (li-lp) - len),
930 memmove(p+li,p+lp,strlen(p+lp)+1);
953 void fstring_sub(char *s,const char *pattern,const char *insert)
955 string_sub(s, pattern, insert, sizeof(fstring));
958 void pstring_sub(char *s,const char *pattern,const char *insert)
960 string_sub(s, pattern, insert, sizeof(pstring));
964 Similar to string_sub, but it will accept only allocated strings
965 and may realloc them so pay attention at what you pass on no
966 pointers inside strings, no pstrings or const may be passed
970 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
974 ssize_t ls,lp,li,ld, i;
976 if (!insert || !pattern || !*pattern || !string || !*string)
983 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
986 ls = (ssize_t)strlen(s);
987 lp = (ssize_t)strlen(pattern);
988 li = (ssize_t)strlen(insert);
1007 while ((p = strstr_m(s,pattern))) {
1009 int offset = PTR_DIFF(s,string);
1010 char *t = Realloc(string, ls + ld + 1);
1012 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1017 p = t + offset + (p - s);
1020 memmove(p+li,p+lp,strlen(p+lp)+1);
1031 Similar to string_sub() but allows for any character to be substituted.
1033 if len==0 then the string cannot be extended. This is different from the old
1034 use of len==0 which was for no length checks to be done.
1037 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1042 if (!insert || !pattern || !s)
1045 ls = (ssize_t)strlen(s);
1046 lp = (ssize_t)strlen(pattern);
1047 li = (ssize_t)strlen(insert);
1053 len = ls + 1; /* len is number of *bytes* */
1055 while (lp <= ls && (p = strstr_m(s,pattern))) {
1056 if (ls + (li-lp) >= len) {
1057 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1058 (int)(ls + (li-lp) - len),
1059 pattern, (int)len));
1063 memmove(p+li,p+lp,strlen(p+lp)+1);
1065 memcpy(p, insert, li);
1072 Similar to all_string_sub but for unicode strings.
1073 Return a new allocated unicode string.
1074 similar to string_sub() but allows for any character to be substituted.
1078 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1079 const smb_ucs2_t *insert)
1082 const smb_ucs2_t *sp;
1083 size_t lr, lp, li, lt;
1085 if (!insert || !pattern || !*pattern || !s)
1088 lt = (size_t)strlen_w(s);
1089 lp = (size_t)strlen_w(pattern);
1090 li = (size_t)strlen_w(insert);
1093 const smb_ucs2_t *st = s;
1095 while ((sp = strstr_w(st, pattern))) {
1101 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1103 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1107 while ((sp = strstr_w(s, pattern))) {
1108 memcpy(rp, s, (sp - s));
1109 rp += ((sp - s) / sizeof(smb_ucs2_t));
1110 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1114 lr = ((rp - r) / sizeof(smb_ucs2_t));
1116 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1124 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1129 if (!insert || !pattern || !s)
1131 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1132 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1133 return all_string_sub_w(s, p, i);
1138 Splits out the front and back at a separator.
1141 static void split_at_last_component(char *path, char *front, char sep, char *back)
1143 char *p = strrchr_m(path, sep);
1149 pstrcpy(front, path);
1163 Write an octal as a string.
1166 const char *octal_string(int i)
1168 static char ret[64];
1171 slprintf(ret, sizeof(ret)-1, "0%o", i);
1177 Truncate a string at a specified length.
1180 char *string_truncate(char *s, unsigned int length)
1182 if (s && strlen(s) > length)
1188 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1189 We convert via ucs2 for now.
1192 char *strchr_m(const char *src, char c)
1199 /* this is quite a common operation, so we want it to be
1200 fast. We optimise for the ascii case, knowing that all our
1201 supported multi-byte character sets are ascii-compatible
1202 (ie. they match for the first 128 chars) */
1204 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1212 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1213 /* With compose characters we must restart from the beginning. JRA. */
1217 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1218 p = strchr_w(ws, UCS2_CHAR(c));
1222 pull_ucs2_pstring(s2, ws);
1223 return (char *)(s+strlen(s2));
1226 char *strrchr_m(const char *s, char c)
1228 /* this is quite a common operation, so we want it to be
1229 fast. We optimise for the ascii case, knowing that all our
1230 supported multi-byte character sets are ascii-compatible
1231 (ie. they match for the first 128 chars). Also, in Samba
1232 we only search for ascii characters in 'c' and that
1233 in all mb character sets with a compound character
1234 containing c, if 'c' is not a match at position
1235 p, then p[-1] > 0x7f. JRA. */
1238 size_t len = strlen(s);
1240 BOOL got_mb = False;
1247 /* Could be a match. Part of a multibyte ? */
1248 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1249 /* Yep - go slow :-( */
1253 /* No - we have a match ! */
1256 } while (cp-- != s);
1261 /* String contained a non-ascii char. Slow path. */
1267 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1268 p = strrchr_w(ws, UCS2_CHAR(c));
1272 pull_ucs2_pstring(s2, ws);
1273 return (char *)(s+strlen(s2));
1277 /***********************************************************************
1278 Return the equivalent of doing strrchr 'n' times - always going
1280 ***********************************************************************/
1282 char *strnrchr_m(const char *s, char c, unsigned int n)
1288 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1289 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1293 pull_ucs2_pstring(s2, ws);
1294 return (char *)(s+strlen(s2));
1297 /***********************************************************************
1298 strstr_m - We convert via ucs2 for now.
1299 ***********************************************************************/
1301 char *strstr_m(const char *src, const char *findstr)
1304 smb_ucs2_t *src_w, *find_w;
1309 /* Samba does single character findstr calls a *lot*. */
1310 if (findstr[1] == '\0')
1311 return strchr_m(src, *findstr);
1313 /* We optimise for the ascii case, knowing that all our
1314 supported multi-byte character sets are ascii-compatible
1315 (ie. they match for the first 128 chars) */
1317 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1318 if (*s == *findstr) {
1319 if (strcmp(s, findstr) == 0) {
1328 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1329 /* With compose characters we must restart from the beginning. JRA. */
1333 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1334 DEBUG(0,("strstr_m: src malloc fail\n"));
1338 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1340 DEBUG(0,("strstr_m: find malloc fail\n"));
1344 for (p = src_w; (p = strchr_w(p, *find_w)) != NULL; p++) {
1345 if (strcmp_w(p, find_w) == 0)
1354 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1357 DEBUG(0,("strstr_m: dest malloc fail\n"));
1360 retp = (char *)(s+strlen(s2));
1368 Convert a string to lower case.
1371 void strlower_m(char *s)
1375 /* this is quite a common operation, so we want it to be
1376 fast. We optimise for the ascii case, knowing that all our
1377 supported multi-byte character sets are ascii-compatible
1378 (ie. they match for the first 128 chars) */
1380 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1381 *s = tolower((unsigned char)*s);
1388 /* I assume that lowercased string takes the same number of bytes
1389 * as source string even in UTF-8 encoding. (VIV) */
1390 len = strlen(s) + 1;
1392 unix_strlower(s,len,s,len);
1393 /* Catch mb conversion errors that may not terminate. */
1399 Convert a string to upper case.
1402 void strupper_m(char *s)
1406 /* this is quite a common operation, so we want it to be
1407 fast. We optimise for the ascii case, knowing that all our
1408 supported multi-byte character sets are ascii-compatible
1409 (ie. they match for the first 128 chars) */
1411 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1412 *s = toupper((unsigned char)*s);
1419 /* I assume that lowercased string takes the same number of bytes
1420 * as source string even in multibyte encoding. (VIV) */
1421 len = strlen(s) + 1;
1423 unix_strupper(s,len,s,len);
1424 /* Catch mb conversion errors that may not terminate. */
1430 Return a RFC2254 binary string representation of a buffer.
1431 Used in LDAP filters.
1435 char *binary_string(char *buf, int len)
1439 const char *hex = "0123456789ABCDEF";
1440 s = malloc(len * 3 + 1);
1443 for (j=i=0;i<len;i++) {
1445 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1446 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1454 Just a typesafety wrapper for snprintf into a pstring.
1457 int pstr_sprintf(pstring s, const char *fmt, ...)
1463 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1470 Just a typesafety wrapper for snprintf into a fstring.
1473 int fstr_sprintf(fstring s, const char *fmt, ...)
1479 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1485 #ifndef HAVE_STRNDUP
1487 Some platforms don't have strndup.
1490 char *strndup(const char *s, size_t n)
1505 #ifndef HAVE_STRNLEN
1507 Some platforms don't have strnlen
1510 size_t strnlen(const char *s, size_t n)
1513 for (i=0; s[i] && i<n; i++)
1520 List of Strings manipulation functions
1523 #define S_LIST_ABS 16 /* List Allocation Block Size */
1525 char **str_list_make(const char *string, const char *sep)
1527 char **list, **rlist;
1533 if (!string || !*string)
1537 DEBUG(0,("str_list_make: Unable to allocate memory"));
1540 if (!sep) sep = LIST_SEP;
1546 while (next_token(&str, tok, sep, sizeof(tok))) {
1548 lsize += S_LIST_ABS;
1549 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1551 DEBUG(0,("str_list_make: Unable to allocate memory"));
1552 str_list_free(&list);
1557 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1560 list[num] = strdup(tok);
1562 DEBUG(0,("str_list_make: Unable to allocate memory"));
1563 str_list_free(&list);
1575 BOOL str_list_copy(char ***dest, const char **src)
1577 char **list, **rlist;
1589 lsize += S_LIST_ABS;
1590 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1592 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1593 str_list_free(&list);
1597 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1600 list[num] = strdup(src[num]);
1602 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1603 str_list_free(&list);
1615 * Return true if all the elements of the list match exactly.
1617 BOOL str_list_compare(char **list1, char **list2)
1621 if (!list1 || !list2)
1622 return (list1 == list2);
1624 for (num = 0; list1[num]; num++) {
1627 if (!strcsequal(list1[num], list2[num]))
1631 return False; /* if list2 has more elements than list1 fail */
1636 void str_list_free(char ***list)
1640 if (!list || !*list)
1643 for(; *tlist; tlist++)
1648 /******************************************************************************
1649 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1651 *****************************************************************************/
1653 BOOL str_list_sub_basic( char **list, const char *smb_name )
1659 tmpstr = alloc_sub_basic(smb_name, s);
1661 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1673 /******************************************************************************
1674 substritute a specific pattern in a string list
1675 *****************************************************************************/
1677 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1680 ssize_t ls, lp, li, ld, i, d;
1689 lp = (ssize_t)strlen(pattern);
1690 li = (ssize_t)strlen(insert);
1695 ls = (ssize_t)strlen(s);
1697 while ((p = strstr_m(s, pattern))) {
1701 t = (char *) malloc(ls +ld +1);
1703 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1706 memcpy(t, *list, d);
1707 memcpy(t +d +li, p +lp, ls -d -lp +1);
1714 for (i = 0; i < li; i++) {
1715 switch (insert[i]) {
1727 t[d +i] = insert[i];
1740 #define IPSTR_LIST_SEP ","
1741 #define IPSTR_LIST_CHAR ','
1744 * Add ip string representation to ipstr list. Used also
1745 * as part of @function ipstr_list_make
1747 * @param ipstr_list pointer to string containing ip list;
1748 * MUST BE already allocated and IS reallocated if necessary
1749 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1750 * as a result of reallocation)
1751 * @param ip IP address which is to be added to list
1752 * @return pointer to string appended with new ip and possibly
1753 * reallocated to new length
1756 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1758 char* new_ipstr = NULL;
1760 /* arguments checking */
1761 if (!ipstr_list || !service) return NULL;
1763 /* attempt to convert ip to a string and append colon separator to it */
1765 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1766 inet_ntoa(service->ip), service->port);
1767 SAFE_FREE(*ipstr_list);
1769 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1771 *ipstr_list = new_ipstr;
1777 * Allocate and initialise an ipstr list using ip adresses
1778 * passed as arguments.
1780 * @param ipstr_list pointer to string meant to be allocated and set
1781 * @param ip_list array of ip addresses to place in the list
1782 * @param ip_count number of addresses stored in ip_list
1783 * @return pointer to allocated ip string
1786 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1790 /* arguments checking */
1791 if (!ip_list && !ipstr_list) return 0;
1795 /* process ip addresses given as arguments */
1796 for (i = 0; i < ip_count; i++)
1797 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1799 return (*ipstr_list);
1804 * Parse given ip string list into array of ip addresses
1805 * (as ip_service structures)
1806 * e.g. 192.168.1.100:389,192.168.1.78, ...
1808 * @param ipstr ip string list to be parsed
1809 * @param ip_list pointer to array of ip addresses which is
1810 * allocated by this function and must be freed by caller
1811 * @return number of succesfully parsed addresses
1814 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1820 if (!ipstr_list || !ip_list)
1823 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1824 if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1825 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1830 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1833 struct in_addr addr;
1835 char *p = strchr(token_str, ':');
1842 /* convert single token to ip address */
1843 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1846 (*ip_list)[i].ip = addr;
1847 (*ip_list)[i].port = port;
1855 * Safely free ip string list
1857 * @param ipstr_list ip string list to be freed
1860 void ipstr_list_free(char* ipstr_list)
1862 SAFE_FREE(ipstr_list);
1867 Unescape a URL encoded string, in place.
1870 void rfc1738_unescape(char *buf)
1874 while (p && *p && (p=strchr_m(p,'%'))) {
1878 if (c1 >= '0' && c1 <= '9')
1880 else if (c1 >= 'A' && c1 <= 'F')
1882 else if (c1 >= 'a' && c1 <= 'f')
1884 else {p++; continue;}
1886 if (c2 >= '0' && c2 <= '9')
1888 else if (c2 >= 'A' && c2 <= 'F')
1890 else if (c2 >= 'a' && c2 <= 'f')
1892 else {p++; continue;}
1896 memmove(p+1, p+3, strlen(p+3)+1);
1901 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1904 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1906 DATA_BLOB base64_decode_data_blob(const char *s)
1908 int bit_offset, byte_offset, idx, i, n;
1909 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1910 unsigned char *d = decoded.data;
1915 while (*s && (p=strchr_m(b64,*s))) {
1916 idx = (int)(p - b64);
1917 byte_offset = (i*6)/8;
1918 bit_offset = (i*6)%8;
1919 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1920 if (bit_offset < 3) {
1921 d[byte_offset] |= (idx << (2-bit_offset));
1924 d[byte_offset] |= (idx >> (bit_offset-2));
1925 d[byte_offset+1] = 0;
1926 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1932 if (*s == '=') n -= 1;
1940 * Decode a base64 string in-place - wrapper for the above
1942 void base64_decode_inplace(char *s)
1944 DATA_BLOB decoded = base64_decode_data_blob(s);
1945 memcpy(s, decoded.data, decoded.length);
1946 /* null terminate */
1947 s[decoded.length] = '\0';
1949 data_blob_free(&decoded);
1953 * Encode a base64 string into a malloc()ed string caller to free.
1955 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1957 char * base64_encode_data_blob(DATA_BLOB data)
1962 size_t len = data.length;
1963 size_t output_len = data.length * 2;
1964 char *result = malloc(output_len); /* get us plenty of space */
1966 while (len-- && out_cnt < (data.length * 2) - 5) {
1967 int c = (unsigned char) *(data.data++);
1970 if (char_count == 3) {
1971 result[out_cnt++] = b64[bits >> 18];
1972 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1973 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1974 result[out_cnt++] = b64[bits & 0x3f];
1981 if (char_count != 0) {
1982 bits <<= 16 - (8 * char_count);
1983 result[out_cnt++] = b64[bits >> 18];
1984 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1985 if (char_count == 1) {
1986 result[out_cnt++] = '=';
1987 result[out_cnt++] = '=';
1989 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1990 result[out_cnt++] = '=';
1993 result[out_cnt] = '\0'; /* terminate */
1997 /* read a SMB_BIG_UINT from a string */
1998 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2001 SMB_BIG_UINT val = -1;
2002 const char *p = nptr;
2004 while (p && *p && isspace(*p))
2006 #ifdef LARGE_SMB_OFF_T
2007 sscanf(p,"%llu",&val);
2008 #else /* LARGE_SMB_OFF_T */
2009 sscanf(p,"%lu",&val);
2010 #endif /* LARGE_SMB_OFF_T */
2012 while (p && *p && isdigit(*p))