preparing for release of alpha-2.6
[Samba/gbeck.git] / source / lib / util_str.c
blob143d45f17207b95bc73cb69c2c22f514b75832df
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
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 extern int DEBUGLEVEL;
26 static char *last_ptr=NULL;
28 void set_first_token(char *ptr)
30 last_ptr = ptr;
33 /****************************************************************************
34 Get the next token from a string, return False if none found
35 handles double-quotes.
36 Based on a routine by GJC@VILLAGE.COM.
37 Extensively modified by Andrew.Tridgell@anu.edu.au
38 ****************************************************************************/
39 BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
41 char *s;
42 BOOL quoted;
43 size_t len=1;
45 if (!ptr) ptr = &last_ptr;
46 if (!ptr) return(False);
48 s = *ptr;
50 /* default to simple separators */
51 if (!sep) sep = " \t\n\r";
53 /* find the first non sep char */
54 while(*s && strchr(sep,*s)) s++;
56 /* nothing left? */
57 if (! *s) return(False);
59 /* copy over the token */
60 for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
62 if (*s == '\"') {
63 quoted = !quoted;
64 } else {
65 len++;
66 *buff++ = *s;
70 *ptr = (*s) ? s+1 : s;
71 *buff = 0;
72 last_ptr = *ptr;
74 return(True);
77 /****************************************************************************
78 Convert list of tokens to array; dependent on above routine.
79 Uses last_ptr from above - bit of a hack.
80 ****************************************************************************/
81 char **toktocliplist(int *ctok, char *sep)
83 char *s=last_ptr;
84 int ictok=0;
85 char **ret, **iret;
87 if (!sep) sep = " \t\n\r";
89 while(*s && strchr(sep,*s)) s++;
91 /* nothing left? */
92 if (!*s) return(NULL);
94 do {
95 ictok++;
96 while(*s && (!strchr(sep,*s))) s++;
97 while(*s && strchr(sep,*s)) *s++=0;
98 } while(*s);
100 *ctok=ictok;
101 s=last_ptr;
103 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
105 while(ictok--) {
106 *iret++=s;
107 while(*s++);
108 while(!*s) s++;
111 return ret;
115 /*******************************************************************
116 case insensitive string compararison
117 ********************************************************************/
118 int StrCaseCmp(const char *s, const char *t)
120 /* compare until we run out of string, either t or s, or find a difference */
121 /* We *must* use toupper rather than tolower here due to the
122 asynchronous upper to lower mapping.
124 #if !defined(KANJI_WIN95_COMPATIBILITY)
126 * For completeness we should put in equivalent code for code pages
127 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
128 * doubt anyone wants Samba to behave differently from Win95 and WinNT
129 * here. They both treat full width ascii characters as case senstive
130 * filenames (ie. they don't do the work we do here).
131 * JRA.
134 if(lp_client_code_page() == KANJI_CODEPAGE)
136 /* Win95 treats full width ascii characters as case sensitive. */
137 int diff;
138 for (;;)
140 if (!*s || !*t)
141 return toupper (*s) - toupper (*t);
142 else if (is_sj_alph (*s) && is_sj_alph (*t))
144 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
145 if (diff)
146 return diff;
147 s += 2;
148 t += 2;
150 else if (is_shift_jis (*s) && is_shift_jis (*t))
152 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
153 if (diff)
154 return diff;
155 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
156 if (diff)
157 return diff;
158 s += 2;
159 t += 2;
161 else if (is_shift_jis (*s))
162 return 1;
163 else if (is_shift_jis (*t))
164 return -1;
165 else
167 diff = toupper (*s) - toupper (*t);
168 if (diff)
169 return diff;
170 s++;
171 t++;
175 else
176 #endif /* KANJI_WIN95_COMPATIBILITY */
178 while (*s && *t && toupper(*s) == toupper(*t))
180 s++;
181 t++;
184 return(toupper(*s) - toupper(*t));
188 /*******************************************************************
189 case insensitive string compararison, length limited
190 ********************************************************************/
191 int StrnCaseCmp(const char *s, const char *t, size_t n)
193 /* compare until we run out of string, either t or s, or chars */
194 /* We *must* use toupper rather than tolower here due to the
195 asynchronous upper to lower mapping.
197 #if !defined(KANJI_WIN95_COMPATIBILITY)
199 * For completeness we should put in equivalent code for code pages
200 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
201 * doubt anyone wants Samba to behave differently from Win95 and WinNT
202 * here. They both treat full width ascii characters as case senstive
203 * filenames (ie. they don't do the work we do here).
204 * JRA.
207 if(lp_client_code_page() == KANJI_CODEPAGE)
209 /* Win95 treats full width ascii characters as case sensitive. */
210 int diff;
211 for (;n > 0;)
213 if (!*s || !*t)
214 return toupper (*s) - toupper (*t);
215 else if (is_sj_alph (*s) && is_sj_alph (*t))
217 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
218 if (diff)
219 return diff;
220 s += 2;
221 t += 2;
222 n -= 2;
224 else if (is_shift_jis (*s) && is_shift_jis (*t))
226 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
227 if (diff)
228 return diff;
229 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
230 if (diff)
231 return diff;
232 s += 2;
233 t += 2;
234 n -= 2;
236 else if (is_shift_jis (*s))
237 return 1;
238 else if (is_shift_jis (*t))
239 return -1;
240 else
242 diff = toupper (*s) - toupper (*t);
243 if (diff)
244 return diff;
245 s++;
246 t++;
247 n--;
250 return 0;
252 else
253 #endif /* KANJI_WIN95_COMPATIBILITY */
255 while (n && *s && *t && toupper(*s) == toupper(*t))
257 s++;
258 t++;
259 n--;
262 /* not run out of chars - strings are different lengths */
263 if (n)
264 return(toupper(*s) - toupper(*t));
266 /* identical up to where we run out of chars,
267 and strings are same length */
268 return(0);
272 /*******************************************************************
273 compare 2 strings
274 ********************************************************************/
275 BOOL strequal(const char *s1, const char *s2)
277 if (s1 == s2) return(True);
278 if (!s1 || !s2) return(False);
280 return(StrCaseCmp(s1,s2)==0);
283 /*******************************************************************
284 compare 2 strings up to and including the nth char.
285 ******************************************************************/
286 BOOL strnequal(const char *s1,const char *s2,size_t n)
288 if (s1 == s2) return(True);
289 if (!s1 || !s2 || !n) return(False);
291 return(StrnCaseCmp(s1,s2,n)==0);
294 /*******************************************************************
295 compare 2 strings (case sensitive)
296 ********************************************************************/
297 BOOL strcsequal(const char *s1,const char *s2)
299 if (s1 == s2) return(True);
300 if (!s1 || !s2) return(False);
302 return(strcmp(s1,s2)==0);
306 /*******************************************************************
307 convert a string to lower case
308 ********************************************************************/
309 void strlower(char *s)
311 while (*s)
313 #if !defined(KANJI_WIN95_COMPATIBILITY)
315 * For completeness we should put in equivalent code for code pages
316 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
317 * doubt anyone wants Samba to behave differently from Win95 and WinNT
318 * here. They both treat full width ascii characters as case senstive
319 * filenames (ie. they don't do the work we do here).
320 * JRA.
323 if(lp_client_code_page() == KANJI_CODEPAGE)
325 /* Win95 treats full width ascii characters as case sensitive. */
326 if (is_shift_jis (*s))
328 if (is_sj_upper (s[0], s[1]))
329 s[1] = sj_tolower2 (s[1]);
330 s += 2;
332 else if (is_kana (*s))
334 s++;
336 else
338 if (isupper(*s))
339 *s = tolower(*s);
340 s++;
343 else
344 #endif /* KANJI_WIN95_COMPATIBILITY */
346 size_t skip = get_character_len( *s );
347 if( skip != 0 )
348 s += skip;
349 else
351 if (isupper(*s))
352 *s = tolower(*s);
353 s++;
359 /*******************************************************************
360 convert a string to upper case
361 ********************************************************************/
362 void strupper(char *s)
364 while (*s)
366 #if !defined(KANJI_WIN95_COMPATIBILITY)
368 * For completeness we should put in equivalent code for code pages
369 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
370 * doubt anyone wants Samba to behave differently from Win95 and WinNT
371 * here. They both treat full width ascii characters as case senstive
372 * filenames (ie. they don't do the work we do here).
373 * JRA.
376 if(lp_client_code_page() == KANJI_CODEPAGE)
378 /* Win95 treats full width ascii characters as case sensitive. */
379 if (is_shift_jis (*s))
381 if (is_sj_lower (s[0], s[1]))
382 s[1] = sj_toupper2 (s[1]);
383 s += 2;
385 else if (is_kana (*s))
387 s++;
389 else
391 if (islower(*s))
392 *s = toupper(*s);
393 s++;
396 else
397 #endif /* KANJI_WIN95_COMPATIBILITY */
399 size_t skip = get_character_len( *s );
400 if( skip != 0 )
401 s += skip;
402 else
404 if (islower(*s))
405 *s = toupper(*s);
406 s++;
412 /*******************************************************************
413 convert a string to "normal" form
414 ********************************************************************/
415 void strnorm(char *s)
417 extern int case_default;
418 if (case_default == CASE_UPPER)
419 strupper(s);
420 else
421 strlower(s);
424 /*******************************************************************
425 check if a string is in "normal" case
426 ********************************************************************/
427 BOOL strisnormal(char *s)
429 extern int case_default;
430 if (case_default == CASE_UPPER)
431 return(!strhaslower(s));
433 return(!strhasupper(s));
437 /****************************************************************************
438 string replace
439 ****************************************************************************/
440 void string_replace(char *s,char oldc,char newc)
442 size_t skip;
445 * sbcs optimization.
447 if(!global_is_multibyte_codepage) {
448 while (*s) {
449 if (oldc == *s)
450 *s = newc;
451 s++;
453 } else {
454 while (*s)
456 skip = get_character_len( *s );
457 if( skip != 0 )
458 s += skip;
459 else
461 if (oldc == *s)
462 *s = newc;
463 s++;
470 /*******************************************************************
471 skip past some strings in a buffer
472 ********************************************************************/
473 char *skip_string(char *buf,size_t n)
475 while (n--)
476 buf += strlen(buf) + 1;
477 return(buf);
480 /*******************************************************************
481 Count the number of characters in a string. Normally this will
482 be the same as the number of bytes in a string for single byte strings,
483 but will be different for multibyte.
484 16.oct.98, jdblair@cobaltnet.com.
485 ********************************************************************/
487 size_t str_charnum(const char *s)
489 size_t len = 0;
492 * sbcs optimization.
494 if(!global_is_multibyte_codepage) {
495 return strlen(s);
496 } else {
497 while (*s != '\0') {
498 int skip = get_character_len(*s);
499 s += (skip ? skip : 1);
500 len++;
503 return len;
506 /*******************************************************************
507 trim the specified elements off the front and back of a string
508 ********************************************************************/
510 BOOL trim_string(char *s,const char *front,const char *back)
512 BOOL ret = False;
513 size_t front_len = (front && *front) ? strlen(front) : 0;
514 size_t back_len = (back && *back) ? strlen(back) : 0;
515 size_t s_len;
517 while (front_len && strncmp(s, front, front_len) == 0)
519 char *p = s;
520 ret = True;
521 while (1)
523 if (!(*p = p[front_len]))
524 break;
525 p++;
530 * We split out the multibyte code page
531 * case here for speed purposes. Under a
532 * multibyte code page we need to walk the
533 * string forwards only and multiple times.
534 * Thanks to John Blair for finding this
535 * one. JRA.
538 if(back_len)
540 if(!global_is_multibyte_codepage)
542 s_len = strlen(s);
543 while ((s_len >= back_len) &&
544 (strncmp(s + s_len - back_len, back, back_len)==0))
546 ret = True;
547 s[s_len - back_len] = '\0';
548 s_len = strlen(s);
551 else
555 * Multibyte code page case.
556 * Keep going through the string, trying
557 * to match the 'back' string with the end
558 * of the string. If we get a match, truncate
559 * 'back' off the end of the string and
560 * go through the string again from the
561 * start. Keep doing this until we have
562 * gone through the string with no match
563 * at the string end.
566 size_t mb_back_len = str_charnum(back);
567 size_t mb_s_len = str_charnum(s);
569 while(mb_s_len >= mb_back_len)
571 size_t charcount = 0;
572 char *mbp = s;
575 * sbcs optimization.
577 if(!global_is_multibyte_codepage) {
578 while(charcount < (mb_s_len - mb_back_len)) {
579 mbp += 1;
580 charcount++;
582 } else {
583 while(charcount < (mb_s_len - mb_back_len)) {
584 size_t skip = skip_multibyte_char(*mbp);
585 mbp += (skip ? skip : 1);
586 charcount++;
591 * mbp now points at mb_back_len multibyte
592 * characters from the end of s.
595 if(strcmp(mbp, back) == 0)
597 ret = True;
598 *mbp = '\0';
599 mb_s_len = str_charnum(s);
600 mbp = s;
602 else
603 break;
604 } /* end while mb_s_len... */
605 } /* end else .. */
606 } /* end if back_len .. */
608 return(ret);
612 /****************************************************************************
613 does a string have any uppercase chars in it?
614 ****************************************************************************/
615 BOOL strhasupper(const char *s)
617 while (*s)
619 #if !defined(KANJI_WIN95_COMPATIBILITY)
621 * For completeness we should put in equivalent code for code pages
622 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
623 * doubt anyone wants Samba to behave differently from Win95 and WinNT
624 * here. They both treat full width ascii characters as case senstive
625 * filenames (ie. they don't do the work we do here).
626 * JRA.
629 if(lp_client_code_page() == KANJI_CODEPAGE)
631 /* Win95 treats full width ascii characters as case sensitive. */
632 if (is_shift_jis (*s))
633 s += 2;
634 else if (is_kana (*s))
635 s++;
636 else
638 if (isupper(*s))
639 return(True);
640 s++;
643 else
644 #endif /* KANJI_WIN95_COMPATIBILITY */
646 size_t skip = get_character_len( *s );
647 if( skip != 0 )
648 s += skip;
649 else {
650 if (isupper(*s))
651 return(True);
652 s++;
656 return(False);
659 /****************************************************************************
660 does a string have any lowercase chars in it?
661 ****************************************************************************/
662 BOOL strhaslower(const char *s)
664 while (*s)
666 #if !defined(KANJI_WIN95_COMPATIBILITY)
668 * For completeness we should put in equivalent code for code pages
669 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
670 * doubt anyone wants Samba to behave differently from Win95 and WinNT
671 * here. They both treat full width ascii characters as case senstive
672 * filenames (ie. they don't do the work we do here).
673 * JRA.
676 if(lp_client_code_page() == KANJI_CODEPAGE)
678 /* Win95 treats full width ascii characters as case sensitive. */
679 if (is_shift_jis (*s))
681 if (is_sj_upper (s[0], s[1]))
682 return(True);
683 if (is_sj_lower (s[0], s[1]))
684 return (True);
685 s += 2;
687 else if (is_kana (*s))
689 s++;
691 else
693 if (islower(*s))
694 return(True);
695 s++;
698 else
699 #endif /* KANJI_WIN95_COMPATIBILITY */
701 size_t skip = get_character_len( *s );
702 if( skip != 0 )
703 s += skip;
704 else {
705 if (islower(*s))
706 return(True);
707 s++;
711 return(False);
714 /****************************************************************************
715 find the number of chars in a string
716 ****************************************************************************/
717 size_t count_chars(const char *s,char c)
719 size_t count=0;
721 #if !defined(KANJI_WIN95_COMPATIBILITY)
723 * For completeness we should put in equivalent code for code pages
724 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
725 * doubt anyone wants Samba to behave differently from Win95 and WinNT
726 * here. They both treat full width ascii characters as case senstive
727 * filenames (ie. they don't do the work we do here).
728 * JRA.
731 if(lp_client_code_page() == KANJI_CODEPAGE)
733 /* Win95 treats full width ascii characters as case sensitive. */
734 while (*s)
736 if (is_shift_jis (*s))
737 s += 2;
738 else
740 if (*s == c)
741 count++;
742 s++;
746 else
747 #endif /* KANJI_WIN95_COMPATIBILITY */
749 while (*s)
751 size_t skip = get_character_len( *s );
752 if( skip != 0 )
753 s += skip;
754 else {
755 if (*s == c)
756 count++;
757 s++;
761 return(count);
764 /*******************************************************************
765 Return True if a string consists only of one particular character.
766 ********************************************************************/
768 BOOL str_is_all(const char *s,char c)
770 if(s == NULL)
771 return False;
772 if(!*s)
773 return False;
775 #if !defined(KANJI_WIN95_COMPATIBILITY)
777 * For completeness we should put in equivalent code for code pages
778 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
779 * doubt anyone wants Samba to behave differently from Win95 and WinNT
780 * here. They both treat full width ascii characters as case senstive
781 * filenames (ie. they don't do the work we do here).
782 * JRA.
785 if(lp_client_code_page() == KANJI_CODEPAGE)
787 /* Win95 treats full width ascii characters as case sensitive. */
788 while (*s)
790 if (is_shift_jis (*s))
791 s += 2;
792 else
794 if (*s != c)
795 return False;
796 s++;
800 else
801 #endif /* KANJI_WIN95_COMPATIBILITY */
803 while (*s)
805 size_t skip = get_character_len( *s );
806 if( skip != 0 )
807 s += skip;
808 else {
809 if (*s != c)
810 return False;
811 s++;
815 return True;
818 /*******************************************************************
819 safe string copy into a known length string. maxlength does not
820 include the terminating zero.
821 ********************************************************************/
822 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
824 size_t len;
826 if (!dest) {
827 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
828 return NULL;
831 if (!src) {
832 *dest = 0;
833 return dest;
836 len = strlen(src);
838 if (len > maxlength) {
839 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
840 (int)(len-maxlength), src));
841 len = maxlength;
844 memcpy(dest, src, len);
845 dest[len] = 0;
846 return dest;
849 /*******************************************************************
850 safe string cat into a string. maxlength does not
851 include the terminating zero.
852 ********************************************************************/
853 char *safe_strcat(char *dest, const char *src, size_t maxlength)
855 size_t src_len, dest_len;
857 if (!dest) {
858 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
859 return NULL;
862 if (!src) {
863 return dest;
866 src_len = strlen(src);
867 dest_len = strlen(dest);
869 if (src_len + dest_len > maxlength) {
870 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
871 (int)(src_len + dest_len - maxlength), src));
872 src_len = maxlength - dest_len;
875 memcpy(&dest[dest_len], src, src_len);
876 dest[dest_len + src_len] = 0;
877 return dest;
880 /*******************************************************************
881 Paranoid strcpy into a buffer of given length (includes terminating
882 zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
883 does *NOT* check for multibyte characters. Don't change it !
884 ********************************************************************/
886 char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
888 size_t len, i;
890 if (!dest) {
891 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
892 return NULL;
895 if (!src) {
896 *dest = 0;
897 return dest;
900 len = strlen(src);
901 if (len >= maxlength)
902 len = maxlength - 1;
904 for(i = 0; i < len; i++) {
905 int val = (src[i] & 0xff);
906 if(isupper(val) ||islower(val) || isdigit(val))
907 dest[i] = src[i];
908 else
909 dest[i] = '_';
912 dest[i] = '\0';
914 return dest;
917 /****************************************************************************
918 Like strncpy but always null terminates. Make sure there is room!
919 The variable n should always be one less than the available size.
920 ****************************************************************************/
921 char *StrnCpy(char *dest,const char *src,size_t n)
923 char *d = dest;
924 if (!dest) return(NULL);
925 if (!src) {
926 *dest = 0;
927 return(dest);
929 while (n-- && (*d++ = *src++)) ;
930 *d = 0;
931 return(dest);
935 /****************************************************************************
936 like strncpy but copies up to the character marker. always null terminates.
937 returns a pointer to the character marker in the source string (src).
938 ****************************************************************************/
939 char *strncpyn(char *dest, const char *src,size_t n, char c)
941 char *p;
942 size_t str_len;
944 p = strchr(src, c);
945 if (p == NULL)
947 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
948 return NULL;
951 str_len = PTR_DIFF(p, src);
952 strncpy(dest, src, MIN(n, str_len));
953 dest[str_len] = '\0';
955 return p;
959 /*************************************************************
960 Routine to get hex characters and turn them into a 16 byte array.
961 the array can be variable length, and any non-hex-numeric
962 characters are skipped. "0xnn" or "0Xnn" is specially catered
963 for.
965 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
967 **************************************************************/
968 size_t strhex_to_str(char *p, size_t len, const char *strhex)
970 size_t i;
971 size_t num_chars = 0;
972 unsigned char lonybble, hinybble;
973 char *hexchars = "0123456789ABCDEF";
974 char *p1 = NULL, *p2 = NULL;
976 for (i = 0; i < len && strhex[i] != 0; i++)
978 if (strnequal(hexchars, "0x", 2))
980 i++; /* skip two chars */
981 continue;
984 if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
986 break;
989 i++; /* next hex digit */
991 if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
993 break;
996 /* get the two nybbles */
997 hinybble = PTR_DIFF(p1, hexchars);
998 lonybble = PTR_DIFF(p2, hexchars);
1000 p[num_chars] = (hinybble << 4) | lonybble;
1001 num_chars++;
1003 p1 = NULL;
1004 p2 = NULL;
1006 return num_chars;
1009 /****************************************************************************
1010 check if a string is part of a list
1011 ****************************************************************************/
1012 BOOL in_list(char *s,char *list,BOOL casesensitive)
1014 pstring tok;
1015 char *p=list;
1017 if (!list) return(False);
1019 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
1020 if (casesensitive) {
1021 if (strcmp(tok,s) == 0)
1022 return(True);
1023 } else {
1024 if (StrCaseCmp(tok,s) == 0)
1025 return(True);
1028 return(False);
1031 /* this is used to prevent lots of mallocs of size 1 */
1032 static char *null_string = NULL;
1034 /****************************************************************************
1035 set a string value, allocing the space for the string
1036 ****************************************************************************/
1037 static BOOL string_init(char **dest,const char *src)
1039 size_t l;
1040 if (!src)
1041 src = "";
1043 l = strlen(src);
1045 if (l == 0)
1047 if (!null_string) {
1048 if((null_string = (char *)malloc(1)) == NULL) {
1049 DEBUG(0,("string_init: malloc fail for null_string.\n"));
1050 return False;
1052 *null_string = 0;
1054 *dest = null_string;
1056 else
1058 (*dest) = (char *)malloc(l+1);
1059 if ((*dest) == NULL) {
1060 DEBUG(0,("Out of memory in string_init\n"));
1061 return False;
1064 pstrcpy(*dest,src);
1066 return(True);
1069 /****************************************************************************
1070 free a string value
1071 ****************************************************************************/
1072 void string_free(char **s)
1074 if (!s || !(*s)) return;
1075 if (*s == null_string)
1076 *s = NULL;
1077 if (*s) free(*s);
1078 *s = NULL;
1081 /****************************************************************************
1082 set a string value, allocing the space for the string, and deallocating any
1083 existing space
1084 ****************************************************************************/
1085 BOOL string_set(char **dest,const char *src)
1087 string_free(dest);
1089 return(string_init(dest,src));
1093 /****************************************************************************
1094 substitute a string for a pattern in another string. Make sure there is
1095 enough room!
1097 This routine looks for pattern in s and replaces it with
1098 insert. It may do multiple replacements.
1100 any of " ; ' $ or ` in the insert string are replaced with _
1101 if len==0 then no length check is performed
1102 ****************************************************************************/
1103 void string_sub(char *s,const char *pattern,const char *insert, size_t len)
1105 char *p;
1106 ssize_t ls,lp,li, i;
1108 if (!insert || !pattern || !s) return;
1110 ls = (ssize_t)strlen(s);
1111 lp = (ssize_t)strlen(pattern);
1112 li = (ssize_t)strlen(insert);
1114 if (!*pattern) return;
1116 while (lp <= ls && (p = strstr(s,pattern))) {
1117 if (len && (ls + (li-lp) >= len)) {
1118 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
1119 (int)(ls + (li-lp) - len),
1120 pattern, (int)len));
1121 break;
1123 if (li != lp) {
1124 memmove(p+li,p+lp,strlen(p+lp)+1);
1126 for (i=0;i<li;i++) {
1127 switch (insert[i]) {
1128 case '`':
1129 case '"':
1130 case '\'':
1131 case ';':
1132 case '$':
1133 case '%':
1134 case '\r':
1135 case '\n':
1136 p[i] = '_';
1137 break;
1138 default:
1139 p[i] = insert[i];
1142 s = p + li;
1143 ls += (li-lp);
1147 void fstring_sub(char *s,const char *pattern,const char *insert)
1149 string_sub(s, pattern, insert, sizeof(fstring));
1152 void pstring_sub(char *s,const char *pattern,const char *insert)
1154 string_sub(s, pattern, insert, sizeof(pstring));
1157 /****************************************************************************
1158 similar to string_sub() but allows for any character to be substituted.
1159 Use with caution!
1160 if len==0 then no length check is performed
1161 ****************************************************************************/
1162 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1164 char *p;
1165 ssize_t ls,lp,li;
1167 if (!insert || !pattern || !s) return;
1169 ls = (ssize_t)strlen(s);
1170 lp = (ssize_t)strlen(pattern);
1171 li = (ssize_t)strlen(insert);
1173 if (!*pattern) return;
1175 while (lp <= ls && (p = strstr(s,pattern))) {
1176 if (len && (ls + (li-lp) >= len)) {
1177 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
1178 (int)(ls + (li-lp) - len),
1179 pattern, (int)len));
1180 break;
1182 if (li != lp) {
1183 memmove(p+li,p+lp,strlen(p+lp)+1);
1185 memcpy(p, insert, li);
1186 s = p + li;
1187 ls += (li-lp);
1191 /****************************************************************************
1192 splits out the front and back at a separator.
1193 ****************************************************************************/
1194 void split_at_first_component(char *path, char *front, char sep, char *back)
1196 char *p = strchr(path, sep);
1198 if (p != NULL)
1200 *p = 0;
1202 if (front != NULL)
1204 pstrcpy(front, path);
1206 if (p != NULL)
1208 if (back != NULL)
1210 pstrcpy(back, p+1);
1212 *p = sep;
1214 else
1216 if (back != NULL)
1218 back[0] = 0;
1223 /****************************************************************************
1224 splits out the front and back at a separator.
1225 ****************************************************************************/
1226 void split_at_last_component(char *path, char *front, char sep, char *back)
1228 char *p = strrchr(path, sep);
1230 if (p != NULL)
1232 *p = 0;
1234 if (front != NULL)
1236 pstrcpy(front, path);
1238 else if (back != NULL)
1240 pstrcpy(back, path);
1242 if (p != NULL)
1244 if (back != NULL)
1246 pstrcpy(back, p+1);
1248 *p = sep;
1250 else
1252 if (back != NULL && front != NULL)
1254 back[0] = 0;
1259 /****************************************************************************
1260 convert a bit field to a string. if you want multiple bits to be detected
1261 set them first, e.g SV_TYPE_ALL to be "All" or "Full Control" for ACB_INFOs.
1263 strings are expected to contain their own separators, although the code
1264 below only assumes that separators are spaces.
1266 ****************************************************************************/
1267 char *bit_field_to_str(uint32 type, struct field_info *bs)
1269 static fstring typestr;
1270 int i = 0;
1272 typestr[0] = 0;
1274 if (type == 0 || bs == NULL)
1276 return NULL;
1279 while (bs[i].str != NULL && type != 0)
1281 if (IS_BITS_SET_ALL(bs[i].bits, type))
1283 fstrcat(typestr, bs[i].str);
1284 type &= ~bs[i].bits;
1286 i++;
1289 i = strlen(typestr)-1;
1290 if (i > 0 && typestr[i] == ' ')
1292 typestr[i] = 0;
1295 return typestr;
1298 /****************************************************************************
1299 convert an enumeration to a string. first item is the default.
1300 ****************************************************************************/
1301 char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default)
1303 int i = 0;
1305 if (bs == NULL)
1307 return NULL;
1310 while (bs[i].str != NULL && type != 0)
1312 if (bs[i].bits == type)
1314 return bs[i].str;
1316 i++;
1319 /* oops - none found */
1321 if (first_default)
1323 return bs[0].str;
1326 return NULL;
1329 /****************************************************************************
1330 opposite to above: convert string to enum. Default/error return passed in.
1331 ****************************************************************************/
1332 uint32 str_to_enum_field(char *in, struct field_info *bs, uint32 def)
1334 uint32 i = 0;
1336 if (in == NULL || bs == NULL)
1338 return def;
1341 if (sscanf(in, "%li", (long*)&i))
1343 return i;
1346 for (i=0; bs[i].str != NULL; i++)
1348 if (!strcasecmp(bs[i].str, in))
1350 return bs[i].bits;
1354 return def;
1357 /****************************************************************************
1358 write an octal as a string
1359 ****************************************************************************/
1360 char *octal_string(int i)
1362 static char ret[64];
1363 if (i == -1) {
1364 return "-1";
1366 slprintf(ret, sizeof(ret), "0%o", i);
1367 return ret;
1371 /****************************************************************************
1372 truncate a string at a specified length
1373 ****************************************************************************/
1374 char *string_truncate(char *s, int length)
1376 if (s && strlen(s) > length) {
1377 s[length] = 0;
1379 return s;
1382 /* Parse a string of the form DOMAIN/user into a domain and a user */
1384 void parse_domain_user(char *domuser, fstring domain, fstring user)
1386 char *p;
1387 char *sep = lp_winbind_separator();
1388 if (!sep) sep = "\\";
1389 p = strchr(domuser,*sep);
1390 if (!p) p = strchr(domuser,'\\');
1391 if (!p) {
1392 fstrcpy(domain,"");
1393 fstrcpy(user, domuser);
1394 return;
1397 fstrcpy(user, p+1);
1398 fstrcpy(domain, domuser);
1399 domain[PTR_DIFF(p, domuser)] = 0;