merge from head
[Samba/gebeck_regimport.git] / source / lib / util_str.c
blob60e0e3837fc3d946a040b8ca3fe219495bd43389
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.
27 Based on a routine by GJC@VILLAGE.COM.
28 Extensively modified by Andrew.Tridgell@anu.edu.au
29 ****************************************************************************/
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;
142 /*******************************************************************
143 Case insensitive string compararison.
144 ********************************************************************/
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);
154 /*******************************************************************
155 Case insensitive string compararison, length limited.
156 ********************************************************************/
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);
166 /*******************************************************************
167 Compare 2 strings.
168 ********************************************************************/
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);
180 /*******************************************************************
181 Compare 2 strings up to and including the nth char.
182 ******************************************************************/
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);
194 /*******************************************************************
195 Compare 2 strings (case sensitive).
196 ********************************************************************/
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);
208 /***************************************************************************
209 Do a case-insensitive, whitespace-ignoring string compare.
210 ***************************************************************************/
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);
239 /*******************************************************************
240 Convert a string to upper case, but don't modify it.
241 ********************************************************************/
243 char *strupper_static(const char *s)
245 static pstring str;
247 pstrcpy(str, s);
248 strupper(str);
250 return str;
253 /*******************************************************************
254 Convert a string to "normal" form.
255 ********************************************************************/
257 void strnorm(char *s)
259 extern int case_default;
260 if (case_default == CASE_UPPER)
261 strupper(s);
262 else
263 strlower(s);
266 /*******************************************************************
267 Check if a string is in "normal" case.
268 ********************************************************************/
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));
280 /****************************************************************************
281 String replace.
282 NOTE: oldc and newc must be 7 bit characters
283 ****************************************************************************/
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);
292 /*******************************************************************
293 Skip past some strings in a buffer.
294 ********************************************************************/
296 char *skip_string(char *buf,size_t n)
298 while (n--)
299 buf += strlen(buf) + 1;
300 return(buf);
303 /*******************************************************************
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.
307 ********************************************************************/
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);
316 /*******************************************************************
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.
320 ********************************************************************/
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);
329 /*******************************************************************
330 Trim the specified elements off the front and back of a string.
331 ********************************************************************/
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;
367 /****************************************************************************
368 Does a string have any uppercase chars in it?
369 ****************************************************************************/
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);
381 /****************************************************************************
382 Does a string have any lowercase chars in it?
383 ****************************************************************************/
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);
395 /****************************************************************************
396 Find the number of 'c' chars in a string
397 ****************************************************************************/
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);
410 /*******************************************************************
411 Return True if a string consists only of one particular character.
412 ********************************************************************/
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;
431 /*******************************************************************
432 Safe string copy into a known length string. maxlength does not
433 include the terminating zero.
434 ********************************************************************/
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 if (!src) {
446 *dest = 0;
447 return dest;
450 len = strlen(src);
452 if (len > maxlength) {
453 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
454 (int)(len-maxlength), src));
455 len = maxlength;
458 memmove(dest, src, len);
459 dest[len] = 0;
460 return dest;
463 /*******************************************************************
464 Safe string cat into a string. maxlength does not
465 include the terminating zero.
466 ********************************************************************/
468 char *safe_strcat(char *dest, const char *src, size_t maxlength)
470 size_t src_len, dest_len;
472 if (!dest) {
473 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
474 return NULL;
477 if (!src)
478 return dest;
480 src_len = strlen(src);
481 dest_len = strlen(dest);
483 if (src_len + dest_len > maxlength) {
484 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
485 (int)(src_len + dest_len - maxlength), src));
486 if (maxlength > dest_len) {
487 memcpy(&dest[dest_len], src, maxlength - dest_len);
489 dest[maxlength] = 0;
490 return NULL;
493 memcpy(&dest[dest_len], src, src_len);
494 dest[dest_len + src_len] = 0;
495 return dest;
498 /*******************************************************************
499 Paranoid strcpy into a buffer of given length (includes terminating
500 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
501 and replaces with '_'. Deliberately does *NOT* check for multibyte
502 characters. Don't change it !
503 ********************************************************************/
505 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
507 size_t len, i;
509 if (!dest) {
510 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
511 return NULL;
514 if (!src) {
515 *dest = 0;
516 return dest;
519 len = strlen(src);
520 if (len >= maxlength)
521 len = maxlength - 1;
523 if (!other_safe_chars)
524 other_safe_chars = "";
526 for(i = 0; i < len; i++) {
527 int val = (src[i] & 0xff);
528 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
529 dest[i] = src[i];
530 else
531 dest[i] = '_';
534 dest[i] = '\0';
536 return dest;
539 /****************************************************************************
540 Like strncpy but always null terminates. Make sure there is room!
541 The variable n should always be one less than the available size.
542 ****************************************************************************/
544 char *StrnCpy(char *dest,const char *src,size_t n)
546 char *d = dest;
547 if (!dest)
548 return(NULL);
549 if (!src) {
550 *dest = 0;
551 return(dest);
553 while (n-- && (*d++ = *src++))
555 *d = 0;
556 return(dest);
559 /****************************************************************************
560 Like strncpy but copies up to the character marker. always null terminates.
561 returns a pointer to the character marker in the source string (src).
562 ****************************************************************************/
564 char *strncpyn(char *dest, const char *src, size_t n, char c)
566 char *p;
567 size_t str_len;
569 p = strchr_m(src, c);
570 if (p == NULL) {
571 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
572 return NULL;
575 str_len = PTR_DIFF(p, src);
576 strncpy(dest, src, MIN(n, str_len));
577 dest[str_len] = '\0';
579 return p;
582 /*************************************************************
583 Routine to get hex characters and turn them into a 16 byte array.
584 the array can be variable length, and any non-hex-numeric
585 characters are skipped. "0xnn" or "0Xnn" is specially catered
586 for.
588 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
590 **************************************************************/
592 size_t strhex_to_str(char *p, size_t len, const char *strhex)
594 size_t i;
595 size_t num_chars = 0;
596 unsigned char lonybble, hinybble;
597 const char *hexchars = "0123456789ABCDEF";
598 char *p1 = NULL, *p2 = NULL;
600 for (i = 0; i < len && strhex[i] != 0; i++) {
601 if (strnequal(hexchars, "0x", 2)) {
602 i++; /* skip two chars */
603 continue;
606 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
607 break;
609 i++; /* next hex digit */
611 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
612 break;
614 /* get the two nybbles */
615 hinybble = PTR_DIFF(p1, hexchars);
616 lonybble = PTR_DIFF(p2, hexchars);
618 p[num_chars] = (hinybble << 4) | lonybble;
619 num_chars++;
621 p1 = NULL;
622 p2 = NULL;
624 return num_chars;
627 /****************************************************************************
628 Check if a string is part of a list.
629 ****************************************************************************/
631 BOOL in_list(char *s,char *list,BOOL casesensitive)
633 pstring tok;
634 const char *p=list;
636 if (!list)
637 return(False);
639 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
640 if (casesensitive) {
641 if (strcmp(tok,s) == 0)
642 return(True);
643 } else {
644 if (StrCaseCmp(tok,s) == 0)
645 return(True);
648 return(False);
651 /* this is used to prevent lots of mallocs of size 1 */
652 static char *null_string = NULL;
654 /****************************************************************************
655 Set a string value, allocing the space for the string
656 ****************************************************************************/
658 static BOOL string_init(char **dest,const char *src)
660 size_t l;
661 if (!src)
662 src = "";
664 l = strlen(src);
666 if (l == 0) {
667 if (!null_string) {
668 if((null_string = (char *)malloc(1)) == NULL) {
669 DEBUG(0,("string_init: malloc fail for null_string.\n"));
670 return False;
672 *null_string = 0;
674 *dest = null_string;
675 } else {
676 (*dest) = strdup(src);
677 if ((*dest) == NULL) {
678 DEBUG(0,("Out of memory in string_init\n"));
679 return False;
682 return(True);
685 /****************************************************************************
686 Free a string value.
687 ****************************************************************************/
689 void string_free(char **s)
691 if (!s || !(*s))
692 return;
693 if (*s == null_string)
694 *s = NULL;
695 SAFE_FREE(*s);
698 /****************************************************************************
699 Set a string value, deallocating any existing space, and allocing the space
700 for the string
701 ****************************************************************************/
703 BOOL string_set(char **dest,const char *src)
705 string_free(dest);
706 return(string_init(dest,src));
709 /****************************************************************************
710 Substitute a string for a pattern in another string. Make sure there is
711 enough room!
713 This routine looks for pattern in s and replaces it with
714 insert. It may do multiple replacements.
716 Any of " ; ' $ or ` in the insert string are replaced with _
717 if len==0 then the string cannot be extended. This is different from the old
718 use of len==0 which was for no length checks to be done.
719 ****************************************************************************/
721 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
723 char *p;
724 ssize_t ls,lp,li, i;
726 if (!insert || !pattern || !*pattern || !s)
727 return;
729 ls = (ssize_t)strlen(s);
730 lp = (ssize_t)strlen(pattern);
731 li = (ssize_t)strlen(insert);
733 if (len == 0)
734 len = ls + 1; /* len is number of *bytes* */
736 while (lp <= ls && (p = strstr(s,pattern))) {
737 if (ls + (li-lp) >= len) {
738 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
739 (int)(ls + (li-lp) - len),
740 pattern, (int)len));
741 break;
743 if (li != lp) {
744 memmove(p+li,p+lp,strlen(p+lp)+1);
746 for (i=0;i<li;i++) {
747 switch (insert[i]) {
748 case '`':
749 case '"':
750 case '\'':
751 case ';':
752 case '$':
753 case '%':
754 case '\r':
755 case '\n':
756 p[i] = '_';
757 break;
758 default:
759 p[i] = insert[i];
762 s = p + li;
763 ls += (li-lp);
767 void fstring_sub(char *s,const char *pattern,const char *insert)
769 string_sub(s, pattern, insert, sizeof(fstring));
772 void pstring_sub(char *s,const char *pattern,const char *insert)
774 string_sub(s, pattern, insert, sizeof(pstring));
777 /****************************************************************************
778 Similar to string_sub, but it will accept only allocated strings
779 and may realloc them so pay attention at what you pass on no
780 pointers inside strings, no pstrings or const may be passed
781 as string.
782 ****************************************************************************/
784 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
786 char *p, *in;
787 char *s;
788 ssize_t ls,lp,li,ld, i;
790 if (!insert || !pattern || !*pattern || !string || !*string)
791 return NULL;
793 s = string;
795 in = strdup(insert);
796 if (!in) {
797 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
798 return NULL;
800 ls = (ssize_t)strlen(s);
801 lp = (ssize_t)strlen(pattern);
802 li = (ssize_t)strlen(insert);
803 ld = li - lp;
804 for (i=0;i<li;i++) {
805 switch (in[i]) {
806 case '`':
807 case '"':
808 case '\'':
809 case ';':
810 case '$':
811 case '%':
812 case '\r':
813 case '\n':
814 in[i] = '_';
815 default:
816 /* ok */
817 break;
821 while ((p = strstr(s,pattern))) {
822 if (ld > 0) {
823 char *t = Realloc(string, ls + ld + 1);
824 if (!t) {
825 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
826 SAFE_FREE(in);
827 return NULL;
829 string = t;
830 p = t + (p - s);
832 if (li != lp) {
833 memmove(p+li,p+lp,strlen(p+lp)+1);
835 memcpy(p, in, li);
836 s = p + li;
837 ls += ld;
839 SAFE_FREE(in);
840 return string;
843 /****************************************************************************
844 Similar to string_sub() but allows for any character to be substituted.
845 Use with caution!
846 if len==0 then the string cannot be extended. This is different from the old
847 use of len==0 which was for no length checks to be done.
848 ****************************************************************************/
850 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
852 char *p;
853 ssize_t ls,lp,li;
855 if (!insert || !pattern || !s)
856 return;
858 ls = (ssize_t)strlen(s);
859 lp = (ssize_t)strlen(pattern);
860 li = (ssize_t)strlen(insert);
862 if (!*pattern)
863 return;
865 if (len == 0)
866 len = ls + 1; /* len is number of *bytes* */
868 while (lp <= ls && (p = strstr(s,pattern))) {
869 if (ls + (li-lp) >= len) {
870 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
871 (int)(ls + (li-lp) - len),
872 pattern, (int)len));
873 break;
875 if (li != lp) {
876 memmove(p+li,p+lp,strlen(p+lp)+1);
878 memcpy(p, insert, li);
879 s = p + li;
880 ls += (li-lp);
884 /****************************************************************************
885 Similar to all_string_sub but for unicode strings.
886 Return a new allocated unicode string.
887 similar to string_sub() but allows for any character to be substituted.
888 Use with caution!
889 ****************************************************************************/
891 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
892 const smb_ucs2_t *insert)
894 smb_ucs2_t *r, *rp;
895 const smb_ucs2_t *sp;
896 size_t lr, lp, li, lt;
898 if (!insert || !pattern || !*pattern || !s)
899 return NULL;
901 lt = (size_t)strlen_w(s);
902 lp = (size_t)strlen_w(pattern);
903 li = (size_t)strlen_w(insert);
905 if (li > lp) {
906 const smb_ucs2_t *st = s;
907 int ld = li - lp;
908 while ((sp = strstr_w(st, pattern))) {
909 st = sp + lp;
910 lt += ld;
914 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
915 if (!r) {
916 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
917 return NULL;
920 while ((sp = strstr_w(s, pattern))) {
921 memcpy(rp, s, (sp - s));
922 rp += ((sp - s) / sizeof(smb_ucs2_t));
923 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
924 s = sp + lp;
925 rp += li;
927 lr = ((rp - r) / sizeof(smb_ucs2_t));
928 if (lr < lt) {
929 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
930 rp += (lt - lr);
932 *rp = 0;
934 return r;
937 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
938 const char *insert)
940 wpstring p, i;
942 if (!insert || !pattern || !s)
943 return NULL;
944 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
945 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
946 return all_string_sub_w(s, p, i);
949 /****************************************************************************
950 Splits out the front and back at a separator.
951 ****************************************************************************/
953 void split_at_last_component(char *path, char *front, char sep, char *back)
955 char *p = strrchr_m(path, sep);
957 if (p != NULL)
958 *p = 0;
960 if (front != NULL)
961 pstrcpy(front, path);
963 if (p != NULL) {
964 if (back != NULL)
965 pstrcpy(back, p+1);
966 *p = '\\';
967 } else {
968 if (back != NULL)
969 back[0] = 0;
973 /****************************************************************************
974 Write an octal as a string.
975 ****************************************************************************/
977 const char *octal_string(int i)
979 static char ret[64];
980 if (i == -1)
981 return "-1";
982 slprintf(ret, sizeof(ret)-1, "0%o", i);
983 return ret;
987 /****************************************************************************
988 Truncate a string at a specified length.
989 ****************************************************************************/
991 char *string_truncate(char *s, int length)
993 if (s && strlen(s) > length)
994 s[length] = 0;
995 return s;
998 /****************************************************************************
999 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1000 We convert via ucs2 for now.
1001 ****************************************************************************/
1003 char *strchr_m(const char *s, char c)
1005 wpstring ws;
1006 pstring s2;
1007 smb_ucs2_t *p;
1009 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1010 p = strchr_w(ws, UCS2_CHAR(c));
1011 if (!p)
1012 return NULL;
1013 *p = 0;
1014 pull_ucs2_pstring(s2, ws);
1015 return (char *)(s+strlen(s2));
1018 char *strrchr_m(const char *s, char c)
1020 wpstring ws;
1021 pstring s2;
1022 smb_ucs2_t *p;
1024 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1025 p = strrchr_w(ws, UCS2_CHAR(c));
1026 if (!p)
1027 return NULL;
1028 *p = 0;
1029 pull_ucs2_pstring(s2, ws);
1030 return (char *)(s+strlen(s2));
1033 /*******************************************************************
1034 Convert a string to lower case.
1035 ********************************************************************/
1037 void strlower_m(char *s)
1039 /* this is quite a common operation, so we want it to be
1040 fast. We optimise for the ascii case, knowing that all our
1041 supported multi-byte character sets are ascii-compatible
1042 (ie. they match for the first 128 chars) */
1044 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1045 *s = tolower((unsigned char)*s);
1046 s++;
1049 if (!*s)
1050 return;
1052 /* I assume that lowercased string takes the same number of bytes
1053 * as source string even in UTF-8 encoding. (VIV) */
1054 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1057 /*******************************************************************
1058 Duplicate convert a string to lower case.
1059 ********************************************************************/
1061 char *strdup_lower(const char *s)
1063 char *t = strdup(s);
1064 if (t == NULL) {
1065 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1066 return NULL;
1068 strlower_m(t);
1069 return t;
1072 /*******************************************************************
1073 Convert a string to upper case.
1074 ********************************************************************/
1076 void strupper_m(char *s)
1078 /* this is quite a common operation, so we want it to be
1079 fast. We optimise for the ascii case, knowing that all our
1080 supported multi-byte character sets are ascii-compatible
1081 (ie. they match for the first 128 chars) */
1083 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1084 *s = toupper((unsigned char)*s);
1085 s++;
1088 if (!*s)
1089 return;
1091 /* I assume that lowercased string takes the same number of bytes
1092 * as source string even in multibyte encoding. (VIV) */
1093 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1096 /*******************************************************************
1097 Convert a string to upper case.
1098 ********************************************************************/
1100 char *strdup_upper(const char *s)
1102 char *t = strdup(s);
1103 if (t == NULL) {
1104 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1105 return NULL;
1107 strupper_m(t);
1108 return t;
1111 /*******************************************************************
1112 Return a RFC2254 binary string representation of a buffer.
1113 Used in LDAP filters.
1114 Caller must free.
1115 ********************************************************************/
1117 char *binary_string(char *buf, int len)
1119 char *s;
1120 int i, j;
1121 const char *hex = "0123456789ABCDEF";
1122 s = malloc(len * 3 + 1);
1123 if (!s)
1124 return NULL;
1125 for (j=i=0;i<len;i++) {
1126 s[j] = '\\';
1127 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1128 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1129 j += 3;
1131 s[j] = 0;
1132 return s;
1135 /*******************************************************************
1136 Just a typesafety wrapper for snprintf into a pstring.
1137 ********************************************************************/
1139 int pstr_sprintf(pstring s, const char *fmt, ...)
1141 va_list ap;
1142 int ret;
1144 va_start(ap, fmt);
1145 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1146 va_end(ap);
1147 return ret;
1150 /*******************************************************************
1151 Just a typesafety wrapper for snprintf into a fstring.
1152 ********************************************************************/
1154 int fstr_sprintf(fstring s, const char *fmt, ...)
1156 va_list ap;
1157 int ret;
1159 va_start(ap, fmt);
1160 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1161 va_end(ap);
1162 return ret;
1165 #ifndef HAVE_STRNDUP
1166 /*******************************************************************
1167 Some platforms don't have strndup.
1168 ********************************************************************/
1170 char *strndup(const char *s, size_t n)
1172 char *ret;
1174 n = strnlen(s, n);
1175 ret = malloc(n+1);
1176 if (!ret)
1177 return NULL;
1178 memcpy(ret, s, n);
1179 ret[n] = 0;
1181 return ret;
1183 #endif
1185 #ifndef HAVE_STRNLEN
1186 /*******************************************************************
1187 Some platforms don't have strnlen
1188 ********************************************************************/
1190 size_t strnlen(const char *s, size_t n)
1192 int i;
1193 for (i=0; s[i] && i<n; i++)
1194 /* noop */ ;
1195 return i;
1197 #endif
1199 /***********************************************************
1200 List of Strings manipulation functions
1201 ***********************************************************/
1203 #define S_LIST_ABS 16 /* List Allocation Block Size */
1205 char **str_list_make(const char *string, const char *sep)
1207 char **list, **rlist;
1208 const char *str;
1209 char *s;
1210 int num, lsize;
1211 pstring tok;
1213 if (!string || !*string)
1214 return NULL;
1215 s = strdup(string);
1216 if (!s) {
1217 DEBUG(0,("str_list_make: Unable to allocate memory"));
1218 return NULL;
1220 if (!sep) sep = LIST_SEP;
1222 num = lsize = 0;
1223 list = NULL;
1225 str = s;
1226 while (next_token(&str, tok, sep, sizeof(tok))) {
1227 if (num == lsize) {
1228 lsize += S_LIST_ABS;
1229 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1230 if (!rlist) {
1231 DEBUG(0,("str_list_make: Unable to allocate memory"));
1232 str_list_free(&list);
1233 SAFE_FREE(s);
1234 return NULL;
1235 } else
1236 list = rlist;
1237 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1240 list[num] = strdup(tok);
1241 if (!list[num]) {
1242 DEBUG(0,("str_list_make: Unable to allocate memory"));
1243 str_list_free(&list);
1244 SAFE_FREE(s);
1245 return NULL;
1248 num++;
1251 SAFE_FREE(s);
1252 return list;
1255 BOOL str_list_copy(char ***dest, const char **src)
1257 char **list, **rlist;
1258 int num, lsize;
1260 *dest = NULL;
1261 if (!src)
1262 return False;
1264 num = lsize = 0;
1265 list = NULL;
1267 while (src[num]) {
1268 if (num == lsize) {
1269 lsize += S_LIST_ABS;
1270 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1271 if (!rlist) {
1272 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1273 str_list_free(&list);
1274 return False;
1275 } else
1276 list = rlist;
1277 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1280 list[num] = strdup(src[num]);
1281 if (!list[num]) {
1282 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1283 str_list_free(&list);
1284 return False;
1287 num++;
1290 *dest = list;
1291 return True;
1294 /***********************************************************
1295 Return true if all the elements of the list match exactly.
1296 ***********************************************************/
1298 BOOL str_list_compare(char **list1, char **list2)
1300 int num;
1302 if (!list1 || !list2)
1303 return (list1 == list2);
1305 for (num = 0; list1[num]; num++) {
1306 if (!list2[num])
1307 return False;
1308 if (!strcsequal(list1[num], list2[num]))
1309 return False;
1311 if (list2[num])
1312 return False; /* if list2 has more elements than list1 fail */
1314 return True;
1317 void str_list_free(char ***list)
1319 char **tlist;
1321 if (!list || !*list)
1322 return;
1323 tlist = *list;
1324 for(; *tlist; tlist++)
1325 SAFE_FREE(*tlist);
1326 SAFE_FREE(*list);
1329 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1331 char *p, *s, *t;
1332 ssize_t ls, lp, li, ld, i, d;
1334 if (!list)
1335 return False;
1336 if (!pattern)
1337 return False;
1338 if (!insert)
1339 return False;
1341 lp = (ssize_t)strlen(pattern);
1342 li = (ssize_t)strlen(insert);
1343 ld = li -lp;
1345 while (*list) {
1346 s = *list;
1347 ls = (ssize_t)strlen(s);
1349 while ((p = strstr(s, pattern))) {
1350 t = *list;
1351 d = p -t;
1352 if (ld) {
1353 t = (char *) malloc(ls +ld +1);
1354 if (!t) {
1355 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1356 return False;
1358 memcpy(t, *list, d);
1359 memcpy(t +d +li, p +lp, ls -d -lp +1);
1360 SAFE_FREE(*list);
1361 *list = t;
1362 ls += ld;
1363 s = t +d +li;
1366 for (i = 0; i < li; i++) {
1367 switch (insert[i]) {
1368 case '`':
1369 case '"':
1370 case '\'':
1371 case ';':
1372 case '$':
1373 case '%':
1374 case '\r':
1375 case '\n':
1376 t[d +i] = '_';
1377 break;
1378 default:
1379 t[d +i] = insert[i];
1384 list++;
1387 return True;
1391 #define IPSTR_LIST_SEP ","
1394 * Add ip string representation to ipstr list. Used also
1395 * as part of @function ipstr_list_make
1397 * @param ipstr_list pointer to string containing ip list;
1398 * MUST BE already allocated and IS reallocated if necessary
1399 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1400 * as a result of reallocation)
1401 * @param ip IP address which is to be added to list
1402 * @return pointer to string appended with new ip and possibly
1403 * reallocated to new length
1406 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1408 char* new_ipstr = NULL;
1410 /* arguments checking */
1411 if (!ipstr_list || !ip) return NULL;
1413 /* attempt to convert ip to a string and append colon separator to it */
1414 if (*ipstr_list) {
1415 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1416 SAFE_FREE(*ipstr_list);
1417 } else {
1418 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1420 *ipstr_list = new_ipstr;
1421 return *ipstr_list;
1426 * Allocate and initialise an ipstr list using ip adresses
1427 * passed as arguments.
1429 * @param ipstr_list pointer to string meant to be allocated and set
1430 * @param ip_list array of ip addresses to place in the list
1431 * @param ip_count number of addresses stored in ip_list
1432 * @return pointer to allocated ip string
1435 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1437 int i;
1439 /* arguments checking */
1440 if (!ip_list && !ipstr_list) return 0;
1442 *ipstr_list = NULL;
1444 /* process ip addresses given as arguments */
1445 for (i = 0; i < ip_count; i++)
1446 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1448 return (*ipstr_list);
1453 * Parse given ip string list into array of ip addresses
1454 * (as in_addr structures)
1456 * @param ipstr ip string list to be parsed
1457 * @param ip_list pointer to array of ip addresses which is
1458 * allocated by this function and must be freed by caller
1459 * @return number of succesfully parsed addresses
1462 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1464 fstring token_str;
1465 int count;
1467 if (!ipstr_list || !ip_list) return 0;
1469 for (*ip_list = NULL, count = 0;
1470 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1471 count++) {
1473 struct in_addr addr;
1475 /* convert single token to ip address */
1476 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1477 break;
1479 /* prepare place for another in_addr structure */
1480 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1481 if (!*ip_list) return -1;
1483 (*ip_list)[count] = addr;
1486 return count;
1491 * Safely free ip string list
1493 * @param ipstr_list ip string list to be freed
1496 void ipstr_list_free(char* ipstr_list)
1498 SAFE_FREE(ipstr_list);
1502 /***********************************************************
1503 Unescape a URL encoded string, in place.
1504 ***********************************************************/
1506 void rfc1738_unescape(char *buf)
1508 char *p=buf;
1510 while ((p=strchr_m(p,'+')))
1511 *p = ' ';
1513 p = buf;
1515 while (p && *p && (p=strchr_m(p,'%'))) {
1516 int c1 = p[1];
1517 int c2 = p[2];
1519 if (c1 >= '0' && c1 <= '9')
1520 c1 = c1 - '0';
1521 else if (c1 >= 'A' && c1 <= 'F')
1522 c1 = 10 + c1 - 'A';
1523 else if (c1 >= 'a' && c1 <= 'f')
1524 c1 = 10 + c1 - 'a';
1525 else {p++; continue;}
1527 if (c2 >= '0' && c2 <= '9')
1528 c2 = c2 - '0';
1529 else if (c2 >= 'A' && c2 <= 'F')
1530 c2 = 10 + c2 - 'A';
1531 else if (c2 >= 'a' && c2 <= 'f')
1532 c2 = 10 + c2 - 'a';
1533 else {p++; continue;}
1535 *p = (c1<<4) | c2;
1537 memmove(p+1, p+3, strlen(p+3)+1);
1538 p++;
1542 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1544 /***************************************************************************
1545 decode a base64 string into a DATA_BLOB - simple and slow algorithm
1546 ***************************************************************************/
1547 DATA_BLOB base64_decode_data_blob(const char *s)
1549 int bit_offset, byte_offset, idx, i, n;
1550 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1551 unsigned char *d = decoded.data;
1552 char *p;
1554 n=i=0;
1556 while (*s && (p=strchr_m(b64,*s))) {
1557 idx = (int)(p - b64);
1558 byte_offset = (i*6)/8;
1559 bit_offset = (i*6)%8;
1560 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1561 if (bit_offset < 3) {
1562 d[byte_offset] |= (idx << (2-bit_offset));
1563 n = byte_offset+1;
1564 } else {
1565 d[byte_offset] |= (idx >> (bit_offset-2));
1566 d[byte_offset+1] = 0;
1567 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1568 n = byte_offset+2;
1570 s++; i++;
1573 /* fix up length */
1574 decoded.length = n;
1575 return decoded;
1578 /***************************************************************************
1579 decode a base64 string in-place - wrapper for the above
1580 ***************************************************************************/
1581 void base64_decode(char *s)
1583 DATA_BLOB decoded = base64_decode_data_blob(s);
1584 memcpy(s, decoded.data, decoded.length);
1585 data_blob_free(&decoded);
1587 /* null terminate */
1588 s[decoded.length] = '\0';
1591 /***************************************************************************
1592 encode a base64 string into a malloc()ed string caller to free.
1594 From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1595 ***************************************************************************/
1596 char * base64_encode_data_blob(DATA_BLOB data)
1598 int bits = 0;
1599 int char_count = 0;
1600 size_t out_cnt = 0;
1601 size_t len = data.length;
1602 size_t output_len = data.length * 2;
1603 char *result = malloc(output_len); /* get us plenty of space */
1605 while (len-- && out_cnt < (data.length * 2) - 5) {
1606 int c = (unsigned char) *(data.data++);
1607 bits += c;
1608 char_count++;
1609 if (char_count == 3) {
1610 result[out_cnt++] = b64[bits >> 18];
1611 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1612 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1613 result[out_cnt++] = b64[bits & 0x3f];
1614 bits = 0;
1615 char_count = 0;
1616 } else {
1617 bits <<= 8;
1620 if (char_count != 0) {
1621 bits <<= 16 - (8 * char_count);
1622 result[out_cnt++] = b64[bits >> 18];
1623 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1624 if (char_count == 1) {
1625 result[out_cnt++] = '=';
1626 result[out_cnt++] = '=';
1627 } else {
1628 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1629 result[out_cnt++] = '=';
1632 result[out_cnt] = '\0'; /* terminate */
1633 return result;
1636 #ifdef VALGRIND
1637 size_t valgrind_strlen(const char *s)
1639 size_t count;
1640 for(count = 0; *s++; count++)
1642 return count;
1644 #endif