r174: Win95 registry files (like USER.DAT) can now be partially parsed
[kai/samba.git] / source / lib / util_str.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-2001
5    Copyright (C) Simo Sorce      2001-2002
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 /**
25  * Get the next token from a string, return False if none found.
26  * Handles double-quotes.
27  * 
28  * Based on a routine by GJC@VILLAGE.COM. 
29  * Extensively modified by Andrew.Tridgell@anu.edu.au
30  **/
31 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
32 {
33         const char *s;
34         BOOL quoted;
35         size_t len=1;
36
37         if (!ptr)
38                 return(False);
39
40         s = *ptr;
41
42         /* default to simple separators */
43         if (!sep)
44                 sep = " \t\n\r";
45
46         /* find the first non sep char */
47         while (*s && strchr_m(sep,*s))
48                 s++;
49         
50         /* nothing left? */
51         if (! *s)
52                 return(False);
53         
54         /* copy over the token */
55         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
56                 if (*s == '\"') {
57                         quoted = !quoted;
58                 } else {
59                         len++;
60                         *buff++ = *s;
61                 }
62         }
63         
64         *ptr = (*s) ? s+1 : s;  
65         *buff = 0;
66         
67         return(True);
68 }
69
70 /**
71 This is like next_token but is not re-entrant and "remembers" the first 
72 parameter so you can pass NULL. This is useful for user interface code
73 but beware the fact that it is not re-entrant!
74 **/
75
76 static char *last_ptr=NULL;
77
78 BOOL next_token_nr(const char **ptr, char *buff, const char *sep, size_t bufsize)
79 {
80         BOOL ret;
81         if (!ptr)
82                 ptr = (const char **)&last_ptr;
83
84         ret = next_token(ptr, buff, sep, bufsize);
85         last_ptr = *ptr;
86         return ret;     
87 }
88
89 static uint16 tmpbuf[sizeof(pstring)];
90
91 void set_first_token(char *ptr)
92 {
93         last_ptr = ptr;
94 }
95
96 /**
97  Convert list of tokens to array; dependent on above routine.
98  Uses last_ptr from above - bit of a hack.
99 **/
100
101 char **toktocliplist(int *ctok, const char *sep)
102 {
103         char *s=last_ptr;
104         int ictok=0;
105         char **ret, **iret;
106
107         if (!sep)
108                 sep = " \t\n\r";
109
110         while(*s && strchr_m(sep,*s))
111                 s++;
112
113         /* nothing left? */
114         if (!*s)
115                 return(NULL);
116
117         do {
118                 ictok++;
119                 while(*s && (!strchr_m(sep,*s)))
120                         s++;
121                 while(*s && strchr_m(sep,*s))
122                         *s++=0;
123         } while(*s);
124         
125         *ctok=ictok;
126         s=last_ptr;
127         
128         if (!(ret=iret=malloc(ictok*sizeof(char *))))
129                 return NULL;
130         
131         while(ictok--) {    
132                 *iret++=s;
133                 while(*s++)
134                         ;
135                 while(!*s)
136                         s++;
137         }
138
139         return ret;
140 }
141
142 /**
143  Case insensitive string compararison.
144 **/
145
146 int StrCaseCmp(const char *s, const char *t)
147 {
148         pstring buf1, buf2;
149         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
150         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
151         return strcmp(buf1,buf2);
152 }
153
154 /**
155  Case insensitive string compararison, length limited.
156 **/
157
158 int StrnCaseCmp(const char *s, const char *t, size_t n)
159 {
160         pstring buf1, buf2;
161         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
162         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
163         return strncmp(buf1,buf2,n);
164 }
165
166 /**
167  * Compare 2 strings.
168  *
169  * @note The comparison is case-insensitive.
170  **/
171 BOOL strequal(const char *s1, const char *s2)
172 {
173         if (s1 == s2)
174                 return(True);
175         if (!s1 || !s2)
176                 return(False);
177   
178         return(StrCaseCmp(s1,s2)==0);
179 }
180
181 /**
182  * Compare 2 strings up to and including the nth char.
183  *
184  * @note The comparison is case-insensitive.
185  **/
186 BOOL strnequal(const char *s1,const char *s2,size_t n)
187 {
188   if (s1 == s2)
189           return(True);
190   if (!s1 || !s2 || !n)
191           return(False);
192   
193   return(StrnCaseCmp(s1,s2,n)==0);
194 }
195
196 /**
197  Compare 2 strings (case sensitive).
198 **/
199
200 BOOL strcsequal(const char *s1,const char *s2)
201 {
202   if (s1 == s2)
203           return(True);
204   if (!s1 || !s2)
205           return(False);
206   
207   return(strcmp(s1,s2)==0);
208 }
209
210 /**
211 Do a case-insensitive, whitespace-ignoring string compare.
212 **/
213
214 int strwicmp(const char *psz1, const char *psz2)
215 {
216         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
217         /* appropriate value. */
218         if (psz1 == psz2)
219                 return (0);
220         else if (psz1 == NULL)
221                 return (-1);
222         else if (psz2 == NULL)
223                 return (1);
224
225         /* sync the strings on first non-whitespace */
226         while (1) {
227                 while (isspace((int)*psz1))
228                         psz1++;
229                 while (isspace((int)*psz2))
230                         psz2++;
231                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
232                     || *psz2 == '\0')
233                         break;
234                 psz1++;
235                 psz2++;
236         }
237         return (*psz1 - *psz2);
238 }
239
240 /**
241  Convert a string to upper case, but don't modify it.
242 **/
243
244 char *strupper_talloc(TALLOC_CTX *mem_ctx, const char *s)
245 {
246         char *str;
247
248         str = talloc_strdup(mem_ctx, s);
249         strupper(str);
250
251         return str;
252 }
253
254
255 /**
256  String replace.
257  NOTE: oldc and newc must be 7 bit characters
258 **/
259
260 void string_replace(char *s,char oldc,char newc)
261 {
262         if (strchr(s, oldc)) {
263                 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
264                 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
265                 pull_ucs2(NULL, s, tmpbuf, strlen(s)+1, sizeof(tmpbuf), STR_TERMINATE);
266         }
267 }
268
269 /**
270  Skip past some strings in a buffer.
271 **/
272
273 char *skip_string(char *buf,size_t n)
274 {
275         while (n--)
276                 buf += strlen(buf) + 1;
277         return(buf);
278 }
279
280 /**
281  Count the number of characters in a string. Normally this will
282  be the same as the number of bytes in a string for single byte strings,
283  but will be different for multibyte.
284 **/
285
286 size_t str_charnum(const char *s)
287 {
288         uint16 tmpbuf2[sizeof(pstring)];
289         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
290         return strlen_w(tmpbuf2);
291 }
292
293 /**
294  Count the number of characters in a string. Normally this will
295  be the same as the number of bytes in a string for single byte strings,
296  but will be different for multibyte.
297 **/
298
299 size_t str_ascii_charnum(const char *s)
300 {
301         pstring tmpbuf2;
302         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
303         return strlen(tmpbuf2);
304 }
305
306 /**
307  Trim the specified elements off the front and back of a string.
308 **/
309
310 BOOL trim_string(char *s,const char *front,const char *back)
311 {
312         BOOL ret = False;
313         size_t front_len;
314         size_t back_len;
315         size_t len;
316
317         /* Ignore null or empty strings. */
318         if (!s || (s[0] == '\0'))
319                 return False;
320
321         front_len       = front? strlen(front) : 0;
322         back_len        = back? strlen(back) : 0;
323
324         len = strlen(s);
325
326         if (front_len) {
327                 while (len && strncmp(s, front, front_len)==0) {
328                         memcpy(s, s+front_len, (len-front_len)+1);
329                         len -= front_len;
330                         ret=True;
331                 }
332         }
333         
334         if (back_len) {
335                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
336                         s[len-back_len]='\0';
337                         len -= back_len;
338                         ret=True;
339                 }
340         }
341         return ret;
342 }
343
344 /**
345  Does a string have any uppercase chars in it?
346 **/
347
348 BOOL strhasupper(const char *s)
349 {
350         smb_ucs2_t *ptr;
351         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
352         for(ptr=tmpbuf;*ptr;ptr++)
353                 if(isupper_w(*ptr))
354                         return True;
355         return(False);
356 }
357
358 /**
359  Does a string have any lowercase chars in it?
360 **/
361
362 BOOL strhaslower(const char *s)
363 {
364         smb_ucs2_t *ptr;
365         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
366         for(ptr=tmpbuf;*ptr;ptr++)
367                 if(islower_w(*ptr))
368                         return True;
369         return(False);
370 }
371
372 /**
373  Find the number of 'c' chars in a string
374 **/
375
376 size_t count_chars(const char *s,char c)
377 {
378         smb_ucs2_t *ptr;
379         int count;
380         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
381         for(count=0,ptr=tmpbuf;*ptr;ptr++)
382                 if(*ptr==UCS2_CHAR(c))
383                         count++;
384         return(count);
385 }
386
387 /**
388 Return True if a string consists only of one particular character.
389 **/
390
391 BOOL str_is_all(const char *s,char c)
392 {
393         smb_ucs2_t *ptr;
394
395         if(s == NULL)
396                 return False;
397         if(!*s)
398                 return False;
399   
400         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
401         for(ptr=tmpbuf;*ptr;ptr++)
402                 if(*ptr!=UCS2_CHAR(c))
403                         return False;
404
405         return True;
406 }
407
408 /**
409  Safe string copy into a known length string. maxlength does not
410  include the terminating zero.
411 **/
412
413 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
414 {
415         size_t len;
416
417         if (!dest) {
418                 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
419                 return NULL;
420         }
421
422 #ifdef DEVELOPER
423         /* We intentionally write out at the extremity of the destination
424          * string.  If the destination is too short (e.g. pstrcpy into mallocd
425          * or fstring) then this should cause an error under a memory
426          * checker. */
427         dest[maxlength] = '\0';
428         if (PTR_DIFF(&len, dest) > 0) {  /* check if destination is on the stack, ok if so */
429                 log_suspicious_usage("safe_strcpy", src);
430         }
431 #endif
432
433         if (!src) {
434                 *dest = 0;
435                 return dest;
436         }  
437
438         len = strlen(src);
439
440         if (len > maxlength) {
441                 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
442                          (unsigned int)(len-maxlength), len, maxlength, src));
443                 len = maxlength;
444         }
445       
446         memmove(dest, src, len);
447         dest[len] = 0;
448         return dest;
449 }  
450
451 /**
452  Safe string cat into a string. maxlength does not
453  include the terminating zero.
454 **/
455
456 char *safe_strcat(char *dest, const char *src, size_t maxlength)
457 {
458         size_t src_len, dest_len;
459
460         if (!dest) {
461                 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
462                 return NULL;
463         }
464
465         if (!src)
466                 return dest;
467         
468 #ifdef DEVELOPER
469         if (PTR_DIFF(&src_len, dest) > 0) {  /* check if destination is on the stack, ok if so */
470                 log_suspicious_usage("safe_strcat", src);
471         }
472 #endif
473         src_len = strlen(src);
474         dest_len = strlen(dest);
475
476         if (src_len + dest_len > maxlength) {
477                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
478                          (int)(src_len + dest_len - maxlength), src));
479                 if (maxlength > dest_len) {
480                         memcpy(&dest[dest_len], src, maxlength - dest_len);
481                 }
482                 dest[maxlength] = 0;
483                 return NULL;
484         }
485         
486         memcpy(&dest[dest_len], src, src_len);
487         dest[dest_len + src_len] = 0;
488         return dest;
489 }
490
491 /**
492  Paranoid strcpy into a buffer of given length (includes terminating
493  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
494  and replaces with '_'. Deliberately does *NOT* check for multibyte
495  characters. Don't change it !
496 **/
497
498 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
499 {
500         size_t len, i;
501
502         if (maxlength == 0) {
503                 /* can't fit any bytes at all! */
504                 return NULL;
505         }
506
507         if (!dest) {
508                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
509                 return NULL;
510         }
511
512         if (!src) {
513                 *dest = 0;
514                 return dest;
515         }  
516
517         len = strlen(src);
518         if (len >= maxlength)
519                 len = maxlength - 1;
520
521         if (!other_safe_chars)
522                 other_safe_chars = "";
523
524         for(i = 0; i < len; i++) {
525                 int val = (src[i] & 0xff);
526                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
527                         dest[i] = src[i];
528                 else
529                         dest[i] = '_';
530         }
531
532         dest[i] = '\0';
533
534         return dest;
535 }
536
537 /**
538  Like strncpy but always null terminates. Make sure there is room!
539  The variable n should always be one less than the available size.
540 **/
541
542 char *StrnCpy(char *dest,const char *src,size_t n)
543 {
544         char *d = dest;
545         if (!dest)
546                 return(NULL);
547         if (!src) {
548                 *dest = 0;
549                 return(dest);
550         }
551         while (n-- && (*d++ = *src++))
552                 ;
553         *d = 0;
554         return(dest);
555 }
556
557 /**
558  Like strncpy but copies up to the character marker.  always null terminates.
559  returns a pointer to the character marker in the source string (src).
560 **/
561
562 char *strncpyn(char *dest, const char *src, size_t n, char c)
563 {
564         char *p;
565         size_t str_len;
566
567         p = strchr_m(src, c);
568         if (p == NULL) {
569                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
570                 return NULL;
571         }
572
573         str_len = PTR_DIFF(p, src);
574         strncpy(dest, src, MIN(n, str_len));
575         dest[str_len] = '\0';
576
577         return p;
578 }
579
580 /**
581  Routine to get hex characters and turn them into a 16 byte array.
582  the array can be variable length, and any non-hex-numeric
583  characters are skipped.  "0xnn" or "0Xnn" is specially catered
584  for.
585
586  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
587
588 **/
589
590 size_t strhex_to_str(char *p, size_t len, const char *strhex)
591 {
592         size_t i;
593         size_t num_chars = 0;
594         unsigned char   lonybble, hinybble;
595         const char     *hexchars = "0123456789ABCDEF";
596         char           *p1 = NULL, *p2 = NULL;
597
598         for (i = 0; i < len && strhex[i] != 0; i++) {
599                 if (strnequal(hexchars, "0x", 2)) {
600                         i++; /* skip two chars */
601                         continue;
602                 }
603
604                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
605                         break;
606
607                 i++; /* next hex digit */
608
609                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
610                         break;
611
612                 /* get the two nybbles */
613                 hinybble = PTR_DIFF(p1, hexchars);
614                 lonybble = PTR_DIFF(p2, hexchars);
615
616                 p[num_chars] = (hinybble << 4) | lonybble;
617                 num_chars++;
618
619                 p1 = NULL;
620                 p2 = NULL;
621         }
622         return num_chars;
623 }
624
625 /**
626  Check if a string is part of a list.
627 **/
628
629 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
630 {
631         pstring tok;
632         const char *p=list;
633
634         if (!list)
635                 return(False);
636
637         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
638                 if (casesensitive) {
639                         if (strcmp(tok,s) == 0)
640                                 return(True);
641                 } else {
642                         if (StrCaseCmp(tok,s) == 0)
643                                 return(True);
644                 }
645         }
646         return(False);
647 }
648
649 /**
650  Set a string value, allocing the space for the string
651 **/
652 static BOOL string_init(char **dest,const char *src)
653 {
654         if (!src) src = "";
655
656         (*dest) = strdup(src);
657         if ((*dest) == NULL) {
658                 DEBUG(0,("Out of memory in string_init\n"));
659                 return False;
660         }
661         return True;
662 }
663
664 /**
665  Free a string value.
666 **/
667 void string_free(char **s)
668 {
669         if (s) SAFE_FREE(*s);
670 }
671
672 /**
673  Set a string value, deallocating any existing space, and allocing the space
674  for the string
675 **/
676 BOOL string_set(char **dest, const char *src)
677 {
678         string_free(dest);
679         return string_init(dest,src);
680 }
681
682 /**
683  Substitute a string for a pattern in another string. Make sure there is 
684  enough room!
685
686  This routine looks for pattern in s and replaces it with 
687  insert. It may do multiple replacements.
688
689  Any of " ; ' $ or ` in the insert string are replaced with _
690  if len==0 then the string cannot be extended. This is different from the old
691  use of len==0 which was for no length checks to be done.
692 **/
693
694 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
695 {
696         char *p;
697         ssize_t ls,lp,li, i;
698
699         if (!insert || !pattern || !*pattern || !s)
700                 return;
701
702         ls = (ssize_t)strlen(s);
703         lp = (ssize_t)strlen(pattern);
704         li = (ssize_t)strlen(insert);
705
706         if (len == 0)
707                 len = ls + 1; /* len is number of *bytes* */
708
709         while (lp <= ls && (p = strstr(s,pattern))) {
710                 if (ls + (li-lp) >= len) {
711                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
712                                  (int)(ls + (li-lp) - len),
713                                  pattern, (int)len));
714                         break;
715                 }
716                 if (li != lp) {
717                         memmove(p+li,p+lp,strlen(p+lp)+1);
718                 }
719                 for (i=0;i<li;i++) {
720                         switch (insert[i]) {
721                         case '`':
722                         case '"':
723                         case '\'':
724                         case ';':
725                         case '$':
726                         case '%':
727                         case '\r':
728                         case '\n':
729                                 p[i] = '_';
730                                 break;
731                         default:
732                                 p[i] = insert[i];
733                         }
734                 }
735                 s = p + li;
736                 ls += (li-lp);
737         }
738 }
739
740 void pstring_sub(char *s,const char *pattern,const char *insert)
741 {
742         string_sub(s, pattern, insert, sizeof(pstring));
743 }
744
745 /**
746  Similar to string_sub, but it will accept only allocated strings
747  and may realloc them so pay attention at what you pass on no
748  pointers inside strings, no pstrings or const may be passed
749  as string.
750 **/
751
752 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
753 {
754         char *p, *in;
755         char *s;
756         ssize_t ls,lp,li,ld, i;
757
758         if (!insert || !pattern || !*pattern || !string || !*string)
759                 return NULL;
760
761         s = string;
762
763         in = strdup(insert);
764         if (!in) {
765                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
766                 return NULL;
767         }
768         ls = (ssize_t)strlen(s);
769         lp = (ssize_t)strlen(pattern);
770         li = (ssize_t)strlen(insert);
771         ld = li - lp;
772         for (i=0;i<li;i++) {
773                 switch (in[i]) {
774                         case '`':
775                         case '"':
776                         case '\'':
777                         case ';':
778                         case '$':
779                         case '%':
780                         case '\r':
781                         case '\n':
782                                 in[i] = '_';
783                         default:
784                                 /* ok */
785                                 break;
786                 }
787         }
788         
789         while ((p = strstr(s,pattern))) {
790                 if (ld > 0) {
791                         char *t = Realloc(string, ls + ld + 1);
792                         if (!t) {
793                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
794                                 SAFE_FREE(in);
795                                 return NULL;
796                         }
797                         string = t;
798                         p = t + (p - s);
799                 }
800                 if (li != lp) {
801                         memmove(p+li,p+lp,strlen(p+lp)+1);
802                 }
803                 memcpy(p, in, li);
804                 s = p + li;
805                 ls += ld;
806         }
807         SAFE_FREE(in);
808         return string;
809 }
810
811 /**
812  Similar to string_sub() but allows for any character to be substituted. 
813  Use with caution!
814  if len==0 then the string cannot be extended. This is different from the old
815  use of len==0 which was for no length checks to be done.
816 **/
817
818 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
819 {
820         char *p;
821         ssize_t ls,lp,li;
822
823         if (!insert || !pattern || !s)
824                 return;
825
826         ls = (ssize_t)strlen(s);
827         lp = (ssize_t)strlen(pattern);
828         li = (ssize_t)strlen(insert);
829
830         if (!*pattern)
831                 return;
832         
833         if (len == 0)
834                 len = ls + 1; /* len is number of *bytes* */
835         
836         while (lp <= ls && (p = strstr(s,pattern))) {
837                 if (ls + (li-lp) >= len) {
838                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
839                                  (int)(ls + (li-lp) - len),
840                                  pattern, (int)len));
841                         break;
842                 }
843                 if (li != lp) {
844                         memmove(p+li,p+lp,strlen(p+lp)+1);
845                 }
846                 memcpy(p, insert, li);
847                 s = p + li;
848                 ls += (li-lp);
849         }
850 }
851
852 /**
853  Splits out the front and back at a separator.
854 **/
855
856 void split_at_last_component(char *path, char *front, char sep, char *back)
857 {
858         char *p = strrchr_m(path, sep);
859
860         if (p != NULL)
861                 *p = 0;
862
863         if (front != NULL)
864                 pstrcpy(front, path);
865
866         if (p != NULL) {
867                 if (back != NULL)
868                         pstrcpy(back, p+1);
869                 *p = '\\';
870         } else {
871                 if (back != NULL)
872                         back[0] = 0;
873         }
874 }
875
876 /**
877  Write an octal as a string.
878 **/
879
880 const char *octal_string(int i)
881 {
882         static char ret[64];
883         if (i == -1)
884                 return "-1";
885         slprintf(ret, sizeof(ret)-1, "0%o", i);
886         return ret;
887 }
888
889
890 /**
891  Truncate a string at a specified length.
892 **/
893
894 char *string_truncate(char *s, int length)
895 {
896         if (s && strlen(s) > length)
897                 s[length] = 0;
898         return s;
899 }
900
901 /**
902  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
903  We convert via ucs2 for now.
904 **/
905
906 char *strchr_m(const char *s, char c)
907 {
908         wpstring ws;
909         pstring s2;
910         smb_ucs2_t *p;
911
912         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
913         p = strchr_w(ws, UCS2_CHAR(c));
914         if (!p)
915                 return NULL;
916         *p = 0;
917         pull_ucs2_pstring(s2, ws);
918         return (char *)(s+strlen(s2));
919 }
920
921 char *strrchr_m(const char *s, char c)
922 {
923         wpstring ws;
924         pstring s2;
925         smb_ucs2_t *p;
926
927         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
928         p = strrchr_w(ws, UCS2_CHAR(c));
929         if (!p)
930                 return NULL;
931         *p = 0;
932         pull_ucs2_pstring(s2, ws);
933         return (char *)(s+strlen(s2));
934 }
935
936 /**
937  Convert a string to lower case.
938 **/
939
940 void strlower_m(char *s)
941 {
942         /* this is quite a common operation, so we want it to be
943            fast. We optimise for the ascii case, knowing that all our
944            supported multi-byte character sets are ascii-compatible
945            (ie. they match for the first 128 chars) */
946
947         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
948                 *s = tolower((unsigned char)*s);
949                 s++;
950         }
951
952         if (!*s)
953                 return;
954
955         /* I assume that lowercased string takes the same number of bytes
956          * as source string even in UTF-8 encoding. (VIV) */
957         unix_strlower(s,strlen(s)+1,s,strlen(s)+1);     
958 }
959
960 /**
961  Duplicate convert a string to lower case.
962 **/
963
964 char *strdup_lower(const char *s)
965 {
966         char *t = strdup(s);
967         if (t == NULL) {
968                 DEBUG(0, ("strdup_lower: Out of memory!\n"));
969                 return NULL;
970         }
971         strlower_m(t);
972         return t;
973 }
974
975 /**
976  Convert a string to upper case.
977 **/
978
979 void strupper_m(char *s)
980 {
981         /* this is quite a common operation, so we want it to be
982            fast. We optimise for the ascii case, knowing that all our
983            supported multi-byte character sets are ascii-compatible
984            (ie. they match for the first 128 chars) */
985
986         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
987                 *s = toupper((unsigned char)*s);
988                 s++;
989         }
990
991         if (!*s)
992                 return;
993
994         /* I assume that lowercased string takes the same number of bytes
995          * as source string even in multibyte encoding. (VIV) */
996         unix_strupper(s,strlen(s)+1,s,strlen(s)+1);     
997 }
998
999
1000 /**
1001    work out the number of multibyte chars in a string
1002 **/
1003 size_t strlen_m(const char *s)
1004 {
1005         size_t count = 0;
1006
1007         if (!s) {
1008                 return 0;
1009         }
1010
1011         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1012                 s++;
1013                 count++;
1014         }
1015
1016         if (!*s) {
1017                 return count;
1018         }
1019
1020         push_ucs2(NULL,tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
1021         return count + strlen_w(tmpbuf);
1022 }
1023
1024 /**
1025    Work out the number of multibyte chars in a string, including the NULL
1026    terminator.
1027 **/
1028 size_t strlen_m_term(const char *s)
1029 {
1030         if (!s) {
1031                 return 0;
1032         }
1033
1034         return strlen_m(s) + 1;
1035 }
1036
1037 /**
1038  Convert a string to upper case.
1039 **/
1040
1041 char *strdup_upper(const char *s)
1042 {
1043         char *t = strdup(s);
1044         if (t == NULL) {
1045                 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1046                 return NULL;
1047         }
1048         strupper_m(t);
1049         return t;
1050 }
1051
1052 /**
1053  Return a RFC2254 binary string representation of a buffer.
1054  Used in LDAP filters.
1055  Caller must free.
1056 **/
1057
1058 char *binary_string(char *buf, int len)
1059 {
1060         char *s;
1061         int i, j;
1062         const char *hex = "0123456789ABCDEF";
1063         s = malloc(len * 3 + 1);
1064         if (!s)
1065                 return NULL;
1066         for (j=i=0;i<len;i++) {
1067                 s[j] = '\\';
1068                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1069                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1070                 j += 3;
1071         }
1072         s[j] = 0;
1073         return s;
1074 }
1075
1076 /**
1077  Just a typesafety wrapper for snprintf into a pstring.
1078 **/
1079
1080  int pstr_sprintf(pstring s, const char *fmt, ...)
1081 {
1082         va_list ap;
1083         int ret;
1084
1085         va_start(ap, fmt);
1086         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1087         va_end(ap);
1088         return ret;
1089 }
1090
1091 #ifndef HAVE_STRNDUP
1092 /**
1093  Some platforms don't have strndup.
1094 **/
1095  char *strndup(const char *s, size_t n)
1096 {
1097         char *ret;
1098         
1099         n = strnlen(s, n);
1100         ret = malloc(n+1);
1101         if (!ret)
1102                 return NULL;
1103         memcpy(ret, s, n);
1104         ret[n] = 0;
1105
1106         return ret;
1107 }
1108 #endif
1109
1110 #ifndef HAVE_STRNLEN
1111 /**
1112  Some platforms don't have strnlen
1113 **/
1114  size_t strnlen(const char *s, size_t n)
1115 {
1116         int i;
1117         for (i=0; s[i] && i<n; i++)
1118                 /* noop */ ;
1119         return i;
1120 }
1121 #endif
1122
1123 /**
1124  List of Strings manipulation functions
1125 **/
1126
1127 #define S_LIST_ABS 16 /* List Allocation Block Size */
1128
1129 char **str_list_make(const char *string, const char *sep)
1130 {
1131         char **list, **rlist;
1132         const char *str;
1133         char *s;
1134         int num, lsize;
1135         pstring tok;
1136         
1137         if (!string || !*string)
1138                 return NULL;
1139         s = strdup(string);
1140         if (!s) {
1141                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1142                 return NULL;
1143         }
1144         if (!sep) sep = LIST_SEP;
1145         
1146         num = lsize = 0;
1147         list = NULL;
1148         
1149         str = s;
1150         while (next_token(&str, tok, sep, sizeof(tok))) {               
1151                 if (num == lsize) {
1152                         lsize += S_LIST_ABS;
1153                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1154                         if (!rlist) {
1155                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1156                                 str_list_free(&list);
1157                                 SAFE_FREE(s);
1158                                 return NULL;
1159                         } else
1160                                 list = rlist;
1161                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1162                 }
1163                 
1164                 list[num] = strdup(tok);
1165                 if (!list[num]) {
1166                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1167                         str_list_free(&list);
1168                         SAFE_FREE(s);
1169                         return NULL;
1170                 }
1171         
1172                 num++;  
1173         }
1174         
1175         SAFE_FREE(s);
1176         return list;
1177 }
1178
1179 BOOL str_list_copy(char ***dest, const char **src)
1180 {
1181         char **list, **rlist;
1182         int num, lsize;
1183         
1184         *dest = NULL;
1185         if (!src)
1186                 return False;
1187         
1188         num = lsize = 0;
1189         list = NULL;
1190                 
1191         while (src[num]) {
1192                 if (num == lsize) {
1193                         lsize += S_LIST_ABS;
1194                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1195                         if (!rlist) {
1196                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1197                                 str_list_free(&list);
1198                                 return False;
1199                         } else
1200                                 list = rlist;
1201                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1202                 }
1203                 
1204                 list[num] = strdup(src[num]);
1205                 if (!list[num]) {
1206                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1207                         str_list_free(&list);
1208                         return False;
1209                 }
1210
1211                 num++;
1212         }
1213         
1214         *dest = list;
1215         return True;    
1216 }
1217
1218 /**
1219  * Return true if all the elements of the list match exactly.
1220  **/
1221 BOOL str_list_compare(char **list1, char **list2)
1222 {
1223         int num;
1224         
1225         if (!list1 || !list2)
1226                 return (list1 == list2); 
1227         
1228         for (num = 0; list1[num]; num++) {
1229                 if (!list2[num])
1230                         return False;
1231                 if (!strcsequal(list1[num], list2[num]))
1232                         return False;
1233         }
1234         if (list2[num])
1235                 return False; /* if list2 has more elements than list1 fail */
1236         
1237         return True;
1238 }
1239
1240 void str_list_free(char ***list)
1241 {
1242         char **tlist;
1243         
1244         if (!list || !*list)
1245                 return;
1246         tlist = *list;
1247         for(; *tlist; tlist++)
1248                 SAFE_FREE(*tlist);
1249         SAFE_FREE(*list);
1250 }
1251
1252 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1253 {
1254         char *p, *s, *t;
1255         ssize_t ls, lp, li, ld, i, d;
1256
1257         if (!list)
1258                 return False;
1259         if (!pattern)
1260                 return False;
1261         if (!insert)
1262                 return False;
1263
1264         lp = (ssize_t)strlen(pattern);
1265         li = (ssize_t)strlen(insert);
1266         ld = li -lp;
1267                         
1268         while (*list) {
1269                 s = *list;
1270                 ls = (ssize_t)strlen(s);
1271
1272                 while ((p = strstr(s, pattern))) {
1273                         t = *list;
1274                         d = p -t;
1275                         if (ld) {
1276                                 t = (char *) malloc(ls +ld +1);
1277                                 if (!t) {
1278                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1279                                         return False;
1280                                 }
1281                                 memcpy(t, *list, d);
1282                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1283                                 SAFE_FREE(*list);
1284                                 *list = t;
1285                                 ls += ld;
1286                                 s = t +d +li;
1287                         }
1288                         
1289                         for (i = 0; i < li; i++) {
1290                                 switch (insert[i]) {
1291                                         case '`':
1292                                         case '"':
1293                                         case '\'':
1294                                         case ';':
1295                                         case '$':
1296                                         case '%':
1297                                         case '\r':
1298                                         case '\n':
1299                                                 t[d +i] = '_';
1300                                                 break;
1301                                         default:
1302                                                 t[d +i] = insert[i];
1303                                 }
1304                         }       
1305                 }
1306                 
1307                 list++;
1308         }
1309         
1310         return True;
1311 }
1312
1313
1314 #define IPSTR_LIST_SEP  ","
1315
1316 /**
1317  * Add ip string representation to ipstr list. Used also
1318  * as part of @function ipstr_list_make
1319  *
1320  * @param ipstr_list pointer to string containing ip list;
1321  *        MUST BE already allocated and IS reallocated if necessary
1322  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1323  *        as a result of reallocation)
1324  * @param ip IP address which is to be added to list
1325  * @return pointer to string appended with new ip and possibly
1326  *         reallocated to new length
1327  **/
1328
1329 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1330 {
1331         char* new_ipstr = NULL;
1332         
1333         /* arguments checking */
1334         if (!ipstr_list || !ip) return NULL;
1335
1336         /* attempt to convert ip to a string and append colon separator to it */
1337         if (*ipstr_list) {
1338                 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1339                 SAFE_FREE(*ipstr_list);
1340         } else {
1341                 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1342         }
1343         *ipstr_list = new_ipstr;
1344         return *ipstr_list;
1345 }
1346
1347
1348 /**
1349  * Allocate and initialise an ipstr list using ip adresses
1350  * passed as arguments.
1351  *
1352  * @param ipstr_list pointer to string meant to be allocated and set
1353  * @param ip_list array of ip addresses to place in the list
1354  * @param ip_count number of addresses stored in ip_list
1355  * @return pointer to allocated ip string
1356  **/
1357  
1358 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1359 {
1360         int i;
1361         
1362         /* arguments checking */
1363         if (!ip_list && !ipstr_list) return 0;
1364
1365         *ipstr_list = NULL;
1366         
1367         /* process ip addresses given as arguments */
1368         for (i = 0; i < ip_count; i++)
1369                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1370         
1371         return (*ipstr_list);
1372 }
1373
1374
1375 /**
1376  * Parse given ip string list into array of ip addresses
1377  * (as in_addr structures)
1378  *
1379  * @param ipstr ip string list to be parsed 
1380  * @param ip_list pointer to array of ip addresses which is
1381  *        allocated by this function and must be freed by caller
1382  * @return number of succesfully parsed addresses
1383  **/
1384  
1385 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1386 {
1387         fstring token_str;
1388         int count;
1389
1390         if (!ipstr_list || !ip_list) return 0;
1391         
1392         for (*ip_list = NULL, count = 0;
1393              next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1394              count++) {
1395              
1396                 struct in_addr addr;
1397
1398                 /* convert single token to ip address */
1399                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1400                         break;
1401                 
1402                 /* prepare place for another in_addr structure */
1403                 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1404                 if (!*ip_list) return -1;
1405                 
1406                 (*ip_list)[count] = addr;
1407         }
1408         
1409         return count;
1410 }
1411
1412
1413 /**
1414  * Safely free ip string list
1415  *
1416  * @param ipstr_list ip string list to be freed
1417  **/
1418
1419 void ipstr_list_free(char* ipstr_list)
1420 {
1421         SAFE_FREE(ipstr_list);
1422 }
1423
1424
1425 /**
1426  Unescape a URL encoded string, in place.
1427 **/
1428
1429 void rfc1738_unescape(char *buf)
1430 {
1431         char *p=buf;
1432
1433         while ((p=strchr_m(p,'+')))
1434                 *p = ' ';
1435
1436         p = buf;
1437
1438         while (p && *p && (p=strchr_m(p,'%'))) {
1439                 int c1 = p[1];
1440                 int c2 = p[2];
1441
1442                 if (c1 >= '0' && c1 <= '9')
1443                         c1 = c1 - '0';
1444                 else if (c1 >= 'A' && c1 <= 'F')
1445                         c1 = 10 + c1 - 'A';
1446                 else if (c1 >= 'a' && c1 <= 'f')
1447                         c1 = 10 + c1 - 'a';
1448                 else {p++; continue;}
1449
1450                 if (c2 >= '0' && c2 <= '9')
1451                         c2 = c2 - '0';
1452                 else if (c2 >= 'A' && c2 <= 'F')
1453                         c2 = 10 + c2 - 'A';
1454                 else if (c2 >= 'a' && c2 <= 'f')
1455                         c2 = 10 + c2 - 'a';
1456                 else {p++; continue;}
1457                         
1458                 *p = (c1<<4) | c2;
1459
1460                 memmove(p+1, p+3, strlen(p+3)+1);
1461                 p++;
1462         }
1463 }
1464
1465 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1466
1467 /**
1468  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1469  **/
1470 DATA_BLOB base64_decode_data_blob(const char *s)
1471 {
1472         int bit_offset, byte_offset, idx, i, n;
1473         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1474         unsigned char *d = decoded.data;
1475         char *p;
1476
1477         n=i=0;
1478
1479         while (*s && (p=strchr_m(b64,*s))) {
1480                 idx = (int)(p - b64);
1481                 byte_offset = (i*6)/8;
1482                 bit_offset = (i*6)%8;
1483                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1484                 if (bit_offset < 3) {
1485                         d[byte_offset] |= (idx << (2-bit_offset));
1486                         n = byte_offset+1;
1487                 } else {
1488                         d[byte_offset] |= (idx >> (bit_offset-2));
1489                         d[byte_offset+1] = 0;
1490                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1491                         n = byte_offset+2;
1492                 }
1493                 s++; i++;
1494         }
1495
1496         /* fix up length */
1497         decoded.length = n;
1498         return decoded;
1499 }
1500
1501 /**
1502  * Decode a base64 string in-place - wrapper for the above
1503  **/
1504 void base64_decode_inplace(char *s)
1505 {
1506         DATA_BLOB decoded = base64_decode_data_blob(s);
1507         memcpy(s, decoded.data, decoded.length);
1508         data_blob_free(&decoded);
1509
1510         /* null terminate */
1511         s[decoded.length] = '\0';
1512 }
1513
1514 /**
1515  * Encode a base64 string into a malloc()ed string caller to free.
1516  *
1517  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1518  **/
1519 char * base64_encode_data_blob(DATA_BLOB data)
1520 {
1521         int bits = 0;
1522         int char_count = 0;
1523         size_t out_cnt = 0;
1524         size_t len = data.length;
1525         size_t output_len = data.length * 2;
1526         char *result = malloc(output_len); /* get us plenty of space */
1527
1528         while (len-- && out_cnt < (data.length * 2) - 5) {
1529                 int c = (unsigned char) *(data.data++);
1530                 bits += c;
1531                 char_count++;
1532                 if (char_count == 3) {
1533                         result[out_cnt++] = b64[bits >> 18];
1534                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1535                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1536             result[out_cnt++] = b64[bits & 0x3f];
1537             bits = 0;
1538             char_count = 0;
1539         } else {
1540             bits <<= 8;
1541         }
1542     }
1543     if (char_count != 0) {
1544         bits <<= 16 - (8 * char_count);
1545         result[out_cnt++] = b64[bits >> 18];
1546         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1547         if (char_count == 1) {
1548             result[out_cnt++] = '=';
1549             result[out_cnt++] = '=';
1550         } else {
1551             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1552             result[out_cnt++] = '=';
1553         }
1554     }
1555     result[out_cnt] = '\0';     /* terminate */
1556     return result;
1557 }
1558
1559 #ifdef VALGRIND
1560 size_t valgrind_strlen(const char *s)
1561 {
1562         size_t count;
1563         for(count = 0; *s++; count++)
1564                 ;
1565         return count;
1566 }
1567 #endif