port latest changes from SAMBA_3_0 tree
[Samba.git] / source / lib / util_str.c
blob7569a39e6acf40b8911322886a70fec5f186546e
1 /*
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.
24 #include "includes.h"
26 /**
27 * @file
28 * @brief String utilities.
29 **/
31 /**
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
37 **/
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
40 const char *s;
41 char *pbuf;
42 BOOL quoted;
43 size_t len=1;
45 if (!ptr)
46 return(False);
48 s = *ptr;
50 /* default to simple separators */
51 if (!sep)
52 sep = " \t\n\r";
54 /* find the first non sep char */
55 while (*s && strchr_m(sep,*s))
56 s++;
58 /* nothing left? */
59 if (! *s)
60 return(False);
62 /* copy over the token */
63 pbuf = buff;
64 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65 if (*s == '\"') {
66 quoted = !quoted;
67 } else {
68 len++;
69 *pbuf++ = *s;
73 *ptr = (*s) ? s+1 : s;
74 *pbuf = 0;
76 return(True);
79 /**
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!
83 **/
85 static const char *last_ptr=NULL;
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
89 BOOL ret;
90 if (!ptr)
91 ptr = (const char **)&last_ptr;
93 ret = next_token(ptr, buff, sep, bufsize);
94 last_ptr = *ptr;
95 return ret;
98 static uint16 tmpbuf[sizeof(pstring)];
100 void set_first_token(char *ptr)
102 last_ptr = 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=last_ptr;
113 int ictok=0;
114 char **ret, **iret;
116 if (!sep)
117 sep = " \t\n\r";
119 while(*s && strchr_m(sep,*s))
120 s++;
122 /* nothing left? */
123 if (!*s)
124 return(NULL);
126 do {
127 ictok++;
128 while(*s && (!strchr_m(sep,*s)))
129 s++;
130 while(*s && strchr_m(sep,*s))
131 *s++=0;
132 } while(*s);
134 *ctok=ictok;
135 s=last_ptr;
137 if (!(ret=iret=malloc(ictok*sizeof(char *))))
138 return NULL;
140 while(ictok--) {
141 *iret++=s;
142 while(*s++)
144 while(!*s)
145 s++;
148 return ret;
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
167 * iconv.
169 * This should never be slower than convering the whole thing, and
170 * often faster.
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
178 * function pointer.
180 int StrCaseCmp(const char *s, const char *t)
183 const char * ps, * pt;
184 size_t size;
185 smb_ucs2_t *buffer_s, *buffer_t;
186 int ret;
188 for (ps = s, pt = t; ; ps++, pt++) {
189 char us, ut;
191 if (!*ps && !*pt)
192 return 0; /* both ended */
193 else if (!*ps)
194 return -1; /* s is a prefix */
195 else if (!*pt)
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 */
199 break;
201 us = toupper(*ps);
202 ut = toupper(*pt);
203 if (us == ut)
204 continue;
205 else if (us < ut)
206 return -1;
207 else if (us > ut)
208 return +1;
211 size = push_ucs2_allocate(&buffer_s, s);
212 if (size == (size_t)-1) {
213 return strcmp(s, t);
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) {
220 SAFE_FREE(buffer_s);
221 return strcmp(s, t);
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);
227 SAFE_FREE(buffer_s);
228 SAFE_FREE(buffer_t);
229 return ret;
234 Case insensitive string compararison, length limited.
236 int StrnCaseCmp(const char *s, const char *t, size_t n)
238 pstring buf1, buf2;
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);
245 * Compare 2 strings.
247 * @note The comparison is case-insensitive.
249 BOOL strequal(const char *s1, const char *s2)
251 if (s1 == s2)
252 return(True);
253 if (!s1 || !s2)
254 return(False);
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)
266 if (s1 == s2)
267 return(True);
268 if (!s1 || !s2 || !n)
269 return(False);
271 return(StrnCaseCmp(s1,s2,n)==0);
275 Compare 2 strings (case sensitive).
278 BOOL strcsequal(const char *s1,const char *s2)
280 if (s1 == s2)
281 return(True);
282 if (!s1 || !s2)
283 return(False);
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. */
296 if (psz1 == psz2)
297 return (0);
298 else if (psz1 == NULL)
299 return (-1);
300 else if (psz2 == NULL)
301 return (1);
303 /* sync the strings on first non-whitespace */
304 while (1) {
305 while (isspace((int)*psz1))
306 psz1++;
307 while (isspace((int)*psz2))
308 psz2++;
309 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
310 || *psz2 == '\0')
311 break;
312 psz1++;
313 psz2++;
315 return (*psz1 - *psz2);
320 Convert a string to upper case, but don't modify it.
323 char *strupper_static(const char *s)
325 static pstring str;
327 pstrcpy(str, s);
328 strupper_m(str);
330 return str;
334 Convert a string to "normal" form.
337 void strnorm(char *s)
339 extern int case_default;
340 if (case_default == CASE_UPPER)
341 strupper_m(s);
342 else
343 strlower_m(s);
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));
361 String replace.
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)
378 while (n--)
379 buf += strlen(buf) + 1;
380 return(buf);
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)
404 pstring tmpbuf2;
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)
415 BOOL ret = False;
416 size_t front_len;
417 size_t back_len;
418 size_t len;
420 /* Ignore null or empty strings. */
421 if (!s || (s[0] == '\0'))
422 return False;
424 front_len = front? strlen(front) : 0;
425 back_len = back? strlen(back) : 0;
427 len = strlen(s);
429 if (front_len) {
430 while (len && strncmp(s, front, front_len)==0) {
431 memcpy(s, s+front_len, (len-front_len)+1);
432 len -= front_len;
433 ret=True;
437 if (back_len) {
438 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
439 s[len-back_len]='\0';
440 len -= back_len;
441 ret=True;
444 return ret;
448 Does a string have any uppercase chars in it?
451 BOOL strhasupper(const char *s)
453 smb_ucs2_t *ptr;
454 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
455 for(ptr=tmpbuf;*ptr;ptr++)
456 if(isupper_w(*ptr))
457 return True;
458 return(False);
462 Does a string have any lowercase chars in it?
465 BOOL strhaslower(const char *s)
467 smb_ucs2_t *ptr;
468 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
469 for(ptr=tmpbuf;*ptr;ptr++)
470 if(islower_w(*ptr))
471 return True;
472 return(False);
476 Find the number of 'c' chars in a string
479 size_t count_chars(const char *s,char c)
481 smb_ucs2_t *ptr;
482 int count;
483 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
484 for(count=0,ptr=tmpbuf;*ptr;ptr++)
485 if(*ptr==UCS2_CHAR(c))
486 count++;
487 return(count);
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)
497 size_t len;
499 if (!dest) {
500 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
501 return NULL;
504 clobber_region(fn,line,dest, maxlength+1);
506 if (!src) {
507 *dest = 0;
508 return dest;
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));
516 len = maxlength;
519 memmove(dest, src, len);
520 dest[len] = 0;
521 return dest;
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;
532 if (!dest) {
533 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
534 return NULL;
537 if (!src)
538 return dest;
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);
551 dest[maxlength] = 0;
552 return NULL;
555 memcpy(&dest[dest_len], src, src_len);
556 dest[dest_len + src_len] = 0;
557 return dest;
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)
568 size_t len, i;
570 clobber_region(fn, line, dest, maxlength);
572 if (!dest) {
573 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
574 return NULL;
577 if (!src) {
578 *dest = 0;
579 return dest;
582 len = strlen(src);
583 if (len >= maxlength)
584 len = maxlength - 1;
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))
592 dest[i] = src[i];
593 else
594 dest[i] = '_';
597 dest[i] = '\0';
599 return dest;
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)
608 char *d = dest;
610 clobber_region(fn, line, dest, n+1);
612 if (!dest)
613 return(NULL);
615 if (!src) {
616 *dest = 0;
617 return(dest);
620 while (n-- && (*d = *src)) {
621 d++;
622 src++;
625 *d = 0;
626 return(dest);
629 #if 0
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)
637 char *p;
638 size_t str_len;
640 clobber_region(dest, n+1);
642 p = strchr_m(src, c);
643 if (p == NULL) {
644 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
645 return NULL;
648 str_len = PTR_DIFF(p, src);
649 strncpy(dest, src, MIN(n, str_len));
650 dest[str_len] = '\0';
652 return p;
654 #endif
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
660 for.
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)
668 size_t i;
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 */
677 continue;
680 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
681 break;
683 i++; /* next hex digit */
685 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
686 break;
688 /* get the two nybbles */
689 hinybble = PTR_DIFF(p1, hexchars);
690 lonybble = PTR_DIFF(p2, hexchars);
692 p[num_chars] = (hinybble << 4) | lonybble;
693 num_chars++;
695 p1 = NULL;
696 p2 = NULL;
698 return num_chars;
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)
707 int i;
708 char *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)
723 pstring tok;
724 const char *p=list;
726 if (!list)
727 return(False);
729 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
730 if (casesensitive) {
731 if (strcmp(tok,s) == 0)
732 return(True);
733 } else {
734 if (StrCaseCmp(tok,s) == 0)
735 return(True);
738 return(False);
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)
750 size_t l;
751 if (!src)
752 src = "";
754 l = strlen(src);
756 if (l == 0) {
757 if (!null_string) {
758 if((null_string = (char *)malloc(1)) == NULL) {
759 DEBUG(0,("string_init: malloc fail for null_string.\n"));
760 return False;
762 *null_string = 0;
764 *dest = null_string;
765 } else {
766 (*dest) = strdup(src);
767 if ((*dest) == NULL) {
768 DEBUG(0,("Out of memory in string_init\n"));
769 return False;
772 return(True);
776 Free a string value.
779 void string_free(char **s)
781 if (!s || !(*s))
782 return;
783 if (*s == null_string)
784 *s = NULL;
785 SAFE_FREE(*s);
789 Set a string value, deallocating any existing space, and allocing the space
790 for the string
793 BOOL string_set(char **dest,const char *src)
795 string_free(dest);
796 return(string_init(dest,src));
800 Substitute a string for a pattern in another string. Make sure there is
801 enough room!
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)
813 char *p;
814 ssize_t ls,lp,li, i;
816 if (!insert || !pattern || !*pattern || !s)
817 return;
819 ls = (ssize_t)strlen(s);
820 lp = (ssize_t)strlen(pattern);
821 li = (ssize_t)strlen(insert);
823 if (len == 0)
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),
830 pattern, (int)len));
831 break;
833 if (li != lp) {
834 memmove(p+li,p+lp,strlen(p+lp)+1);
836 for (i=0;i<li;i++) {
837 switch (insert[i]) {
838 case '`':
839 case '"':
840 case '\'':
841 case ';':
842 case '$':
843 case '%':
844 case '\r':
845 case '\n':
846 p[i] = '_';
847 break;
848 default:
849 p[i] = insert[i];
852 s = p + li;
853 ls += (li-lp);
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
871 as string.
874 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
876 char *p, *in;
877 char *s;
878 ssize_t ls,lp,li,ld, i;
880 if (!insert || !pattern || !*pattern || !string || !*string)
881 return NULL;
883 s = string;
885 in = strdup(insert);
886 if (!in) {
887 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
888 return NULL;
890 ls = (ssize_t)strlen(s);
891 lp = (ssize_t)strlen(pattern);
892 li = (ssize_t)strlen(insert);
893 ld = li - lp;
894 for (i=0;i<li;i++) {
895 switch (in[i]) {
896 case '`':
897 case '"':
898 case '\'':
899 case ';':
900 case '$':
901 case '%':
902 case '\r':
903 case '\n':
904 in[i] = '_';
905 default:
906 /* ok */
907 break;
911 while ((p = strstr(s,pattern))) {
912 if (ld > 0) {
913 char *t = Realloc(string, ls + ld + 1);
914 if (!t) {
915 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
916 SAFE_FREE(in);
917 return NULL;
919 string = t;
920 p = t + (p - s);
922 if (li != lp) {
923 memmove(p+li,p+lp,strlen(p+lp)+1);
925 memcpy(p, in, li);
926 s = p + li;
927 ls += ld;
929 SAFE_FREE(in);
930 return string;
934 Similar to string_sub() but allows for any character to be substituted.
935 Use with caution!
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)
942 char *p;
943 ssize_t ls,lp,li;
945 if (!insert || !pattern || !s)
946 return;
948 ls = (ssize_t)strlen(s);
949 lp = (ssize_t)strlen(pattern);
950 li = (ssize_t)strlen(insert);
952 if (!*pattern)
953 return;
955 if (len == 0)
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),
962 pattern, (int)len));
963 break;
965 if (li != lp) {
966 memmove(p+li,p+lp,strlen(p+lp)+1);
968 memcpy(p, insert, li);
969 s = p + li;
970 ls += (li-lp);
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.
978 Use with caution!
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)
984 smb_ucs2_t *r, *rp;
985 const smb_ucs2_t *sp;
986 size_t lr, lp, li, lt;
988 if (!insert || !pattern || !*pattern || !s)
989 return NULL;
991 lt = (size_t)strlen_w(s);
992 lp = (size_t)strlen_w(pattern);
993 li = (size_t)strlen_w(insert);
995 if (li > lp) {
996 const smb_ucs2_t *st = s;
997 int ld = li - lp;
998 while ((sp = strstr_w(st, pattern))) {
999 st = sp + lp;
1000 lt += ld;
1004 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1005 if (!r) {
1006 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1007 return NULL;
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)));
1014 s = sp + lp;
1015 rp += li;
1017 lr = ((rp - r) / sizeof(smb_ucs2_t));
1018 if (lr < lt) {
1019 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1020 rp += (lt - lr);
1022 *rp = 0;
1024 return r;
1027 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1028 const char *insert)
1030 wpstring p, i;
1032 if (!insert || !pattern || !s)
1033 return NULL;
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);
1039 #if 0
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);
1048 if (p != NULL)
1049 *p = 0;
1051 if (front != NULL)
1052 pstrcpy(front, path);
1054 if (p != NULL) {
1055 if (back != NULL)
1056 pstrcpy(back, p+1);
1057 *p = '\\';
1058 } else {
1059 if (back != NULL)
1060 back[0] = 0;
1063 #endif
1066 Write an octal as a string.
1069 const char *octal_string(int i)
1071 static char ret[64];
1072 if (i == -1)
1073 return "-1";
1074 slprintf(ret, sizeof(ret)-1, "0%o", i);
1075 return ret;
1080 Truncate a string at a specified length.
1083 char *string_truncate(char *s, unsigned int length)
1085 if (s && strlen(s) > length)
1086 s[length] = 0;
1087 return s;
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)
1097 wpstring ws;
1098 pstring s2;
1099 smb_ucs2_t *p;
1101 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1102 p = strchr_w(ws, UCS2_CHAR(c));
1103 if (!p)
1104 return NULL;
1105 *p = 0;
1106 pull_ucs2_pstring(s2, ws);
1107 return (char *)(s+strlen(s2));
1110 char *strrchr_m(const char *s, char c)
1112 wpstring ws;
1113 pstring s2;
1114 smb_ucs2_t *p;
1116 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1117 p = strrchr_w(ws, UCS2_CHAR(c));
1118 if (!p)
1119 return NULL;
1120 *p = 0;
1121 pull_ucs2_pstring(s2, ws);
1122 return (char *)(s+strlen(s2));
1125 /***********************************************************************
1126 Return the equivalent of doing strrchr 'n' times - always going
1127 backwards.
1128 ***********************************************************************/
1130 char *strnrchr_m(const char *s, char c, unsigned int n)
1132 wpstring ws;
1133 pstring s2;
1134 smb_ucs2_t *p;
1136 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1137 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1138 if (!p)
1139 return NULL;
1140 *p = 0;
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);
1158 s++;
1161 if (!*s)
1162 return;
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);
1182 s++;
1185 if (!*s)
1186 return;
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.
1196 Caller must free.
1199 char *binary_string(char *buf, int len)
1201 char *s;
1202 int i, j;
1203 const char *hex = "0123456789ABCDEF";
1204 s = malloc(len * 3 + 1);
1205 if (!s)
1206 return NULL;
1207 for (j=i=0;i<len;i++) {
1208 s[j] = '\\';
1209 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1210 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1211 j += 3;
1213 s[j] = 0;
1214 return s;
1218 Just a typesafety wrapper for snprintf into a pstring.
1221 int pstr_sprintf(pstring s, const char *fmt, ...)
1223 va_list ap;
1224 int ret;
1226 va_start(ap, fmt);
1227 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1228 va_end(ap);
1229 return ret;
1234 Just a typesafety wrapper for snprintf into a fstring.
1237 int fstr_sprintf(fstring s, const char *fmt, ...)
1239 va_list ap;
1240 int ret;
1242 va_start(ap, fmt);
1243 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1244 va_end(ap);
1245 return ret;
1249 #ifndef HAVE_STRNDUP
1251 Some platforms don't have strndup.
1254 char *strndup(const char *s, size_t n)
1256 char *ret;
1258 n = strnlen(s, n);
1259 ret = malloc(n+1);
1260 if (!ret)
1261 return NULL;
1262 memcpy(ret, s, n);
1263 ret[n] = 0;
1265 return ret;
1267 #endif
1269 #ifndef HAVE_STRNLEN
1271 Some platforms don't have strnlen
1274 size_t strnlen(const char *s, size_t n)
1276 int i;
1277 for (i=0; s[i] && i<n; i++)
1278 /* noop */ ;
1279 return i;
1281 #endif
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;
1292 const char *str;
1293 char *s;
1294 int num, lsize;
1295 pstring tok;
1297 if (!string || !*string)
1298 return NULL;
1299 s = strdup(string);
1300 if (!s) {
1301 DEBUG(0,("str_list_make: Unable to allocate memory"));
1302 return NULL;
1304 if (!sep) sep = LIST_SEP;
1306 num = lsize = 0;
1307 list = NULL;
1309 str = s;
1310 while (next_token(&str, tok, sep, sizeof(tok))) {
1311 if (num == lsize) {
1312 lsize += S_LIST_ABS;
1313 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1314 if (!rlist) {
1315 DEBUG(0,("str_list_make: Unable to allocate memory"));
1316 str_list_free(&list);
1317 SAFE_FREE(s);
1318 return NULL;
1319 } else
1320 list = rlist;
1321 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1324 list[num] = strdup(tok);
1325 if (!list[num]) {
1326 DEBUG(0,("str_list_make: Unable to allocate memory"));
1327 str_list_free(&list);
1328 SAFE_FREE(s);
1329 return NULL;
1332 num++;
1335 SAFE_FREE(s);
1336 return list;
1339 BOOL str_list_copy(char ***dest, const char **src)
1341 char **list, **rlist;
1342 int num, lsize;
1344 *dest = NULL;
1345 if (!src)
1346 return False;
1348 num = lsize = 0;
1349 list = NULL;
1351 while (src[num]) {
1352 if (num == lsize) {
1353 lsize += S_LIST_ABS;
1354 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1355 if (!rlist) {
1356 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1357 str_list_free(&list);
1358 return False;
1359 } else
1360 list = rlist;
1361 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1364 list[num] = strdup(src[num]);
1365 if (!list[num]) {
1366 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1367 str_list_free(&list);
1368 return False;
1371 num++;
1374 *dest = list;
1375 return True;
1379 * Return true if all the elements of the list match exactly.
1381 BOOL str_list_compare(char **list1, char **list2)
1383 int num;
1385 if (!list1 || !list2)
1386 return (list1 == list2);
1388 for (num = 0; list1[num]; num++) {
1389 if (!list2[num])
1390 return False;
1391 if (!strcsequal(list1[num], list2[num]))
1392 return False;
1394 if (list2[num])
1395 return False; /* if list2 has more elements than list1 fail */
1397 return True;
1400 void str_list_free(char ***list)
1402 char **tlist;
1404 if (!list || !*list)
1405 return;
1406 tlist = *list;
1407 for(; *tlist; tlist++)
1408 SAFE_FREE(*tlist);
1409 SAFE_FREE(*list);
1412 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1414 char *p, *s, *t;
1415 ssize_t ls, lp, li, ld, i, d;
1417 if (!list)
1418 return False;
1419 if (!pattern)
1420 return False;
1421 if (!insert)
1422 return False;
1424 lp = (ssize_t)strlen(pattern);
1425 li = (ssize_t)strlen(insert);
1426 ld = li -lp;
1428 while (*list) {
1429 s = *list;
1430 ls = (ssize_t)strlen(s);
1432 while ((p = strstr(s, pattern))) {
1433 t = *list;
1434 d = p -t;
1435 if (ld) {
1436 t = (char *) malloc(ls +ld +1);
1437 if (!t) {
1438 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1439 return False;
1441 memcpy(t, *list, d);
1442 memcpy(t +d +li, p +lp, ls -d -lp +1);
1443 SAFE_FREE(*list);
1444 *list = t;
1445 ls += ld;
1446 s = t +d +li;
1449 for (i = 0; i < li; i++) {
1450 switch (insert[i]) {
1451 case '`':
1452 case '"':
1453 case '\'':
1454 case ';':
1455 case '$':
1456 case '%':
1457 case '\r':
1458 case '\n':
1459 t[d +i] = '_';
1460 break;
1461 default:
1462 t[d +i] = insert[i];
1467 list++;
1470 return True;
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 */
1498 if (*ipstr_list) {
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);
1502 } else {
1503 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1505 *ipstr_list = new_ipstr;
1506 return *ipstr_list;
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)
1522 int i;
1524 /* arguments checking */
1525 if (!ip_list && !ipstr_list) return 0;
1527 *ipstr_list = NULL;
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)
1550 fstring token_str;
1551 size_t count;
1552 int i;
1554 if (!ipstr_list || !ip_list)
1555 return 0;
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));
1560 return 0;
1563 for ( i=0;
1564 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
1565 i++ )
1567 struct in_addr addr;
1568 unsigned port = 0;
1569 char *p = strchr(token_str, ':');
1571 if (p) {
1572 *p = 0;
1573 port = atoi(p+1);
1576 /* convert single token to ip address */
1577 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1578 break;
1580 (*ip_list)[i].ip = addr;
1581 (*ip_list)[i].port = port;
1584 return count;
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)
1606 char *p=buf;
1608 while ((p=strchr_m(p,'+')))
1609 *p = ' ';
1611 p = buf;
1613 while (p && *p && (p=strchr_m(p,'%'))) {
1614 int c1 = p[1];
1615 int c2 = p[2];
1617 if (c1 >= '0' && c1 <= '9')
1618 c1 = c1 - '0';
1619 else if (c1 >= 'A' && c1 <= 'F')
1620 c1 = 10 + c1 - 'A';
1621 else if (c1 >= 'a' && c1 <= 'f')
1622 c1 = 10 + c1 - 'a';
1623 else {p++; continue;}
1625 if (c2 >= '0' && c2 <= '9')
1626 c2 = c2 - '0';
1627 else if (c2 >= 'A' && c2 <= 'F')
1628 c2 = 10 + c2 - 'A';
1629 else if (c2 >= 'a' && c2 <= 'f')
1630 c2 = 10 + c2 - 'a';
1631 else {p++; continue;}
1633 *p = (c1<<4) | c2;
1635 memmove(p+1, p+3, strlen(p+3)+1);
1636 p++;
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;
1650 char *p;
1652 n=i=0;
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));
1661 n = byte_offset+1;
1662 } else {
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;
1666 n = byte_offset+2;
1668 s++; i++;
1671 /* fix up length */
1672 decoded.length = n;
1673 return decoded;
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)
1696 int bits = 0;
1697 int char_count = 0;
1698 size_t out_cnt = 0;
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++);
1705 bits += c;
1706 char_count++;
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];
1712 bits = 0;
1713 char_count = 0;
1714 } else {
1715 bits <<= 8;
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++] = '=';
1725 } else {
1726 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1727 result[out_cnt++] = '=';
1730 result[out_cnt] = '\0'; /* terminate */
1731 return result;
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))
1742 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 */
1748 if (entptr) {
1749 while (p && *p && isdigit(*p))
1750 p++;
1751 *entptr = p;
1754 return val;