cad0df48a494adddf9bb08a462c1596dc2549c29
[samba.git] / source3 / lib / util_str.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    
5    Copyright (C) Andrew Tridgell 1992-2001
6    Copyright (C) Simo Sorce      2001-2002
7    Copyright (C) Martin Pool     2003
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 /**
27  * @file
28  * @brief String utilities.
29  **/
30
31 /**
32  * Get the next token from a string, return False if none found.
33  * Handles double-quotes.
34  * 
35  * Based on a routine by GJC@VILLAGE.COM. 
36  * Extensively modified by Andrew.Tridgell@anu.edu.au
37  **/
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
39 {
40         char *s;
41         char *pbuf;
42         BOOL quoted;
43         size_t len=1;
44
45         if (!ptr)
46                 return(False);
47
48         s = (char *)*ptr;
49
50         /* default to simple separators */
51         if (!sep)
52                 sep = " \t\n\r";
53
54         /* find the first non sep char */
55         while (*s && strchr_m(sep,*s))
56                 s++;
57         
58         /* nothing left? */
59         if (! *s)
60                 return(False);
61         
62         /* copy over the token */
63         pbuf = buff;
64         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65                 if (*s == '\"' || *s == '\'') {
66                         quoted = !quoted;
67                 } else {
68                         len++;
69                         *pbuf++ = *s;
70                 }
71         }
72         
73         *ptr = (*s) ? s+1 : s;  
74         *pbuf = 0;
75         
76         return(True);
77 }
78
79 /**
80 This is like next_token but is not re-entrant and "remembers" the first 
81 parameter so you can pass NULL. This is useful for user interface code
82 but beware the fact that it is not re-entrant!
83 **/
84
85 static const char *last_ptr=NULL;
86
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
88 {
89         BOOL ret;
90         if (!ptr)
91                 ptr = &last_ptr;
92
93         ret = next_token(ptr, buff, sep, bufsize);
94         last_ptr = *ptr;
95         return ret;     
96 }
97
98 static uint16 tmpbuf[sizeof(pstring)];
99
100 void set_first_token(char *ptr)
101 {
102         last_ptr = ptr;
103 }
104
105 /**
106  Convert list of tokens to array; dependent on above routine.
107  Uses last_ptr from above - bit of a hack.
108 **/
109
110 char **toktocliplist(int *ctok, const char *sep)
111 {
112         char *s=(char *)last_ptr;
113         int ictok=0;
114         char **ret, **iret;
115
116         if (!sep)
117                 sep = " \t\n\r";
118
119         while(*s && strchr_m(sep,*s))
120                 s++;
121
122         /* nothing left? */
123         if (!*s)
124                 return(NULL);
125
126         do {
127                 ictok++;
128                 while(*s && (!strchr_m(sep,*s)))
129                         s++;
130                 while(*s && strchr_m(sep,*s))
131                         *s++=0;
132         } while(*s);
133         
134         *ctok=ictok;
135         s=(char *)last_ptr;
136         
137         if (!(ret=iret=malloc(ictok*sizeof(char *))))
138                 return NULL;
139         
140         while(ictok--) {    
141                 *iret++=s;
142                 while(*s++)
143                         ;
144                 while(!*s)
145                         s++;
146         }
147
148         return ret;
149 }
150
151 /**
152  * Case insensitive string compararison.
153  *
154  * iconv does not directly give us a way to compare strings in
155  * arbitrary unix character sets -- all we can is convert and then
156  * compare.  This is expensive.
157  *
158  * As an optimization, we do a first pass that considers only the
159  * prefix of the strings that is entirely 7-bit.  Within this, we
160  * check whether they have the same value.
161  *
162  * Hopefully this will often give the answer without needing to copy.
163  * In particular it should speed comparisons to literal ascii strings
164  * or comparisons of strings that are "obviously" different.
165  *
166  * If we find a non-ascii character we fall back to converting via
167  * iconv.
168  *
169  * This should never be slower than convering the whole thing, and
170  * often faster.
171  *
172  * A different optimization would be to compare for bitwise equality
173  * in the binary encoding.  (It would be possible thought hairy to do
174  * both simultaneously.)  But in that case if they turn out to be
175  * different, we'd need to restart the whole thing.
176  *
177  * Even better is to implement strcasecmp for each encoding and use a
178  * function pointer. 
179  **/
180 int StrCaseCmp(const char *s, const char *t)
181 {
182
183         const char * ps, * pt;
184         size_t size;
185         smb_ucs2_t *buffer_s, *buffer_t;
186         int ret;
187
188         for (ps = s, pt = t; ; ps++, pt++) {
189                 char us, ut;
190
191                 if (!*ps && !*pt)
192                         return 0; /* both ended */
193                 else if (!*ps)
194                         return -1; /* s is a prefix */
195                 else if (!*pt)
196                         return +1; /* t is a prefix */
197                 else if ((*ps & 0x80) || (*pt & 0x80))
198                         /* not ascii anymore, do it the hard way from here on in */
199                         break;
200
201                 us = toupper(*ps);
202                 ut = toupper(*pt);
203                 if (us == ut)
204                         continue;
205                 else if (us < ut)
206                         return -1;
207                 else if (us > ut)
208                         return +1;
209         }
210
211         size = push_ucs2_allocate(&buffer_s, s);
212         if (size == (size_t)-1) {
213                 return strcmp(s, t); 
214                 /* Not quite the right answer, but finding the right one
215                    under this failure case is expensive, and it's pretty close */
216         }
217         
218         size = push_ucs2_allocate(&buffer_t, t);
219         if (size == (size_t)-1) {
220                 SAFE_FREE(buffer_s);
221                 return strcmp(s, t); 
222                 /* Not quite the right answer, but finding the right one
223                    under this failure case is expensive, and it's pretty close */
224         }
225         
226         ret = strcasecmp_w(buffer_s, buffer_t);
227         SAFE_FREE(buffer_s);
228         SAFE_FREE(buffer_t);
229         return ret;
230 }
231
232
233 /**
234  Case insensitive string compararison, length limited.
235 **/
236 int StrnCaseCmp(const char *s, const char *t, size_t n)
237 {
238         pstring buf1, buf2;
239         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
240         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
241         return strncmp(buf1,buf2,n);
242 }
243
244 /**
245  * Compare 2 strings.
246  *
247  * @note The comparison is case-insensitive.
248  **/
249 BOOL strequal(const char *s1, const char *s2)
250 {
251         if (s1 == s2)
252                 return(True);
253         if (!s1 || !s2)
254                 return(False);
255   
256         return(StrCaseCmp(s1,s2)==0);
257 }
258
259 /**
260  * Compare 2 strings up to and including the nth char.
261  *
262  * @note The comparison is case-insensitive.
263  **/
264 BOOL strnequal(const char *s1,const char *s2,size_t n)
265 {
266   if (s1 == s2)
267           return(True);
268   if (!s1 || !s2 || !n)
269           return(False);
270   
271   return(StrnCaseCmp(s1,s2,n)==0);
272 }
273
274 /**
275  Compare 2 strings (case sensitive).
276 **/
277
278 BOOL strcsequal(const char *s1,const char *s2)
279 {
280   if (s1 == s2)
281           return(True);
282   if (!s1 || !s2)
283           return(False);
284   
285   return(strcmp(s1,s2)==0);
286 }
287
288 /**
289 Do a case-insensitive, whitespace-ignoring string compare.
290 **/
291
292 int strwicmp(const char *psz1, const char *psz2)
293 {
294         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
295         /* appropriate value. */
296         if (psz1 == psz2)
297                 return (0);
298         else if (psz1 == NULL)
299                 return (-1);
300         else if (psz2 == NULL)
301                 return (1);
302
303         /* sync the strings on first non-whitespace */
304         while (1) {
305                 while (isspace((int)*psz1))
306                         psz1++;
307                 while (isspace((int)*psz2))
308                         psz2++;
309                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
310                     || *psz2 == '\0')
311                         break;
312                 psz1++;
313                 psz2++;
314         }
315         return (*psz1 - *psz2);
316 }
317
318
319 /**
320  Convert a string to upper case, but don't modify it.
321 **/
322
323 char *strupper_static(const char *s)
324 {
325         static pstring str;
326
327         pstrcpy(str, s);
328         strupper_m(str);
329
330         return str;
331 }
332
333 /**
334  Convert a string to "normal" form.
335 **/
336
337 void strnorm(char *s)
338 {
339         extern int case_default;
340         if (case_default == CASE_UPPER)
341                 strupper_m(s);
342         else
343                 strlower_m(s);
344 }
345
346 /**
347  Check if a string is in "normal" case.
348 **/
349
350 BOOL strisnormal(const char *s)
351 {
352         extern int case_default;
353         if (case_default == CASE_UPPER)
354                 return(!strhaslower(s));
355         
356         return(!strhasupper(s));
357 }
358
359
360 /**
361  String replace.
362  NOTE: oldc and newc must be 7 bit characters
363 **/
364
365 void string_replace(pstring s,char oldc,char newc)
366 {
367         unsigned char *p;
368
369         /* this is quite a common operation, so we want it to be
370            fast. We optimise for the ascii case, knowing that all our
371            supported multi-byte character sets are ascii-compatible
372            (ie. they match for the first 128 chars) */
373
374         for (p = (unsigned char *)s; *p; p++) {
375                 if (*p & 0x80) /* mb string - slow path. */
376                         break;
377                 if (*p == oldc)
378                         *p = newc;
379         }
380
381         if (!*p)
382                 return;
383
384         /* Slow (mb) path. */
385 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
386         /* With compose characters we must restart from the beginning. JRA. */
387         p = s;
388 #endif
389         push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
390         string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
391         pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
392 }
393
394 /**
395  Skip past some strings in a buffer.
396 **/
397
398 char *skip_string(char *buf,size_t n)
399 {
400         while (n--)
401                 buf += strlen(buf) + 1;
402         return(buf);
403 }
404
405 /**
406  Count the number of characters in a string. Normally this will
407  be the same as the number of bytes in a string for single byte strings,
408  but will be different for multibyte.
409 **/
410
411 size_t str_charnum(const char *s)
412 {
413         uint16 tmpbuf2[sizeof(pstring)];
414         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
415         return strlen_w(tmpbuf2);
416 }
417
418 /**
419  Count the number of characters in a string. Normally this will
420  be the same as the number of bytes in a string for single byte strings,
421  but will be different for multibyte.
422 **/
423
424 size_t str_ascii_charnum(const char *s)
425 {
426         pstring tmpbuf2;
427         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
428         return strlen(tmpbuf2);
429 }
430
431 BOOL trim_char(char *s,char cfront,char cback)
432 {
433         BOOL ret = False;
434         char *ep;
435         char *fp = s;
436
437         /* Ignore null or empty strings. */
438         if (!s || (s[0] == '\0'))
439                 return False;
440
441         if (cfront) {
442                 while (*fp && *fp == cfront)
443                         fp++;
444                 if (!*fp) {
445                         /* We ate the string. */
446                         s[0] = '\0';
447                         return True;
448                 }
449                 if (fp != s)
450                         ret = True;
451         }
452
453         ep = fp + strlen(fp) - 1;
454         if (cback) {
455                 /* Attempt ascii only. Bail for mb strings. */
456                 while ((ep >= fp) && (*ep == cback)) {
457                         ret = True;
458                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
459                                 /* Could be mb... bail back to tim_string. */
460                                 char fs[2], bs[2];
461                                 if (cfront) {
462                                         fs[0] = cfront;
463                                         fs[1] = '\0';
464                                 }
465                                 bs[0] = cback;
466                                 bs[1] = '\0';
467                                 return trim_string(s, cfront ? fs : NULL, bs);
468                         } else {
469                                 ep--;
470                         }
471                 }
472                 if (ep < fp) {
473                         /* We ate the string. */
474                         s[0] = '\0';
475                         return True;
476                 }
477         }
478
479         ep[1] = '\0';
480         memmove(s, fp, ep-fp+2);
481         return ret;
482 }
483
484 /**
485  Trim the specified elements off the front and back of a string.
486 **/
487
488 BOOL trim_string(char *s,const char *front,const char *back)
489 {
490         BOOL ret = False;
491         size_t front_len;
492         size_t back_len;
493         size_t len;
494
495         /* Ignore null or empty strings. */
496         if (!s || (s[0] == '\0'))
497                 return False;
498
499         front_len       = front? strlen(front) : 0;
500         back_len        = back? strlen(back) : 0;
501
502         len = strlen(s);
503
504         if (front_len) {
505                 while (len && strncmp(s, front, front_len)==0) {
506                         /* Must use memmove here as src & dest can
507                          * easily overlap. Found by valgrind. JRA. */
508                         memmove(s, s+front_len, (len-front_len)+1);
509                         len -= front_len;
510                         ret=True;
511                 }
512         }
513         
514         if (back_len) {
515                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
516                         s[len-back_len]='\0';
517                         len -= back_len;
518                         ret=True;
519                 }
520         }
521         return ret;
522 }
523
524 /**
525  Does a string have any uppercase chars in it?
526 **/
527
528 BOOL strhasupper(const char *s)
529 {
530         smb_ucs2_t *ptr;
531         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
532         for(ptr=tmpbuf;*ptr;ptr++)
533                 if(isupper_w(*ptr))
534                         return True;
535         return(False);
536 }
537
538 /**
539  Does a string have any lowercase chars in it?
540 **/
541
542 BOOL strhaslower(const char *s)
543 {
544         smb_ucs2_t *ptr;
545         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
546         for(ptr=tmpbuf;*ptr;ptr++)
547                 if(islower_w(*ptr))
548                         return True;
549         return(False);
550 }
551
552 /**
553  Find the number of 'c' chars in a string
554 **/
555
556 size_t count_chars(const char *s,char c)
557 {
558         smb_ucs2_t *ptr;
559         int count;
560         smb_ucs2_t *alloc_tmpbuf = NULL;
561
562         if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
563                 return 0;
564         }
565
566         for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
567                 if(*ptr==UCS2_CHAR(c))
568                         count++;
569
570         SAFE_FREE(alloc_tmpbuf);
571         return(count);
572 }
573
574 /**
575  Safe string copy into a known length string. maxlength does not
576  include the terminating zero.
577 **/
578
579 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
580 {
581         size_t len;
582
583         if (!dest) {
584                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
585                 return NULL;
586         }
587
588 #ifdef DEVELOPER
589         clobber_region(fn,line,dest, maxlength+1);
590 #endif
591
592         if (!src) {
593                 *dest = 0;
594                 return dest;
595         }  
596
597         len = strnlen(src, maxlength+1);
598
599         if (len > maxlength) {
600                 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
601                          (unsigned long)(len-maxlength), (unsigned long)len, 
602                          (unsigned long)maxlength, src));
603                 len = maxlength;
604         }
605       
606         memmove(dest, src, len);
607         dest[len] = 0;
608         return dest;
609 }  
610
611 /**
612  Safe string cat into a string. maxlength does not
613  include the terminating zero.
614 **/
615 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
616 {
617         size_t src_len, dest_len;
618
619         if (!dest) {
620                 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
621                 return NULL;
622         }
623
624         if (!src)
625                 return dest;
626         
627         src_len = strnlen(src, maxlength + 1);
628         dest_len = strnlen(dest, maxlength + 1);
629
630 #ifdef DEVELOPER
631         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
632 #endif
633
634         if (src_len + dest_len > maxlength) {
635                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
636                          (int)(src_len + dest_len - maxlength), src));
637                 if (maxlength > dest_len) {
638                         memcpy(&dest[dest_len], src, maxlength - dest_len);
639                 }
640                 dest[maxlength] = 0;
641                 return NULL;
642         }
643
644         memcpy(&dest[dest_len], src, src_len);
645         dest[dest_len + src_len] = 0;
646         return dest;
647 }
648
649 /**
650  Paranoid strcpy into a buffer of given length (includes terminating
651  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
652  and replaces with '_'. Deliberately does *NOT* check for multibyte
653  characters. Don't change it !
654 **/
655 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
656 {
657         size_t len, i;
658
659 #ifdef DEVELOPER
660         clobber_region(fn, line, dest, maxlength);
661 #endif
662
663         if (!dest) {
664                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
665                 return NULL;
666         }
667
668         if (!src) {
669                 *dest = 0;
670                 return dest;
671         }  
672
673         len = strlen(src);
674         if (len >= maxlength)
675                 len = maxlength - 1;
676
677         if (!other_safe_chars)
678                 other_safe_chars = "";
679
680         for(i = 0; i < len; i++) {
681                 int val = (src[i] & 0xff);
682                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
683                         dest[i] = src[i];
684                 else
685                         dest[i] = '_';
686         }
687
688         dest[i] = '\0';
689
690         return dest;
691 }
692
693 /**
694  Like strncpy but always null terminates. Make sure there is room!
695  The variable n should always be one less than the available size.
696 **/
697 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
698 {
699         char *d = dest;
700
701 #ifdef DEVELOPER
702         clobber_region(fn, line, dest, n+1);
703 #endif
704
705         if (!dest) {
706                 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
707                 return(NULL);
708         }
709
710         if (!src) {
711                 *dest = 0;
712                 return(dest);
713         }
714         
715         while (n-- && (*d = *src)) {
716                 d++;
717                 src++;
718         }
719
720         *d = 0;
721         return(dest);
722 }
723
724 #if 0
725 /**
726  Like strncpy but copies up to the character marker.  always null terminates.
727  returns a pointer to the character marker in the source string (src).
728 **/
729
730 static char *strncpyn(char *dest, const char *src, size_t n, char c)
731 {
732         char *p;
733         size_t str_len;
734
735 #ifdef DEVELOPER
736         clobber_region(dest, n+1);
737 #endif
738         p = strchr_m(src, c);
739         if (p == NULL) {
740                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
741                 return NULL;
742         }
743
744         str_len = PTR_DIFF(p, src);
745         strncpy(dest, src, MIN(n, str_len));
746         dest[str_len] = '\0';
747
748         return p;
749 }
750 #endif
751
752 /**
753  Routine to get hex characters and turn them into a 16 byte array.
754  the array can be variable length, and any non-hex-numeric
755  characters are skipped.  "0xnn" or "0Xnn" is specially catered
756  for.
757
758  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
759
760 **/
761
762 size_t strhex_to_str(char *p, size_t len, const char *strhex)
763 {
764         size_t i;
765         size_t num_chars = 0;
766         unsigned char   lonybble, hinybble;
767         const char     *hexchars = "0123456789ABCDEF";
768         char           *p1 = NULL, *p2 = NULL;
769
770         for (i = 0; i < len && strhex[i] != 0; i++) {
771                 if (strnequal(hexchars, "0x", 2)) {
772                         i++; /* skip two chars */
773                         continue;
774                 }
775
776                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
777                         break;
778
779                 i++; /* next hex digit */
780
781                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
782                         break;
783
784                 /* get the two nybbles */
785                 hinybble = PTR_DIFF(p1, hexchars);
786                 lonybble = PTR_DIFF(p2, hexchars);
787
788                 p[num_chars] = (hinybble << 4) | lonybble;
789                 num_chars++;
790
791                 p1 = NULL;
792                 p2 = NULL;
793         }
794         return num_chars;
795 }
796
797 /**
798  * Routine to print a buffer as HEX digits, into an allocated string.
799  */
800
801 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
802 {
803         int i;
804         char *hex_buffer;
805
806         *out_hex_buffer = smb_xmalloc((len*2)+1);
807         hex_buffer = *out_hex_buffer;
808
809         for (i = 0; i < len; i++)
810                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
811 }
812
813 /**
814  Check if a string is part of a list.
815 **/
816
817 BOOL in_list(char *s,char *list,BOOL casesensitive)
818 {
819         pstring tok;
820         const char *p=list;
821
822         if (!list)
823                 return(False);
824
825         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
826                 if (casesensitive) {
827                         if (strcmp(tok,s) == 0)
828                                 return(True);
829                 } else {
830                         if (StrCaseCmp(tok,s) == 0)
831                                 return(True);
832                 }
833         }
834         return(False);
835 }
836
837 /* this is used to prevent lots of mallocs of size 1 */
838 static char *null_string = NULL;
839
840 /**
841  Set a string value, allocing the space for the string
842 **/
843
844 static BOOL string_init(char **dest,const char *src)
845 {
846         size_t l;
847         if (!src)     
848                 src = "";
849
850         l = strlen(src);
851
852         if (l == 0) {
853                 if (!null_string) {
854                         if((null_string = (char *)malloc(1)) == NULL) {
855                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
856                                 return False;
857                         }
858                         *null_string = 0;
859                 }
860                 *dest = null_string;
861         } else {
862                 (*dest) = strdup(src);
863                 if ((*dest) == NULL) {
864                         DEBUG(0,("Out of memory in string_init\n"));
865                         return False;
866                 }
867         }
868         return(True);
869 }
870
871 /**
872  Free a string value.
873 **/
874
875 void string_free(char **s)
876 {
877         if (!s || !(*s))
878                 return;
879         if (*s == null_string)
880                 *s = NULL;
881         SAFE_FREE(*s);
882 }
883
884 /**
885  Set a string value, deallocating any existing space, and allocing the space
886  for the string
887 **/
888
889 BOOL string_set(char **dest,const char *src)
890 {
891         string_free(dest);
892         return(string_init(dest,src));
893 }
894
895 /**
896  Substitute a string for a pattern in another string. Make sure there is 
897  enough room!
898
899  This routine looks for pattern in s and replaces it with 
900  insert. It may do multiple replacements.
901
902  Any of " ; ' $ or ` in the insert string are replaced with _
903  if len==0 then the string cannot be extended. This is different from the old
904  use of len==0 which was for no length checks to be done.
905 **/
906
907 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
908 {
909         char *p;
910         ssize_t ls,lp,li, i;
911
912         if (!insert || !pattern || !*pattern || !s)
913                 return;
914
915         ls = (ssize_t)strlen(s);
916         lp = (ssize_t)strlen(pattern);
917         li = (ssize_t)strlen(insert);
918
919         if (len == 0)
920                 len = ls + 1; /* len is number of *bytes* */
921
922         while (lp <= ls && (p = strstr_m(s,pattern))) {
923                 if (ls + (li-lp) >= len) {
924                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
925                                  (int)(ls + (li-lp) - len),
926                                  pattern, (int)len));
927                         break;
928                 }
929                 if (li != lp) {
930                         memmove(p+li,p+lp,strlen(p+lp)+1);
931                 }
932                 for (i=0;i<li;i++) {
933                         switch (insert[i]) {
934                         case '`':
935                         case '"':
936                         case '\'':
937                         case ';':
938                         case '$':
939                         case '%':
940                         case '\r':
941                         case '\n':
942                                 p[i] = '_';
943                                 break;
944                         default:
945                                 p[i] = insert[i];
946                         }
947                 }
948                 s = p + li;
949                 ls += (li-lp);
950         }
951 }
952
953 void fstring_sub(char *s,const char *pattern,const char *insert)
954 {
955         string_sub(s, pattern, insert, sizeof(fstring));
956 }
957
958 void pstring_sub(char *s,const char *pattern,const char *insert)
959 {
960         string_sub(s, pattern, insert, sizeof(pstring));
961 }
962
963 /**
964  Similar to string_sub, but it will accept only allocated strings
965  and may realloc them so pay attention at what you pass on no
966  pointers inside strings, no pstrings or const may be passed
967  as string.
968 **/
969
970 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
971 {
972         char *p, *in;
973         char *s;
974         ssize_t ls,lp,li,ld, i;
975
976         if (!insert || !pattern || !*pattern || !string || !*string)
977                 return NULL;
978
979         s = string;
980
981         in = strdup(insert);
982         if (!in) {
983                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
984                 return NULL;
985         }
986         ls = (ssize_t)strlen(s);
987         lp = (ssize_t)strlen(pattern);
988         li = (ssize_t)strlen(insert);
989         ld = li - lp;
990         for (i=0;i<li;i++) {
991                 switch (in[i]) {
992                         case '`':
993                         case '"':
994                         case '\'':
995                         case ';':
996                         case '$':
997                         case '%':
998                         case '\r':
999                         case '\n':
1000                                 in[i] = '_';
1001                         default:
1002                                 /* ok */
1003                                 break;
1004                 }
1005         }
1006         
1007         while ((p = strstr_m(s,pattern))) {
1008                 if (ld > 0) {
1009                         int offset = PTR_DIFF(s,string);
1010                         char *t = Realloc(string, ls + ld + 1);
1011                         if (!t) {
1012                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1013                                 SAFE_FREE(in);
1014                                 return NULL;
1015                         }
1016                         string = t;
1017                         p = t + offset + (p - s);
1018                 }
1019                 if (li != lp) {
1020                         memmove(p+li,p+lp,strlen(p+lp)+1);
1021                 }
1022                 memcpy(p, in, li);
1023                 s = p + li;
1024                 ls += ld;
1025         }
1026         SAFE_FREE(in);
1027         return string;
1028 }
1029
1030 /**
1031  Similar to string_sub() but allows for any character to be substituted. 
1032  Use with caution!
1033  if len==0 then the string cannot be extended. This is different from the old
1034  use of len==0 which was for no length checks to be done.
1035 **/
1036
1037 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1038 {
1039         char *p;
1040         ssize_t ls,lp,li;
1041
1042         if (!insert || !pattern || !s)
1043                 return;
1044
1045         ls = (ssize_t)strlen(s);
1046         lp = (ssize_t)strlen(pattern);
1047         li = (ssize_t)strlen(insert);
1048
1049         if (!*pattern)
1050                 return;
1051         
1052         if (len == 0)
1053                 len = ls + 1; /* len is number of *bytes* */
1054         
1055         while (lp <= ls && (p = strstr_m(s,pattern))) {
1056                 if (ls + (li-lp) >= len) {
1057                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1058                                  (int)(ls + (li-lp) - len),
1059                                  pattern, (int)len));
1060                         break;
1061                 }
1062                 if (li != lp) {
1063                         memmove(p+li,p+lp,strlen(p+lp)+1);
1064                 }
1065                 memcpy(p, insert, li);
1066                 s = p + li;
1067                 ls += (li-lp);
1068         }
1069 }
1070
1071 /**
1072  Similar to all_string_sub but for unicode strings.
1073  Return a new allocated unicode string.
1074  similar to string_sub() but allows for any character to be substituted.
1075  Use with caution!
1076 **/
1077
1078 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1079                                 const smb_ucs2_t *insert)
1080 {
1081         smb_ucs2_t *r, *rp;
1082         const smb_ucs2_t *sp;
1083         size_t  lr, lp, li, lt;
1084
1085         if (!insert || !pattern || !*pattern || !s)
1086                 return NULL;
1087
1088         lt = (size_t)strlen_w(s);
1089         lp = (size_t)strlen_w(pattern);
1090         li = (size_t)strlen_w(insert);
1091
1092         if (li > lp) {
1093                 const smb_ucs2_t *st = s;
1094                 int ld = li - lp;
1095                 while ((sp = strstr_w(st, pattern))) {
1096                         st = sp + lp;
1097                         lt += ld;
1098                 }
1099         }
1100
1101         r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1102         if (!r) {
1103                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1104                 return NULL;
1105         }
1106
1107         while ((sp = strstr_w(s, pattern))) {
1108                 memcpy(rp, s, (sp - s));
1109                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1110                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1111                 s = sp + lp;
1112                 rp += li;
1113         }
1114         lr = ((rp - r) / sizeof(smb_ucs2_t));
1115         if (lr < lt) {
1116                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1117                 rp += (lt - lr);
1118         }
1119         *rp = 0;
1120
1121         return r;
1122 }
1123
1124 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1125                                              const char *insert)
1126 {
1127         wpstring p, i;
1128
1129         if (!insert || !pattern || !s)
1130                 return NULL;
1131         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1132         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1133         return all_string_sub_w(s, p, i);
1134 }
1135
1136 #if 0
1137 /**
1138  Splits out the front and back at a separator.
1139 **/
1140
1141 static void split_at_last_component(char *path, char *front, char sep, char *back)
1142 {
1143         char *p = strrchr_m(path, sep);
1144
1145         if (p != NULL)
1146                 *p = 0;
1147
1148         if (front != NULL)
1149                 pstrcpy(front, path);
1150
1151         if (p != NULL) {
1152                 if (back != NULL)
1153                         pstrcpy(back, p+1);
1154                 *p = '\\';
1155         } else {
1156                 if (back != NULL)
1157                         back[0] = 0;
1158         }
1159 }
1160 #endif
1161
1162 /**
1163  Write an octal as a string.
1164 **/
1165
1166 const char *octal_string(int i)
1167 {
1168         static char ret[64];
1169         if (i == -1)
1170                 return "-1";
1171         slprintf(ret, sizeof(ret)-1, "0%o", i);
1172         return ret;
1173 }
1174
1175
1176 /**
1177  Truncate a string at a specified length.
1178 **/
1179
1180 char *string_truncate(char *s, unsigned int length)
1181 {
1182         if (s && strlen(s) > length)
1183                 s[length] = 0;
1184         return s;
1185 }
1186
1187 /**
1188  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1189  We convert via ucs2 for now.
1190 **/
1191
1192 char *strchr_m(const char *src, char c)
1193 {
1194         wpstring ws;
1195         pstring s2;
1196         smb_ucs2_t *p;
1197         const char *s;
1198
1199         /* this is quite a common operation, so we want it to be
1200            fast. We optimise for the ascii case, knowing that all our
1201            supported multi-byte character sets are ascii-compatible
1202            (ie. they match for the first 128 chars) */
1203
1204         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1205                 if (*s == c)
1206                         return (char *)s;
1207         }
1208
1209         if (!*s)
1210                 return NULL;
1211
1212 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1213         /* With compose characters we must restart from the beginning. JRA. */
1214         s = src;
1215 #endif
1216
1217         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1218         p = strchr_w(ws, UCS2_CHAR(c));
1219         if (!p)
1220                 return NULL;
1221         *p = 0;
1222         pull_ucs2_pstring(s2, ws);
1223         return (char *)(s+strlen(s2));
1224 }
1225
1226 char *strrchr_m(const char *s, char c)
1227 {
1228         /* this is quite a common operation, so we want it to be
1229            fast. We optimise for the ascii case, knowing that all our
1230            supported multi-byte character sets are ascii-compatible
1231            (ie. they match for the first 128 chars). Also, in Samba
1232            we only search for ascii characters in 'c' and that
1233            in all mb character sets with a compound character
1234            containing c, if 'c' is not a match at position
1235            p, then p[-1] > 0x7f. JRA. */
1236
1237         {
1238                 size_t len = strlen(s);
1239                 const char *cp = s;
1240                 BOOL got_mb = False;
1241
1242                 if (len == 0)
1243                         return NULL;
1244                 cp += (len - 1);
1245                 do {
1246                         if (c == *cp) {
1247                                 /* Could be a match. Part of a multibyte ? */
1248                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1249                                         /* Yep - go slow :-( */
1250                                         got_mb = True;
1251                                         break;
1252                                 }
1253                                 /* No - we have a match ! */
1254                                 return (char *)cp;
1255                         }
1256                 } while (cp-- != s);
1257                 if (!got_mb)
1258                         return NULL;
1259         }
1260
1261         /* String contained a non-ascii char. Slow path. */
1262         {
1263                 wpstring ws;
1264                 pstring s2;
1265                 smb_ucs2_t *p;
1266
1267                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1268                 p = strrchr_w(ws, UCS2_CHAR(c));
1269                 if (!p)
1270                         return NULL;
1271                 *p = 0;
1272                 pull_ucs2_pstring(s2, ws);
1273                 return (char *)(s+strlen(s2));
1274         }
1275 }
1276
1277 /***********************************************************************
1278  Return the equivalent of doing strrchr 'n' times - always going
1279  backwards.
1280 ***********************************************************************/
1281
1282 char *strnrchr_m(const char *s, char c, unsigned int n)
1283 {
1284         wpstring ws;
1285         pstring s2;
1286         smb_ucs2_t *p;
1287
1288         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1289         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1290         if (!p)
1291                 return NULL;
1292         *p = 0;
1293         pull_ucs2_pstring(s2, ws);
1294         return (char *)(s+strlen(s2));
1295 }
1296
1297 /***********************************************************************
1298  strstr_m - We convert via ucs2 for now.
1299 ***********************************************************************/
1300
1301 char *strstr_m(const char *src, const char *findstr)
1302 {
1303         smb_ucs2_t *p;
1304         smb_ucs2_t *src_w, *find_w;
1305         const char *s;
1306         char *s2;
1307         char *retp;
1308
1309         /* Samba does single character findstr calls a *lot*. */
1310         if (findstr[1] == '\0')
1311                 return strchr_m(src, *findstr);
1312
1313         /* We optimise for the ascii case, knowing that all our
1314            supported multi-byte character sets are ascii-compatible
1315            (ie. they match for the first 128 chars) */
1316
1317         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1318                 if (*s == *findstr) {
1319                         if (strcmp(s, findstr) == 0) {
1320                                 return (char *)s;
1321                         }
1322                 }
1323         }
1324
1325         if (!*s)
1326                 return NULL;
1327
1328 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1329         /* With compose characters we must restart from the beginning. JRA. */
1330         s = src;
1331 #endif
1332
1333         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1334                 DEBUG(0,("strstr_m: src malloc fail\n"));
1335                 return NULL;
1336         }
1337         
1338         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1339                 SAFE_FREE(src_w);
1340                 DEBUG(0,("strstr_m: find malloc fail\n"));
1341                 return NULL;
1342         }
1343         
1344         for (p = src_w; (p = strchr_w(p, *find_w)) != NULL; p++) {
1345                 if (strcmp_w(p, find_w) == 0)
1346                         break;
1347         }
1348         if (!p) {
1349                 SAFE_FREE(src_w);
1350                 SAFE_FREE(find_w);
1351                 return NULL;
1352         }
1353         *p = 0;
1354         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1355                 SAFE_FREE(src_w);
1356                 SAFE_FREE(find_w);
1357                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1358                 return NULL;
1359         }
1360         retp = (char *)(s+strlen(s2));
1361         SAFE_FREE(src_w);
1362         SAFE_FREE(find_w);
1363         SAFE_FREE(s2);
1364         return retp;
1365 }
1366
1367 /**
1368  Convert a string to lower case.
1369 **/
1370
1371 void strlower_m(char *s)
1372 {
1373         size_t len;
1374
1375         /* this is quite a common operation, so we want it to be
1376            fast. We optimise for the ascii case, knowing that all our
1377            supported multi-byte character sets are ascii-compatible
1378            (ie. they match for the first 128 chars) */
1379
1380         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1381                 *s = tolower((unsigned char)*s);
1382                 s++;
1383         }
1384
1385         if (!*s)
1386                 return;
1387
1388         /* I assume that lowercased string takes the same number of bytes
1389          * as source string even in UTF-8 encoding. (VIV) */
1390         len = strlen(s) + 1;
1391         errno = 0;
1392         unix_strlower(s,len,s,len);     
1393         /* Catch mb conversion errors that may not terminate. */
1394         if (errno)
1395                 s[len-1] = '\0';
1396 }
1397
1398 /**
1399  Convert a string to upper case.
1400 **/
1401
1402 void strupper_m(char *s)
1403 {
1404         size_t len;
1405
1406         /* this is quite a common operation, so we want it to be
1407            fast. We optimise for the ascii case, knowing that all our
1408            supported multi-byte character sets are ascii-compatible
1409            (ie. they match for the first 128 chars) */
1410
1411         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1412                 *s = toupper((unsigned char)*s);
1413                 s++;
1414         }
1415
1416         if (!*s)
1417                 return;
1418
1419         /* I assume that lowercased string takes the same number of bytes
1420          * as source string even in multibyte encoding. (VIV) */
1421         len = strlen(s) + 1;
1422         errno = 0;
1423         unix_strupper(s,len,s,len);     
1424         /* Catch mb conversion errors that may not terminate. */
1425         if (errno)
1426                 s[len-1] = '\0';
1427 }
1428
1429 /**
1430  Return a RFC2254 binary string representation of a buffer.
1431  Used in LDAP filters.
1432  Caller must free.
1433 **/
1434
1435 char *binary_string(char *buf, int len)
1436 {
1437         char *s;
1438         int i, j;
1439         const char *hex = "0123456789ABCDEF";
1440         s = malloc(len * 3 + 1);
1441         if (!s)
1442                 return NULL;
1443         for (j=i=0;i<len;i++) {
1444                 s[j] = '\\';
1445                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1446                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1447                 j += 3;
1448         }
1449         s[j] = 0;
1450         return s;
1451 }
1452
1453 /**
1454  Just a typesafety wrapper for snprintf into a pstring.
1455 **/
1456
1457  int pstr_sprintf(pstring s, const char *fmt, ...)
1458 {
1459         va_list ap;
1460         int ret;
1461
1462         va_start(ap, fmt);
1463         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1464         va_end(ap);
1465         return ret;
1466 }
1467
1468
1469 /**
1470  Just a typesafety wrapper for snprintf into a fstring.
1471 **/
1472
1473 int fstr_sprintf(fstring s, const char *fmt, ...)
1474 {
1475         va_list ap;
1476         int ret;
1477
1478         va_start(ap, fmt);
1479         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1480         va_end(ap);
1481         return ret;
1482 }
1483
1484
1485 #ifndef HAVE_STRNDUP
1486 /**
1487  Some platforms don't have strndup.
1488 **/
1489
1490  char *strndup(const char *s, size_t n)
1491 {
1492         char *ret;
1493         
1494         n = strnlen(s, n);
1495         ret = malloc(n+1);
1496         if (!ret)
1497                 return NULL;
1498         memcpy(ret, s, n);
1499         ret[n] = 0;
1500
1501         return ret;
1502 }
1503 #endif
1504
1505 #ifndef HAVE_STRNLEN
1506 /**
1507  Some platforms don't have strnlen
1508 **/
1509
1510  size_t strnlen(const char *s, size_t n)
1511 {
1512         int i;
1513         for (i=0; s[i] && i<n; i++)
1514                 /* noop */ ;
1515         return i;
1516 }
1517 #endif
1518
1519 /**
1520  List of Strings manipulation functions
1521 **/
1522
1523 #define S_LIST_ABS 16 /* List Allocation Block Size */
1524
1525 char **str_list_make(const char *string, const char *sep)
1526 {
1527         char **list, **rlist;
1528         const char *str;
1529         char *s;
1530         int num, lsize;
1531         pstring tok;
1532         
1533         if (!string || !*string)
1534                 return NULL;
1535         s = strdup(string);
1536         if (!s) {
1537                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1538                 return NULL;
1539         }
1540         if (!sep) sep = LIST_SEP;
1541         
1542         num = lsize = 0;
1543         list = NULL;
1544         
1545         str = s;
1546         while (next_token(&str, tok, sep, sizeof(tok))) {               
1547                 if (num == lsize) {
1548                         lsize += S_LIST_ABS;
1549                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1550                         if (!rlist) {
1551                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1552                                 str_list_free(&list);
1553                                 SAFE_FREE(s);
1554                                 return NULL;
1555                         } else
1556                                 list = rlist;
1557                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1558                 }
1559                 
1560                 list[num] = strdup(tok);
1561                 if (!list[num]) {
1562                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1563                         str_list_free(&list);
1564                         SAFE_FREE(s);
1565                         return NULL;
1566                 }
1567         
1568                 num++;  
1569         }
1570         
1571         SAFE_FREE(s);
1572         return list;
1573 }
1574
1575 BOOL str_list_copy(char ***dest, const char **src)
1576 {
1577         char **list, **rlist;
1578         int num, lsize;
1579         
1580         *dest = NULL;
1581         if (!src)
1582                 return False;
1583         
1584         num = lsize = 0;
1585         list = NULL;
1586                 
1587         while (src[num]) {
1588                 if (num == lsize) {
1589                         lsize += S_LIST_ABS;
1590                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1591                         if (!rlist) {
1592                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1593                                 str_list_free(&list);
1594                                 return False;
1595                         } else
1596                                 list = rlist;
1597                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1598                 }
1599                 
1600                 list[num] = strdup(src[num]);
1601                 if (!list[num]) {
1602                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1603                         str_list_free(&list);
1604                         return False;
1605                 }
1606
1607                 num++;
1608         }
1609         
1610         *dest = list;
1611         return True;    
1612 }
1613
1614 /**
1615  * Return true if all the elements of the list match exactly.
1616  **/
1617 BOOL str_list_compare(char **list1, char **list2)
1618 {
1619         int num;
1620         
1621         if (!list1 || !list2)
1622                 return (list1 == list2); 
1623         
1624         for (num = 0; list1[num]; num++) {
1625                 if (!list2[num])
1626                         return False;
1627                 if (!strcsequal(list1[num], list2[num]))
1628                         return False;
1629         }
1630         if (list2[num])
1631                 return False; /* if list2 has more elements than list1 fail */
1632         
1633         return True;
1634 }
1635
1636 void str_list_free(char ***list)
1637 {
1638         char **tlist;
1639         
1640         if (!list || !*list)
1641                 return;
1642         tlist = *list;
1643         for(; *tlist; tlist++)
1644                 SAFE_FREE(*tlist);
1645         SAFE_FREE(*list);
1646 }
1647
1648 /******************************************************************************
1649  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1650  for the work
1651  *****************************************************************************/
1652  
1653 BOOL str_list_sub_basic( char **list, const char *smb_name )
1654 {
1655         char *s, *tmpstr;
1656         
1657         while ( *list ) {
1658                 s = *list;
1659                 tmpstr = alloc_sub_basic(smb_name, s);
1660                 if ( !tmpstr ) {
1661                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1662                         return False;
1663                 }
1664
1665                 *list = tmpstr;
1666                         
1667                 list++;
1668         }
1669
1670         return True;
1671 }
1672
1673 /******************************************************************************
1674  substritute a specific pattern in a string list
1675  *****************************************************************************/
1676  
1677 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1678 {
1679         char *p, *s, *t;
1680         ssize_t ls, lp, li, ld, i, d;
1681
1682         if (!list)
1683                 return False;
1684         if (!pattern)
1685                 return False;
1686         if (!insert)
1687                 return False;
1688
1689         lp = (ssize_t)strlen(pattern);
1690         li = (ssize_t)strlen(insert);
1691         ld = li -lp;
1692                         
1693         while (*list) {
1694                 s = *list;
1695                 ls = (ssize_t)strlen(s);
1696
1697                 while ((p = strstr_m(s, pattern))) {
1698                         t = *list;
1699                         d = p -t;
1700                         if (ld) {
1701                                 t = (char *) malloc(ls +ld +1);
1702                                 if (!t) {
1703                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1704                                         return False;
1705                                 }
1706                                 memcpy(t, *list, d);
1707                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1708                                 SAFE_FREE(*list);
1709                                 *list = t;
1710                                 ls += ld;
1711                                 s = t +d +li;
1712                         }
1713                         
1714                         for (i = 0; i < li; i++) {
1715                                 switch (insert[i]) {
1716                                         case '`':
1717                                         case '"':
1718                                         case '\'':
1719                                         case ';':
1720                                         case '$':
1721                                         case '%':
1722                                         case '\r':
1723                                         case '\n':
1724                                                 t[d +i] = '_';
1725                                                 break;
1726                                         default:
1727                                                 t[d +i] = insert[i];
1728                                 }
1729                         }       
1730                 }
1731                 
1732                 
1733                 list++;
1734         }
1735         
1736         return True;
1737 }
1738
1739
1740 #define IPSTR_LIST_SEP  ","
1741 #define IPSTR_LIST_CHAR ','
1742
1743 /**
1744  * Add ip string representation to ipstr list. Used also
1745  * as part of @function ipstr_list_make
1746  *
1747  * @param ipstr_list pointer to string containing ip list;
1748  *        MUST BE already allocated and IS reallocated if necessary
1749  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1750  *        as a result of reallocation)
1751  * @param ip IP address which is to be added to list
1752  * @return pointer to string appended with new ip and possibly
1753  *         reallocated to new length
1754  **/
1755
1756 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1757 {
1758         char* new_ipstr = NULL;
1759         
1760         /* arguments checking */
1761         if (!ipstr_list || !service) return NULL;
1762
1763         /* attempt to convert ip to a string and append colon separator to it */
1764         if (*ipstr_list) {
1765                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1766                         inet_ntoa(service->ip), service->port);
1767                 SAFE_FREE(*ipstr_list);
1768         } else {
1769                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1770         }
1771         *ipstr_list = new_ipstr;
1772         return *ipstr_list;
1773 }
1774
1775
1776 /**
1777  * Allocate and initialise an ipstr list using ip adresses
1778  * passed as arguments.
1779  *
1780  * @param ipstr_list pointer to string meant to be allocated and set
1781  * @param ip_list array of ip addresses to place in the list
1782  * @param ip_count number of addresses stored in ip_list
1783  * @return pointer to allocated ip string
1784  **/
1785  
1786 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1787 {
1788         int i;
1789         
1790         /* arguments checking */
1791         if (!ip_list && !ipstr_list) return 0;
1792
1793         *ipstr_list = NULL;
1794         
1795         /* process ip addresses given as arguments */
1796         for (i = 0; i < ip_count; i++)
1797                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1798         
1799         return (*ipstr_list);
1800 }
1801
1802
1803 /**
1804  * Parse given ip string list into array of ip addresses
1805  * (as ip_service structures)  
1806  *    e.g. 192.168.1.100:389,192.168.1.78, ...
1807  *
1808  * @param ipstr ip string list to be parsed 
1809  * @param ip_list pointer to array of ip addresses which is
1810  *        allocated by this function and must be freed by caller
1811  * @return number of succesfully parsed addresses
1812  **/
1813  
1814 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1815 {
1816         fstring token_str;
1817         size_t count;
1818         int i;
1819
1820         if (!ipstr_list || !ip_list) 
1821                 return 0;
1822         
1823         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1824         if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1825                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1826                 return 0;
1827         }
1828         
1829         for ( i=0; 
1830                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
1831                 i++ ) 
1832         {
1833                 struct in_addr addr;
1834                 unsigned port = 0;      
1835                 char *p = strchr(token_str, ':');
1836                 
1837                 if (p) {
1838                         *p = 0;
1839                         port = atoi(p+1);
1840                 }
1841
1842                 /* convert single token to ip address */
1843                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1844                         break;
1845                                 
1846                 (*ip_list)[i].ip = addr;
1847                 (*ip_list)[i].port = port;
1848         }
1849         
1850         return count;
1851 }
1852
1853
1854 /**
1855  * Safely free ip string list
1856  *
1857  * @param ipstr_list ip string list to be freed
1858  **/
1859
1860 void ipstr_list_free(char* ipstr_list)
1861 {
1862         SAFE_FREE(ipstr_list);
1863 }
1864
1865
1866 /**
1867  Unescape a URL encoded string, in place.
1868 **/
1869
1870 void rfc1738_unescape(char *buf)
1871 {
1872         char *p=buf;
1873
1874         while (p && *p && (p=strchr_m(p,'%'))) {
1875                 int c1 = p[1];
1876                 int c2 = p[2];
1877
1878                 if (c1 >= '0' && c1 <= '9')
1879                         c1 = c1 - '0';
1880                 else if (c1 >= 'A' && c1 <= 'F')
1881                         c1 = 10 + c1 - 'A';
1882                 else if (c1 >= 'a' && c1 <= 'f')
1883                         c1 = 10 + c1 - 'a';
1884                 else {p++; continue;}
1885
1886                 if (c2 >= '0' && c2 <= '9')
1887                         c2 = c2 - '0';
1888                 else if (c2 >= 'A' && c2 <= 'F')
1889                         c2 = 10 + c2 - 'A';
1890                 else if (c2 >= 'a' && c2 <= 'f')
1891                         c2 = 10 + c2 - 'a';
1892                 else {p++; continue;}
1893                         
1894                 *p = (c1<<4) | c2;
1895
1896                 memmove(p+1, p+3, strlen(p+3)+1);
1897                 p++;
1898         }
1899 }
1900
1901 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1902
1903 /**
1904  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1905  **/
1906 DATA_BLOB base64_decode_data_blob(const char *s)
1907 {
1908         int bit_offset, byte_offset, idx, i, n;
1909         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1910         unsigned char *d = decoded.data;
1911         char *p;
1912
1913         n=i=0;
1914
1915         while (*s && (p=strchr_m(b64,*s))) {
1916                 idx = (int)(p - b64);
1917                 byte_offset = (i*6)/8;
1918                 bit_offset = (i*6)%8;
1919                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1920                 if (bit_offset < 3) {
1921                         d[byte_offset] |= (idx << (2-bit_offset));
1922                         n = byte_offset+1;
1923                 } else {
1924                         d[byte_offset] |= (idx >> (bit_offset-2));
1925                         d[byte_offset+1] = 0;
1926                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1927                         n = byte_offset+2;
1928                 }
1929                 s++; i++;
1930         }
1931
1932         if (*s == '=') n -= 1;
1933
1934         /* fix up length */
1935         decoded.length = n;
1936         return decoded;
1937 }
1938
1939 /**
1940  * Decode a base64 string in-place - wrapper for the above
1941  **/
1942 void base64_decode_inplace(char *s)
1943 {
1944         DATA_BLOB decoded = base64_decode_data_blob(s);
1945         memcpy(s, decoded.data, decoded.length);
1946         /* null terminate */
1947         s[decoded.length] = '\0';
1948
1949         data_blob_free(&decoded);
1950 }
1951
1952 /**
1953  * Encode a base64 string into a malloc()ed string caller to free.
1954  *
1955  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1956  **/
1957 char * base64_encode_data_blob(DATA_BLOB data)
1958 {
1959         int bits = 0;
1960         int char_count = 0;
1961         size_t out_cnt = 0;
1962         size_t len = data.length;
1963         size_t output_len = data.length * 2;
1964         char *result = malloc(output_len); /* get us plenty of space */
1965
1966         while (len-- && out_cnt < (data.length * 2) - 5) {
1967                 int c = (unsigned char) *(data.data++);
1968                 bits += c;
1969                 char_count++;
1970                 if (char_count == 3) {
1971                         result[out_cnt++] = b64[bits >> 18];
1972                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1973                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1974             result[out_cnt++] = b64[bits & 0x3f];
1975             bits = 0;
1976             char_count = 0;
1977         } else {
1978             bits <<= 8;
1979         }
1980     }
1981     if (char_count != 0) {
1982         bits <<= 16 - (8 * char_count);
1983         result[out_cnt++] = b64[bits >> 18];
1984         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1985         if (char_count == 1) {
1986             result[out_cnt++] = '=';
1987             result[out_cnt++] = '=';
1988         } else {
1989             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1990             result[out_cnt++] = '=';
1991         }
1992     }
1993     result[out_cnt] = '\0';     /* terminate */
1994     return result;
1995 }
1996
1997 /* read a SMB_BIG_UINT from a string */
1998 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1999 {
2000
2001         SMB_BIG_UINT val = -1;
2002         const char *p = nptr;
2003         
2004         while (p && *p && isspace(*p))
2005                 p++;
2006 #ifdef LARGE_SMB_OFF_T
2007         sscanf(p,"%llu",&val);  
2008 #else /* LARGE_SMB_OFF_T */
2009         sscanf(p,"%lu",&val);
2010 #endif /* LARGE_SMB_OFF_T */
2011         if (entptr) {
2012                 while (p && *p && isdigit(*p))
2013                         p++;
2014                 *entptr = p;
2015         }
2016
2017         return val;
2018 }