first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[kai/samba.git] / source3 / lib / util_str.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 static char *last_ptr=NULL;
27
28 void set_first_token(char *ptr)
29 {
30         last_ptr = ptr;
31 }
32
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)
40 {
41   char *s;
42   BOOL quoted;
43   size_t len=1;
44
45   if (!ptr) ptr = &last_ptr;
46   if (!ptr) return(False);
47
48   s = *ptr;
49
50   /* default to simple separators */
51   if (!sep) sep = " \t\n\r";
52
53   /* find the first non sep char */
54   while(*s && strchr(sep,*s)) s++;
55
56   /* nothing left? */
57   if (! *s) return(False);
58
59   /* copy over the token */
60   for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
61     {
62             if (*s == '\"') {
63                     quoted = !quoted;
64             } else {
65                     len++;
66                     *buff++ = *s;
67             }
68     }
69
70   *ptr = (*s) ? s+1 : s;  
71   *buff = 0;
72   last_ptr = *ptr;
73
74   return(True);
75 }
76
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)
82 {
83   char *s=last_ptr;
84   int ictok=0;
85   char **ret, **iret;
86
87   if (!sep) sep = " \t\n\r";
88
89   while(*s && strchr(sep,*s)) s++;
90
91   /* nothing left? */
92   if (!*s) return(NULL);
93
94   do {
95     ictok++;
96     while(*s && (!strchr(sep,*s))) s++;
97     while(*s && strchr(sep,*s)) *s++=0;
98   } while(*s);
99
100   *ctok=ictok;
101   s=last_ptr;
102
103   if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
104   
105   while(ictok--) {    
106     *iret++=s;
107     while(*s++);
108     while(!*s) s++;
109   }
110
111   return ret;
112 }
113
114
115 /*******************************************************************
116   case insensitive string compararison
117 ********************************************************************/
118 int StrCaseCmp(const char *s, const char *t)
119 {
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.
123    */
124 #if !defined(KANJI_WIN95_COMPATIBILITY)
125   /*
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.
132    */
133
134   if(lp_client_code_page() == KANJI_CODEPAGE)
135   {
136     /* Win95 treats full width ascii characters as case sensitive. */
137     int diff;
138     for (;;)
139     {
140       if (!*s || !*t)
141             return toupper (*s) - toupper (*t);
142       else if (is_sj_alph (*s) && is_sj_alph (*t))
143       {
144         diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
145         if (diff)
146           return diff;
147         s += 2;
148         t += 2;
149       }
150       else if (is_shift_jis (*s) && is_shift_jis (*t))
151       {
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;
160       }
161       else if (is_shift_jis (*s))
162         return 1;
163       else if (is_shift_jis (*t))
164         return -1;
165       else 
166       {
167         diff = toupper (*s) - toupper (*t);
168         if (diff)
169           return diff;
170         s++;
171         t++;
172       }
173     }
174   }
175   else
176 #endif /* KANJI_WIN95_COMPATIBILITY */
177   {
178     while (*s && *t && toupper(*s) == toupper(*t))
179     {
180       s++;
181       t++;
182     }
183
184     return(toupper(*s) - toupper(*t));
185   }
186 }
187
188 /*******************************************************************
189   case insensitive string compararison, length limited
190 ********************************************************************/
191 int StrnCaseCmp(const char *s, const char *t, size_t n)
192 {
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.
196    */
197 #if !defined(KANJI_WIN95_COMPATIBILITY)
198   /*
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. 
205    */
206
207   if(lp_client_code_page() == KANJI_CODEPAGE)
208   {
209     /* Win95 treats full width ascii characters as case sensitive. */
210     int diff;
211     for (;n > 0;)
212     {
213       if (!*s || !*t)
214         return toupper (*s) - toupper (*t);
215       else if (is_sj_alph (*s) && is_sj_alph (*t))
216       {
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;
223       }
224       else if (is_shift_jis (*s) && is_shift_jis (*t))
225       {
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;
235       }
236       else if (is_shift_jis (*s))
237         return 1;
238       else if (is_shift_jis (*t))
239         return -1;
240       else 
241       {
242         diff = toupper (*s) - toupper (*t);
243         if (diff)
244           return diff;
245         s++;
246         t++;
247         n--;
248       }
249     }
250     return 0;
251   }
252   else
253 #endif /* KANJI_WIN95_COMPATIBILITY */
254   {
255     while (n && *s && *t && toupper(*s) == toupper(*t))
256     {
257       s++;
258       t++;
259       n--;
260     }
261
262     /* not run out of chars - strings are different lengths */
263     if (n) 
264       return(toupper(*s) - toupper(*t));
265
266     /* identical up to where we run out of chars, 
267        and strings are same length */
268     return(0);
269   }
270 }
271
272 /*******************************************************************
273   compare 2 strings 
274 ********************************************************************/
275 BOOL strequal(const char *s1, const char *s2)
276 {
277   if (s1 == s2) return(True);
278   if (!s1 || !s2) return(False);
279   
280   return(StrCaseCmp(s1,s2)==0);
281 }
282
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)
287 {
288   if (s1 == s2) return(True);
289   if (!s1 || !s2 || !n) return(False);
290   
291   return(StrnCaseCmp(s1,s2,n)==0);
292 }
293
294 /*******************************************************************
295   compare 2 strings (case sensitive)
296 ********************************************************************/
297 BOOL strcsequal(const char *s1,const char *s2)
298 {
299   if (s1 == s2) return(True);
300   if (!s1 || !s2) return(False);
301   
302   return(strcmp(s1,s2)==0);
303 }
304
305
306 /*******************************************************************
307   convert a string to lower case
308 ********************************************************************/
309 void strlower(char *s)
310 {
311   while (*s)
312   {
313 #if !defined(KANJI_WIN95_COMPATIBILITY)
314   /*
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. 
321    */
322
323     if(lp_client_code_page() == KANJI_CODEPAGE)
324     {
325       /* Win95 treats full width ascii characters as case sensitive. */
326       if (is_shift_jis (*s))
327       {
328         if (is_sj_upper (s[0], s[1]))
329           s[1] = sj_tolower2 (s[1]);
330         s += 2;
331       }
332       else if (is_kana (*s))
333       {
334         s++;
335       }
336       else
337       {
338         if (isupper(*s))
339           *s = tolower(*s);
340         s++;
341       }
342     }
343     else
344 #endif /* KANJI_WIN95_COMPATIBILITY */
345     {
346       size_t skip = skip_multibyte_char( *s );
347       if( skip != 0 )
348         s += skip;
349       else
350       {
351         if (isupper(*s))
352           *s = tolower(*s);
353         s++;
354       }
355     }
356   }
357 }
358
359 /*******************************************************************
360   convert a string to upper case
361 ********************************************************************/
362 void strupper(char *s)
363 {
364   while (*s)
365   {
366 #if !defined(KANJI_WIN95_COMPATIBILITY)
367   /*
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. 
374    */
375
376     if(lp_client_code_page() == KANJI_CODEPAGE)
377     {
378       /* Win95 treats full width ascii characters as case sensitive. */
379       if (is_shift_jis (*s))
380       {
381         if (is_sj_lower (s[0], s[1]))
382           s[1] = sj_toupper2 (s[1]);
383         s += 2;
384       }
385       else if (is_kana (*s))
386       {
387         s++;
388       }
389       else
390       {
391         if (islower(*s))
392           *s = toupper(*s);
393         s++;
394       }
395     }
396     else
397 #endif /* KANJI_WIN95_COMPATIBILITY */
398     {
399       size_t skip = skip_multibyte_char( *s );
400       if( skip != 0 )
401         s += skip;
402       else
403       {
404         if (islower(*s))
405           *s = toupper(*s);
406         s++;
407       }
408     }
409   }
410 }
411
412 /*******************************************************************
413   convert a string to "normal" form
414 ********************************************************************/
415 void strnorm(char *s)
416 {
417   extern int case_default;
418   if (case_default == CASE_UPPER)
419     strupper(s);
420   else
421     strlower(s);
422 }
423
424 /*******************************************************************
425 check if a string is in "normal" case
426 ********************************************************************/
427 BOOL strisnormal(char *s)
428 {
429   extern int case_default;
430   if (case_default == CASE_UPPER)
431     return(!strhaslower(s));
432
433   return(!strhasupper(s));
434 }
435
436
437 /****************************************************************************
438   string replace
439 ****************************************************************************/
440 void string_replace(char *s,char oldc,char newc)
441 {
442   size_t skip;
443   while (*s)
444   {
445     skip = skip_multibyte_char( *s );
446     if( skip != 0 )
447       s += skip;
448     else
449     {
450       if (oldc == *s)
451         *s = newc;
452       s++;
453     }
454   }
455 }
456
457
458 /*******************************************************************
459 skip past some strings in a buffer
460 ********************************************************************/
461 char *skip_string(char *buf,size_t n)
462 {
463   while (n--)
464     buf += strlen(buf) + 1;
465   return(buf);
466 }
467
468 /*******************************************************************
469  Count the number of characters in a string. Normally this will
470  be the same as the number of bytes in a string for single byte strings,
471  but will be different for multibyte.
472  16.oct.98, jdblair@cobaltnet.com.
473 ********************************************************************/
474
475 size_t str_charnum(const char *s)
476 {
477   size_t len = 0;
478   
479   while (*s != '\0') {
480     int skip = skip_multibyte_char(*s);
481     s += (skip ? skip : 1);
482     len++;
483   }
484   return len;
485 }
486
487 /*******************************************************************
488 trim the specified elements off the front and back of a string
489 ********************************************************************/
490
491 BOOL trim_string(char *s,const char *front,const char *back)
492 {
493   BOOL ret = False;
494   size_t front_len = (front && *front) ? strlen(front) : 0;
495   size_t back_len = (back && *back) ? strlen(back) : 0;
496   size_t s_len;
497
498   while (front_len && strncmp(s, front, front_len) == 0)
499   {
500     char *p = s;
501     ret = True;
502     while (1)
503     {
504       if (!(*p = p[front_len]))
505         break;
506       p++;
507     }
508   }
509
510   /*
511    * We split out the multibyte code page
512    * case here for speed purposes. Under a
513    * multibyte code page we need to walk the
514    * string forwards only and multiple times.
515    * Thanks to John Blair for finding this
516    * one. JRA.
517    */
518
519   if(back_len)
520   {
521     if(!is_multibyte_codepage())
522     {
523       s_len = strlen(s);
524       while ((s_len >= back_len) && 
525              (strncmp(s + s_len - back_len, back, back_len)==0))  
526       {
527         ret = True;
528         s[s_len - back_len] = '\0';
529         s_len = strlen(s);
530       }
531     }
532     else
533     {
534
535       /*
536        * Multibyte code page case.
537        * Keep going through the string, trying
538        * to match the 'back' string with the end
539        * of the string. If we get a match, truncate
540        * 'back' off the end of the string and
541        * go through the string again from the
542        * start. Keep doing this until we have
543        * gone through the string with no match
544        * at the string end.
545        */
546
547       size_t mb_back_len = str_charnum(back);
548       size_t mb_s_len = str_charnum(s);
549
550       while(mb_s_len >= mb_back_len)
551       {
552         size_t charcount = 0;
553         char *mbp = s;
554
555         while(charcount < (mb_s_len - mb_back_len))
556         {
557           size_t skip = skip_multibyte_char(*mbp);
558           mbp += (skip ? skip : 1);
559           charcount++;
560         }
561
562         /*
563          * mbp now points at mb_back_len multibyte
564          * characters from the end of s.
565          */
566
567         if(strcmp(mbp, back) == 0)
568         {
569           ret = True;
570           *mbp = '\0';
571           mb_s_len = str_charnum(s);
572           mbp = s;
573         }
574         else
575           break;
576       } /* end while mb_s_len... */
577     } /* end else .. */
578   } /* end if back_len .. */
579
580   return(ret);
581 }
582
583
584 /****************************************************************************
585 does a string have any uppercase chars in it?
586 ****************************************************************************/
587 BOOL strhasupper(const char *s)
588 {
589   while (*s) 
590   {
591 #if !defined(KANJI_WIN95_COMPATIBILITY)
592   /*
593    * For completeness we should put in equivalent code for code pages
594    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
595    * doubt anyone wants Samba to behave differently from Win95 and WinNT
596    * here. They both treat full width ascii characters as case senstive
597    * filenames (ie. they don't do the work we do here).
598    * JRA. 
599    */
600
601     if(lp_client_code_page() == KANJI_CODEPAGE)
602     {
603       /* Win95 treats full width ascii characters as case sensitive. */
604       if (is_shift_jis (*s))
605         s += 2;
606       else if (is_kana (*s))
607         s++;
608       else
609       {
610         if (isupper(*s))
611           return(True);
612         s++;
613       }
614     }
615     else
616 #endif /* KANJI_WIN95_COMPATIBILITY */
617     {
618       size_t skip = skip_multibyte_char( *s );
619       if( skip != 0 )
620         s += skip;
621       else {
622         if (isupper(*s))
623           return(True);
624         s++;
625       }
626     }
627   }
628   return(False);
629 }
630
631 /****************************************************************************
632 does a string have any lowercase chars in it?
633 ****************************************************************************/
634 BOOL strhaslower(const char *s)
635 {
636   while (*s) 
637   {
638 #if !defined(KANJI_WIN95_COMPATIBILITY)
639   /*
640    * For completeness we should put in equivalent code for code pages
641    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
642    * doubt anyone wants Samba to behave differently from Win95 and WinNT
643    * here. They both treat full width ascii characters as case senstive
644    * filenames (ie. they don't do the work we do here).
645    * JRA. 
646    */
647
648     if(lp_client_code_page() == KANJI_CODEPAGE)
649     {
650       /* Win95 treats full width ascii characters as case sensitive. */
651       if (is_shift_jis (*s))
652       {
653         if (is_sj_upper (s[0], s[1]))
654           return(True);
655         if (is_sj_lower (s[0], s[1]))
656           return (True);
657         s += 2;
658       }
659       else if (is_kana (*s))
660       {
661         s++;
662       }
663       else
664       {
665         if (islower(*s))
666           return(True);
667         s++;
668       }
669     }
670     else
671 #endif /* KANJI_WIN95_COMPATIBILITY */
672     {
673       size_t skip = skip_multibyte_char( *s );
674       if( skip != 0 )
675         s += skip;
676       else {
677         if (islower(*s))
678           return(True);
679         s++;
680       }
681     }
682   }
683   return(False);
684 }
685
686 /****************************************************************************
687 find the number of chars in a string
688 ****************************************************************************/
689 size_t count_chars(const char *s,char c)
690 {
691   size_t count=0;
692
693 #if !defined(KANJI_WIN95_COMPATIBILITY)
694   /*
695    * For completeness we should put in equivalent code for code pages
696    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
697    * doubt anyone wants Samba to behave differently from Win95 and WinNT
698    * here. They both treat full width ascii characters as case senstive
699    * filenames (ie. they don't do the work we do here).
700    * JRA. 
701    */
702
703   if(lp_client_code_page() == KANJI_CODEPAGE)
704   {
705     /* Win95 treats full width ascii characters as case sensitive. */
706     while (*s) 
707     {
708       if (is_shift_jis (*s))
709         s += 2;
710       else 
711       {
712         if (*s == c)
713           count++;
714         s++;
715       }
716     }
717   }
718   else
719 #endif /* KANJI_WIN95_COMPATIBILITY */
720   {
721     while (*s) 
722     {
723       size_t skip = skip_multibyte_char( *s );
724       if( skip != 0 )
725         s += skip;
726       else {
727         if (*s == c)
728           count++;
729         s++;
730       }
731     }
732   }
733   return(count);
734 }
735
736 /*******************************************************************
737 Return True if a string consists only of one particular character.
738 ********************************************************************/
739
740 BOOL str_is_all(const char *s,char c)
741 {
742   if(s == NULL)
743     return False;
744   if(!*s)
745     return False;
746
747 #if !defined(KANJI_WIN95_COMPATIBILITY)
748   /*
749    * For completeness we should put in equivalent code for code pages
750    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
751    * doubt anyone wants Samba to behave differently from Win95 and WinNT
752    * here. They both treat full width ascii characters as case senstive
753    * filenames (ie. they don't do the work we do here).
754    * JRA.
755    */
756
757   if(lp_client_code_page() == KANJI_CODEPAGE)
758   {
759     /* Win95 treats full width ascii characters as case sensitive. */
760     while (*s)
761     {
762       if (is_shift_jis (*s))
763         s += 2;
764       else
765       {
766         if (*s != c)
767           return False;
768         s++;
769       }
770     }
771   }
772   else
773 #endif /* KANJI_WIN95_COMPATIBILITY */
774   {
775     while (*s)
776     {
777       size_t skip = skip_multibyte_char( *s );
778       if( skip != 0 )
779         s += skip;
780       else {
781         if (*s != c)
782           return False;
783         s++;
784       }
785     }
786   }
787   return True;
788 }
789
790 /*******************************************************************
791 safe string copy into a known length string. maxlength does not
792 include the terminating zero.
793 ********************************************************************/
794
795 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
796 {
797     size_t len;
798
799     if (!dest) {
800         DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
801         return NULL;
802     }
803
804     if (!src) {
805         *dest = 0;
806         return dest;
807     }  
808
809     len = strlen(src);
810
811     if (len > maxlength) {
812             DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
813                      (int)(len-maxlength), src));
814             len = maxlength;
815     }
816       
817     memcpy(dest, src, len);
818     dest[len] = 0;
819     return dest;
820 }  
821
822 /*******************************************************************
823 safe string cat into a string. maxlength does not
824 include the terminating zero.
825 ********************************************************************/
826
827 char *safe_strcat(char *dest, const char *src, size_t maxlength)
828 {
829     size_t src_len, dest_len;
830
831     if (!dest) {
832         DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
833         return NULL;
834     }
835
836     if (!src) {
837         return dest;
838     }  
839
840     src_len = strlen(src);
841     dest_len = strlen(dest);
842
843     if (src_len + dest_len > maxlength) {
844             DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
845                      (int)(src_len + dest_len - maxlength), src));
846             src_len = maxlength - dest_len;
847     }
848       
849     memcpy(&dest[dest_len], src, src_len);
850     dest[dest_len + src_len] = 0;
851     return dest;
852 }
853
854 /*******************************************************************
855  Paranoid strcpy into a buffer of given length (includes terminating
856  zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
857  does *NOT* check for multibyte characters. Don't change it !
858 ********************************************************************/
859
860 char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
861 {
862         size_t len, i;
863
864         if (!dest) {
865                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
866                 return NULL;
867         }
868
869         if (!src) {
870                 *dest = 0;
871                 return dest;
872         }  
873
874         len = strlen(src);
875         if (len >= maxlength)
876                 len = maxlength - 1;
877
878         for(i = 0; i < len; i++) {
879                 int val = (src[i] & 0xff);
880                 if(isupper(val) ||islower(val) || isdigit(val))
881                         dest[i] = src[i];
882                 else
883                         dest[i] = '_';
884         }
885
886         dest[i] = '\0';
887
888         return dest;
889 }
890
891 /****************************************************************************
892  Like strncpy but always null terminates. Make sure there is room!
893  The variable n should always be one less than the available size.
894 ****************************************************************************/
895
896 char *StrnCpy(char *dest,const char *src,size_t n)
897 {
898   char *d = dest;
899   if (!dest) return(NULL);
900   if (!src) {
901     *dest = 0;
902     return(dest);
903   }
904   while (n-- && (*d++ = *src++)) ;
905   *d = 0;
906   return(dest);
907 }
908
909 /****************************************************************************
910 like strncpy but copies up to the character marker.  always null terminates.
911 returns a pointer to the character marker in the source string (src).
912 ****************************************************************************/
913 char *strncpyn(char *dest, const char *src,size_t n, char c)
914 {
915         char *p;
916         size_t str_len;
917
918         p = strchr(src, c);
919         if (p == NULL)
920         {
921                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
922                 return NULL;
923         }
924
925         str_len = PTR_DIFF(p, src);
926         strncpy(dest, src, MIN(n, str_len));
927         dest[str_len] = '\0';
928
929         return p;
930 }
931
932
933 /*************************************************************
934  Routine to get hex characters and turn them into a 16 byte array.
935  the array can be variable length, and any non-hex-numeric
936  characters are skipped.  "0xnn" or "0Xnn" is specially catered
937  for.
938
939  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
940
941 **************************************************************/
942 size_t strhex_to_str(char *p, size_t len, const char *strhex)
943 {
944         size_t i;
945         size_t num_chars = 0;
946         unsigned char   lonybble, hinybble;
947         char           *hexchars = "0123456789ABCDEF";
948         char           *p1 = NULL, *p2 = NULL;
949
950         for (i = 0; i < len && strhex[i] != 0; i++)
951         {
952                 if (strnequal(hexchars, "0x", 2))
953                 {
954                         i++; /* skip two chars */
955                         continue;
956                 }
957
958                 if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
959                 {
960                         break;
961                 }
962
963                 i++; /* next hex digit */
964
965                 if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
966                 {
967                         break;
968                 }
969
970                 /* get the two nybbles */
971                 hinybble = PTR_DIFF(p1, hexchars);
972                 lonybble = PTR_DIFF(p2, hexchars);
973
974                 p[num_chars] = (hinybble << 4) | lonybble;
975                 num_chars++;
976
977                 p1 = NULL;
978                 p2 = NULL;
979         }
980         return num_chars;
981 }
982
983 /****************************************************************************
984 check if a string is part of a list
985 ****************************************************************************/
986 BOOL in_list(char *s,char *list,BOOL casesensitive)
987 {
988   pstring tok;
989   char *p=list;
990
991   if (!list) return(False);
992
993   while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
994     if (casesensitive) {
995       if (strcmp(tok,s) == 0)
996         return(True);
997     } else {
998       if (StrCaseCmp(tok,s) == 0)
999         return(True);
1000     }
1001   }
1002   return(False);
1003 }
1004
1005 /* this is used to prevent lots of mallocs of size 1 */
1006 static char *null_string = NULL;
1007
1008 /****************************************************************************
1009 set a string value, allocing the space for the string
1010 ****************************************************************************/
1011 BOOL string_init(char **dest,const char *src)
1012 {
1013   size_t l;
1014   if (!src)     
1015     src = "";
1016
1017   l = strlen(src);
1018
1019   if (l == 0)
1020     {
1021       if (!null_string) {
1022         if((null_string = (char *)malloc(1)) == NULL) {
1023           DEBUG(0,("string_init: malloc fail for null_string.\n"));
1024           return False;
1025         }
1026         *null_string = 0;
1027       }
1028       *dest = null_string;
1029     }
1030   else
1031     {
1032       (*dest) = (char *)malloc(l+1);
1033       if ((*dest) == NULL) {
1034               DEBUG(0,("Out of memory in string_init\n"));
1035               return False;
1036       }
1037
1038       pstrcpy(*dest,src);
1039     }
1040   return(True);
1041 }
1042
1043 /****************************************************************************
1044 free a string value
1045 ****************************************************************************/
1046 void string_free(char **s)
1047 {
1048   if (!s || !(*s)) return;
1049   if (*s == null_string)
1050     *s = NULL;
1051   if (*s) free(*s);
1052   *s = NULL;
1053 }
1054
1055 /****************************************************************************
1056 set a string value, allocing the space for the string, and deallocating any 
1057 existing space
1058 ****************************************************************************/
1059 BOOL string_set(char **dest,const char *src)
1060 {
1061   string_free(dest);
1062
1063   return(string_init(dest,src));
1064 }
1065
1066
1067 /****************************************************************************
1068 substitute a string for a pattern in another string. Make sure there is 
1069 enough room!
1070
1071 This routine looks for pattern in s and replaces it with 
1072 insert. It may do multiple replacements.
1073
1074 any of " ; ' $ or ` in the insert string are replaced with _
1075 if len==0 then no length check is performed
1076 ****************************************************************************/
1077 void string_sub(char *s,const char *pattern,const char *insert, size_t len)
1078 {
1079         char *p;
1080         ssize_t ls,lp,li, i;
1081
1082         if (!insert || !pattern || !s) return;
1083
1084         ls = (ssize_t)strlen(s);
1085         lp = (ssize_t)strlen(pattern);
1086         li = (ssize_t)strlen(insert);
1087
1088         if (!*pattern) return;
1089         
1090         while (lp <= ls && (p = strstr(s,pattern))) {
1091                 if (len && (ls + (li-lp) >= len)) {
1092                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
1093                                  (int)(ls + (li-lp) - len),
1094                                  pattern, (int)len));
1095                         break;
1096                 }
1097                 if (li != lp) {
1098                         memmove(p+li,p+lp,strlen(p+lp)+1);
1099                 }
1100                 for (i=0;i<li;i++) {
1101                         switch (insert[i]) {
1102                         case '`':
1103                         case '"':
1104                         case '\'':
1105                         case ';':
1106                         case '$':
1107                         case '%':
1108                         case '\r':
1109                         case '\n':
1110                                 p[i] = '_';
1111                                 break;
1112                         default:
1113                                 p[i] = insert[i];
1114                         }
1115                 }
1116                 s = p + li;
1117                 ls += (li-lp);
1118         }
1119 }
1120
1121 void fstring_sub(char *s,const char *pattern,const char *insert)
1122 {
1123         string_sub(s, pattern, insert, sizeof(fstring));
1124 }
1125
1126 void pstring_sub(char *s,const char *pattern,const char *insert)
1127 {
1128         string_sub(s, pattern, insert, sizeof(pstring));
1129 }
1130
1131 /****************************************************************************
1132 similar to string_sub() but allows for any character to be substituted. 
1133 Use with caution!
1134 if len==0 then no length check is performed
1135 ****************************************************************************/
1136 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1137 {
1138         char *p;
1139         ssize_t ls,lp,li;
1140
1141         if (!insert || !pattern || !s) return;
1142
1143         ls = (ssize_t)strlen(s);
1144         lp = (ssize_t)strlen(pattern);
1145         li = (ssize_t)strlen(insert);
1146
1147         if (!*pattern) return;
1148         
1149         while (lp <= ls && (p = strstr(s,pattern))) {
1150                 if (len && (ls + (li-lp) >= len)) {
1151                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1152                                  (int)(ls + (li-lp) - len),
1153                                  pattern, (int)len));
1154                         break;
1155                 }
1156                 if (li != lp) {
1157                         memmove(p+li,p+lp,strlen(p+lp)+1);
1158                 }
1159                 memcpy(p, insert, li);
1160                 s = p + li;
1161                 ls += (li-lp);
1162         }
1163 }
1164
1165 /****************************************************************************
1166  splits out the front and back at a separator.
1167 ****************************************************************************/
1168 void split_at_last_component(char *path, char *front, char sep, char *back)
1169 {
1170         char *p = strrchr(path, sep);
1171
1172         if (p != NULL)
1173         {
1174                 *p = 0;
1175         }
1176         if (front != NULL)
1177         {
1178                 pstrcpy(front, path);
1179         }
1180         if (p != NULL)
1181         {
1182                 if (back != NULL)
1183                 {
1184                         pstrcpy(back, p+1);
1185                 }
1186                 *p = '\\';
1187         }
1188         else
1189         {
1190                 if (back != NULL)
1191                 {
1192                         back[0] = 0;
1193                 }
1194         }
1195 }
1196
1197
1198 /****************************************************************************
1199 write an octal as a string
1200 ****************************************************************************/
1201 char *octal_string(int i)
1202 {
1203         static char ret[64];
1204         if (i == -1) {
1205                 return "-1";
1206         }
1207         slprintf(ret, sizeof(ret), "0%o", i);
1208         return ret;
1209 }
1210
1211
1212 /****************************************************************************
1213 truncate a string at a specified length
1214 ****************************************************************************/
1215 char *string_truncate(char *s, int length)
1216 {
1217         if (s && strlen(s) > length) {
1218                 s[length] = 0;
1219         }
1220         return s;
1221 }