check a pointer before dereferencing it; not sure why userdata == NULL though
[Samba.git] / source / lib / util_str.c
blobcc4b6fe5c5910676e21c54ca935869c57d41cc6d
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-2001
5 Copyright (C) Simo Sorce 2001-2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /**
25 * Get the next token from a string, return False if none found.
26 * Handles double-quotes.
28 * Based on a routine by GJC@VILLAGE.COM.
29 * Extensively modified by Andrew.Tridgell@anu.edu.au
30 **/
31 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
33 const char *s;
34 BOOL quoted;
35 size_t len=1;
37 if (!ptr)
38 return(False);
40 s = *ptr;
42 /* default to simple separators */
43 if (!sep)
44 sep = " \t\n\r";
46 /* find the first non sep char */
47 while (*s && strchr_m(sep,*s))
48 s++;
50 /* nothing left? */
51 if (! *s)
52 return(False);
54 /* copy over the token */
55 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
56 if (*s == '\"') {
57 quoted = !quoted;
58 } else {
59 len++;
60 *buff++ = *s;
64 *ptr = (*s) ? s+1 : s;
65 *buff = 0;
67 return(True);
70 /**
71 This is like next_token but is not re-entrant and "remembers" the first
72 parameter so you can pass NULL. This is useful for user interface code
73 but beware the fact that it is not re-entrant!
74 **/
76 static char *last_ptr=NULL;
78 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
80 BOOL ret;
81 if (!ptr)
82 ptr = (const char **)&last_ptr;
84 ret = next_token(ptr, buff, sep, bufsize);
85 last_ptr = *ptr;
86 return ret;
89 static uint16 tmpbuf[sizeof(pstring)];
91 void set_first_token(char *ptr)
93 last_ptr = ptr;
96 /**
97 Convert list of tokens to array; dependent on above routine.
98 Uses last_ptr from above - bit of a hack.
99 **/
101 char **toktocliplist(int *ctok, const char *sep)
103 char *s=last_ptr;
104 int ictok=0;
105 char **ret, **iret;
107 if (!sep)
108 sep = " \t\n\r";
110 while(*s && strchr_m(sep,*s))
111 s++;
113 /* nothing left? */
114 if (!*s)
115 return(NULL);
117 do {
118 ictok++;
119 while(*s && (!strchr_m(sep,*s)))
120 s++;
121 while(*s && strchr_m(sep,*s))
122 *s++=0;
123 } while(*s);
125 *ctok=ictok;
126 s=last_ptr;
128 if (!(ret=iret=malloc(ictok*sizeof(char *))))
129 return NULL;
131 while(ictok--) {
132 *iret++=s;
133 while(*s++)
135 while(!*s)
136 s++;
139 return ret;
143 Case insensitive string compararison.
146 int StrCaseCmp(const char *s, const char *t)
148 pstring buf1, buf2;
149 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
150 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
151 return strcmp(buf1,buf2);
155 Case insensitive string compararison, length limited.
158 int StrnCaseCmp(const char *s, const char *t, size_t n)
160 pstring buf1, buf2;
161 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
162 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
163 return strncmp(buf1,buf2,n);
167 Compare 2 strings.
170 BOOL strequal(const char *s1, const char *s2)
172 if (s1 == s2)
173 return(True);
174 if (!s1 || !s2)
175 return(False);
177 return(StrCaseCmp(s1,s2)==0);
181 Compare 2 strings up to and including the nth char.
184 BOOL strnequal(const char *s1,const char *s2,size_t n)
186 if (s1 == s2)
187 return(True);
188 if (!s1 || !s2 || !n)
189 return(False);
191 return(StrnCaseCmp(s1,s2,n)==0);
195 Compare 2 strings (case sensitive).
198 BOOL strcsequal(const char *s1,const char *s2)
200 if (s1 == s2)
201 return(True);
202 if (!s1 || !s2)
203 return(False);
205 return(strcmp(s1,s2)==0);
209 Do a case-insensitive, whitespace-ignoring string compare.
212 int strwicmp(const char *psz1, const char *psz2)
214 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
215 /* appropriate value. */
216 if (psz1 == psz2)
217 return (0);
218 else if (psz1 == NULL)
219 return (-1);
220 else if (psz2 == NULL)
221 return (1);
223 /* sync the strings on first non-whitespace */
224 while (1) {
225 while (isspace((int)*psz1))
226 psz1++;
227 while (isspace((int)*psz2))
228 psz2++;
229 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
230 || *psz2 == '\0')
231 break;
232 psz1++;
233 psz2++;
235 return (*psz1 - *psz2);
240 Convert a string to upper case, but don't modify it.
243 char *strupper_static(const char *s)
245 static pstring str;
247 pstrcpy(str, s);
248 strupper(str);
250 return str;
254 Convert a string to "normal" form.
257 void strnorm(char *s)
259 extern int case_default;
260 if (case_default == CASE_UPPER)
261 strupper(s);
262 else
263 strlower(s);
267 Check if a string is in "normal" case.
270 BOOL strisnormal(const char *s)
272 extern int case_default;
273 if (case_default == CASE_UPPER)
274 return(!strhaslower(s));
276 return(!strhasupper(s));
281 String replace.
282 NOTE: oldc and newc must be 7 bit characters
285 void string_replace(char *s,char oldc,char newc)
287 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
288 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
289 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
293 Skip past some strings in a buffer.
296 char *skip_string(char *buf,size_t n)
298 while (n--)
299 buf += strlen(buf) + 1;
300 return(buf);
304 Count the number of characters in a string. Normally this will
305 be the same as the number of bytes in a string for single byte strings,
306 but will be different for multibyte.
309 size_t str_charnum(const char *s)
311 uint16 tmpbuf2[sizeof(pstring)];
312 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
313 return strlen_w(tmpbuf2);
317 Count the number of characters in a string. Normally this will
318 be the same as the number of bytes in a string for single byte strings,
319 but will be different for multibyte.
322 size_t str_ascii_charnum(const char *s)
324 pstring tmpbuf2;
325 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
326 return strlen(tmpbuf2);
330 Trim the specified elements off the front and back of a string.
333 BOOL trim_string(char *s,const char *front,const char *back)
335 BOOL ret = False;
336 size_t front_len;
337 size_t back_len;
338 size_t len;
340 /* Ignore null or empty strings. */
341 if (!s || (s[0] == '\0'))
342 return False;
344 front_len = front? strlen(front) : 0;
345 back_len = back? strlen(back) : 0;
347 len = strlen(s);
349 if (front_len) {
350 while (len && strncmp(s, front, front_len)==0) {
351 memcpy(s, s+front_len, (len-front_len)+1);
352 len -= front_len;
353 ret=True;
357 if (back_len) {
358 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
359 s[len-back_len]='\0';
360 len -= back_len;
361 ret=True;
364 return ret;
368 Does a string have any uppercase chars in it?
371 BOOL strhasupper(const char *s)
373 smb_ucs2_t *ptr;
374 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
375 for(ptr=tmpbuf;*ptr;ptr++)
376 if(isupper_w(*ptr))
377 return True;
378 return(False);
382 Does a string have any lowercase chars in it?
385 BOOL strhaslower(const char *s)
387 smb_ucs2_t *ptr;
388 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
389 for(ptr=tmpbuf;*ptr;ptr++)
390 if(islower_w(*ptr))
391 return True;
392 return(False);
396 Find the number of 'c' chars in a string
399 size_t count_chars(const char *s,char c)
401 smb_ucs2_t *ptr;
402 int count;
403 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
404 for(count=0,ptr=tmpbuf;*ptr;ptr++)
405 if(*ptr==UCS2_CHAR(c))
406 count++;
407 return(count);
411 Return True if a string consists only of one particular character.
414 BOOL str_is_all(const char *s,char c)
416 smb_ucs2_t *ptr;
418 if(s == NULL)
419 return False;
420 if(!*s)
421 return False;
423 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
424 for(ptr=tmpbuf;*ptr;ptr++)
425 if(*ptr!=UCS2_CHAR(c))
426 return False;
428 return True;
432 Safe string copy into a known length string. maxlength does not
433 include the terminating zero.
436 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
438 size_t len;
440 if (!dest) {
441 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
442 return NULL;
445 #ifdef DEVELOPER
446 /* We intentionally write out at the extremity of the destination
447 * string. If the destination is too short (e.g. pstrcpy into mallocd
448 * or fstring) then this should cause an error under a memory
449 * checker. */
450 dest[maxlength] = '\0';
451 #endif
453 if (!src) {
454 *dest = 0;
455 return dest;
458 len = strlen(src);
460 if (len > maxlength) {
461 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
462 (unsigned int)(len-maxlength), len, maxlength, src));
463 len = maxlength;
466 memmove(dest, src, len);
467 dest[len] = 0;
468 return dest;
472 Safe string cat into a string. maxlength does not
473 include the terminating zero.
476 char *safe_strcat(char *dest, const char *src, size_t maxlength)
478 size_t src_len, dest_len;
480 if (!dest) {
481 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
482 return NULL;
485 if (!src)
486 return dest;
488 src_len = strlen(src);
489 dest_len = strlen(dest);
491 if (src_len + dest_len > maxlength) {
492 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
493 (int)(src_len + dest_len - maxlength), src));
494 if (maxlength > dest_len) {
495 memcpy(&dest[dest_len], src, maxlength - dest_len);
497 dest[maxlength] = 0;
498 return NULL;
501 memcpy(&dest[dest_len], src, src_len);
502 dest[dest_len + src_len] = 0;
503 return dest;
507 Paranoid strcpy into a buffer of given length (includes terminating
508 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
509 and replaces with '_'. Deliberately does *NOT* check for multibyte
510 characters. Don't change it !
513 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
515 size_t len, i;
517 if (!dest) {
518 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
519 return NULL;
522 if (!src) {
523 *dest = 0;
524 return dest;
527 len = strlen(src);
528 if (len >= maxlength)
529 len = maxlength - 1;
531 if (!other_safe_chars)
532 other_safe_chars = "";
534 for(i = 0; i < len; i++) {
535 int val = (src[i] & 0xff);
536 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
537 dest[i] = src[i];
538 else
539 dest[i] = '_';
542 dest[i] = '\0';
544 return dest;
548 Like strncpy but always null terminates. Make sure there is room!
549 The variable n should always be one less than the available size.
552 char *StrnCpy(char *dest,const char *src,size_t n)
554 char *d = dest;
555 if (!dest)
556 return(NULL);
557 if (!src) {
558 *dest = 0;
559 return(dest);
561 while (n-- && (*d++ = *src++))
563 *d = 0;
564 return(dest);
568 Like strncpy but copies up to the character marker. always null terminates.
569 returns a pointer to the character marker in the source string (src).
572 char *strncpyn(char *dest, const char *src, size_t n, char c)
574 char *p;
575 size_t str_len;
577 p = strchr_m(src, c);
578 if (p == NULL) {
579 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
580 return NULL;
583 str_len = PTR_DIFF(p, src);
584 strncpy(dest, src, MIN(n, str_len));
585 dest[str_len] = '\0';
587 return p;
591 Routine to get hex characters and turn them into a 16 byte array.
592 the array can be variable length, and any non-hex-numeric
593 characters are skipped. "0xnn" or "0Xnn" is specially catered
594 for.
596 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
600 size_t strhex_to_str(char *p, size_t len, const char *strhex)
602 size_t i;
603 size_t num_chars = 0;
604 unsigned char lonybble, hinybble;
605 const char *hexchars = "0123456789ABCDEF";
606 char *p1 = NULL, *p2 = NULL;
608 for (i = 0; i < len && strhex[i] != 0; i++) {
609 if (strnequal(hexchars, "0x", 2)) {
610 i++; /* skip two chars */
611 continue;
614 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
615 break;
617 i++; /* next hex digit */
619 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
620 break;
622 /* get the two nybbles */
623 hinybble = PTR_DIFF(p1, hexchars);
624 lonybble = PTR_DIFF(p2, hexchars);
626 p[num_chars] = (hinybble << 4) | lonybble;
627 num_chars++;
629 p1 = NULL;
630 p2 = NULL;
632 return num_chars;
636 Check if a string is part of a list.
639 BOOL in_list(char *s,char *list,BOOL casesensitive)
641 pstring tok;
642 const char *p=list;
644 if (!list)
645 return(False);
647 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
648 if (casesensitive) {
649 if (strcmp(tok,s) == 0)
650 return(True);
651 } else {
652 if (StrCaseCmp(tok,s) == 0)
653 return(True);
656 return(False);
659 /* this is used to prevent lots of mallocs of size 1 */
660 static char *null_string = NULL;
663 Set a string value, allocing the space for the string
666 static BOOL string_init(char **dest,const char *src)
668 size_t l;
669 if (!src)
670 src = "";
672 l = strlen(src);
674 if (l == 0) {
675 if (!null_string) {
676 if((null_string = (char *)malloc(1)) == NULL) {
677 DEBUG(0,("string_init: malloc fail for null_string.\n"));
678 return False;
680 *null_string = 0;
682 *dest = null_string;
683 } else {
684 (*dest) = strdup(src);
685 if ((*dest) == NULL) {
686 DEBUG(0,("Out of memory in string_init\n"));
687 return False;
690 return(True);
694 Free a string value.
697 void string_free(char **s)
699 if (!s || !(*s))
700 return;
701 if (*s == null_string)
702 *s = NULL;
703 SAFE_FREE(*s);
707 Set a string value, deallocating any existing space, and allocing the space
708 for the string
711 BOOL string_set(char **dest,const char *src)
713 string_free(dest);
714 return(string_init(dest,src));
718 Substitute a string for a pattern in another string. Make sure there is
719 enough room!
721 This routine looks for pattern in s and replaces it with
722 insert. It may do multiple replacements.
724 Any of " ; ' $ or ` in the insert string are replaced with _
725 if len==0 then the string cannot be extended. This is different from the old
726 use of len==0 which was for no length checks to be done.
729 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
731 char *p;
732 ssize_t ls,lp,li, i;
734 if (!insert || !pattern || !*pattern || !s)
735 return;
737 ls = (ssize_t)strlen(s);
738 lp = (ssize_t)strlen(pattern);
739 li = (ssize_t)strlen(insert);
741 if (len == 0)
742 len = ls + 1; /* len is number of *bytes* */
744 while (lp <= ls && (p = strstr(s,pattern))) {
745 if (ls + (li-lp) >= len) {
746 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
747 (int)(ls + (li-lp) - len),
748 pattern, (int)len));
749 break;
751 if (li != lp) {
752 memmove(p+li,p+lp,strlen(p+lp)+1);
754 for (i=0;i<li;i++) {
755 switch (insert[i]) {
756 case '`':
757 case '"':
758 case '\'':
759 case ';':
760 case '$':
761 case '%':
762 case '\r':
763 case '\n':
764 p[i] = '_';
765 break;
766 default:
767 p[i] = insert[i];
770 s = p + li;
771 ls += (li-lp);
775 void fstring_sub(char *s,const char *pattern,const char *insert)
777 string_sub(s, pattern, insert, sizeof(fstring));
780 void pstring_sub(char *s,const char *pattern,const char *insert)
782 string_sub(s, pattern, insert, sizeof(pstring));
786 Similar to string_sub, but it will accept only allocated strings
787 and may realloc them so pay attention at what you pass on no
788 pointers inside strings, no pstrings or const may be passed
789 as string.
792 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
794 char *p, *in;
795 char *s;
796 ssize_t ls,lp,li,ld, i;
798 if (!insert || !pattern || !*pattern || !string || !*string)
799 return NULL;
801 s = string;
803 in = strdup(insert);
804 if (!in) {
805 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
806 return NULL;
808 ls = (ssize_t)strlen(s);
809 lp = (ssize_t)strlen(pattern);
810 li = (ssize_t)strlen(insert);
811 ld = li - lp;
812 for (i=0;i<li;i++) {
813 switch (in[i]) {
814 case '`':
815 case '"':
816 case '\'':
817 case ';':
818 case '$':
819 case '%':
820 case '\r':
821 case '\n':
822 in[i] = '_';
823 default:
824 /* ok */
825 break;
829 while ((p = strstr(s,pattern))) {
830 if (ld > 0) {
831 char *t = Realloc(string, ls + ld + 1);
832 if (!t) {
833 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
834 SAFE_FREE(in);
835 return NULL;
837 string = t;
838 p = t + (p - s);
840 if (li != lp) {
841 memmove(p+li,p+lp,strlen(p+lp)+1);
843 memcpy(p, in, li);
844 s = p + li;
845 ls += ld;
847 SAFE_FREE(in);
848 return string;
852 Similar to string_sub() but allows for any character to be substituted.
853 Use with caution!
854 if len==0 then the string cannot be extended. This is different from the old
855 use of len==0 which was for no length checks to be done.
858 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
860 char *p;
861 ssize_t ls,lp,li;
863 if (!insert || !pattern || !s)
864 return;
866 ls = (ssize_t)strlen(s);
867 lp = (ssize_t)strlen(pattern);
868 li = (ssize_t)strlen(insert);
870 if (!*pattern)
871 return;
873 if (len == 0)
874 len = ls + 1; /* len is number of *bytes* */
876 while (lp <= ls && (p = strstr(s,pattern))) {
877 if (ls + (li-lp) >= len) {
878 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
879 (int)(ls + (li-lp) - len),
880 pattern, (int)len));
881 break;
883 if (li != lp) {
884 memmove(p+li,p+lp,strlen(p+lp)+1);
886 memcpy(p, insert, li);
887 s = p + li;
888 ls += (li-lp);
893 Similar to all_string_sub but for unicode strings.
894 Return a new allocated unicode string.
895 similar to string_sub() but allows for any character to be substituted.
896 Use with caution!
899 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
900 const smb_ucs2_t *insert)
902 smb_ucs2_t *r, *rp;
903 const smb_ucs2_t *sp;
904 size_t lr, lp, li, lt;
906 if (!insert || !pattern || !*pattern || !s)
907 return NULL;
909 lt = (size_t)strlen_w(s);
910 lp = (size_t)strlen_w(pattern);
911 li = (size_t)strlen_w(insert);
913 if (li > lp) {
914 const smb_ucs2_t *st = s;
915 int ld = li - lp;
916 while ((sp = strstr_w(st, pattern))) {
917 st = sp + lp;
918 lt += ld;
922 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
923 if (!r) {
924 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
925 return NULL;
928 while ((sp = strstr_w(s, pattern))) {
929 memcpy(rp, s, (sp - s));
930 rp += ((sp - s) / sizeof(smb_ucs2_t));
931 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
932 s = sp + lp;
933 rp += li;
935 lr = ((rp - r) / sizeof(smb_ucs2_t));
936 if (lr < lt) {
937 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
938 rp += (lt - lr);
940 *rp = 0;
942 return r;
945 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
946 const char *insert)
948 wpstring p, i;
950 if (!insert || !pattern || !s)
951 return NULL;
952 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
953 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
954 return all_string_sub_w(s, p, i);
958 Splits out the front and back at a separator.
961 void split_at_last_component(char *path, char *front, char sep, char *back)
963 char *p = strrchr_m(path, sep);
965 if (p != NULL)
966 *p = 0;
968 if (front != NULL)
969 pstrcpy(front, path);
971 if (p != NULL) {
972 if (back != NULL)
973 pstrcpy(back, p+1);
974 *p = '\\';
975 } else {
976 if (back != NULL)
977 back[0] = 0;
982 Write an octal as a string.
985 const char *octal_string(int i)
987 static char ret[64];
988 if (i == -1)
989 return "-1";
990 slprintf(ret, sizeof(ret)-1, "0%o", i);
991 return ret;
996 Truncate a string at a specified length.
999 char *string_truncate(char *s, int length)
1001 if (s && strlen(s) > length)
1002 s[length] = 0;
1003 return s;
1007 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1008 We convert via ucs2 for now.
1011 char *strchr_m(const char *s, char c)
1013 wpstring ws;
1014 pstring s2;
1015 smb_ucs2_t *p;
1017 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1018 p = strchr_w(ws, UCS2_CHAR(c));
1019 if (!p)
1020 return NULL;
1021 *p = 0;
1022 pull_ucs2_pstring(s2, ws);
1023 return (char *)(s+strlen(s2));
1026 char *strrchr_m(const char *s, char c)
1028 wpstring ws;
1029 pstring s2;
1030 smb_ucs2_t *p;
1032 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1033 p = strrchr_w(ws, UCS2_CHAR(c));
1034 if (!p)
1035 return NULL;
1036 *p = 0;
1037 pull_ucs2_pstring(s2, ws);
1038 return (char *)(s+strlen(s2));
1042 Convert a string to lower case.
1045 void strlower_m(char *s)
1047 /* this is quite a common operation, so we want it to be
1048 fast. We optimise for the ascii case, knowing that all our
1049 supported multi-byte character sets are ascii-compatible
1050 (ie. they match for the first 128 chars) */
1052 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1053 *s = tolower((unsigned char)*s);
1054 s++;
1057 if (!*s)
1058 return;
1060 /* I assume that lowercased string takes the same number of bytes
1061 * as source string even in UTF-8 encoding. (VIV) */
1062 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1066 Duplicate convert a string to lower case.
1069 char *strdup_lower(const char *s)
1071 char *t = strdup(s);
1072 if (t == NULL) {
1073 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1074 return NULL;
1076 strlower_m(t);
1077 return t;
1081 Convert a string to upper case.
1084 void strupper_m(char *s)
1086 /* this is quite a common operation, so we want it to be
1087 fast. We optimise for the ascii case, knowing that all our
1088 supported multi-byte character sets are ascii-compatible
1089 (ie. they match for the first 128 chars) */
1091 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1092 *s = toupper((unsigned char)*s);
1093 s++;
1096 if (!*s)
1097 return;
1099 /* I assume that lowercased string takes the same number of bytes
1100 * as source string even in multibyte encoding. (VIV) */
1101 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1105 Convert a string to upper case.
1108 char *strdup_upper(const char *s)
1110 char *t = strdup(s);
1111 if (t == NULL) {
1112 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1113 return NULL;
1115 strupper_m(t);
1116 return t;
1120 Return a RFC2254 binary string representation of a buffer.
1121 Used in LDAP filters.
1122 Caller must free.
1125 char *binary_string(char *buf, int len)
1127 char *s;
1128 int i, j;
1129 const char *hex = "0123456789ABCDEF";
1130 s = malloc(len * 3 + 1);
1131 if (!s)
1132 return NULL;
1133 for (j=i=0;i<len;i++) {
1134 s[j] = '\\';
1135 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1136 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1137 j += 3;
1139 s[j] = 0;
1140 return s;
1144 Just a typesafety wrapper for snprintf into a pstring.
1147 int pstr_sprintf(pstring s, const char *fmt, ...)
1149 va_list ap;
1150 int ret;
1152 va_start(ap, fmt);
1153 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1154 va_end(ap);
1155 return ret;
1159 Just a typesafety wrapper for snprintf into a fstring.
1162 int fstr_sprintf(fstring s, const char *fmt, ...)
1164 va_list ap;
1165 int ret;
1167 va_start(ap, fmt);
1168 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1169 va_end(ap);
1170 return ret;
1173 #ifndef HAVE_STRNDUP
1175 Some platforms don't have strndup.
1178 char *strndup(const char *s, size_t n)
1180 char *ret;
1182 n = strnlen(s, n);
1183 ret = malloc(n+1);
1184 if (!ret)
1185 return NULL;
1186 memcpy(ret, s, n);
1187 ret[n] = 0;
1189 return ret;
1191 #endif
1193 #ifndef HAVE_STRNLEN
1195 Some platforms don't have strnlen
1198 size_t strnlen(const char *s, size_t n)
1200 int i;
1201 for (i=0; s[i] && i<n; i++)
1202 /* noop */ ;
1203 return i;
1205 #endif
1208 List of Strings manipulation functions
1211 #define S_LIST_ABS 16 /* List Allocation Block Size */
1213 char **str_list_make(const char *string, const char *sep)
1215 char **list, **rlist;
1216 const char *str;
1217 char *s;
1218 int num, lsize;
1219 pstring tok;
1221 if (!string || !*string)
1222 return NULL;
1223 s = strdup(string);
1224 if (!s) {
1225 DEBUG(0,("str_list_make: Unable to allocate memory"));
1226 return NULL;
1228 if (!sep) sep = LIST_SEP;
1230 num = lsize = 0;
1231 list = NULL;
1233 str = s;
1234 while (next_token(&str, tok, sep, sizeof(tok))) {
1235 if (num == lsize) {
1236 lsize += S_LIST_ABS;
1237 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1238 if (!rlist) {
1239 DEBUG(0,("str_list_make: Unable to allocate memory"));
1240 str_list_free(&list);
1241 SAFE_FREE(s);
1242 return NULL;
1243 } else
1244 list = rlist;
1245 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1248 list[num] = strdup(tok);
1249 if (!list[num]) {
1250 DEBUG(0,("str_list_make: Unable to allocate memory"));
1251 str_list_free(&list);
1252 SAFE_FREE(s);
1253 return NULL;
1256 num++;
1259 SAFE_FREE(s);
1260 return list;
1263 BOOL str_list_copy(char ***dest, const char **src)
1265 char **list, **rlist;
1266 int num, lsize;
1268 *dest = NULL;
1269 if (!src)
1270 return False;
1272 num = lsize = 0;
1273 list = NULL;
1275 while (src[num]) {
1276 if (num == lsize) {
1277 lsize += S_LIST_ABS;
1278 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1279 if (!rlist) {
1280 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1281 str_list_free(&list);
1282 return False;
1283 } else
1284 list = rlist;
1285 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1288 list[num] = strdup(src[num]);
1289 if (!list[num]) {
1290 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1291 str_list_free(&list);
1292 return False;
1295 num++;
1298 *dest = list;
1299 return True;
1303 * Return true if all the elements of the list match exactly.
1305 BOOL str_list_compare(char **list1, char **list2)
1307 int num;
1309 if (!list1 || !list2)
1310 return (list1 == list2);
1312 for (num = 0; list1[num]; num++) {
1313 if (!list2[num])
1314 return False;
1315 if (!strcsequal(list1[num], list2[num]))
1316 return False;
1318 if (list2[num])
1319 return False; /* if list2 has more elements than list1 fail */
1321 return True;
1324 void str_list_free(char ***list)
1326 char **tlist;
1328 if (!list || !*list)
1329 return;
1330 tlist = *list;
1331 for(; *tlist; tlist++)
1332 SAFE_FREE(*tlist);
1333 SAFE_FREE(*list);
1336 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1338 char *p, *s, *t;
1339 ssize_t ls, lp, li, ld, i, d;
1341 if (!list)
1342 return False;
1343 if (!pattern)
1344 return False;
1345 if (!insert)
1346 return False;
1348 lp = (ssize_t)strlen(pattern);
1349 li = (ssize_t)strlen(insert);
1350 ld = li -lp;
1352 while (*list) {
1353 s = *list;
1354 ls = (ssize_t)strlen(s);
1356 while ((p = strstr(s, pattern))) {
1357 t = *list;
1358 d = p -t;
1359 if (ld) {
1360 t = (char *) malloc(ls +ld +1);
1361 if (!t) {
1362 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1363 return False;
1365 memcpy(t, *list, d);
1366 memcpy(t +d +li, p +lp, ls -d -lp +1);
1367 SAFE_FREE(*list);
1368 *list = t;
1369 ls += ld;
1370 s = t +d +li;
1373 for (i = 0; i < li; i++) {
1374 switch (insert[i]) {
1375 case '`':
1376 case '"':
1377 case '\'':
1378 case ';':
1379 case '$':
1380 case '%':
1381 case '\r':
1382 case '\n':
1383 t[d +i] = '_';
1384 break;
1385 default:
1386 t[d +i] = insert[i];
1391 list++;
1394 return True;
1398 #define IPSTR_LIST_SEP ","
1401 * Add ip string representation to ipstr list. Used also
1402 * as part of @function ipstr_list_make
1404 * @param ipstr_list pointer to string containing ip list;
1405 * MUST BE already allocated and IS reallocated if necessary
1406 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1407 * as a result of reallocation)
1408 * @param ip IP address which is to be added to list
1409 * @return pointer to string appended with new ip and possibly
1410 * reallocated to new length
1413 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1415 char* new_ipstr = NULL;
1417 /* arguments checking */
1418 if (!ipstr_list || !ip) return NULL;
1420 /* attempt to convert ip to a string and append colon separator to it */
1421 if (*ipstr_list) {
1422 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1423 SAFE_FREE(*ipstr_list);
1424 } else {
1425 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1427 *ipstr_list = new_ipstr;
1428 return *ipstr_list;
1433 * Allocate and initialise an ipstr list using ip adresses
1434 * passed as arguments.
1436 * @param ipstr_list pointer to string meant to be allocated and set
1437 * @param ip_list array of ip addresses to place in the list
1438 * @param ip_count number of addresses stored in ip_list
1439 * @return pointer to allocated ip string
1442 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1444 int i;
1446 /* arguments checking */
1447 if (!ip_list && !ipstr_list) return 0;
1449 *ipstr_list = NULL;
1451 /* process ip addresses given as arguments */
1452 for (i = 0; i < ip_count; i++)
1453 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1455 return (*ipstr_list);
1460 * Parse given ip string list into array of ip addresses
1461 * (as in_addr structures)
1463 * @param ipstr ip string list to be parsed
1464 * @param ip_list pointer to array of ip addresses which is
1465 * allocated by this function and must be freed by caller
1466 * @return number of succesfully parsed addresses
1469 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1471 fstring token_str;
1472 int count;
1474 if (!ipstr_list || !ip_list) return 0;
1476 for (*ip_list = NULL, count = 0;
1477 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1478 count++) {
1480 struct in_addr addr;
1482 /* convert single token to ip address */
1483 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1484 break;
1486 /* prepare place for another in_addr structure */
1487 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1488 if (!*ip_list) return -1;
1490 (*ip_list)[count] = addr;
1493 return count;
1498 * Safely free ip string list
1500 * @param ipstr_list ip string list to be freed
1503 void ipstr_list_free(char* ipstr_list)
1505 SAFE_FREE(ipstr_list);
1510 Unescape a URL encoded string, in place.
1513 void rfc1738_unescape(char *buf)
1515 char *p=buf;
1517 while ((p=strchr_m(p,'+')))
1518 *p = ' ';
1520 p = buf;
1522 while (p && *p && (p=strchr_m(p,'%'))) {
1523 int c1 = p[1];
1524 int c2 = p[2];
1526 if (c1 >= '0' && c1 <= '9')
1527 c1 = c1 - '0';
1528 else if (c1 >= 'A' && c1 <= 'F')
1529 c1 = 10 + c1 - 'A';
1530 else if (c1 >= 'a' && c1 <= 'f')
1531 c1 = 10 + c1 - 'a';
1532 else {p++; continue;}
1534 if (c2 >= '0' && c2 <= '9')
1535 c2 = c2 - '0';
1536 else if (c2 >= 'A' && c2 <= 'F')
1537 c2 = 10 + c2 - 'A';
1538 else if (c2 >= 'a' && c2 <= 'f')
1539 c2 = 10 + c2 - 'a';
1540 else {p++; continue;}
1542 *p = (c1<<4) | c2;
1544 memmove(p+1, p+3, strlen(p+3)+1);
1545 p++;
1549 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1552 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1554 DATA_BLOB base64_decode_data_blob(const char *s)
1556 int bit_offset, byte_offset, idx, i, n;
1557 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1558 unsigned char *d = decoded.data;
1559 char *p;
1561 n=i=0;
1563 while (*s && (p=strchr_m(b64,*s))) {
1564 idx = (int)(p - b64);
1565 byte_offset = (i*6)/8;
1566 bit_offset = (i*6)%8;
1567 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1568 if (bit_offset < 3) {
1569 d[byte_offset] |= (idx << (2-bit_offset));
1570 n = byte_offset+1;
1571 } else {
1572 d[byte_offset] |= (idx >> (bit_offset-2));
1573 d[byte_offset+1] = 0;
1574 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1575 n = byte_offset+2;
1577 s++; i++;
1580 /* fix up length */
1581 decoded.length = n;
1582 return decoded;
1586 * Decode a base64 string in-place - wrapper for the above
1588 void base64_decode_inplace(char *s)
1590 DATA_BLOB decoded = base64_decode_data_blob(s);
1591 memcpy(s, decoded.data, decoded.length);
1592 data_blob_free(&decoded);
1594 /* null terminate */
1595 s[decoded.length] = '\0';
1599 * Encode a base64 string into a malloc()ed string caller to free.
1601 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1603 char * base64_encode_data_blob(DATA_BLOB data)
1605 int bits = 0;
1606 int char_count = 0;
1607 size_t out_cnt = 0;
1608 size_t len = data.length;
1609 size_t output_len = data.length * 2;
1610 char *result = malloc(output_len); /* get us plenty of space */
1612 while (len-- && out_cnt < (data.length * 2) - 5) {
1613 int c = (unsigned char) *(data.data++);
1614 bits += c;
1615 char_count++;
1616 if (char_count == 3) {
1617 result[out_cnt++] = b64[bits >> 18];
1618 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1619 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1620 result[out_cnt++] = b64[bits & 0x3f];
1621 bits = 0;
1622 char_count = 0;
1623 } else {
1624 bits <<= 8;
1627 if (char_count != 0) {
1628 bits <<= 16 - (8 * char_count);
1629 result[out_cnt++] = b64[bits >> 18];
1630 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1631 if (char_count == 1) {
1632 result[out_cnt++] = '=';
1633 result[out_cnt++] = '=';
1634 } else {
1635 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1636 result[out_cnt++] = '=';
1639 result[out_cnt] = '\0'; /* terminate */
1640 return result;
1643 #ifdef VALGRIND
1644 size_t valgrind_strlen(const char *s)
1646 size_t count;
1647 for(count = 0; *s++; count++)
1649 return count;
1651 #endif