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)
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 push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
386 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
387 pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
391 Skip past some strings in a buffer.
394 char *skip_string(char *buf,size_t n)
397 buf += strlen(buf) + 1;
402 Count the number of characters in a string. Normally this will
403 be the same as the number of bytes in a string for single byte strings,
404 but will be different for multibyte.
407 size_t str_charnum(const char *s)
409 uint16 tmpbuf2[sizeof(pstring)];
410 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
411 return strlen_w(tmpbuf2);
415 Count the number of characters in a string. Normally this will
416 be the same as the number of bytes in a string for single byte strings,
417 but will be different for multibyte.
420 size_t str_ascii_charnum(const char *s)
423 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
424 return strlen(tmpbuf2);
427 BOOL trim_char(char *s,char cfront,char cback)
433 /* Ignore null or empty strings. */
434 if (!s || (s[0] == '\0'))
438 while (*fp && *fp == cfront)
441 /* We ate the string. */
449 ep = fp + strlen(fp) - 1;
451 /* Attempt ascii only. Bail for mb strings. */
452 while ((ep >= fp) && (*ep == cback)) {
454 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
455 /* Could be mb... bail back to tim_string. */
463 return trim_string(s, cfront ? fs : NULL, bs);
469 /* We ate the string. */
476 memmove(s, fp, ep-fp+2);
481 Trim the specified elements off the front and back of a string.
484 BOOL trim_string(char *s,const char *front,const char *back)
491 /* Ignore null or empty strings. */
492 if (!s || (s[0] == '\0'))
495 front_len = front? strlen(front) : 0;
496 back_len = back? strlen(back) : 0;
501 while (len && strncmp(s, front, front_len)==0) {
502 /* Must use memmove here as src & dest can
503 * easily overlap. Found by valgrind. JRA. */
504 memmove(s, s+front_len, (len-front_len)+1);
511 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
512 s[len-back_len]='\0';
521 Does a string have any uppercase chars in it?
524 BOOL strhasupper(const char *s)
527 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
528 for(ptr=tmpbuf;*ptr;ptr++)
535 Does a string have any lowercase chars in it?
538 BOOL strhaslower(const char *s)
541 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
542 for(ptr=tmpbuf;*ptr;ptr++)
549 Find the number of 'c' chars in a string
552 size_t count_chars(const char *s,char c)
556 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
557 for(count=0,ptr=tmpbuf;*ptr;ptr++)
558 if(*ptr==UCS2_CHAR(c))
564 Safe string copy into a known length string. maxlength does not
565 include the terminating zero.
568 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
573 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
578 clobber_region(fn,line,dest, maxlength+1);
586 len = strnlen(src, maxlength+1);
588 if (len > maxlength) {
589 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
590 (unsigned int)(len-maxlength), len, maxlength, src));
594 memmove(dest, src, len);
600 Safe string cat into a string. maxlength does not
601 include the terminating zero.
603 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
605 size_t src_len, dest_len;
608 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
615 src_len = strnlen(src, maxlength + 1);
616 dest_len = strnlen(dest, maxlength + 1);
619 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
622 if (src_len + dest_len > maxlength) {
623 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
624 (int)(src_len + dest_len - maxlength), src));
625 if (maxlength > dest_len) {
626 memcpy(&dest[dest_len], src, maxlength - dest_len);
632 memcpy(&dest[dest_len], src, src_len);
633 dest[dest_len + src_len] = 0;
638 Paranoid strcpy into a buffer of given length (includes terminating
639 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
640 and replaces with '_'. Deliberately does *NOT* check for multibyte
641 characters. Don't change it !
643 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
648 clobber_region(fn, line, dest, maxlength);
652 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
662 if (len >= maxlength)
665 if (!other_safe_chars)
666 other_safe_chars = "";
668 for(i = 0; i < len; i++) {
669 int val = (src[i] & 0xff);
670 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
682 Like strncpy but always null terminates. Make sure there is room!
683 The variable n should always be one less than the available size.
685 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
690 clobber_region(fn, line, dest, n+1);
701 while (n-- && (*d = *src)) {
712 Like strncpy but copies up to the character marker. always null terminates.
713 returns a pointer to the character marker in the source string (src).
716 static char *strncpyn(char *dest, const char *src, size_t n, char c)
722 clobber_region(dest, n+1);
724 p = strchr_m(src, c);
726 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
730 str_len = PTR_DIFF(p, src);
731 strncpy(dest, src, MIN(n, str_len));
732 dest[str_len] = '\0';
739 Routine to get hex characters and turn them into a 16 byte array.
740 the array can be variable length, and any non-hex-numeric
741 characters are skipped. "0xnn" or "0Xnn" is specially catered
744 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
748 size_t strhex_to_str(char *p, size_t len, const char *strhex)
751 size_t num_chars = 0;
752 unsigned char lonybble, hinybble;
753 const char *hexchars = "0123456789ABCDEF";
754 char *p1 = NULL, *p2 = NULL;
756 for (i = 0; i < len && strhex[i] != 0; i++) {
757 if (strnequal(hexchars, "0x", 2)) {
758 i++; /* skip two chars */
762 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
765 i++; /* next hex digit */
767 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
770 /* get the two nybbles */
771 hinybble = PTR_DIFF(p1, hexchars);
772 lonybble = PTR_DIFF(p2, hexchars);
774 p[num_chars] = (hinybble << 4) | lonybble;
784 * Routine to print a buffer as HEX digits, into an allocated string.
787 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
792 *out_hex_buffer = smb_xmalloc((len*2)+1);
793 hex_buffer = *out_hex_buffer;
795 for (i = 0; i < len; i++)
796 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
800 Check if a string is part of a list.
803 BOOL in_list(char *s,char *list,BOOL casesensitive)
811 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
813 if (strcmp(tok,s) == 0)
816 if (StrCaseCmp(tok,s) == 0)
823 /* this is used to prevent lots of mallocs of size 1 */
824 static char *null_string = NULL;
827 Set a string value, allocing the space for the string
830 static BOOL string_init(char **dest,const char *src)
840 if((null_string = (char *)malloc(1)) == NULL) {
841 DEBUG(0,("string_init: malloc fail for null_string.\n"));
848 (*dest) = strdup(src);
849 if ((*dest) == NULL) {
850 DEBUG(0,("Out of memory in string_init\n"));
861 void string_free(char **s)
865 if (*s == null_string)
871 Set a string value, deallocating any existing space, and allocing the space
875 BOOL string_set(char **dest,const char *src)
878 return(string_init(dest,src));
882 Substitute a string for a pattern in another string. Make sure there is
885 This routine looks for pattern in s and replaces it with
886 insert. It may do multiple replacements.
888 Any of " ; ' $ or ` in the insert string are replaced with _
889 if len==0 then the string cannot be extended. This is different from the old
890 use of len==0 which was for no length checks to be done.
893 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
898 if (!insert || !pattern || !*pattern || !s)
901 ls = (ssize_t)strlen(s);
902 lp = (ssize_t)strlen(pattern);
903 li = (ssize_t)strlen(insert);
906 len = ls + 1; /* len is number of *bytes* */
908 while (lp <= ls && (p = strstr(s,pattern))) {
909 if (ls + (li-lp) >= len) {
910 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
911 (int)(ls + (li-lp) - len),
916 memmove(p+li,p+lp,strlen(p+lp)+1);
939 void fstring_sub(char *s,const char *pattern,const char *insert)
941 string_sub(s, pattern, insert, sizeof(fstring));
944 void pstring_sub(char *s,const char *pattern,const char *insert)
946 string_sub(s, pattern, insert, sizeof(pstring));
950 Similar to string_sub, but it will accept only allocated strings
951 and may realloc them so pay attention at what you pass on no
952 pointers inside strings, no pstrings or const may be passed
956 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
960 ssize_t ls,lp,li,ld, i;
962 if (!insert || !pattern || !*pattern || !string || !*string)
969 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
972 ls = (ssize_t)strlen(s);
973 lp = (ssize_t)strlen(pattern);
974 li = (ssize_t)strlen(insert);
993 while ((p = strstr(s,pattern))) {
995 int offset = PTR_DIFF(s,string);
996 char *t = Realloc(string, ls + ld + 1);
998 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1003 p = t + offset + (p - s);
1006 memmove(p+li,p+lp,strlen(p+lp)+1);
1017 Similar to string_sub() but allows for any character to be substituted.
1019 if len==0 then the string cannot be extended. This is different from the old
1020 use of len==0 which was for no length checks to be done.
1023 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1028 if (!insert || !pattern || !s)
1031 ls = (ssize_t)strlen(s);
1032 lp = (ssize_t)strlen(pattern);
1033 li = (ssize_t)strlen(insert);
1039 len = ls + 1; /* len is number of *bytes* */
1041 while (lp <= ls && (p = strstr(s,pattern))) {
1042 if (ls + (li-lp) >= len) {
1043 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1044 (int)(ls + (li-lp) - len),
1045 pattern, (int)len));
1049 memmove(p+li,p+lp,strlen(p+lp)+1);
1051 memcpy(p, insert, li);
1058 Similar to all_string_sub but for unicode strings.
1059 Return a new allocated unicode string.
1060 similar to string_sub() but allows for any character to be substituted.
1064 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1065 const smb_ucs2_t *insert)
1068 const smb_ucs2_t *sp;
1069 size_t lr, lp, li, lt;
1071 if (!insert || !pattern || !*pattern || !s)
1074 lt = (size_t)strlen_w(s);
1075 lp = (size_t)strlen_w(pattern);
1076 li = (size_t)strlen_w(insert);
1079 const smb_ucs2_t *st = s;
1081 while ((sp = strstr_w(st, pattern))) {
1087 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1089 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1093 while ((sp = strstr_w(s, pattern))) {
1094 memcpy(rp, s, (sp - s));
1095 rp += ((sp - s) / sizeof(smb_ucs2_t));
1096 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1100 lr = ((rp - r) / sizeof(smb_ucs2_t));
1102 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1110 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1115 if (!insert || !pattern || !s)
1117 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1118 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1119 return all_string_sub_w(s, p, i);
1124 Splits out the front and back at a separator.
1127 static void split_at_last_component(char *path, char *front, char sep, char *back)
1129 char *p = strrchr_m(path, sep);
1135 pstrcpy(front, path);
1149 Write an octal as a string.
1152 const char *octal_string(int i)
1154 static char ret[64];
1157 slprintf(ret, sizeof(ret)-1, "0%o", i);
1163 Truncate a string at a specified length.
1166 char *string_truncate(char *s, unsigned int length)
1168 if (s && strlen(s) > length)
1174 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1175 We convert via ucs2 for now.
1178 char *strchr_m(const char *s, char c)
1184 /* this is quite a common operation, so we want it to be
1185 fast. We optimise for the ascii case, knowing that all our
1186 supported multi-byte character sets are ascii-compatible
1187 (ie. they match for the first 128 chars) */
1189 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1198 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1199 p = strchr_w(ws, UCS2_CHAR(c));
1203 pull_ucs2_pstring(s2, ws);
1204 return (char *)(s+strlen(s2));
1207 char *strrchr_m(const char *s, char c)
1209 /* this is quite a common operation, so we want it to be
1210 fast. We optimise for the ascii case, knowing that all our
1211 supported multi-byte character sets are ascii-compatible
1212 (ie. they match for the first 128 chars). Also, in Samba
1213 we only search for ascii characters in 'c' and that
1214 in all mb character sets with a compound character
1215 containing c, if 'c' is not a match at position
1216 p, then p[-1] > 0x7f. JRA. */
1219 size_t len = strlen(s);
1221 BOOL got_mb = False;
1228 /* Could be a match. Part of a multibyte ? */
1229 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1230 /* Yep - go slow :-( */
1234 /* No - we have a match ! */
1237 } while (cp-- != s);
1242 /* String contained a non-ascii char. Slow path. */
1248 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1249 p = strrchr_w(ws, UCS2_CHAR(c));
1253 pull_ucs2_pstring(s2, ws);
1254 return (char *)(s+strlen(s2));
1258 /***********************************************************************
1259 Return the equivalent of doing strrchr 'n' times - always going
1261 ***********************************************************************/
1263 char *strnrchr_m(const char *s, char c, unsigned int n)
1269 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1270 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1274 pull_ucs2_pstring(s2, ws);
1275 return (char *)(s+strlen(s2));
1279 Convert a string to lower case.
1282 void strlower_m(char *s)
1284 /* this is quite a common operation, so we want it to be
1285 fast. We optimise for the ascii case, knowing that all our
1286 supported multi-byte character sets are ascii-compatible
1287 (ie. they match for the first 128 chars) */
1289 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1290 *s = tolower((unsigned char)*s);
1297 /* I assume that lowercased string takes the same number of bytes
1298 * as source string even in UTF-8 encoding. (VIV) */
1299 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1303 Convert a string to upper case.
1306 void strupper_m(char *s)
1308 /* this is quite a common operation, so we want it to be
1309 fast. We optimise for the ascii case, knowing that all our
1310 supported multi-byte character sets are ascii-compatible
1311 (ie. they match for the first 128 chars) */
1313 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1314 *s = toupper((unsigned char)*s);
1321 /* I assume that lowercased string takes the same number of bytes
1322 * as source string even in multibyte encoding. (VIV) */
1323 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1327 Return a RFC2254 binary string representation of a buffer.
1328 Used in LDAP filters.
1332 char *binary_string(char *buf, int len)
1336 const char *hex = "0123456789ABCDEF";
1337 s = malloc(len * 3 + 1);
1340 for (j=i=0;i<len;i++) {
1342 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1343 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1351 Just a typesafety wrapper for snprintf into a pstring.
1354 int pstr_sprintf(pstring s, const char *fmt, ...)
1360 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1367 Just a typesafety wrapper for snprintf into a fstring.
1370 int fstr_sprintf(fstring s, const char *fmt, ...)
1376 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1382 #ifndef HAVE_STRNDUP
1384 Some platforms don't have strndup.
1387 char *strndup(const char *s, size_t n)
1402 #ifndef HAVE_STRNLEN
1404 Some platforms don't have strnlen
1407 size_t strnlen(const char *s, size_t n)
1410 for (i=0; s[i] && i<n; i++)
1417 List of Strings manipulation functions
1420 #define S_LIST_ABS 16 /* List Allocation Block Size */
1422 char **str_list_make(const char *string, const char *sep)
1424 char **list, **rlist;
1430 if (!string || !*string)
1434 DEBUG(0,("str_list_make: Unable to allocate memory"));
1437 if (!sep) sep = LIST_SEP;
1443 while (next_token(&str, tok, sep, sizeof(tok))) {
1445 lsize += S_LIST_ABS;
1446 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1448 DEBUG(0,("str_list_make: Unable to allocate memory"));
1449 str_list_free(&list);
1454 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1457 list[num] = strdup(tok);
1459 DEBUG(0,("str_list_make: Unable to allocate memory"));
1460 str_list_free(&list);
1472 BOOL str_list_copy(char ***dest, const char **src)
1474 char **list, **rlist;
1486 lsize += S_LIST_ABS;
1487 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1489 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1490 str_list_free(&list);
1494 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1497 list[num] = strdup(src[num]);
1499 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1500 str_list_free(&list);
1512 * Return true if all the elements of the list match exactly.
1514 BOOL str_list_compare(char **list1, char **list2)
1518 if (!list1 || !list2)
1519 return (list1 == list2);
1521 for (num = 0; list1[num]; num++) {
1524 if (!strcsequal(list1[num], list2[num]))
1528 return False; /* if list2 has more elements than list1 fail */
1533 void str_list_free(char ***list)
1537 if (!list || !*list)
1540 for(; *tlist; tlist++)
1545 /******************************************************************************
1546 version of standard_sub_basic() for string lists; uses alloc_sub_basic()
1548 *****************************************************************************/
1550 BOOL str_list_sub_basic( char **list, const char *smb_name )
1556 tmpstr = alloc_sub_basic(smb_name, s);
1558 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1570 /******************************************************************************
1571 substritute a specific pattern in a string list
1572 *****************************************************************************/
1574 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1577 ssize_t ls, lp, li, ld, i, d;
1586 lp = (ssize_t)strlen(pattern);
1587 li = (ssize_t)strlen(insert);
1592 ls = (ssize_t)strlen(s);
1594 while ((p = strstr(s, pattern))) {
1598 t = (char *) malloc(ls +ld +1);
1600 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1603 memcpy(t, *list, d);
1604 memcpy(t +d +li, p +lp, ls -d -lp +1);
1611 for (i = 0; i < li; i++) {
1612 switch (insert[i]) {
1624 t[d +i] = insert[i];
1637 #define IPSTR_LIST_SEP ","
1638 #define IPSTR_LIST_CHAR ','
1641 * Add ip string representation to ipstr list. Used also
1642 * as part of @function ipstr_list_make
1644 * @param ipstr_list pointer to string containing ip list;
1645 * MUST BE already allocated and IS reallocated if necessary
1646 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1647 * as a result of reallocation)
1648 * @param ip IP address which is to be added to list
1649 * @return pointer to string appended with new ip and possibly
1650 * reallocated to new length
1653 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1655 char* new_ipstr = NULL;
1657 /* arguments checking */
1658 if (!ipstr_list || !service) return NULL;
1660 /* attempt to convert ip to a string and append colon separator to it */
1662 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1663 inet_ntoa(service->ip), service->port);
1664 SAFE_FREE(*ipstr_list);
1666 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1668 *ipstr_list = new_ipstr;
1674 * Allocate and initialise an ipstr list using ip adresses
1675 * passed as arguments.
1677 * @param ipstr_list pointer to string meant to be allocated and set
1678 * @param ip_list array of ip addresses to place in the list
1679 * @param ip_count number of addresses stored in ip_list
1680 * @return pointer to allocated ip string
1683 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1687 /* arguments checking */
1688 if (!ip_list && !ipstr_list) return 0;
1692 /* process ip addresses given as arguments */
1693 for (i = 0; i < ip_count; i++)
1694 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1696 return (*ipstr_list);
1701 * Parse given ip string list into array of ip addresses
1702 * (as ip_service structures)
1703 * e.g. 192.168.1.100:389,192.168.1.78, ...
1705 * @param ipstr ip string list to be parsed
1706 * @param ip_list pointer to array of ip addresses which is
1707 * allocated by this function and must be freed by caller
1708 * @return number of succesfully parsed addresses
1711 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1717 if (!ipstr_list || !ip_list)
1720 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1721 if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1722 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1727 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1730 struct in_addr addr;
1732 char *p = strchr(token_str, ':');
1739 /* convert single token to ip address */
1740 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1743 (*ip_list)[i].ip = addr;
1744 (*ip_list)[i].port = port;
1752 * Safely free ip string list
1754 * @param ipstr_list ip string list to be freed
1757 void ipstr_list_free(char* ipstr_list)
1759 SAFE_FREE(ipstr_list);
1764 Unescape a URL encoded string, in place.
1767 void rfc1738_unescape(char *buf)
1771 while ((p=strchr_m(p,'+')))
1776 while (p && *p && (p=strchr_m(p,'%'))) {
1780 if (c1 >= '0' && c1 <= '9')
1782 else if (c1 >= 'A' && c1 <= 'F')
1784 else if (c1 >= 'a' && c1 <= 'f')
1786 else {p++; continue;}
1788 if (c2 >= '0' && c2 <= '9')
1790 else if (c2 >= 'A' && c2 <= 'F')
1792 else if (c2 >= 'a' && c2 <= 'f')
1794 else {p++; continue;}
1798 memmove(p+1, p+3, strlen(p+3)+1);
1803 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1806 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1808 DATA_BLOB base64_decode_data_blob(const char *s)
1810 int bit_offset, byte_offset, idx, i, n;
1811 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1812 unsigned char *d = decoded.data;
1817 while (*s && (p=strchr_m(b64,*s))) {
1818 idx = (int)(p - b64);
1819 byte_offset = (i*6)/8;
1820 bit_offset = (i*6)%8;
1821 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1822 if (bit_offset < 3) {
1823 d[byte_offset] |= (idx << (2-bit_offset));
1826 d[byte_offset] |= (idx >> (bit_offset-2));
1827 d[byte_offset+1] = 0;
1828 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1840 * Decode a base64 string in-place - wrapper for the above
1842 void base64_decode_inplace(char *s)
1844 DATA_BLOB decoded = base64_decode_data_blob(s);
1845 memcpy(s, decoded.data, decoded.length);
1846 /* null terminate */
1847 s[decoded.length] = '\0';
1849 data_blob_free(&decoded);
1853 * Encode a base64 string into a malloc()ed string caller to free.
1855 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1857 char * base64_encode_data_blob(DATA_BLOB data)
1862 size_t len = data.length;
1863 size_t output_len = data.length * 2;
1864 char *result = malloc(output_len); /* get us plenty of space */
1866 while (len-- && out_cnt < (data.length * 2) - 5) {
1867 int c = (unsigned char) *(data.data++);
1870 if (char_count == 3) {
1871 result[out_cnt++] = b64[bits >> 18];
1872 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1873 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1874 result[out_cnt++] = b64[bits & 0x3f];
1881 if (char_count != 0) {
1882 bits <<= 16 - (8 * char_count);
1883 result[out_cnt++] = b64[bits >> 18];
1884 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1885 if (char_count == 1) {
1886 result[out_cnt++] = '=';
1887 result[out_cnt++] = '=';
1889 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1890 result[out_cnt++] = '=';
1893 result[out_cnt] = '\0'; /* terminate */
1897 /* read a SMB_BIG_UINT from a string */
1898 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1901 SMB_BIG_UINT val = -1;
1902 const char *p = nptr;
1904 while (p && *p && isspace(*p))
1906 #ifdef LARGE_SMB_OFF_T
1907 sscanf(p,"%llu",&val);
1908 #else /* LARGE_SMB_OFF_T */
1909 sscanf(p,"%lu",&val);
1910 #endif /* LARGE_SMB_OFF_T */
1912 while (p && *p && isdigit(*p))