Changes from APPLIANCE_HEAD:
[ira/wip.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 Do a case-insensitive, whitespace-ignoring string compare.
307 ***************************************************************************/
308 int strwicmp(char *psz1, char *psz2)
309 {
310         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
311         /* appropriate value. */
312         if (psz1 == psz2)
313                 return (0);
314         else if (psz1 == NULL)
315                 return (-1);
316         else if (psz2 == NULL)
317                 return (1);
318
319         /* sync the strings on first non-whitespace */
320         while (1)
321         {
322                 while (isspace(*psz1))
323                         psz1++;
324                 while (isspace(*psz2))
325                         psz2++;
326                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
327                     || *psz2 == '\0')
328                         break;
329                 psz1++;
330                 psz2++;
331         }
332         return (*psz1 - *psz2);
333 }
334
335
336 /*******************************************************************
337   convert a string to lower case
338 ********************************************************************/
339 void strlower(char *s)
340 {
341   while (*s)
342   {
343 #if !defined(KANJI_WIN95_COMPATIBILITY)
344   /*
345    * For completeness we should put in equivalent code for code pages
346    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
347    * doubt anyone wants Samba to behave differently from Win95 and WinNT
348    * here. They both treat full width ascii characters as case senstive
349    * filenames (ie. they don't do the work we do here).
350    * JRA. 
351    */
352
353     if(lp_client_code_page() == KANJI_CODEPAGE)
354     {
355       /* Win95 treats full width ascii characters as case sensitive. */
356       if (is_shift_jis (*s))
357       {
358         if (is_sj_upper (s[0], s[1]))
359           s[1] = sj_tolower2 (s[1]);
360         s += 2;
361       }
362       else if (is_kana (*s))
363       {
364         s++;
365       }
366       else
367       {
368         if (isupper(*s))
369           *s = tolower(*s);
370         s++;
371       }
372     }
373     else
374 #endif /* KANJI_WIN95_COMPATIBILITY */
375     {
376       size_t skip = get_character_len( *s );
377       if( skip != 0 )
378         s += skip;
379       else
380       {
381         if (isupper(*s))
382           *s = tolower(*s);
383         s++;
384       }
385     }
386   }
387 }
388
389 /*******************************************************************
390   convert a string to upper case
391 ********************************************************************/
392 void strupper(char *s)
393 {
394   while (*s)
395   {
396 #if !defined(KANJI_WIN95_COMPATIBILITY)
397   /*
398    * For completeness we should put in equivalent code for code pages
399    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
400    * doubt anyone wants Samba to behave differently from Win95 and WinNT
401    * here. They both treat full width ascii characters as case senstive
402    * filenames (ie. they don't do the work we do here).
403    * JRA. 
404    */
405
406     if(lp_client_code_page() == KANJI_CODEPAGE)
407     {
408       /* Win95 treats full width ascii characters as case sensitive. */
409       if (is_shift_jis (*s))
410       {
411         if (is_sj_lower (s[0], s[1]))
412           s[1] = sj_toupper2 (s[1]);
413         s += 2;
414       }
415       else if (is_kana (*s))
416       {
417         s++;
418       }
419       else
420       {
421         if (islower(*s))
422           *s = toupper(*s);
423         s++;
424       }
425     }
426     else
427 #endif /* KANJI_WIN95_COMPATIBILITY */
428     {
429       size_t skip = get_character_len( *s );
430       if( skip != 0 )
431         s += skip;
432       else
433       {
434         if (islower(*s))
435           *s = toupper(*s);
436         s++;
437       }
438     }
439   }
440 }
441
442 /*******************************************************************
443   convert a string to "normal" form
444 ********************************************************************/
445 void strnorm(char *s)
446 {
447   extern int case_default;
448   if (case_default == CASE_UPPER)
449     strupper(s);
450   else
451     strlower(s);
452 }
453
454 /*******************************************************************
455 check if a string is in "normal" case
456 ********************************************************************/
457 BOOL strisnormal(char *s)
458 {
459   extern int case_default;
460   if (case_default == CASE_UPPER)
461     return(!strhaslower(s));
462
463   return(!strhasupper(s));
464 }
465
466
467 /****************************************************************************
468   string replace
469 ****************************************************************************/
470 void string_replace(char *s,char oldc,char newc)
471 {
472   size_t skip;
473
474   /*
475    * sbcs optimization.
476    */
477   if(!global_is_multibyte_codepage) {
478     while (*s) {
479       if (oldc == *s)
480         *s = newc;
481       s++;
482     }
483   } else {
484     while (*s)
485     {
486       skip = get_character_len( *s );
487       if( skip != 0 )
488         s += skip;
489       else
490       {
491         if (oldc == *s)
492           *s = newc;
493         s++;
494       }
495     }
496   }
497 }
498
499
500 /*******************************************************************
501 skip past some strings in a buffer
502 ********************************************************************/
503 char *skip_string(char *buf,size_t n)
504 {
505   while (n--)
506     buf += strlen(buf) + 1;
507   return(buf);
508 }
509
510 /*******************************************************************
511  Count the number of characters in a string. Normally this will
512  be the same as the number of bytes in a string for single byte strings,
513  but will be different for multibyte.
514  16.oct.98, jdblair@cobaltnet.com.
515 ********************************************************************/
516
517 size_t str_charnum(const char *s)
518 {
519   size_t len = 0;
520   
521   /*
522    * sbcs optimization.
523    */
524   if(!global_is_multibyte_codepage) {
525     return strlen(s);
526   } else {
527     while (*s != '\0') {
528       int skip = get_character_len(*s);
529       s += (skip ? skip : 1);
530       len++;
531     }
532   }
533   return len;
534 }
535
536 /*******************************************************************
537 trim the specified elements off the front and back of a string
538 ********************************************************************/
539
540 BOOL trim_string(char *s,const char *front,const char *back)
541 {
542   BOOL ret = False;
543   size_t front_len = (front && *front) ? strlen(front) : 0;
544   size_t back_len = (back && *back) ? strlen(back) : 0;
545   size_t s_len;
546
547   while (front_len && strncmp(s, front, front_len) == 0)
548   {
549     char *p = s;
550     ret = True;
551     while (1)
552     {
553       if (!(*p = p[front_len]))
554         break;
555       p++;
556     }
557   }
558
559   /*
560    * We split out the multibyte code page
561    * case here for speed purposes. Under a
562    * multibyte code page we need to walk the
563    * string forwards only and multiple times.
564    * Thanks to John Blair for finding this
565    * one. JRA.
566    */
567
568   if(back_len)
569   {
570     if(!global_is_multibyte_codepage)
571     {
572       s_len = strlen(s);
573       while ((s_len >= back_len) && 
574              (strncmp(s + s_len - back_len, back, back_len)==0))  
575       {
576         ret = True;
577         s[s_len - back_len] = '\0';
578         s_len = strlen(s);
579       }
580     }
581     else
582     {
583
584       /*
585        * Multibyte code page case.
586        * Keep going through the string, trying
587        * to match the 'back' string with the end
588        * of the string. If we get a match, truncate
589        * 'back' off the end of the string and
590        * go through the string again from the
591        * start. Keep doing this until we have
592        * gone through the string with no match
593        * at the string end.
594        */
595
596       size_t mb_back_len = str_charnum(back);
597       size_t mb_s_len = str_charnum(s);
598
599       while(mb_s_len >= mb_back_len)
600       {
601         size_t charcount = 0;
602         char *mbp = s;
603
604         /*
605          * sbcs optimization.
606          */
607         if(!global_is_multibyte_codepage) {
608           while(charcount < (mb_s_len - mb_back_len)) {
609             mbp += 1;
610             charcount++;
611           }
612         } else {
613           while(charcount < (mb_s_len - mb_back_len)) {
614             size_t skip = skip_multibyte_char(*mbp);
615             mbp += (skip ? skip : 1);
616             charcount++;
617           }
618         }
619
620         /*
621          * mbp now points at mb_back_len multibyte
622          * characters from the end of s.
623          */
624
625         if(strcmp(mbp, back) == 0)
626         {
627           ret = True;
628           *mbp = '\0';
629           mb_s_len = str_charnum(s);
630           mbp = s;
631         }
632         else
633           break;
634       } /* end while mb_s_len... */
635     } /* end else .. */
636   } /* end if back_len .. */
637
638   return(ret);
639 }
640
641
642 /****************************************************************************
643 does a string have any uppercase chars in it?
644 ****************************************************************************/
645 BOOL strhasupper(const char *s)
646 {
647   while (*s) 
648   {
649 #if !defined(KANJI_WIN95_COMPATIBILITY)
650   /*
651    * For completeness we should put in equivalent code for code pages
652    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
653    * doubt anyone wants Samba to behave differently from Win95 and WinNT
654    * here. They both treat full width ascii characters as case senstive
655    * filenames (ie. they don't do the work we do here).
656    * JRA. 
657    */
658
659     if(lp_client_code_page() == KANJI_CODEPAGE)
660     {
661       /* Win95 treats full width ascii characters as case sensitive. */
662       if (is_shift_jis (*s))
663         s += 2;
664       else if (is_kana (*s))
665         s++;
666       else
667       {
668         if (isupper(*s))
669           return(True);
670         s++;
671       }
672     }
673     else
674 #endif /* KANJI_WIN95_COMPATIBILITY */
675     {
676       size_t skip = get_character_len( *s );
677       if( skip != 0 )
678         s += skip;
679       else {
680         if (isupper(*s))
681           return(True);
682         s++;
683       }
684     }
685   }
686   return(False);
687 }
688
689 /****************************************************************************
690 does a string have any lowercase chars in it?
691 ****************************************************************************/
692 BOOL strhaslower(const char *s)
693 {
694   while (*s) 
695   {
696 #if !defined(KANJI_WIN95_COMPATIBILITY)
697   /*
698    * For completeness we should put in equivalent code for code pages
699    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
700    * doubt anyone wants Samba to behave differently from Win95 and WinNT
701    * here. They both treat full width ascii characters as case senstive
702    * filenames (ie. they don't do the work we do here).
703    * JRA. 
704    */
705
706     if(lp_client_code_page() == KANJI_CODEPAGE)
707     {
708       /* Win95 treats full width ascii characters as case sensitive. */
709       if (is_shift_jis (*s))
710       {
711         if (is_sj_upper (s[0], s[1]))
712           return(True);
713         if (is_sj_lower (s[0], s[1]))
714           return (True);
715         s += 2;
716       }
717       else if (is_kana (*s))
718       {
719         s++;
720       }
721       else
722       {
723         if (islower(*s))
724           return(True);
725         s++;
726       }
727     }
728     else
729 #endif /* KANJI_WIN95_COMPATIBILITY */
730     {
731       size_t skip = get_character_len( *s );
732       if( skip != 0 )
733         s += skip;
734       else {
735         if (islower(*s))
736           return(True);
737         s++;
738       }
739     }
740   }
741   return(False);
742 }
743
744 /****************************************************************************
745 find the number of chars in a string
746 ****************************************************************************/
747 size_t count_chars(const char *s,char c)
748 {
749   size_t count=0;
750
751 #if !defined(KANJI_WIN95_COMPATIBILITY)
752   /*
753    * For completeness we should put in equivalent code for code pages
754    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
755    * doubt anyone wants Samba to behave differently from Win95 and WinNT
756    * here. They both treat full width ascii characters as case senstive
757    * filenames (ie. they don't do the work we do here).
758    * JRA. 
759    */
760
761   if(lp_client_code_page() == KANJI_CODEPAGE)
762   {
763     /* Win95 treats full width ascii characters as case sensitive. */
764     while (*s) 
765     {
766       if (is_shift_jis (*s))
767         s += 2;
768       else 
769       {
770         if (*s == c)
771           count++;
772         s++;
773       }
774     }
775   }
776   else
777 #endif /* KANJI_WIN95_COMPATIBILITY */
778   {
779     while (*s) 
780     {
781       size_t skip = get_character_len( *s );
782       if( skip != 0 )
783         s += skip;
784       else {
785         if (*s == c)
786           count++;
787         s++;
788       }
789     }
790   }
791   return(count);
792 }
793
794 /*******************************************************************
795 Return True if a string consists only of one particular character.
796 ********************************************************************/
797
798 BOOL str_is_all(const char *s,char c)
799 {
800   if(s == NULL)
801     return False;
802   if(!*s)
803     return False;
804
805 #if !defined(KANJI_WIN95_COMPATIBILITY)
806   /*
807    * For completeness we should put in equivalent code for code pages
808    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
809    * doubt anyone wants Samba to behave differently from Win95 and WinNT
810    * here. They both treat full width ascii characters as case senstive
811    * filenames (ie. they don't do the work we do here).
812    * JRA.
813    */
814
815   if(lp_client_code_page() == KANJI_CODEPAGE)
816   {
817     /* Win95 treats full width ascii characters as case sensitive. */
818     while (*s)
819     {
820       if (is_shift_jis (*s))
821         s += 2;
822       else
823       {
824         if (*s != c)
825           return False;
826         s++;
827       }
828     }
829   }
830   else
831 #endif /* KANJI_WIN95_COMPATIBILITY */
832   {
833     while (*s)
834     {
835       size_t skip = get_character_len( *s );
836       if( skip != 0 )
837         s += skip;
838       else {
839         if (*s != c)
840           return False;
841         s++;
842       }
843     }
844   }
845   return True;
846 }
847
848 /*******************************************************************
849 safe string copy into a known length string. maxlength does not
850 include the terminating zero.
851 ********************************************************************/
852
853 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
854 {
855     size_t len;
856
857     if (!dest) {
858         DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
859         return NULL;
860     }
861
862     if (!src) {
863         *dest = 0;
864         return dest;
865     }  
866
867     len = strlen(src);
868
869     if (len > maxlength) {
870             DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
871                      (int)(len-maxlength), src));
872             len = maxlength;
873     }
874       
875     memcpy(dest, src, len);
876     dest[len] = 0;
877     return dest;
878 }  
879
880 /*******************************************************************
881 safe string cat into a string. maxlength does not
882 include the terminating zero.
883 ********************************************************************/
884
885 char *safe_strcat(char *dest, const char *src, size_t maxlength)
886 {
887     size_t src_len, dest_len;
888
889     if (!dest) {
890         DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
891         return NULL;
892     }
893
894     if (!src) {
895         return dest;
896     }  
897
898     src_len = strlen(src);
899     dest_len = strlen(dest);
900
901     if (src_len + dest_len > maxlength) {
902             DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
903                      (int)(src_len + dest_len - maxlength), src));
904             src_len = maxlength - dest_len;
905     }
906       
907     memcpy(&dest[dest_len], src, src_len);
908     dest[dest_len + src_len] = 0;
909     return dest;
910 }
911
912 /*******************************************************************
913  Paranoid strcpy into a buffer of given length (includes terminating
914  zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
915  does *NOT* check for multibyte characters. Don't change it !
916 ********************************************************************/
917
918 char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
919 {
920         size_t len, i;
921
922         if (!dest) {
923                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
924                 return NULL;
925         }
926
927         if (!src) {
928                 *dest = 0;
929                 return dest;
930         }  
931
932         len = strlen(src);
933         if (len >= maxlength)
934                 len = maxlength - 1;
935
936         for(i = 0; i < len; i++) {
937                 int val = (src[i] & 0xff);
938                 if(isupper(val) ||islower(val) || isdigit(val))
939                         dest[i] = src[i];
940                 else
941                         dest[i] = '_';
942         }
943
944         dest[i] = '\0';
945
946         return dest;
947 }
948
949 /****************************************************************************
950  Like strncpy but always null terminates. Make sure there is room!
951  The variable n should always be one less than the available size.
952 ****************************************************************************/
953
954 char *StrnCpy(char *dest,const char *src,size_t n)
955 {
956   char *d = dest;
957   if (!dest) return(NULL);
958   if (!src) {
959     *dest = 0;
960     return(dest);
961   }
962   while (n-- && (*d++ = *src++)) ;
963   *d = 0;
964   return(dest);
965 }
966
967 /****************************************************************************
968 like strncpy but copies up to the character marker.  always null terminates.
969 returns a pointer to the character marker in the source string (src).
970 ****************************************************************************/
971 char *strncpyn(char *dest, const char *src,size_t n, char c)
972 {
973         char *p;
974         size_t str_len;
975
976         p = strchr(src, c);
977         if (p == NULL)
978         {
979                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
980                 return NULL;
981         }
982
983         str_len = PTR_DIFF(p, src);
984         strncpy(dest, src, MIN(n, str_len));
985         dest[str_len] = '\0';
986
987         return p;
988 }
989
990
991 /*************************************************************
992  Routine to get hex characters and turn them into a 16 byte array.
993  the array can be variable length, and any non-hex-numeric
994  characters are skipped.  "0xnn" or "0Xnn" is specially catered
995  for.
996
997  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
998
999 **************************************************************/
1000 size_t strhex_to_str(char *p, size_t len, const char *strhex)
1001 {
1002         size_t i;
1003         size_t num_chars = 0;
1004         unsigned char   lonybble, hinybble;
1005         char           *hexchars = "0123456789ABCDEF";
1006         char           *p1 = NULL, *p2 = NULL;
1007
1008         for (i = 0; i < len && strhex[i] != 0; i++)
1009         {
1010                 if (strnequal(hexchars, "0x", 2))
1011                 {
1012                         i++; /* skip two chars */
1013                         continue;
1014                 }
1015
1016                 if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
1017                 {
1018                         break;
1019                 }
1020
1021                 i++; /* next hex digit */
1022
1023                 if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
1024                 {
1025                         break;
1026                 }
1027
1028                 /* get the two nybbles */
1029                 hinybble = PTR_DIFF(p1, hexchars);
1030                 lonybble = PTR_DIFF(p2, hexchars);
1031
1032                 p[num_chars] = (hinybble << 4) | lonybble;
1033                 num_chars++;
1034
1035                 p1 = NULL;
1036                 p2 = NULL;
1037         }
1038         return num_chars;
1039 }
1040
1041 /****************************************************************************
1042 check if a string is part of a list
1043 ****************************************************************************/
1044 BOOL in_list(char *s,char *list,BOOL casesensitive)
1045 {
1046   pstring tok;
1047   char *p=list;
1048
1049   if (!list) return(False);
1050
1051   while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
1052     if (casesensitive) {
1053       if (strcmp(tok,s) == 0)
1054         return(True);
1055     } else {
1056       if (StrCaseCmp(tok,s) == 0)
1057         return(True);
1058     }
1059   }
1060   return(False);
1061 }
1062
1063 /* this is used to prevent lots of mallocs of size 1 */
1064 static char *null_string = NULL;
1065
1066 /****************************************************************************
1067 set a string value, allocing the space for the string
1068 ****************************************************************************/
1069 static BOOL string_init(char **dest,const char *src)
1070 {
1071   size_t l;
1072   if (!src)     
1073     src = "";
1074
1075   l = strlen(src);
1076
1077   if (l == 0)
1078     {
1079       if (!null_string) {
1080         if((null_string = (char *)malloc(1)) == NULL) {
1081           DEBUG(0,("string_init: malloc fail for null_string.\n"));
1082           return False;
1083         }
1084         *null_string = 0;
1085       }
1086       *dest = null_string;
1087     }
1088   else
1089     {
1090       (*dest) = (char *)malloc(l+1);
1091       if ((*dest) == NULL) {
1092               DEBUG(0,("Out of memory in string_init\n"));
1093               return False;
1094       }
1095
1096       pstrcpy(*dest,src);
1097     }
1098   return(True);
1099 }
1100
1101 /****************************************************************************
1102 free a string value
1103 ****************************************************************************/
1104 void string_free(char **s)
1105 {
1106   if (!s || !(*s)) return;
1107   if (*s == null_string)
1108     *s = NULL;
1109   if (*s) free(*s);
1110   *s = NULL;
1111 }
1112
1113 /****************************************************************************
1114 set a string value, allocing the space for the string, and deallocating any 
1115 existing space
1116 ****************************************************************************/
1117 BOOL string_set(char **dest,const char *src)
1118 {
1119   string_free(dest);
1120
1121   return(string_init(dest,src));
1122 }
1123
1124
1125 /****************************************************************************
1126 substitute a string for a pattern in another string. Make sure there is 
1127 enough room!
1128
1129 This routine looks for pattern in s and replaces it with 
1130 insert. It may do multiple replacements.
1131
1132 any of " ; ' $ or ` in the insert string are replaced with _
1133 if len==0 then no length check is performed
1134 ****************************************************************************/
1135 void string_sub(char *s,const char *pattern,const char *insert, size_t len)
1136 {
1137         char *p;
1138         ssize_t ls,lp,li, i;
1139
1140         if (!insert || !pattern || !s) return;
1141
1142         ls = (ssize_t)strlen(s);
1143         lp = (ssize_t)strlen(pattern);
1144         li = (ssize_t)strlen(insert);
1145
1146         if (!*pattern) return;
1147         
1148         while (lp <= ls && (p = strstr(s,pattern))) {
1149                 if (len && (ls + (li-lp) >= len)) {
1150                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
1151                                  (int)(ls + (li-lp) - len),
1152                                  pattern, (int)len));
1153                         break;
1154                 }
1155                 if (li != lp) {
1156                         memmove(p+li,p+lp,strlen(p+lp)+1);
1157                 }
1158                 for (i=0;i<li;i++) {
1159                         switch (insert[i]) {
1160                         case '`':
1161                         case '"':
1162                         case '\'':
1163                         case ';':
1164                         case '$':
1165                         case '%':
1166                         case '\r':
1167                         case '\n':
1168                                 p[i] = '_';
1169                                 break;
1170                         default:
1171                                 p[i] = insert[i];
1172                         }
1173                 }
1174                 s = p + li;
1175                 ls += (li-lp);
1176         }
1177 }
1178
1179 void fstring_sub(char *s,const char *pattern,const char *insert)
1180 {
1181         string_sub(s, pattern, insert, sizeof(fstring));
1182 }
1183
1184 void pstring_sub(char *s,const char *pattern,const char *insert)
1185 {
1186         string_sub(s, pattern, insert, sizeof(pstring));
1187 }
1188
1189 /****************************************************************************
1190 similar to string_sub() but allows for any character to be substituted. 
1191 Use with caution!
1192 if len==0 then no length check is performed
1193 ****************************************************************************/
1194 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1195 {
1196         char *p;
1197         ssize_t ls,lp,li;
1198
1199         if (!insert || !pattern || !s) return;
1200
1201         ls = (ssize_t)strlen(s);
1202         lp = (ssize_t)strlen(pattern);
1203         li = (ssize_t)strlen(insert);
1204
1205         if (!*pattern) return;
1206         
1207         while (lp <= ls && (p = strstr(s,pattern))) {
1208                 if (len && (ls + (li-lp) >= len)) {
1209                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1210                                  (int)(ls + (li-lp) - len),
1211                                  pattern, (int)len));
1212                         break;
1213                 }
1214                 if (li != lp) {
1215                         memmove(p+li,p+lp,strlen(p+lp)+1);
1216                 }
1217                 memcpy(p, insert, li);
1218                 s = p + li;
1219                 ls += (li-lp);
1220         }
1221 }
1222
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)
1227 {
1228         char *p = strrchr(path, sep);
1229
1230         if (p != NULL)
1231         {
1232                 *p = 0;
1233         }
1234         if (front != NULL)
1235         {
1236                 pstrcpy(front, path);
1237         }
1238         if (p != NULL)
1239         {
1240                 if (back != NULL)
1241                 {
1242                         pstrcpy(back, p+1);
1243                 }
1244                 *p = '\\';
1245         }
1246         else
1247         {
1248                 if (back != NULL)
1249                 {
1250                         back[0] = 0;
1251                 }
1252         }
1253 }
1254
1255
1256 /****************************************************************************
1257 write an octal as a string
1258 ****************************************************************************/
1259 char *octal_string(int i)
1260 {
1261         static char ret[64];
1262         if (i == -1) {
1263                 return "-1";
1264         }
1265         slprintf(ret, sizeof(ret), "0%o", i);
1266         return ret;
1267 }
1268
1269
1270 /****************************************************************************
1271 truncate a string at a specified length
1272 ****************************************************************************/
1273 char *string_truncate(char *s, int length)
1274 {
1275         if (s && strlen(s) > length) {
1276                 s[length] = 0;
1277         }
1278         return s;
1279 }
1280
1281 /* Parse a string of the form DOMAIN/user into a domain and a user */
1282
1283 void parse_domain_user(char *domuser, fstring domain, fstring user)
1284 {
1285         char *p;
1286         char *sep = lp_winbind_separator();
1287         if (!sep) sep = "\\";
1288         p = strchr(domuser,*sep);
1289         if (!p) p = strchr(domuser,'\\');
1290         if (!p) {
1291                 fstrcpy(domain,"");
1292                 fstrcpy(user, domuser);
1293                 return;
1294         }
1295         
1296         fstrcpy(user, p+1);
1297         fstrcpy(domain, domuser);
1298         domain[PTR_DIFF(p, domuser)] = 0;
1299         strupper(domain);
1300 }