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
)
91 ptr
= (const char **)&last_ptr
;
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
)
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 memcpy(s
, s
+front_len
, (len
-front_len
)+1);
438 while ((len
>= back_len
) && strncmp(s
+len
-back_len
,back
,back_len
)==0) {
439 s
[len
-back_len
]='\0';
448 Does a string have any uppercase chars in it?
451 BOOL
strhasupper(const char *s
)
454 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
455 for(ptr
=tmpbuf
;*ptr
;ptr
++)
462 Does a string have any lowercase chars in it?
465 BOOL
strhaslower(const char *s
)
468 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
469 for(ptr
=tmpbuf
;*ptr
;ptr
++)
476 Find the number of 'c' chars in a string
479 size_t count_chars(const char *s
,char c
)
483 push_ucs2(NULL
, tmpbuf
,s
, sizeof(tmpbuf
), STR_TERMINATE
);
484 for(count
=0,ptr
=tmpbuf
;*ptr
;ptr
++)
485 if(*ptr
==UCS2_CHAR(c
))
491 Safe string copy into a known length string. maxlength does not
492 include the terminating zero.
495 char *safe_strcpy_fn(const char *fn
, int line
, char *dest
,const char *src
, size_t maxlength
)
500 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
504 clobber_region(fn
,line
,dest
, maxlength
+1);
511 len
= strnlen(src
, maxlength
+1);
513 if (len
> maxlength
) {
514 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
515 (unsigned int)(len
-maxlength
), len
, maxlength
, src
));
519 memmove(dest
, src
, len
);
525 Safe string cat into a string. maxlength does not
526 include the terminating zero.
528 char *safe_strcat_fn(const char *fn
, int line
, char *dest
, const char *src
, size_t maxlength
)
530 size_t src_len
, dest_len
;
533 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
540 src_len
= strnlen(src
, maxlength
+ 1);
541 dest_len
= strnlen(dest
, maxlength
+ 1);
543 clobber_region(fn
, line
, dest
+ dest_len
, maxlength
+ 1 - dest_len
);
545 if (src_len
+ dest_len
> maxlength
) {
546 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
547 (int)(src_len
+ dest_len
- maxlength
), src
));
548 if (maxlength
> dest_len
) {
549 memcpy(&dest
[dest_len
], src
, maxlength
- dest_len
);
555 memcpy(&dest
[dest_len
], src
, src_len
);
556 dest
[dest_len
+ src_len
] = 0;
561 Paranoid strcpy into a buffer of given length (includes terminating
562 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
563 and replaces with '_'. Deliberately does *NOT* check for multibyte
564 characters. Don't change it !
566 char *alpha_strcpy_fn(const char *fn
, int line
, char *dest
, const char *src
, const char *other_safe_chars
, size_t maxlength
)
570 clobber_region(fn
, line
, dest
, maxlength
);
573 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
583 if (len
>= maxlength
)
586 if (!other_safe_chars
)
587 other_safe_chars
= "";
589 for(i
= 0; i
< len
; i
++) {
590 int val
= (src
[i
] & 0xff);
591 if (isupper(val
) || islower(val
) || isdigit(val
) || strchr_m(other_safe_chars
, val
))
603 Like strncpy but always null terminates. Make sure there is room!
604 The variable n should always be one less than the available size.
606 char *StrnCpy_fn(const char *fn
, int line
,char *dest
,const char *src
,size_t n
)
610 clobber_region(fn
, line
, dest
, n
+1);
620 while (n
-- && (*d
= *src
)) {
631 Like strncpy but copies up to the character marker. always null terminates.
632 returns a pointer to the character marker in the source string (src).
635 static char *strncpyn(char *dest
, const char *src
, size_t n
, char c
)
640 clobber_region(dest
, n
+1);
642 p
= strchr_m(src
, c
);
644 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c
));
648 str_len
= PTR_DIFF(p
, src
);
649 strncpy(dest
, src
, MIN(n
, str_len
));
650 dest
[str_len
] = '\0';
657 Routine to get hex characters and turn them into a 16 byte array.
658 the array can be variable length, and any non-hex-numeric
659 characters are skipped. "0xnn" or "0Xnn" is specially catered
662 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
666 size_t strhex_to_str(char *p
, size_t len
, const char *strhex
)
669 size_t num_chars
= 0;
670 unsigned char lonybble
, hinybble
;
671 const char *hexchars
= "0123456789ABCDEF";
672 char *p1
= NULL
, *p2
= NULL
;
674 for (i
= 0; i
< len
&& strhex
[i
] != 0; i
++) {
675 if (strnequal(hexchars
, "0x", 2)) {
676 i
++; /* skip two chars */
680 if (!(p1
= strchr_m(hexchars
, toupper(strhex
[i
]))))
683 i
++; /* next hex digit */
685 if (!(p2
= strchr_m(hexchars
, toupper(strhex
[i
]))))
688 /* get the two nybbles */
689 hinybble
= PTR_DIFF(p1
, hexchars
);
690 lonybble
= PTR_DIFF(p2
, hexchars
);
692 p
[num_chars
] = (hinybble
<< 4) | lonybble
;
702 * Routine to print a buffer as HEX digits, into an allocated string.
705 void hex_encode(const unsigned char *buff_in
, size_t len
, char **out_hex_buffer
)
710 *out_hex_buffer
= smb_xmalloc((len
*2)+1);
711 hex_buffer
= *out_hex_buffer
;
713 for (i
= 0; i
< len
; i
++)
714 slprintf(&hex_buffer
[i
*2], 3, "%02X", buff_in
[i
]);
718 Check if a string is part of a list.
721 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
729 while (next_token(&p
,tok
,LIST_SEP
,sizeof(tok
))) {
731 if (strcmp(tok
,s
) == 0)
734 if (StrCaseCmp(tok
,s
) == 0)
741 /* this is used to prevent lots of mallocs of size 1 */
742 static char *null_string
= NULL
;
745 Set a string value, allocing the space for the string
748 static BOOL
string_init(char **dest
,const char *src
)
758 if((null_string
= (char *)malloc(1)) == NULL
) {
759 DEBUG(0,("string_init: malloc fail for null_string.\n"));
766 (*dest
) = strdup(src
);
767 if ((*dest
) == NULL
) {
768 DEBUG(0,("Out of memory in string_init\n"));
779 void string_free(char **s
)
783 if (*s
== null_string
)
789 Set a string value, deallocating any existing space, and allocing the space
793 BOOL
string_set(char **dest
,const char *src
)
796 return(string_init(dest
,src
));
800 Substitute a string for a pattern in another string. Make sure there is
803 This routine looks for pattern in s and replaces it with
804 insert. It may do multiple replacements.
806 Any of " ; ' $ or ` in the insert string are replaced with _
807 if len==0 then the string cannot be extended. This is different from the old
808 use of len==0 which was for no length checks to be done.
811 void string_sub(char *s
,const char *pattern
, const char *insert
, size_t len
)
816 if (!insert
|| !pattern
|| !*pattern
|| !s
)
819 ls
= (ssize_t
)strlen(s
);
820 lp
= (ssize_t
)strlen(pattern
);
821 li
= (ssize_t
)strlen(insert
);
824 len
= ls
+ 1; /* len is number of *bytes* */
826 while (lp
<= ls
&& (p
= strstr(s
,pattern
))) {
827 if (ls
+ (li
-lp
) >= len
) {
828 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
829 (int)(ls
+ (li
-lp
) - len
),
834 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
857 void fstring_sub(char *s
,const char *pattern
,const char *insert
)
859 string_sub(s
, pattern
, insert
, sizeof(fstring
));
862 void pstring_sub(char *s
,const char *pattern
,const char *insert
)
864 string_sub(s
, pattern
, insert
, sizeof(pstring
));
868 Similar to string_sub, but it will accept only allocated strings
869 and may realloc them so pay attention at what you pass on no
870 pointers inside strings, no pstrings or const may be passed
874 char *realloc_string_sub(char *string
, const char *pattern
, const char *insert
)
878 ssize_t ls
,lp
,li
,ld
, i
;
880 if (!insert
|| !pattern
|| !*pattern
|| !string
|| !*string
)
887 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
890 ls
= (ssize_t
)strlen(s
);
891 lp
= (ssize_t
)strlen(pattern
);
892 li
= (ssize_t
)strlen(insert
);
911 while ((p
= strstr(s
,pattern
))) {
913 char *t
= Realloc(string
, ls
+ ld
+ 1);
915 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
923 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
934 Similar to string_sub() but allows for any character to be substituted.
936 if len==0 then the string cannot be extended. This is different from the old
937 use of len==0 which was for no length checks to be done.
940 void all_string_sub(char *s
,const char *pattern
,const char *insert
, size_t len
)
945 if (!insert
|| !pattern
|| !s
)
948 ls
= (ssize_t
)strlen(s
);
949 lp
= (ssize_t
)strlen(pattern
);
950 li
= (ssize_t
)strlen(insert
);
956 len
= ls
+ 1; /* len is number of *bytes* */
958 while (lp
<= ls
&& (p
= strstr(s
,pattern
))) {
959 if (ls
+ (li
-lp
) >= len
) {
960 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
961 (int)(ls
+ (li
-lp
) - len
),
966 memmove(p
+li
,p
+lp
,strlen(p
+lp
)+1);
968 memcpy(p
, insert
, li
);
975 Similar to all_string_sub but for unicode strings.
976 Return a new allocated unicode string.
977 similar to string_sub() but allows for any character to be substituted.
981 static smb_ucs2_t
*all_string_sub_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*pattern
,
982 const smb_ucs2_t
*insert
)
985 const smb_ucs2_t
*sp
;
986 size_t lr
, lp
, li
, lt
;
988 if (!insert
|| !pattern
|| !*pattern
|| !s
)
991 lt
= (size_t)strlen_w(s
);
992 lp
= (size_t)strlen_w(pattern
);
993 li
= (size_t)strlen_w(insert
);
996 const smb_ucs2_t
*st
= s
;
998 while ((sp
= strstr_w(st
, pattern
))) {
1004 r
= rp
= (smb_ucs2_t
*)malloc((lt
+ 1)*(sizeof(smb_ucs2_t
)));
1006 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1010 while ((sp
= strstr_w(s
, pattern
))) {
1011 memcpy(rp
, s
, (sp
- s
));
1012 rp
+= ((sp
- s
) / sizeof(smb_ucs2_t
));
1013 memcpy(rp
, insert
, (li
* sizeof(smb_ucs2_t
)));
1017 lr
= ((rp
- r
) / sizeof(smb_ucs2_t
));
1019 memcpy(rp
, s
, ((lt
- lr
) * sizeof(smb_ucs2_t
)));
1027 smb_ucs2_t
*all_string_sub_wa(smb_ucs2_t
*s
, const char *pattern
,
1032 if (!insert
|| !pattern
|| !s
)
1034 push_ucs2(NULL
, p
, pattern
, sizeof(wpstring
) - 1, STR_TERMINATE
);
1035 push_ucs2(NULL
, i
, insert
, sizeof(wpstring
) - 1, STR_TERMINATE
);
1036 return all_string_sub_w(s
, p
, i
);
1041 Splits out the front and back at a separator.
1044 static void split_at_last_component(char *path
, char *front
, char sep
, char *back
)
1046 char *p
= strrchr_m(path
, sep
);
1052 pstrcpy(front
, path
);
1066 Write an octal as a string.
1069 const char *octal_string(int i
)
1071 static char ret
[64];
1074 slprintf(ret
, sizeof(ret
)-1, "0%o", i
);
1080 Truncate a string at a specified length.
1083 char *string_truncate(char *s
, unsigned int length
)
1085 if (s
&& strlen(s
) > length
)
1091 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1092 We convert via ucs2 for now.
1095 char *strchr_m(const char *s
, char c
)
1101 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1102 p
= strchr_w(ws
, UCS2_CHAR(c
));
1106 pull_ucs2_pstring(s2
, ws
);
1107 return (char *)(s
+strlen(s2
));
1110 char *strrchr_m(const char *s
, char c
)
1116 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1117 p
= strrchr_w(ws
, UCS2_CHAR(c
));
1121 pull_ucs2_pstring(s2
, ws
);
1122 return (char *)(s
+strlen(s2
));
1125 /***********************************************************************
1126 Return the equivalent of doing strrchr 'n' times - always going
1128 ***********************************************************************/
1130 char *strnrchr_m(const char *s
, char c
, unsigned int n
)
1136 push_ucs2(NULL
, ws
, s
, sizeof(ws
), STR_TERMINATE
);
1137 p
= strnrchr_w(ws
, UCS2_CHAR(c
), n
);
1141 pull_ucs2_pstring(s2
, ws
);
1142 return (char *)(s
+strlen(s2
));
1146 Convert a string to lower case.
1149 void strlower_m(char *s
)
1151 /* this is quite a common operation, so we want it to be
1152 fast. We optimise for the ascii case, knowing that all our
1153 supported multi-byte character sets are ascii-compatible
1154 (ie. they match for the first 128 chars) */
1156 while (*s
&& !(((unsigned char)s
[0]) & 0x7F)) {
1157 *s
= tolower((unsigned char)*s
);
1164 /* I assume that lowercased string takes the same number of bytes
1165 * as source string even in UTF-8 encoding. (VIV) */
1166 unix_strlower(s
,strlen(s
)+1,s
,strlen(s
)+1);
1170 Convert a string to upper case.
1173 void strupper_m(char *s
)
1175 /* this is quite a common operation, so we want it to be
1176 fast. We optimise for the ascii case, knowing that all our
1177 supported multi-byte character sets are ascii-compatible
1178 (ie. they match for the first 128 chars) */
1180 while (*s
&& !(((unsigned char)s
[0]) & 0x7F)) {
1181 *s
= toupper((unsigned char)*s
);
1188 /* I assume that lowercased string takes the same number of bytes
1189 * as source string even in multibyte encoding. (VIV) */
1190 unix_strupper(s
,strlen(s
)+1,s
,strlen(s
)+1);
1194 Return a RFC2254 binary string representation of a buffer.
1195 Used in LDAP filters.
1199 char *binary_string(char *buf
, int len
)
1203 const char *hex
= "0123456789ABCDEF";
1204 s
= malloc(len
* 3 + 1);
1207 for (j
=i
=0;i
<len
;i
++) {
1209 s
[j
+1] = hex
[((unsigned char)buf
[i
]) >> 4];
1210 s
[j
+2] = hex
[((unsigned char)buf
[i
]) & 0xF];
1218 Just a typesafety wrapper for snprintf into a pstring.
1221 int pstr_sprintf(pstring s
, const char *fmt
, ...)
1227 ret
= vsnprintf(s
, PSTRING_LEN
, fmt
, ap
);
1234 Just a typesafety wrapper for snprintf into a fstring.
1237 int fstr_sprintf(fstring s
, const char *fmt
, ...)
1243 ret
= vsnprintf(s
, FSTRING_LEN
, fmt
, ap
);
1249 #ifndef HAVE_STRNDUP
1251 Some platforms don't have strndup.
1254 char *strndup(const char *s
, size_t n
)
1269 #ifndef HAVE_STRNLEN
1271 Some platforms don't have strnlen
1274 size_t strnlen(const char *s
, size_t n
)
1277 for (i
=0; s
[i
] && i
<n
; i
++)
1284 List of Strings manipulation functions
1287 #define S_LIST_ABS 16 /* List Allocation Block Size */
1289 char **str_list_make(const char *string
, const char *sep
)
1291 char **list
, **rlist
;
1297 if (!string
|| !*string
)
1301 DEBUG(0,("str_list_make: Unable to allocate memory"));
1304 if (!sep
) sep
= LIST_SEP
;
1310 while (next_token(&str
, tok
, sep
, sizeof(tok
))) {
1312 lsize
+= S_LIST_ABS
;
1313 rlist
= (char **)Realloc(list
, ((sizeof(char **)) * (lsize
+1)));
1315 DEBUG(0,("str_list_make: Unable to allocate memory"));
1316 str_list_free(&list
);
1321 memset (&list
[num
], 0, ((sizeof(char**)) * (S_LIST_ABS
+1)));
1324 list
[num
] = strdup(tok
);
1326 DEBUG(0,("str_list_make: Unable to allocate memory"));
1327 str_list_free(&list
);
1339 BOOL
str_list_copy(char ***dest
, const char **src
)
1341 char **list
, **rlist
;
1353 lsize
+= S_LIST_ABS
;
1354 rlist
= (char **)Realloc(list
, ((sizeof(char **)) * (lsize
+1)));
1356 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1357 str_list_free(&list
);
1361 memset (&list
[num
], 0, ((sizeof(char **)) * (S_LIST_ABS
+1)));
1364 list
[num
] = strdup(src
[num
]);
1366 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1367 str_list_free(&list
);
1379 * Return true if all the elements of the list match exactly.
1381 BOOL
str_list_compare(char **list1
, char **list2
)
1385 if (!list1
|| !list2
)
1386 return (list1
== list2
);
1388 for (num
= 0; list1
[num
]; num
++) {
1391 if (!strcsequal(list1
[num
], list2
[num
]))
1395 return False
; /* if list2 has more elements than list1 fail */
1400 void str_list_free(char ***list
)
1404 if (!list
|| !*list
)
1407 for(; *tlist
; tlist
++)
1412 BOOL
str_list_substitute(char **list
, const char *pattern
, const char *insert
)
1415 ssize_t ls
, lp
, li
, ld
, i
, d
;
1424 lp
= (ssize_t
)strlen(pattern
);
1425 li
= (ssize_t
)strlen(insert
);
1430 ls
= (ssize_t
)strlen(s
);
1432 while ((p
= strstr(s
, pattern
))) {
1436 t
= (char *) malloc(ls
+ld
+1);
1438 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1441 memcpy(t
, *list
, d
);
1442 memcpy(t
+d
+li
, p
+lp
, ls
-d
-lp
+1);
1449 for (i
= 0; i
< li
; i
++) {
1450 switch (insert
[i
]) {
1462 t
[d
+i
] = insert
[i
];
1474 #define IPSTR_LIST_SEP ","
1475 #define IPSTR_LIST_CHAR ','
1478 * Add ip string representation to ipstr list. Used also
1479 * as part of @function ipstr_list_make
1481 * @param ipstr_list pointer to string containing ip list;
1482 * MUST BE already allocated and IS reallocated if necessary
1483 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1484 * as a result of reallocation)
1485 * @param ip IP address which is to be added to list
1486 * @return pointer to string appended with new ip and possibly
1487 * reallocated to new length
1490 char* ipstr_list_add(char** ipstr_list
, const struct ip_service
*service
)
1492 char* new_ipstr
= NULL
;
1494 /* arguments checking */
1495 if (!ipstr_list
|| !service
) return NULL
;
1497 /* attempt to convert ip to a string and append colon separator to it */
1499 asprintf(&new_ipstr
, "%s%s%s:%d", *ipstr_list
, IPSTR_LIST_SEP
,
1500 inet_ntoa(service
->ip
), service
->port
);
1501 SAFE_FREE(*ipstr_list
);
1503 asprintf(&new_ipstr
, "%s:%d", inet_ntoa(service
->ip
), service
->port
);
1505 *ipstr_list
= new_ipstr
;
1511 * Allocate and initialise an ipstr list using ip adresses
1512 * passed as arguments.
1514 * @param ipstr_list pointer to string meant to be allocated and set
1515 * @param ip_list array of ip addresses to place in the list
1516 * @param ip_count number of addresses stored in ip_list
1517 * @return pointer to allocated ip string
1520 char* ipstr_list_make(char** ipstr_list
, const struct ip_service
* ip_list
, int ip_count
)
1524 /* arguments checking */
1525 if (!ip_list
&& !ipstr_list
) return 0;
1529 /* process ip addresses given as arguments */
1530 for (i
= 0; i
< ip_count
; i
++)
1531 *ipstr_list
= ipstr_list_add(ipstr_list
, &ip_list
[i
]);
1533 return (*ipstr_list
);
1538 * Parse given ip string list into array of ip addresses
1539 * (as ip_service structures)
1540 * e.g. 192.168.1.100:389,192.168.1.78, ...
1542 * @param ipstr ip string list to be parsed
1543 * @param ip_list pointer to array of ip addresses which is
1544 * allocated by this function and must be freed by caller
1545 * @return number of succesfully parsed addresses
1548 int ipstr_list_parse(const char* ipstr_list
, struct ip_service
**ip_list
)
1554 if (!ipstr_list
|| !ip_list
)
1557 count
= count_chars(ipstr_list
, IPSTR_LIST_CHAR
) + 1;
1558 if ( (*ip_list
= (struct ip_service
*)malloc(count
* sizeof(struct ip_service
))) == NULL
) {
1559 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count
));
1564 next_token(&ipstr_list
, token_str
, IPSTR_LIST_SEP
, FSTRING_LEN
) && i
<count
;
1567 struct in_addr addr
;
1569 char *p
= strchr(token_str
, ':');
1576 /* convert single token to ip address */
1577 if ( (addr
.s_addr
= inet_addr(token_str
)) == INADDR_NONE
)
1580 (*ip_list
)[i
].ip
= addr
;
1581 (*ip_list
)[i
].port
= port
;
1589 * Safely free ip string list
1591 * @param ipstr_list ip string list to be freed
1594 void ipstr_list_free(char* ipstr_list
)
1596 SAFE_FREE(ipstr_list
);
1601 Unescape a URL encoded string, in place.
1604 void rfc1738_unescape(char *buf
)
1608 while ((p
=strchr_m(p
,'+')))
1613 while (p
&& *p
&& (p
=strchr_m(p
,'%'))) {
1617 if (c1
>= '0' && c1
<= '9')
1619 else if (c1
>= 'A' && c1
<= 'F')
1621 else if (c1
>= 'a' && c1
<= 'f')
1623 else {p
++; continue;}
1625 if (c2
>= '0' && c2
<= '9')
1627 else if (c2
>= 'A' && c2
<= 'F')
1629 else if (c2
>= 'a' && c2
<= 'f')
1631 else {p
++; continue;}
1635 memmove(p
+1, p
+3, strlen(p
+3)+1);
1640 static const char *b64
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1643 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1645 DATA_BLOB
base64_decode_data_blob(const char *s
)
1647 int bit_offset
, byte_offset
, idx
, i
, n
;
1648 DATA_BLOB decoded
= data_blob(s
, strlen(s
)+1);
1649 unsigned char *d
= decoded
.data
;
1654 while (*s
&& (p
=strchr_m(b64
,*s
))) {
1655 idx
= (int)(p
- b64
);
1656 byte_offset
= (i
*6)/8;
1657 bit_offset
= (i
*6)%8;
1658 d
[byte_offset
] &= ~((1<<(8-bit_offset
))-1);
1659 if (bit_offset
< 3) {
1660 d
[byte_offset
] |= (idx
<< (2-bit_offset
));
1663 d
[byte_offset
] |= (idx
>> (bit_offset
-2));
1664 d
[byte_offset
+1] = 0;
1665 d
[byte_offset
+1] |= (idx
<< (8-(bit_offset
-2))) & 0xFF;
1677 * Decode a base64 string in-place - wrapper for the above
1679 void base64_decode_inplace(char *s
)
1681 DATA_BLOB decoded
= base64_decode_data_blob(s
);
1682 memcpy(s
, decoded
.data
, decoded
.length
);
1683 /* null terminate */
1684 s
[decoded
.length
] = '\0';
1686 data_blob_free(&decoded
);
1690 * Encode a base64 string into a malloc()ed string caller to free.
1692 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1694 char * base64_encode_data_blob(DATA_BLOB data
)
1699 size_t len
= data
.length
;
1700 size_t output_len
= data
.length
* 2;
1701 char *result
= malloc(output_len
); /* get us plenty of space */
1703 while (len
-- && out_cnt
< (data
.length
* 2) - 5) {
1704 int c
= (unsigned char) *(data
.data
++);
1707 if (char_count
== 3) {
1708 result
[out_cnt
++] = b64
[bits
>> 18];
1709 result
[out_cnt
++] = b64
[(bits
>> 12) & 0x3f];
1710 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
1711 result
[out_cnt
++] = b64
[bits
& 0x3f];
1718 if (char_count
!= 0) {
1719 bits
<<= 16 - (8 * char_count
);
1720 result
[out_cnt
++] = b64
[bits
>> 18];
1721 result
[out_cnt
++] = b64
[(bits
>> 12) & 0x3f];
1722 if (char_count
== 1) {
1723 result
[out_cnt
++] = '=';
1724 result
[out_cnt
++] = '=';
1726 result
[out_cnt
++] = b64
[(bits
>> 6) & 0x3f];
1727 result
[out_cnt
++] = '=';
1730 result
[out_cnt
] = '\0'; /* terminate */
1734 /* read a SMB_BIG_UINT from a string */
1735 SMB_BIG_UINT
STR_TO_SMB_BIG_UINT(const char *nptr
, const char **entptr
)
1738 SMB_BIG_UINT val
= -1;
1739 const char *p
= nptr
;
1741 while (p
&& *p
&& isspace(*p
))
1743 #ifdef LARGE_SMB_OFF_T
1744 sscanf(p
,"%llu",&val
);
1745 #else /* LARGE_SMB_OFF_T */
1746 sscanf(p
,"%lu",&val
);
1747 #endif /* LARGE_SMB_OFF_T */
1749 while (p
&& *p
&& isdigit(*p
))