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++) {
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)
367 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
368 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
369 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
373 Skip past some strings in a buffer.
376 char *skip_string(char *buf,size_t n)
379 buf += strlen(buf) + 1;
384 Count the number of characters in a string. Normally this will
385 be the same as the number of bytes in a string for single byte strings,
386 but will be different for multibyte.
389 size_t str_charnum(const char *s)
391 uint16 tmpbuf2[sizeof(pstring)];
392 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
393 return strlen_w(tmpbuf2);
397 Count the number of characters in a string. Normally this will
398 be the same as the number of bytes in a string for single byte strings,
399 but will be different for multibyte.
402 size_t str_ascii_charnum(const char *s)
405 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
406 return strlen(tmpbuf2);
410 Trim the specified elements off the front and back of a string.
413 BOOL trim_string(char *s,const char *front,const char *back)
420 /* Ignore null or empty strings. */
421 if (!s || (s[0] == '\0'))
424 front_len = front? strlen(front) : 0;
425 back_len = back? strlen(back) : 0;
430 while (len && strncmp(s, front, front_len)==0) {
431 /* Must use memmove here as src & dest can
432 * easily overlap. Found by valgrind. JRA. */
433 memmove(s, s+front_len, (len-front_len)+1);
440 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
441 s[len-back_len]='\0';
450 Does a string have any uppercase chars in it?
453 BOOL strhasupper(const char *s)
456 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
457 for(ptr=tmpbuf;*ptr;ptr++)
464 Does a string have any lowercase chars in it?
467 BOOL strhaslower(const char *s)
470 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
471 for(ptr=tmpbuf;*ptr;ptr++)
478 Find the number of 'c' chars in a string
481 size_t count_chars(const char *s,char c)
485 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
486 for(count=0,ptr=tmpbuf;*ptr;ptr++)
487 if(*ptr==UCS2_CHAR(c))
493 Safe string copy into a known length string. maxlength does not
494 include the terminating zero.
497 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
502 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
507 clobber_region(fn,line,dest, maxlength+1);
515 len = strnlen(src, maxlength+1);
517 if (len > maxlength) {
518 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
519 (unsigned int)(len-maxlength), len, maxlength, src));
523 memmove(dest, src, len);
529 Safe string cat into a string. maxlength does not
530 include the terminating zero.
532 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
534 size_t src_len, dest_len;
537 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
544 src_len = strnlen(src, maxlength + 1);
545 dest_len = strnlen(dest, maxlength + 1);
548 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
551 if (src_len + dest_len > maxlength) {
552 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
553 (int)(src_len + dest_len - maxlength), src));
554 if (maxlength > dest_len) {
555 memcpy(&dest[dest_len], src, maxlength - dest_len);
561 memcpy(&dest[dest_len], src, src_len);
562 dest[dest_len + src_len] = 0;
567 Paranoid strcpy into a buffer of given length (includes terminating
568 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
569 and replaces with '_'. Deliberately does *NOT* check for multibyte
570 characters. Don't change it !
572 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
577 clobber_region(fn, line, dest, maxlength);
581 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
591 if (len >= maxlength)
594 if (!other_safe_chars)
595 other_safe_chars = "";
597 for(i = 0; i < len; i++) {
598 int val = (src[i] & 0xff);
599 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
611 Like strncpy but always null terminates. Make sure there is room!
612 The variable n should always be one less than the available size.
614 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
619 clobber_region(fn, line, dest, n+1);
630 while (n-- && (*d = *src)) {
641 Like strncpy but copies up to the character marker. always null terminates.
642 returns a pointer to the character marker in the source string (src).
645 static char *strncpyn(char *dest, const char *src, size_t n, char c)
651 clobber_region(dest, n+1);
653 p = strchr_m(src, c);
655 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
659 str_len = PTR_DIFF(p, src);
660 strncpy(dest, src, MIN(n, str_len));
661 dest[str_len] = '\0';
668 Routine to get hex characters and turn them into a 16 byte array.
669 the array can be variable length, and any non-hex-numeric
670 characters are skipped. "0xnn" or "0Xnn" is specially catered
673 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
677 size_t strhex_to_str(char *p, size_t len, const char *strhex)
680 size_t num_chars = 0;
681 unsigned char lonybble, hinybble;
682 const char *hexchars = "0123456789ABCDEF";
683 char *p1 = NULL, *p2 = NULL;
685 for (i = 0; i < len && strhex[i] != 0; i++) {
686 if (strnequal(hexchars, "0x", 2)) {
687 i++; /* skip two chars */
691 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
694 i++; /* next hex digit */
696 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
699 /* get the two nybbles */
700 hinybble = PTR_DIFF(p1, hexchars);
701 lonybble = PTR_DIFF(p2, hexchars);
703 p[num_chars] = (hinybble << 4) | lonybble;
713 * Routine to print a buffer as HEX digits, into an allocated string.
716 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
721 *out_hex_buffer = smb_xmalloc((len*2)+1);
722 hex_buffer = *out_hex_buffer;
724 for (i = 0; i < len; i++)
725 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
729 Check if a string is part of a list.
732 BOOL in_list(char *s,char *list,BOOL casesensitive)
740 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
742 if (strcmp(tok,s) == 0)
745 if (StrCaseCmp(tok,s) == 0)
752 /* this is used to prevent lots of mallocs of size 1 */
753 static char *null_string = NULL;
756 Set a string value, allocing the space for the string
759 static BOOL string_init(char **dest,const char *src)
769 if((null_string = (char *)malloc(1)) == NULL) {
770 DEBUG(0,("string_init: malloc fail for null_string.\n"));
777 (*dest) = strdup(src);
778 if ((*dest) == NULL) {
779 DEBUG(0,("Out of memory in string_init\n"));
790 void string_free(char **s)
794 if (*s == null_string)
800 Set a string value, deallocating any existing space, and allocing the space
804 BOOL string_set(char **dest,const char *src)
807 return(string_init(dest,src));
811 Substitute a string for a pattern in another string. Make sure there is
814 This routine looks for pattern in s and replaces it with
815 insert. It may do multiple replacements.
817 Any of " ; ' $ or ` in the insert string are replaced with _
818 if len==0 then the string cannot be extended. This is different from the old
819 use of len==0 which was for no length checks to be done.
822 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
827 if (!insert || !pattern || !*pattern || !s)
830 ls = (ssize_t)strlen(s);
831 lp = (ssize_t)strlen(pattern);
832 li = (ssize_t)strlen(insert);
835 len = ls + 1; /* len is number of *bytes* */
837 while (lp <= ls && (p = strstr(s,pattern))) {
838 if (ls + (li-lp) >= len) {
839 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
840 (int)(ls + (li-lp) - len),
845 memmove(p+li,p+lp,strlen(p+lp)+1);
868 void fstring_sub(char *s,const char *pattern,const char *insert)
870 string_sub(s, pattern, insert, sizeof(fstring));
873 void pstring_sub(char *s,const char *pattern,const char *insert)
875 string_sub(s, pattern, insert, sizeof(pstring));
879 Similar to string_sub, but it will accept only allocated strings
880 and may realloc them so pay attention at what you pass on no
881 pointers inside strings, no pstrings or const may be passed
885 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
889 ssize_t ls,lp,li,ld, i;
891 if (!insert || !pattern || !*pattern || !string || !*string)
898 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
901 ls = (ssize_t)strlen(s);
902 lp = (ssize_t)strlen(pattern);
903 li = (ssize_t)strlen(insert);
922 while ((p = strstr(s,pattern))) {
924 int offset = PTR_DIFF(s,string);
925 char *t = Realloc(string, ls + ld + 1);
927 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
932 p = t + offset + (p - s);
935 memmove(p+li,p+lp,strlen(p+lp)+1);
946 Similar to string_sub() but allows for any character to be substituted.
948 if len==0 then the string cannot be extended. This is different from the old
949 use of len==0 which was for no length checks to be done.
952 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
957 if (!insert || !pattern || !s)
960 ls = (ssize_t)strlen(s);
961 lp = (ssize_t)strlen(pattern);
962 li = (ssize_t)strlen(insert);
968 len = ls + 1; /* len is number of *bytes* */
970 while (lp <= ls && (p = strstr(s,pattern))) {
971 if (ls + (li-lp) >= len) {
972 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
973 (int)(ls + (li-lp) - len),
978 memmove(p+li,p+lp,strlen(p+lp)+1);
980 memcpy(p, insert, li);
987 Similar to all_string_sub but for unicode strings.
988 Return a new allocated unicode string.
989 similar to string_sub() but allows for any character to be substituted.
993 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
994 const smb_ucs2_t *insert)
997 const smb_ucs2_t *sp;
998 size_t lr, lp, li, lt;
1000 if (!insert || !pattern || !*pattern || !s)
1003 lt = (size_t)strlen_w(s);
1004 lp = (size_t)strlen_w(pattern);
1005 li = (size_t)strlen_w(insert);
1008 const smb_ucs2_t *st = s;
1010 while ((sp = strstr_w(st, pattern))) {
1016 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1018 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1022 while ((sp = strstr_w(s, pattern))) {
1023 memcpy(rp, s, (sp - s));
1024 rp += ((sp - s) / sizeof(smb_ucs2_t));
1025 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1029 lr = ((rp - r) / sizeof(smb_ucs2_t));
1031 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1039 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1044 if (!insert || !pattern || !s)
1046 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1047 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1048 return all_string_sub_w(s, p, i);
1053 Splits out the front and back at a separator.
1056 static void split_at_last_component(char *path, char *front, char sep, char *back)
1058 char *p = strrchr_m(path, sep);
1064 pstrcpy(front, path);
1078 Write an octal as a string.
1081 const char *octal_string(int i)
1083 static char ret[64];
1086 slprintf(ret, sizeof(ret)-1, "0%o", i);
1092 Truncate a string at a specified length.
1095 char *string_truncate(char *s, unsigned int length)
1097 if (s && strlen(s) > length)
1103 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1104 We convert via ucs2 for now.
1107 char *strchr_m(const char *s, char c)
1113 /* this is quite a common operation, so we want it to be
1114 fast. We optimise for the ascii case, knowing that all our
1115 supported multi-byte character sets are ascii-compatible
1116 (ie. they match for the first 128 chars) */
1118 while (*s && (((unsigned char)s[0]) & 0x80)) {
1126 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1127 p = strchr_w(ws, UCS2_CHAR(c));
1131 pull_ucs2_pstring(s2, ws);
1132 return (char *)(s+strlen(s2));
1135 char *strrchr_m(const char *s, char c)
1137 /* this is quite a common operation, so we want it to be
1138 fast. We optimise for the ascii case, knowing that all our
1139 supported multi-byte character sets are ascii-compatible
1140 (ie. they match for the first 128 chars). Also, in Samba
1141 we only search for ascii characters in 'c' and that
1142 in all mb character sets with a compound character
1143 containing c, if 'c' is not a match at position
1144 p, then p[-1] > 0x7f. JRA. */
1147 size_t len = strlen(s);
1149 BOOL got_mb = False;
1156 /* Could be a match. Part of a multibyte ? */
1157 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1158 /* Yep - go slow :-( */
1162 /* No - we have a match ! */
1165 } while (cp-- != s);
1170 /* String contained a non-ascii char. Slow path. */
1176 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1177 p = strrchr_w(ws, UCS2_CHAR(c));
1181 pull_ucs2_pstring(s2, ws);
1182 return (char *)(s+strlen(s2));
1186 /***********************************************************************
1187 Return the equivalent of doing strrchr 'n' times - always going
1189 ***********************************************************************/
1191 char *strnrchr_m(const char *s, char c, unsigned int n)
1197 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1198 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1202 pull_ucs2_pstring(s2, ws);
1203 return (char *)(s+strlen(s2));
1207 Convert a string to lower case.
1210 void strlower_m(char *s)
1212 /* this is quite a common operation, so we want it to be
1213 fast. We optimise for the ascii case, knowing that all our
1214 supported multi-byte character sets are ascii-compatible
1215 (ie. they match for the first 128 chars) */
1217 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1218 *s = tolower((unsigned char)*s);
1225 /* I assume that lowercased string takes the same number of bytes
1226 * as source string even in UTF-8 encoding. (VIV) */
1227 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1231 Convert a string to upper case.
1234 void strupper_m(char *s)
1236 /* this is quite a common operation, so we want it to be
1237 fast. We optimise for the ascii case, knowing that all our
1238 supported multi-byte character sets are ascii-compatible
1239 (ie. they match for the first 128 chars) */
1241 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1242 *s = toupper((unsigned char)*s);
1249 /* I assume that lowercased string takes the same number of bytes
1250 * as source string even in multibyte encoding. (VIV) */
1251 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1255 Return a RFC2254 binary string representation of a buffer.
1256 Used in LDAP filters.
1260 char *binary_string(char *buf, int len)
1264 const char *hex = "0123456789ABCDEF";
1265 s = malloc(len * 3 + 1);
1268 for (j=i=0;i<len;i++) {
1270 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1271 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1279 Just a typesafety wrapper for snprintf into a pstring.
1282 int pstr_sprintf(pstring s, const char *fmt, ...)
1288 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1295 Just a typesafety wrapper for snprintf into a fstring.
1298 int fstr_sprintf(fstring s, const char *fmt, ...)
1304 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1310 #ifndef HAVE_STRNDUP
1312 Some platforms don't have strndup.
1315 char *strndup(const char *s, size_t n)
1330 #ifndef HAVE_STRNLEN
1332 Some platforms don't have strnlen
1335 size_t strnlen(const char *s, size_t n)
1338 for (i=0; s[i] && i<n; i++)
1345 List of Strings manipulation functions
1348 #define S_LIST_ABS 16 /* List Allocation Block Size */
1350 char **str_list_make(const char *string, const char *sep)
1352 char **list, **rlist;
1358 if (!string || !*string)
1362 DEBUG(0,("str_list_make: Unable to allocate memory"));
1365 if (!sep) sep = LIST_SEP;
1371 while (next_token(&str, tok, sep, sizeof(tok))) {
1373 lsize += S_LIST_ABS;
1374 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1376 DEBUG(0,("str_list_make: Unable to allocate memory"));
1377 str_list_free(&list);
1382 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1385 list[num] = strdup(tok);
1387 DEBUG(0,("str_list_make: Unable to allocate memory"));
1388 str_list_free(&list);
1400 BOOL str_list_copy(char ***dest, const char **src)
1402 char **list, **rlist;
1414 lsize += S_LIST_ABS;
1415 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1417 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1418 str_list_free(&list);
1422 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1425 list[num] = strdup(src[num]);
1427 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1428 str_list_free(&list);
1440 * Return true if all the elements of the list match exactly.
1442 BOOL str_list_compare(char **list1, char **list2)
1446 if (!list1 || !list2)
1447 return (list1 == list2);
1449 for (num = 0; list1[num]; num++) {
1452 if (!strcsequal(list1[num], list2[num]))
1456 return False; /* if list2 has more elements than list1 fail */
1461 void str_list_free(char ***list)
1465 if (!list || !*list)
1468 for(; *tlist; tlist++)
1473 /******************************************************************************
1474 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1476 *****************************************************************************/
1478 BOOL str_list_sub_basic( char **list, const char *smb_name )
1484 tmpstr = alloc_sub_basic(smb_name, s);
1486 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1498 /******************************************************************************
1499 substritute a specific pattern in a string list
1500 *****************************************************************************/
1502 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1505 ssize_t ls, lp, li, ld, i, d;
1514 lp = (ssize_t)strlen(pattern);
1515 li = (ssize_t)strlen(insert);
1520 ls = (ssize_t)strlen(s);
1522 while ((p = strstr(s, pattern))) {
1526 t = (char *) malloc(ls +ld +1);
1528 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1531 memcpy(t, *list, d);
1532 memcpy(t +d +li, p +lp, ls -d -lp +1);
1539 for (i = 0; i < li; i++) {
1540 switch (insert[i]) {
1552 t[d +i] = insert[i];
1565 #define IPSTR_LIST_SEP ","
1566 #define IPSTR_LIST_CHAR ','
1569 * Add ip string representation to ipstr list. Used also
1570 * as part of @function ipstr_list_make
1572 * @param ipstr_list pointer to string containing ip list;
1573 * MUST BE already allocated and IS reallocated if necessary
1574 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1575 * as a result of reallocation)
1576 * @param ip IP address which is to be added to list
1577 * @return pointer to string appended with new ip and possibly
1578 * reallocated to new length
1581 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1583 char* new_ipstr = NULL;
1585 /* arguments checking */
1586 if (!ipstr_list || !service) return NULL;
1588 /* attempt to convert ip to a string and append colon separator to it */
1590 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1591 inet_ntoa(service->ip), service->port);
1592 SAFE_FREE(*ipstr_list);
1594 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1596 *ipstr_list = new_ipstr;
1602 * Allocate and initialise an ipstr list using ip adresses
1603 * passed as arguments.
1605 * @param ipstr_list pointer to string meant to be allocated and set
1606 * @param ip_list array of ip addresses to place in the list
1607 * @param ip_count number of addresses stored in ip_list
1608 * @return pointer to allocated ip string
1611 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1615 /* arguments checking */
1616 if (!ip_list && !ipstr_list) return 0;
1620 /* process ip addresses given as arguments */
1621 for (i = 0; i < ip_count; i++)
1622 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1624 return (*ipstr_list);
1629 * Parse given ip string list into array of ip addresses
1630 * (as ip_service structures)
1631 * e.g. 192.168.1.100:389,192.168.1.78, ...
1633 * @param ipstr ip string list to be parsed
1634 * @param ip_list pointer to array of ip addresses which is
1635 * allocated by this function and must be freed by caller
1636 * @return number of succesfully parsed addresses
1639 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1645 if (!ipstr_list || !ip_list)
1648 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1649 if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1650 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1655 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1658 struct in_addr addr;
1660 char *p = strchr(token_str, ':');
1667 /* convert single token to ip address */
1668 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1671 (*ip_list)[i].ip = addr;
1672 (*ip_list)[i].port = port;
1680 * Safely free ip string list
1682 * @param ipstr_list ip string list to be freed
1685 void ipstr_list_free(char* ipstr_list)
1687 SAFE_FREE(ipstr_list);
1692 Unescape a URL encoded string, in place.
1695 void rfc1738_unescape(char *buf)
1699 while ((p=strchr_m(p,'+')))
1704 while (p && *p && (p=strchr_m(p,'%'))) {
1708 if (c1 >= '0' && c1 <= '9')
1710 else if (c1 >= 'A' && c1 <= 'F')
1712 else if (c1 >= 'a' && c1 <= 'f')
1714 else {p++; continue;}
1716 if (c2 >= '0' && c2 <= '9')
1718 else if (c2 >= 'A' && c2 <= 'F')
1720 else if (c2 >= 'a' && c2 <= 'f')
1722 else {p++; continue;}
1726 memmove(p+1, p+3, strlen(p+3)+1);
1731 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1734 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1736 DATA_BLOB base64_decode_data_blob(const char *s)
1738 int bit_offset, byte_offset, idx, i, n;
1739 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1740 unsigned char *d = decoded.data;
1745 while (*s && (p=strchr_m(b64,*s))) {
1746 idx = (int)(p - b64);
1747 byte_offset = (i*6)/8;
1748 bit_offset = (i*6)%8;
1749 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1750 if (bit_offset < 3) {
1751 d[byte_offset] |= (idx << (2-bit_offset));
1754 d[byte_offset] |= (idx >> (bit_offset-2));
1755 d[byte_offset+1] = 0;
1756 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1768 * Decode a base64 string in-place - wrapper for the above
1770 void base64_decode_inplace(char *s)
1772 DATA_BLOB decoded = base64_decode_data_blob(s);
1773 memcpy(s, decoded.data, decoded.length);
1774 /* null terminate */
1775 s[decoded.length] = '\0';
1777 data_blob_free(&decoded);
1781 * Encode a base64 string into a malloc()ed string caller to free.
1783 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1785 char * base64_encode_data_blob(DATA_BLOB data)
1790 size_t len = data.length;
1791 size_t output_len = data.length * 2;
1792 char *result = malloc(output_len); /* get us plenty of space */
1794 while (len-- && out_cnt < (data.length * 2) - 5) {
1795 int c = (unsigned char) *(data.data++);
1798 if (char_count == 3) {
1799 result[out_cnt++] = b64[bits >> 18];
1800 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1801 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1802 result[out_cnt++] = b64[bits & 0x3f];
1809 if (char_count != 0) {
1810 bits <<= 16 - (8 * char_count);
1811 result[out_cnt++] = b64[bits >> 18];
1812 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1813 if (char_count == 1) {
1814 result[out_cnt++] = '=';
1815 result[out_cnt++] = '=';
1817 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1818 result[out_cnt++] = '=';
1821 result[out_cnt] = '\0'; /* terminate */
1825 /* read a SMB_BIG_UINT from a string */
1826 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1829 SMB_BIG_UINT val = -1;
1830 const char *p = nptr;
1832 while (p && *p && isspace(*p))
1834 #ifdef LARGE_SMB_OFF_T
1835 sscanf(p,"%llu",&val);
1836 #else /* LARGE_SMB_OFF_T */
1837 sscanf(p,"%lu",&val);
1838 #endif /* LARGE_SMB_OFF_T */
1840 while (p && *p && isdigit(*p))