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 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
561 for(count=0,ptr=tmpbuf;*ptr;ptr++)
562 if(*ptr==UCS2_CHAR(c))
568 Safe string copy into a known length string. maxlength does not
569 include the terminating zero.
572 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
577 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
582 clobber_region(fn,line,dest, maxlength+1);
590 len = strnlen(src, maxlength+1);
592 if (len > maxlength) {
593 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
594 (unsigned long)(len-maxlength), (unsigned long)len,
595 (unsigned long)maxlength, src));
599 memmove(dest, src, len);
605 Safe string cat into a string. maxlength does not
606 include the terminating zero.
608 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
610 size_t src_len, dest_len;
613 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
620 src_len = strnlen(src, maxlength + 1);
621 dest_len = strnlen(dest, maxlength + 1);
624 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
627 if (src_len + dest_len > maxlength) {
628 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
629 (int)(src_len + dest_len - maxlength), src));
630 if (maxlength > dest_len) {
631 memcpy(&dest[dest_len], src, maxlength - dest_len);
637 memcpy(&dest[dest_len], src, src_len);
638 dest[dest_len + src_len] = 0;
643 Paranoid strcpy into a buffer of given length (includes terminating
644 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
645 and replaces with '_'. Deliberately does *NOT* check for multibyte
646 characters. Don't change it !
648 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
653 clobber_region(fn, line, dest, maxlength);
657 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
667 if (len >= maxlength)
670 if (!other_safe_chars)
671 other_safe_chars = "";
673 for(i = 0; i < len; i++) {
674 int val = (src[i] & 0xff);
675 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
687 Like strncpy but always null terminates. Make sure there is room!
688 The variable n should always be one less than the available size.
690 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
695 clobber_region(fn, line, dest, n+1);
699 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
708 while (n-- && (*d = *src)) {
719 Like strncpy but copies up to the character marker. always null terminates.
720 returns a pointer to the character marker in the source string (src).
723 static char *strncpyn(char *dest, const char *src, size_t n, char c)
729 clobber_region(dest, n+1);
731 p = strchr_m(src, c);
733 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
737 str_len = PTR_DIFF(p, src);
738 strncpy(dest, src, MIN(n, str_len));
739 dest[str_len] = '\0';
746 Routine to get hex characters and turn them into a 16 byte array.
747 the array can be variable length, and any non-hex-numeric
748 characters are skipped. "0xnn" or "0Xnn" is specially catered
751 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
755 size_t strhex_to_str(char *p, size_t len, const char *strhex)
758 size_t num_chars = 0;
759 unsigned char lonybble, hinybble;
760 const char *hexchars = "0123456789ABCDEF";
761 char *p1 = NULL, *p2 = NULL;
763 for (i = 0; i < len && strhex[i] != 0; i++) {
764 if (strnequal(hexchars, "0x", 2)) {
765 i++; /* skip two chars */
769 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
772 i++; /* next hex digit */
774 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
777 /* get the two nybbles */
778 hinybble = PTR_DIFF(p1, hexchars);
779 lonybble = PTR_DIFF(p2, hexchars);
781 p[num_chars] = (hinybble << 4) | lonybble;
791 * Routine to print a buffer as HEX digits, into an allocated string.
794 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
799 *out_hex_buffer = smb_xmalloc((len*2)+1);
800 hex_buffer = *out_hex_buffer;
802 for (i = 0; i < len; i++)
803 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
807 Check if a string is part of a list.
810 BOOL in_list(char *s,char *list,BOOL casesensitive)
818 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
820 if (strcmp(tok,s) == 0)
823 if (StrCaseCmp(tok,s) == 0)
830 /* this is used to prevent lots of mallocs of size 1 */
831 static char *null_string = NULL;
834 Set a string value, allocing the space for the string
837 static BOOL string_init(char **dest,const char *src)
847 if((null_string = (char *)malloc(1)) == NULL) {
848 DEBUG(0,("string_init: malloc fail for null_string.\n"));
855 (*dest) = strdup(src);
856 if ((*dest) == NULL) {
857 DEBUG(0,("Out of memory in string_init\n"));
868 void string_free(char **s)
872 if (*s == null_string)
878 Set a string value, deallocating any existing space, and allocing the space
882 BOOL string_set(char **dest,const char *src)
885 return(string_init(dest,src));
889 Substitute a string for a pattern in another string. Make sure there is
892 This routine looks for pattern in s and replaces it with
893 insert. It may do multiple replacements.
895 Any of " ; ' $ or ` in the insert string are replaced with _
896 if len==0 then the string cannot be extended. This is different from the old
897 use of len==0 which was for no length checks to be done.
900 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
905 if (!insert || !pattern || !*pattern || !s)
908 ls = (ssize_t)strlen(s);
909 lp = (ssize_t)strlen(pattern);
910 li = (ssize_t)strlen(insert);
913 len = ls + 1; /* len is number of *bytes* */
915 while (lp <= ls && (p = strstr(s,pattern))) {
916 if (ls + (li-lp) >= len) {
917 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
918 (int)(ls + (li-lp) - len),
923 memmove(p+li,p+lp,strlen(p+lp)+1);
946 void fstring_sub(char *s,const char *pattern,const char *insert)
948 string_sub(s, pattern, insert, sizeof(fstring));
951 void pstring_sub(char *s,const char *pattern,const char *insert)
953 string_sub(s, pattern, insert, sizeof(pstring));
957 Similar to string_sub, but it will accept only allocated strings
958 and may realloc them so pay attention at what you pass on no
959 pointers inside strings, no pstrings or const may be passed
963 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
967 ssize_t ls,lp,li,ld, i;
969 if (!insert || !pattern || !*pattern || !string || !*string)
976 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
979 ls = (ssize_t)strlen(s);
980 lp = (ssize_t)strlen(pattern);
981 li = (ssize_t)strlen(insert);
1000 while ((p = strstr(s,pattern))) {
1002 int offset = PTR_DIFF(s,string);
1003 char *t = Realloc(string, ls + ld + 1);
1005 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1010 p = t + offset + (p - s);
1013 memmove(p+li,p+lp,strlen(p+lp)+1);
1024 Similar to string_sub() but allows for any character to be substituted.
1026 if len==0 then the string cannot be extended. This is different from the old
1027 use of len==0 which was for no length checks to be done.
1030 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1035 if (!insert || !pattern || !s)
1038 ls = (ssize_t)strlen(s);
1039 lp = (ssize_t)strlen(pattern);
1040 li = (ssize_t)strlen(insert);
1046 len = ls + 1; /* len is number of *bytes* */
1048 while (lp <= ls && (p = strstr(s,pattern))) {
1049 if (ls + (li-lp) >= len) {
1050 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1051 (int)(ls + (li-lp) - len),
1052 pattern, (int)len));
1056 memmove(p+li,p+lp,strlen(p+lp)+1);
1058 memcpy(p, insert, li);
1065 Similar to all_string_sub but for unicode strings.
1066 Return a new allocated unicode string.
1067 similar to string_sub() but allows for any character to be substituted.
1071 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1072 const smb_ucs2_t *insert)
1075 const smb_ucs2_t *sp;
1076 size_t lr, lp, li, lt;
1078 if (!insert || !pattern || !*pattern || !s)
1081 lt = (size_t)strlen_w(s);
1082 lp = (size_t)strlen_w(pattern);
1083 li = (size_t)strlen_w(insert);
1086 const smb_ucs2_t *st = s;
1088 while ((sp = strstr_w(st, pattern))) {
1094 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1096 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1100 while ((sp = strstr_w(s, pattern))) {
1101 memcpy(rp, s, (sp - s));
1102 rp += ((sp - s) / sizeof(smb_ucs2_t));
1103 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1107 lr = ((rp - r) / sizeof(smb_ucs2_t));
1109 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1117 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1122 if (!insert || !pattern || !s)
1124 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1125 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1126 return all_string_sub_w(s, p, i);
1131 Splits out the front and back at a separator.
1134 static void split_at_last_component(char *path, char *front, char sep, char *back)
1136 char *p = strrchr_m(path, sep);
1142 pstrcpy(front, path);
1156 Write an octal as a string.
1159 const char *octal_string(int i)
1161 static char ret[64];
1164 slprintf(ret, sizeof(ret)-1, "0%o", i);
1170 Truncate a string at a specified length.
1173 char *string_truncate(char *s, unsigned int length)
1175 if (s && strlen(s) > length)
1181 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1182 We convert via ucs2 for now.
1185 char *strchr_m(const char *src, char c)
1192 /* this is quite a common operation, so we want it to be
1193 fast. We optimise for the ascii case, knowing that all our
1194 supported multi-byte character sets are ascii-compatible
1195 (ie. they match for the first 128 chars) */
1197 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1205 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1206 /* With compose characters we must restart from the beginning. JRA. */
1210 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1211 p = strchr_w(ws, UCS2_CHAR(c));
1215 pull_ucs2_pstring(s2, ws);
1216 return (char *)(s+strlen(s2));
1219 char *strrchr_m(const char *s, char c)
1221 /* this is quite a common operation, so we want it to be
1222 fast. We optimise for the ascii case, knowing that all our
1223 supported multi-byte character sets are ascii-compatible
1224 (ie. they match for the first 128 chars). Also, in Samba
1225 we only search for ascii characters in 'c' and that
1226 in all mb character sets with a compound character
1227 containing c, if 'c' is not a match at position
1228 p, then p[-1] > 0x7f. JRA. */
1231 size_t len = strlen(s);
1233 BOOL got_mb = False;
1240 /* Could be a match. Part of a multibyte ? */
1241 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1242 /* Yep - go slow :-( */
1246 /* No - we have a match ! */
1249 } while (cp-- != s);
1254 /* String contained a non-ascii char. Slow path. */
1260 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1261 p = strrchr_w(ws, UCS2_CHAR(c));
1265 pull_ucs2_pstring(s2, ws);
1266 return (char *)(s+strlen(s2));
1270 /***********************************************************************
1271 Return the equivalent of doing strrchr 'n' times - always going
1273 ***********************************************************************/
1275 char *strnrchr_m(const char *s, char c, unsigned int n)
1281 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1282 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1286 pull_ucs2_pstring(s2, ws);
1287 return (char *)(s+strlen(s2));
1291 Convert a string to lower case.
1294 void strlower_m(char *s)
1298 /* this is quite a common operation, so we want it to be
1299 fast. We optimise for the ascii case, knowing that all our
1300 supported multi-byte character sets are ascii-compatible
1301 (ie. they match for the first 128 chars) */
1303 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1304 *s = tolower((unsigned char)*s);
1311 /* I assume that lowercased string takes the same number of bytes
1312 * as source string even in UTF-8 encoding. (VIV) */
1313 len = strlen(s) + 1;
1315 unix_strlower(s,len,s,len);
1316 /* Catch mb conversion errors that may not terminate. */
1322 Convert a string to upper case.
1325 void strupper_m(char *s)
1329 /* this is quite a common operation, so we want it to be
1330 fast. We optimise for the ascii case, knowing that all our
1331 supported multi-byte character sets are ascii-compatible
1332 (ie. they match for the first 128 chars) */
1334 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1335 *s = toupper((unsigned char)*s);
1342 /* I assume that lowercased string takes the same number of bytes
1343 * as source string even in multibyte encoding. (VIV) */
1344 len = strlen(s) + 1;
1346 unix_strupper(s,len,s,len);
1347 /* Catch mb conversion errors that may not terminate. */
1353 Return a RFC2254 binary string representation of a buffer.
1354 Used in LDAP filters.
1358 char *binary_string(char *buf, int len)
1362 const char *hex = "0123456789ABCDEF";
1363 s = malloc(len * 3 + 1);
1366 for (j=i=0;i<len;i++) {
1368 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1369 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1377 Just a typesafety wrapper for snprintf into a pstring.
1380 int pstr_sprintf(pstring s, const char *fmt, ...)
1386 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1393 Just a typesafety wrapper for snprintf into a fstring.
1396 int fstr_sprintf(fstring s, const char *fmt, ...)
1402 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1408 #ifndef HAVE_STRNDUP
1410 Some platforms don't have strndup.
1413 char *strndup(const char *s, size_t n)
1428 #ifndef HAVE_STRNLEN
1430 Some platforms don't have strnlen
1433 size_t strnlen(const char *s, size_t n)
1436 for (i=0; s[i] && i<n; i++)
1443 List of Strings manipulation functions
1446 #define S_LIST_ABS 16 /* List Allocation Block Size */
1448 char **str_list_make(const char *string, const char *sep)
1450 char **list, **rlist;
1456 if (!string || !*string)
1460 DEBUG(0,("str_list_make: Unable to allocate memory"));
1463 if (!sep) sep = LIST_SEP;
1469 while (next_token(&str, tok, sep, sizeof(tok))) {
1471 lsize += S_LIST_ABS;
1472 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1474 DEBUG(0,("str_list_make: Unable to allocate memory"));
1475 str_list_free(&list);
1480 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1483 list[num] = strdup(tok);
1485 DEBUG(0,("str_list_make: Unable to allocate memory"));
1486 str_list_free(&list);
1498 BOOL str_list_copy(char ***dest, const char **src)
1500 char **list, **rlist;
1512 lsize += S_LIST_ABS;
1513 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1515 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1516 str_list_free(&list);
1520 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1523 list[num] = strdup(src[num]);
1525 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1526 str_list_free(&list);
1538 * Return true if all the elements of the list match exactly.
1540 BOOL str_list_compare(char **list1, char **list2)
1544 if (!list1 || !list2)
1545 return (list1 == list2);
1547 for (num = 0; list1[num]; num++) {
1550 if (!strcsequal(list1[num], list2[num]))
1554 return False; /* if list2 has more elements than list1 fail */
1559 void str_list_free(char ***list)
1563 if (!list || !*list)
1566 for(; *tlist; tlist++)
1571 /******************************************************************************
1572 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1574 *****************************************************************************/
1576 BOOL str_list_sub_basic( char **list, const char *smb_name )
1582 tmpstr = alloc_sub_basic(smb_name, s);
1584 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1596 /******************************************************************************
1597 substritute a specific pattern in a string list
1598 *****************************************************************************/
1600 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1603 ssize_t ls, lp, li, ld, i, d;
1612 lp = (ssize_t)strlen(pattern);
1613 li = (ssize_t)strlen(insert);
1618 ls = (ssize_t)strlen(s);
1620 while ((p = strstr(s, pattern))) {
1624 t = (char *) malloc(ls +ld +1);
1626 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1629 memcpy(t, *list, d);
1630 memcpy(t +d +li, p +lp, ls -d -lp +1);
1637 for (i = 0; i < li; i++) {
1638 switch (insert[i]) {
1650 t[d +i] = insert[i];
1663 #define IPSTR_LIST_SEP ","
1664 #define IPSTR_LIST_CHAR ','
1667 * Add ip string representation to ipstr list. Used also
1668 * as part of @function ipstr_list_make
1670 * @param ipstr_list pointer to string containing ip list;
1671 * MUST BE already allocated and IS reallocated if necessary
1672 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1673 * as a result of reallocation)
1674 * @param ip IP address which is to be added to list
1675 * @return pointer to string appended with new ip and possibly
1676 * reallocated to new length
1679 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1681 char* new_ipstr = NULL;
1683 /* arguments checking */
1684 if (!ipstr_list || !service) return NULL;
1686 /* attempt to convert ip to a string and append colon separator to it */
1688 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1689 inet_ntoa(service->ip), service->port);
1690 SAFE_FREE(*ipstr_list);
1692 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1694 *ipstr_list = new_ipstr;
1700 * Allocate and initialise an ipstr list using ip adresses
1701 * passed as arguments.
1703 * @param ipstr_list pointer to string meant to be allocated and set
1704 * @param ip_list array of ip addresses to place in the list
1705 * @param ip_count number of addresses stored in ip_list
1706 * @return pointer to allocated ip string
1709 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1713 /* arguments checking */
1714 if (!ip_list && !ipstr_list) return 0;
1718 /* process ip addresses given as arguments */
1719 for (i = 0; i < ip_count; i++)
1720 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1722 return (*ipstr_list);
1727 * Parse given ip string list into array of ip addresses
1728 * (as ip_service structures)
1729 * e.g. 192.168.1.100:389,192.168.1.78, ...
1731 * @param ipstr ip string list to be parsed
1732 * @param ip_list pointer to array of ip addresses which is
1733 * allocated by this function and must be freed by caller
1734 * @return number of succesfully parsed addresses
1737 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1743 if (!ipstr_list || !ip_list)
1746 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1747 if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1748 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1753 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1756 struct in_addr addr;
1758 char *p = strchr(token_str, ':');
1765 /* convert single token to ip address */
1766 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1769 (*ip_list)[i].ip = addr;
1770 (*ip_list)[i].port = port;
1778 * Safely free ip string list
1780 * @param ipstr_list ip string list to be freed
1783 void ipstr_list_free(char* ipstr_list)
1785 SAFE_FREE(ipstr_list);
1790 Unescape a URL encoded string, in place.
1793 void rfc1738_unescape(char *buf)
1797 while (p && *p && (p=strchr_m(p,'%'))) {
1801 if (c1 >= '0' && c1 <= '9')
1803 else if (c1 >= 'A' && c1 <= 'F')
1805 else if (c1 >= 'a' && c1 <= 'f')
1807 else {p++; continue;}
1809 if (c2 >= '0' && c2 <= '9')
1811 else if (c2 >= 'A' && c2 <= 'F')
1813 else if (c2 >= 'a' && c2 <= 'f')
1815 else {p++; continue;}
1819 memmove(p+1, p+3, strlen(p+3)+1);
1824 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1827 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1829 DATA_BLOB base64_decode_data_blob(const char *s)
1831 int bit_offset, byte_offset, idx, i, n;
1832 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1833 unsigned char *d = decoded.data;
1838 while (*s && (p=strchr_m(b64,*s))) {
1839 idx = (int)(p - b64);
1840 byte_offset = (i*6)/8;
1841 bit_offset = (i*6)%8;
1842 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1843 if (bit_offset < 3) {
1844 d[byte_offset] |= (idx << (2-bit_offset));
1847 d[byte_offset] |= (idx >> (bit_offset-2));
1848 d[byte_offset+1] = 0;
1849 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1855 if (*s == '=') n -= 1;
1863 * Decode a base64 string in-place - wrapper for the above
1865 void base64_decode_inplace(char *s)
1867 DATA_BLOB decoded = base64_decode_data_blob(s);
1868 memcpy(s, decoded.data, decoded.length);
1869 /* null terminate */
1870 s[decoded.length] = '\0';
1872 data_blob_free(&decoded);
1876 * Encode a base64 string into a malloc()ed string caller to free.
1878 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1880 char * base64_encode_data_blob(DATA_BLOB data)
1885 size_t len = data.length;
1886 size_t output_len = data.length * 2;
1887 char *result = malloc(output_len); /* get us plenty of space */
1889 while (len-- && out_cnt < (data.length * 2) - 5) {
1890 int c = (unsigned char) *(data.data++);
1893 if (char_count == 3) {
1894 result[out_cnt++] = b64[bits >> 18];
1895 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1896 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1897 result[out_cnt++] = b64[bits & 0x3f];
1904 if (char_count != 0) {
1905 bits <<= 16 - (8 * char_count);
1906 result[out_cnt++] = b64[bits >> 18];
1907 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1908 if (char_count == 1) {
1909 result[out_cnt++] = '=';
1910 result[out_cnt++] = '=';
1912 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1913 result[out_cnt++] = '=';
1916 result[out_cnt] = '\0'; /* terminate */
1920 /* read a SMB_BIG_UINT from a string */
1921 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1924 SMB_BIG_UINT val = -1;
1925 const char *p = nptr;
1927 while (p && *p && isspace(*p))
1929 #ifdef LARGE_SMB_OFF_T
1930 sscanf(p,"%llu",&val);
1931 #else /* LARGE_SMB_OFF_T */
1932 sscanf(p,"%lu",&val);
1933 #endif /* LARGE_SMB_OFF_T */
1935 while (p && *p && isdigit(*p))