c1f3a620fc5773326872cb43a55aa7a89eed0ba1
[tprouty/samba.git] / source / 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    Copyright (C) James Peach     2006
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 /**
28  * @file
29  * @brief String utilities.
30  **/
31
32 /**
33  * Internal function to get the next token from a string, return False if none
34  * found.  Handles double-quotes.  This is the work horse function called by
35  * next_token() and next_token_no_ltrim().
36  *
37  * Based on a routine by GJC@VILLAGE.COM. 
38  * Extensively modified by Andrew.Tridgell@anu.edu.au
39  */
40 static BOOL next_token_internal(const char **ptr,
41                                 char *buff,
42                                 const char *sep,
43                                 size_t bufsize,
44                                 BOOL ltrim)
45 {
46         char *s;
47         char *pbuf;
48         BOOL quoted;
49         size_t len=1;
50
51         if (!ptr)
52                 return(False);
53
54         s = (char *)*ptr;
55
56         /* default to simple separators */
57         if (!sep)
58                 sep = " \t\n\r";
59
60         /* find the first non sep char, if left-trimming is requested */
61         if (ltrim) {
62                 while (*s && strchr_m(sep,*s))
63                         s++;
64         }
65         
66         /* nothing left? */
67         if (! *s)
68                 return(False);
69         
70         /* copy over the token */
71         pbuf = buff;
72         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
73                 if ( *s == '\"' ) {
74                         quoted = !quoted;
75                 } else {
76                         len++;
77                         *pbuf++ = *s;
78                 }
79         }
80         
81         *ptr = (*s) ? s+1 : s;  
82         *pbuf = 0;
83         
84         return(True);
85 }
86
87 /*
88  * Get the next token from a string, return False if none found.  Handles
89  * double-quotes.  This version trims leading separator characters before
90  * looking for a token.
91  */
92 BOOL next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
93 {
94     return next_token_internal(ptr, buff, sep, bufsize, True);
95 }
96
97 /*
98  * Get the next token from a string, return False if none found.  Handles
99  * double-quotes.  This version does not trim leading separator characters
100  * before looking for a token.
101  */
102 BOOL next_token_no_ltrim(const char **ptr,
103                          char *buff,
104                          const char *sep,
105                          size_t bufsize)
106 {
107     return next_token_internal(ptr, buff, sep, bufsize, False);
108 }
109
110 /**
111 This is like next_token but is not re-entrant and "remembers" the first 
112 parameter so you can pass NULL. This is useful for user interface code
113 but beware the fact that it is not re-entrant!
114 **/
115
116 static const char *last_ptr=NULL;
117
118 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
119 {
120         BOOL ret;
121         if (!ptr)
122                 ptr = &last_ptr;
123
124         ret = next_token(ptr, buff, sep, bufsize);
125         last_ptr = *ptr;
126         return ret;     
127 }
128
129 void set_first_token(char *ptr)
130 {
131         last_ptr = ptr;
132 }
133
134 /**
135  Convert list of tokens to array; dependent on above routine.
136  Uses last_ptr from above - bit of a hack.
137 **/
138
139 char **toktocliplist(int *ctok, const char *sep)
140 {
141         char *s=(char *)last_ptr;
142         int ictok=0;
143         char **ret, **iret;
144
145         if (!sep)
146                 sep = " \t\n\r";
147
148         while(*s && strchr_m(sep,*s))
149                 s++;
150
151         /* nothing left? */
152         if (!*s)
153                 return(NULL);
154
155         do {
156                 ictok++;
157                 while(*s && (!strchr_m(sep,*s)))
158                         s++;
159                 while(*s && strchr_m(sep,*s))
160                         *s++=0;
161         } while(*s);
162         
163         *ctok=ictok;
164         s=(char *)last_ptr;
165         
166         if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
167                 return NULL;
168         
169         while(ictok--) {    
170                 *iret++=s;
171                 if (ictok > 0) {
172                         while(*s++)
173                                 ;
174                         while(!*s)
175                                 s++;
176                 }
177         }
178
179         ret[*ctok] = NULL;
180         return ret;
181 }
182
183 /**
184  * Case insensitive string compararison.
185  *
186  * iconv does not directly give us a way to compare strings in
187  * arbitrary unix character sets -- all we can is convert and then
188  * compare.  This is expensive.
189  *
190  * As an optimization, we do a first pass that considers only the
191  * prefix of the strings that is entirely 7-bit.  Within this, we
192  * check whether they have the same value.
193  *
194  * Hopefully this will often give the answer without needing to copy.
195  * In particular it should speed comparisons to literal ascii strings
196  * or comparisons of strings that are "obviously" different.
197  *
198  * If we find a non-ascii character we fall back to converting via
199  * iconv.
200  *
201  * This should never be slower than convering the whole thing, and
202  * often faster.
203  *
204  * A different optimization would be to compare for bitwise equality
205  * in the binary encoding.  (It would be possible thought hairy to do
206  * both simultaneously.)  But in that case if they turn out to be
207  * different, we'd need to restart the whole thing.
208  *
209  * Even better is to implement strcasecmp for each encoding and use a
210  * function pointer. 
211  **/
212 int StrCaseCmp(const char *s, const char *t)
213 {
214
215         const char *ps, *pt;
216         size_t size;
217         smb_ucs2_t *buffer_s, *buffer_t;
218         int ret;
219
220         for (ps = s, pt = t; ; ps++, pt++) {
221                 char us, ut;
222
223                 if (!*ps && !*pt)
224                         return 0; /* both ended */
225                 else if (!*ps)
226                         return -1; /* s is a prefix */
227                 else if (!*pt)
228                         return +1; /* t is a prefix */
229                 else if ((*ps & 0x80) || (*pt & 0x80))
230                         /* not ascii anymore, do it the hard way from here on in */
231                         break;
232
233                 us = toupper_ascii(*ps);
234                 ut = toupper_ascii(*pt);
235                 if (us == ut)
236                         continue;
237                 else if (us < ut)
238                         return -1;
239                 else if (us > ut)
240                         return +1;
241         }
242
243         size = push_ucs2_allocate(&buffer_s, ps);
244         if (size == (size_t)-1) {
245                 return strcmp(ps, pt); 
246                 /* Not quite the right answer, but finding the right one
247                    under this failure case is expensive, and it's pretty close */
248         }
249         
250         size = push_ucs2_allocate(&buffer_t, pt);
251         if (size == (size_t)-1) {
252                 SAFE_FREE(buffer_s);
253                 return strcmp(ps, pt); 
254                 /* Not quite the right answer, but finding the right one
255                    under this failure case is expensive, and it's pretty close */
256         }
257         
258         ret = strcasecmp_w(buffer_s, buffer_t);
259         SAFE_FREE(buffer_s);
260         SAFE_FREE(buffer_t);
261         return ret;
262 }
263
264
265 /**
266  Case insensitive string compararison, length limited.
267 **/
268 int StrnCaseCmp(const char *s, const char *t, size_t n)
269 {
270         pstring buf1, buf2;
271         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
272         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
273         return strncmp(buf1,buf2,n);
274 }
275
276 /**
277  * Compare 2 strings.
278  *
279  * @note The comparison is case-insensitive.
280  **/
281 BOOL strequal(const char *s1, const char *s2)
282 {
283         if (s1 == s2)
284                 return(True);
285         if (!s1 || !s2)
286                 return(False);
287   
288         return(StrCaseCmp(s1,s2)==0);
289 }
290
291 /**
292  * Compare 2 strings up to and including the nth char.
293  *
294  * @note The comparison is case-insensitive.
295  **/
296 BOOL strnequal(const char *s1,const char *s2,size_t n)
297 {
298         if (s1 == s2)
299                 return(True);
300         if (!s1 || !s2 || !n)
301                 return(False);
302   
303         return(StrnCaseCmp(s1,s2,n)==0);
304 }
305
306 /**
307  Compare 2 strings (case sensitive).
308 **/
309
310 BOOL strcsequal(const char *s1,const char *s2)
311 {
312         if (s1 == s2)
313                 return(True);
314         if (!s1 || !s2)
315                 return(False);
316   
317         return(strcmp(s1,s2)==0);
318 }
319
320 /**
321 Do a case-insensitive, whitespace-ignoring string compare.
322 **/
323
324 int strwicmp(const char *psz1, const char *psz2)
325 {
326         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
327         /* appropriate value. */
328         if (psz1 == psz2)
329                 return (0);
330         else if (psz1 == NULL)
331                 return (-1);
332         else if (psz2 == NULL)
333                 return (1);
334
335         /* sync the strings on first non-whitespace */
336         while (1) {
337                 while (isspace((int)*psz1))
338                         psz1++;
339                 while (isspace((int)*psz2))
340                         psz2++;
341                 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
342                     || *psz2 == '\0')
343                         break;
344                 psz1++;
345                 psz2++;
346         }
347         return (*psz1 - *psz2);
348 }
349
350
351 /**
352  Convert a string to upper case, but don't modify it.
353 **/
354
355 char *strupper_static(const char *s)
356 {
357         static pstring str;
358
359         pstrcpy(str, s);
360         strupper_m(str);
361
362         return str;
363 }
364
365 /**
366  Convert a string to "normal" form.
367 **/
368
369 void strnorm(char *s, int case_default)
370 {
371         if (case_default == CASE_UPPER)
372                 strupper_m(s);
373         else
374                 strlower_m(s);
375 }
376
377 /**
378  Check if a string is in "normal" case.
379 **/
380
381 BOOL strisnormal(const char *s, int case_default)
382 {
383         if (case_default == CASE_UPPER)
384                 return(!strhaslower(s));
385         
386         return(!strhasupper(s));
387 }
388
389
390 /**
391  String replace.
392  NOTE: oldc and newc must be 7 bit characters
393 **/
394
395 void string_replace( char *s, char oldc, char newc )
396 {
397         char *p;
398         smb_ucs2_t *tmp;
399         size_t src_len, len;
400
401         /* this is quite a common operation, so we want it to be
402            fast. We optimise for the ascii case, knowing that all our
403            supported multi-byte character sets are ascii-compatible
404            (ie. they match for the first 128 chars) */
405
406         for (p = s; *p; p++) {
407                 if (*p & 0x80) /* mb string - slow path. */
408                         break;
409                 if (*p == oldc)
410                         *p = newc;
411         }
412
413         if (!*p)
414                 return;
415
416         /* Slow (mb) path. */
417 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
418         /* With compose characters we must restart from the beginning. JRA. */
419         p = s;
420 #endif
421         src_len = strlen(p);
422         len = push_ucs2_allocate(&tmp, p);
423         if (len == -1) {
424                 return;
425         }
426         string_replace_w(tmp, UCS2_CHAR(oldc), UCS2_CHAR(newc));
427         pull_ucs2(NULL, p, tmp, src_len+1, -1, STR_TERMINATE);
428         SAFE_FREE(tmp);
429 }
430
431 /**
432  *  Skip past some strings in a buffer - old version - no checks.
433  *  **/
434
435 char *push_skip_string(char *buf)
436 {
437         buf += strlen(buf) + 1;
438         return(buf);
439 }
440
441 /**
442  Skip past a string in a buffer. Buffer may not be
443  null terminated. end_ptr points to the first byte after
444  then end of the buffer.
445 **/
446
447 char *skip_string(const char *base, size_t len, char *buf)
448 {
449         const char *end_ptr = base + len;
450
451         if (end_ptr < base || !base || !buf || buf >= end_ptr) {
452                 return NULL;
453         }
454
455         /* Skip the string */
456         while (*buf) {
457                 buf++;
458                 if (buf >= end_ptr) {
459                         return NULL;
460                 }
461         }
462         /* Skip the '\0' */
463         buf++;
464         return buf;
465 }
466
467 /**
468  Count the number of characters in a string. Normally this will
469  be the same as the number of bytes in a string for single byte strings,
470  but will be different for multibyte.
471 **/
472
473 size_t str_charnum(const char *s)
474 {
475         uint16 tmpbuf2[sizeof(pstring)];
476         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
477         return strlen_w(tmpbuf2);
478 }
479
480 /**
481  Count the number of characters in a string. Normally this will
482  be the same as the number of bytes in a string for single byte strings,
483  but will be different for multibyte.
484 **/
485
486 size_t str_ascii_charnum(const char *s)
487 {
488         pstring tmpbuf2;
489         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
490         return strlen(tmpbuf2);
491 }
492
493 BOOL trim_char(char *s,char cfront,char cback)
494 {
495         BOOL ret = False;
496         char *ep;
497         char *fp = s;
498
499         /* Ignore null or empty strings. */
500         if (!s || (s[0] == '\0'))
501                 return False;
502
503         if (cfront) {
504                 while (*fp && *fp == cfront)
505                         fp++;
506                 if (!*fp) {
507                         /* We ate the string. */
508                         s[0] = '\0';
509                         return True;
510                 }
511                 if (fp != s)
512                         ret = True;
513         }
514
515         ep = fp + strlen(fp) - 1;
516         if (cback) {
517                 /* Attempt ascii only. Bail for mb strings. */
518                 while ((ep >= fp) && (*ep == cback)) {
519                         ret = True;
520                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
521                                 /* Could be mb... bail back to tim_string. */
522                                 char fs[2], bs[2];
523                                 if (cfront) {
524                                         fs[0] = cfront;
525                                         fs[1] = '\0';
526                                 }
527                                 bs[0] = cback;
528                                 bs[1] = '\0';
529                                 return trim_string(s, cfront ? fs : NULL, bs);
530                         } else {
531                                 ep--;
532                         }
533                 }
534                 if (ep < fp) {
535                         /* We ate the string. */
536                         s[0] = '\0';
537                         return True;
538                 }
539         }
540
541         ep[1] = '\0';
542         memmove(s, fp, ep-fp+2);
543         return ret;
544 }
545
546 /**
547  Trim the specified elements off the front and back of a string.
548 **/
549
550 BOOL trim_string(char *s,const char *front,const char *back)
551 {
552         BOOL ret = False;
553         size_t front_len;
554         size_t back_len;
555         size_t len;
556
557         /* Ignore null or empty strings. */
558         if (!s || (s[0] == '\0'))
559                 return False;
560
561         front_len       = front? strlen(front) : 0;
562         back_len        = back? strlen(back) : 0;
563
564         len = strlen(s);
565
566         if (front_len) {
567                 while (len && strncmp(s, front, front_len)==0) {
568                         /* Must use memmove here as src & dest can
569                          * easily overlap. Found by valgrind. JRA. */
570                         memmove(s, s+front_len, (len-front_len)+1);
571                         len -= front_len;
572                         ret=True;
573                 }
574         }
575         
576         if (back_len) {
577                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
578                         s[len-back_len]='\0';
579                         len -= back_len;
580                         ret=True;
581                 }
582         }
583         return ret;
584 }
585
586 /**
587  Does a string have any uppercase chars in it?
588 **/
589
590 BOOL strhasupper(const char *s)
591 {
592         smb_ucs2_t *tmp, *p;
593         BOOL ret;
594
595         if (push_ucs2_allocate(&tmp, s) == -1) {
596                 return False;
597         }
598
599         for(p = tmp; *p != 0; p++) {
600                 if(isupper_w(*p)) {
601                         break;
602                 }
603         }
604
605         ret = (*p != 0);
606         SAFE_FREE(tmp);
607         return ret;
608 }
609
610 /**
611  Does a string have any lowercase chars in it?
612 **/
613
614 BOOL strhaslower(const char *s)
615 {
616         smb_ucs2_t *tmp, *p;
617         BOOL ret;
618
619         if (push_ucs2_allocate(&tmp, s) == -1) {
620                 return False;
621         }
622
623         for(p = tmp; *p != 0; p++) {
624                 if(islower_w(*p)) {
625                         break;
626                 }
627         }
628
629         ret = (*p != 0);
630         SAFE_FREE(tmp);
631         return ret;
632 }
633
634 /**
635  Find the number of 'c' chars in a string
636 **/
637
638 size_t count_chars(const char *s,char c)
639 {
640         smb_ucs2_t *ptr;
641         int count;
642         smb_ucs2_t *alloc_tmpbuf = NULL;
643
644         if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
645                 return 0;
646         }
647
648         for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
649                 if(*ptr==UCS2_CHAR(c))
650                         count++;
651
652         SAFE_FREE(alloc_tmpbuf);
653         return(count);
654 }
655
656 /**
657  Safe string copy into a known length string. maxlength does not
658  include the terminating zero.
659 **/
660
661 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
662 {
663         size_t len;
664
665         if (!dest) {
666                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
667                 return NULL;
668         }
669
670 #ifdef DEVELOPER
671         clobber_region(fn,line,dest, maxlength+1);
672 #endif
673
674         if (!src) {
675                 *dest = 0;
676                 return dest;
677         }  
678
679         len = strnlen(src, maxlength+1);
680
681         if (len > maxlength) {
682                 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
683                          (unsigned long)(len-maxlength), (unsigned long)len, 
684                          (unsigned long)maxlength, src));
685                 len = maxlength;
686         }
687       
688         memmove(dest, src, len);
689         dest[len] = 0;
690         return dest;
691 }  
692
693 /**
694  Safe string cat into a string. maxlength does not
695  include the terminating zero.
696 **/
697 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
698 {
699         size_t src_len, dest_len;
700
701         if (!dest) {
702                 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
703                 return NULL;
704         }
705
706         if (!src)
707                 return dest;
708         
709         src_len = strnlen(src, maxlength + 1);
710         dest_len = strnlen(dest, maxlength + 1);
711
712 #ifdef DEVELOPER
713         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
714 #endif
715
716         if (src_len + dest_len > maxlength) {
717                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
718                          (int)(src_len + dest_len - maxlength), src));
719                 if (maxlength > dest_len) {
720                         memcpy(&dest[dest_len], src, maxlength - dest_len);
721                 }
722                 dest[maxlength] = 0;
723                 return NULL;
724         }
725
726         memcpy(&dest[dest_len], src, src_len);
727         dest[dest_len + src_len] = 0;
728         return dest;
729 }
730
731 /**
732  Paranoid strcpy into a buffer of given length (includes terminating
733  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
734  and replaces with '_'. Deliberately does *NOT* check for multibyte
735  characters. Don't change it !
736 **/
737 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
738 {
739         size_t len, i;
740
741 #ifdef DEVELOPER
742         clobber_region(fn, line, dest, maxlength);
743 #endif
744
745         if (!dest) {
746                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
747                 return NULL;
748         }
749
750         if (!src) {
751                 *dest = 0;
752                 return dest;
753         }  
754
755         len = strlen(src);
756         if (len >= maxlength)
757                 len = maxlength - 1;
758
759         if (!other_safe_chars)
760                 other_safe_chars = "";
761
762         for(i = 0; i < len; i++) {
763                 int val = (src[i] & 0xff);
764                 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
765                         dest[i] = src[i];
766                 else
767                         dest[i] = '_';
768         }
769
770         dest[i] = '\0';
771
772         return dest;
773 }
774
775 /**
776  Like strncpy but always null terminates. Make sure there is room!
777  The variable n should always be one less than the available size.
778 **/
779 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
780 {
781         char *d = dest;
782
783 #ifdef DEVELOPER
784         clobber_region(fn, line, dest, n+1);
785 #endif
786
787         if (!dest) {
788                 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
789                 return(NULL);
790         }
791
792         if (!src) {
793                 *dest = 0;
794                 return(dest);
795         }
796         
797         while (n-- && (*d = *src)) {
798                 d++;
799                 src++;
800         }
801
802         *d = 0;
803         return(dest);
804 }
805
806 #if 0
807 /**
808  Like strncpy but copies up to the character marker.  always null terminates.
809  returns a pointer to the character marker in the source string (src).
810 **/
811
812 static char *strncpyn(char *dest, const char *src, size_t n, char c)
813 {
814         char *p;
815         size_t str_len;
816
817 #ifdef DEVELOPER
818         clobber_region(dest, n+1);
819 #endif
820         p = strchr_m(src, c);
821         if (p == NULL) {
822                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
823                 return NULL;
824         }
825
826         str_len = PTR_DIFF(p, src);
827         strncpy(dest, src, MIN(n, str_len));
828         dest[str_len] = '\0';
829
830         return p;
831 }
832 #endif
833
834 /**
835  Routine to get hex characters and turn them into a 16 byte array.
836  the array can be variable length, and any non-hex-numeric
837  characters are skipped.  "0xnn" or "0Xnn" is specially catered
838  for.
839
840  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
841
842 **/
843
844 size_t strhex_to_str(char *p, size_t len, const char *strhex)
845 {
846         size_t i;
847         size_t num_chars = 0;
848         unsigned char   lonybble, hinybble;
849         const char     *hexchars = "0123456789ABCDEF";
850         char           *p1 = NULL, *p2 = NULL;
851
852         for (i = 0; i < len && strhex[i] != 0; i++) {
853                 if (strnequal(hexchars, "0x", 2)) {
854                         i++; /* skip two chars */
855                         continue;
856                 }
857
858                 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
859                         break;
860
861                 i++; /* next hex digit */
862
863                 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
864                         break;
865
866                 /* get the two nybbles */
867                 hinybble = PTR_DIFF(p1, hexchars);
868                 lonybble = PTR_DIFF(p2, hexchars);
869
870                 p[num_chars] = (hinybble << 4) | lonybble;
871                 num_chars++;
872
873                 p1 = NULL;
874                 p2 = NULL;
875         }
876         return num_chars;
877 }
878
879 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
880 {
881         DATA_BLOB ret_blob;
882
883         if (mem_ctx != NULL)
884                 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
885         else
886                 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
887
888         ret_blob.length = strhex_to_str((char*)ret_blob.data,   
889                                         strlen(strhex), 
890                                         strhex);
891
892         return ret_blob;
893 }
894
895 /**
896  * Routine to print a buffer as HEX digits, into an allocated string.
897  */
898
899 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
900 {
901         int i;
902         char *hex_buffer;
903
904         hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
905
906         for (i = 0; i < len; i++)
907                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
908
909         return hex_buffer;
910 }
911
912 /**
913  Check if a string is part of a list.
914 **/
915
916 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
917 {
918         pstring tok;
919         const char *p=list;
920
921         if (!list)
922                 return(False);
923
924         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
925                 if (casesensitive) {
926                         if (strcmp(tok,s) == 0)
927                                 return(True);
928                 } else {
929                         if (StrCaseCmp(tok,s) == 0)
930                                 return(True);
931                 }
932         }
933         return(False);
934 }
935
936 /* this is used to prevent lots of mallocs of size 1 */
937 static const char *null_string = "";
938
939 /**
940  Set a string value, allocing the space for the string
941 **/
942
943 static BOOL string_init(char **dest,const char *src)
944 {
945         size_t l;
946
947         if (!src)     
948                 src = "";
949
950         l = strlen(src);
951
952         if (l == 0) {
953                 *dest = CONST_DISCARD(char*, null_string);
954         } else {
955                 (*dest) = SMB_STRDUP(src);
956                 if ((*dest) == NULL) {
957                         DEBUG(0,("Out of memory in string_init\n"));
958                         return False;
959                 }
960         }
961         return(True);
962 }
963
964 /**
965  Free a string value.
966 **/
967
968 void string_free(char **s)
969 {
970         if (!s || !(*s))
971                 return;
972         if (*s == null_string)
973                 *s = NULL;
974         SAFE_FREE(*s);
975 }
976
977 /**
978  Set a string value, deallocating any existing space, and allocing the space
979  for the string
980 **/
981
982 BOOL string_set(char **dest,const char *src)
983 {
984         string_free(dest);
985         return(string_init(dest,src));
986 }
987
988 /**
989  Substitute a string for a pattern in another string. Make sure there is 
990  enough room!
991
992  This routine looks for pattern in s and replaces it with 
993  insert. It may do multiple replacements or just one.
994
995  Any of " ; ' $ or ` in the insert string are replaced with _
996  if len==0 then the string cannot be extended. This is different from the old
997  use of len==0 which was for no length checks to be done.
998 **/
999
1000 void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
1001                  BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
1002 {
1003         char *p;
1004         ssize_t ls,lp,li, i;
1005
1006         if (!insert || !pattern || !*pattern || !s)
1007                 return;
1008
1009         ls = (ssize_t)strlen(s);
1010         lp = (ssize_t)strlen(pattern);
1011         li = (ssize_t)strlen(insert);
1012
1013         if (len == 0)
1014                 len = ls + 1; /* len is number of *bytes* */
1015
1016         while (lp <= ls && (p = strstr_m(s,pattern))) {
1017                 if (ls + (li-lp) >= len) {
1018                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
1019                                  (int)(ls + (li-lp) - len),
1020                                  pattern, (int)len));
1021                         break;
1022                 }
1023                 if (li != lp) {
1024                         memmove(p+li,p+lp,strlen(p+lp)+1);
1025                 }
1026                 for (i=0;i<li;i++) {
1027                         switch (insert[i]) {
1028                         case '`':
1029                         case '"':
1030                         case '\'':
1031                         case ';':
1032                         case '$':
1033                                 /* allow a trailing $ (as in machine accounts) */
1034                                 if (allow_trailing_dollar && (i == li - 1 )) {
1035                                         p[i] = insert[i];
1036                                         break;
1037                                 }
1038                         case '%':
1039                         case '\r':
1040                         case '\n':
1041                                 if ( remove_unsafe_characters ) {
1042                                         p[i] = '_';
1043                                         /* yes this break should be here since we want to 
1044                                            fall throw if not replacing unsafe chars */
1045                                         break;
1046                                 }
1047                         default:
1048                                 p[i] = insert[i];
1049                         }
1050                 }
1051                 s = p + li;
1052                 ls += (li-lp);
1053
1054                 if (replace_once)
1055                         break;
1056         }
1057 }
1058
1059 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1060 {
1061         string_sub2( s, pattern, insert, len, True, True, False );
1062 }
1063
1064 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1065 {
1066         string_sub2( s, pattern, insert, len, True, False, False );
1067 }
1068
1069 void fstring_sub(char *s,const char *pattern,const char *insert)
1070 {
1071         string_sub(s, pattern, insert, sizeof(fstring));
1072 }
1073
1074 void pstring_sub(char *s,const char *pattern,const char *insert)
1075 {
1076         string_sub(s, pattern, insert, sizeof(pstring));
1077 }
1078
1079 /**
1080  Similar to string_sub, but it will accept only allocated strings
1081  and may realloc them so pay attention at what you pass on no
1082  pointers inside strings, no pstrings or const may be passed
1083  as string.
1084 **/
1085
1086 char *realloc_string_sub(char *string, const char *pattern,
1087                          const char *insert)
1088 {
1089         char *p, *in;
1090         char *s;
1091         ssize_t ls,lp,li,ld, i;
1092
1093         if (!insert || !pattern || !*pattern || !string || !*string)
1094                 return NULL;
1095
1096         s = string;
1097
1098         in = SMB_STRDUP(insert);
1099         if (!in) {
1100                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1101                 return NULL;
1102         }
1103         ls = (ssize_t)strlen(s);
1104         lp = (ssize_t)strlen(pattern);
1105         li = (ssize_t)strlen(insert);
1106         ld = li - lp;
1107         for (i=0;i<li;i++) {
1108                 switch (in[i]) {
1109                         case '`':
1110                         case '"':
1111                         case '\'':
1112                         case ';':
1113                         case '$':
1114                         case '%':
1115                         case '\r':
1116                         case '\n':
1117                                 in[i] = '_';
1118                         default:
1119                                 /* ok */
1120                                 break;
1121                 }
1122         }
1123         
1124         while ((p = strstr_m(s,pattern))) {
1125                 if (ld > 0) {
1126                         int offset = PTR_DIFF(s,string);
1127                         string = (char *)SMB_REALLOC(string, ls + ld + 1);
1128                         if (!string) {
1129                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1130                                 SAFE_FREE(in);
1131                                 return NULL;
1132                         }
1133                         p = string + offset + (p - s);
1134                 }
1135                 if (li != lp) {
1136                         memmove(p+li,p+lp,strlen(p+lp)+1);
1137                 }
1138                 memcpy(p, in, li);
1139                 s = p + li;
1140                 ls += ld;
1141         }
1142         SAFE_FREE(in);
1143         return string;
1144 }
1145
1146 /* Same as string_sub, but returns a talloc'ed string */
1147
1148 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1149                         const char *pattern, const char *insert)
1150 {
1151         char *p, *in;
1152         char *s;
1153         char *string;
1154         ssize_t ls,lp,li,ld, i;
1155
1156         if (!insert || !pattern || !*pattern || !src || !*src)
1157                 return NULL;
1158
1159         string = talloc_strdup(mem_ctx, src);
1160         if (string == NULL) {
1161                 DEBUG(0, ("talloc_strdup failed\n"));
1162                 return NULL;
1163         }
1164
1165         s = string;
1166
1167         in = SMB_STRDUP(insert);
1168         if (!in) {
1169                 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1170                 return NULL;
1171         }
1172         ls = (ssize_t)strlen(s);
1173         lp = (ssize_t)strlen(pattern);
1174         li = (ssize_t)strlen(insert);
1175         ld = li - lp;
1176         for (i=0;i<li;i++) {
1177                 switch (in[i]) {
1178                         case '`':
1179                         case '"':
1180                         case '\'':
1181                         case ';':
1182                         case '$':
1183                         case '%':
1184                         case '\r':
1185                         case '\n':
1186                                 in[i] = '_';
1187                         default:
1188                                 /* ok */
1189                                 break;
1190                 }
1191         }
1192         
1193         while ((p = strstr_m(s,pattern))) {
1194                 if (ld > 0) {
1195                         int offset = PTR_DIFF(s,string);
1196                         string = (char *)TALLOC_REALLOC(mem_ctx, string,
1197                                                         ls + ld + 1);
1198                         if (!string) {
1199                                 DEBUG(0, ("talloc_string_sub: out of "
1200                                           "memory!\n"));
1201                                 SAFE_FREE(in);
1202                                 return NULL;
1203                         }
1204                         p = string + offset + (p - s);
1205                 }
1206                 if (li != lp) {
1207                         memmove(p+li,p+lp,strlen(p+lp)+1);
1208                 }
1209                 memcpy(p, in, li);
1210                 s = p + li;
1211                 ls += ld;
1212         }
1213         SAFE_FREE(in);
1214         return string;
1215 }
1216
1217 /**
1218  Similar to string_sub() but allows for any character to be substituted. 
1219  Use with caution!
1220  if len==0 then the string cannot be extended. This is different from the old
1221  use of len==0 which was for no length checks to be done.
1222 **/
1223
1224 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1225 {
1226         char *p;
1227         ssize_t ls,lp,li;
1228
1229         if (!insert || !pattern || !s)
1230                 return;
1231
1232         ls = (ssize_t)strlen(s);
1233         lp = (ssize_t)strlen(pattern);
1234         li = (ssize_t)strlen(insert);
1235
1236         if (!*pattern)
1237                 return;
1238         
1239         if (len == 0)
1240                 len = ls + 1; /* len is number of *bytes* */
1241         
1242         while (lp <= ls && (p = strstr_m(s,pattern))) {
1243                 if (ls + (li-lp) >= len) {
1244                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1245                                  (int)(ls + (li-lp) - len),
1246                                  pattern, (int)len));
1247                         break;
1248                 }
1249                 if (li != lp) {
1250                         memmove(p+li,p+lp,strlen(p+lp)+1);
1251                 }
1252                 memcpy(p, insert, li);
1253                 s = p + li;
1254                 ls += (li-lp);
1255         }
1256 }
1257
1258 /**
1259  Similar to all_string_sub but for unicode strings.
1260  Return a new allocated unicode string.
1261  similar to string_sub() but allows for any character to be substituted.
1262  Use with caution!
1263 **/
1264
1265 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1266                                 const smb_ucs2_t *insert)
1267 {
1268         smb_ucs2_t *r, *rp;
1269         const smb_ucs2_t *sp;
1270         size_t  lr, lp, li, lt;
1271
1272         if (!insert || !pattern || !*pattern || !s)
1273                 return NULL;
1274
1275         lt = (size_t)strlen_w(s);
1276         lp = (size_t)strlen_w(pattern);
1277         li = (size_t)strlen_w(insert);
1278
1279         if (li > lp) {
1280                 const smb_ucs2_t *st = s;
1281                 int ld = li - lp;
1282                 while ((sp = strstr_w(st, pattern))) {
1283                         st = sp + lp;
1284                         lt += ld;
1285                 }
1286         }
1287
1288         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1289         if (!r) {
1290                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1291                 return NULL;
1292         }
1293
1294         while ((sp = strstr_w(s, pattern))) {
1295                 memcpy(rp, s, (sp - s));
1296                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1297                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1298                 s = sp + lp;
1299                 rp += li;
1300         }
1301         lr = ((rp - r) / sizeof(smb_ucs2_t));
1302         if (lr < lt) {
1303                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1304                 rp += (lt - lr);
1305         }
1306         *rp = 0;
1307
1308         return r;
1309 }
1310
1311 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1312                                              const char *insert)
1313 {
1314         wpstring p, i;
1315
1316         if (!insert || !pattern || !s)
1317                 return NULL;
1318         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1319         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1320         return all_string_sub_w(s, p, i);
1321 }
1322
1323 #if 0
1324 /**
1325  Splits out the front and back at a separator.
1326 **/
1327
1328 static void split_at_last_component(char *path, char *front, char sep, char *back)
1329 {
1330         char *p = strrchr_m(path, sep);
1331
1332         if (p != NULL)
1333                 *p = 0;
1334
1335         if (front != NULL)
1336                 pstrcpy(front, path);
1337
1338         if (p != NULL) {
1339                 if (back != NULL)
1340                         pstrcpy(back, p+1);
1341                 *p = '\\';
1342         } else {
1343                 if (back != NULL)
1344                         back[0] = 0;
1345         }
1346 }
1347 #endif
1348
1349 /**
1350  Write an octal as a string.
1351 **/
1352
1353 const char *octal_string(int i)
1354 {
1355         static char ret[64];
1356         if (i == -1)
1357                 return "-1";
1358         slprintf(ret, sizeof(ret)-1, "0%o", i);
1359         return ret;
1360 }
1361
1362
1363 /**
1364  Truncate a string at a specified length.
1365 **/
1366
1367 char *string_truncate(char *s, unsigned int length)
1368 {
1369         if (s && strlen(s) > length)
1370                 s[length] = 0;
1371         return s;
1372 }
1373
1374 /**
1375  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1376  We convert via ucs2 for now.
1377 **/
1378
1379 char *strchr_m(const char *src, char c)
1380 {
1381         wpstring ws;
1382         pstring s2;
1383         smb_ucs2_t *p;
1384         const char *s;
1385
1386         /* characters below 0x3F are guaranteed to not appear in
1387            non-initial position in multi-byte charsets */
1388         if ((c & 0xC0) == 0) {
1389                 return strchr(src, c);
1390         }
1391
1392         /* this is quite a common operation, so we want it to be
1393            fast. We optimise for the ascii case, knowing that all our
1394            supported multi-byte character sets are ascii-compatible
1395            (ie. they match for the first 128 chars) */
1396
1397         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1398                 if (*s == c)
1399                         return (char *)s;
1400         }
1401
1402         if (!*s)
1403                 return NULL;
1404
1405 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1406         /* With compose characters we must restart from the beginning. JRA. */
1407         s = src;
1408 #endif
1409
1410         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1411         p = strchr_w(ws, UCS2_CHAR(c));
1412         if (!p)
1413                 return NULL;
1414         *p = 0;
1415         pull_ucs2_pstring(s2, ws);
1416         return (char *)(s+strlen(s2));
1417 }
1418
1419 char *strrchr_m(const char *s, char c)
1420 {
1421         /* characters below 0x3F are guaranteed to not appear in
1422            non-initial position in multi-byte charsets */
1423         if ((c & 0xC0) == 0) {
1424                 return strrchr(s, c);
1425         }
1426
1427         /* this is quite a common operation, so we want it to be
1428            fast. We optimise for the ascii case, knowing that all our
1429            supported multi-byte character sets are ascii-compatible
1430            (ie. they match for the first 128 chars). Also, in Samba
1431            we only search for ascii characters in 'c' and that
1432            in all mb character sets with a compound character
1433            containing c, if 'c' is not a match at position
1434            p, then p[-1] > 0x7f. JRA. */
1435
1436         {
1437                 size_t len = strlen(s);
1438                 const char *cp = s;
1439                 BOOL got_mb = False;
1440
1441                 if (len == 0)
1442                         return NULL;
1443                 cp += (len - 1);
1444                 do {
1445                         if (c == *cp) {
1446                                 /* Could be a match. Part of a multibyte ? */
1447                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1448                                         /* Yep - go slow :-( */
1449                                         got_mb = True;
1450                                         break;
1451                                 }
1452                                 /* No - we have a match ! */
1453                                 return (char *)cp;
1454                         }
1455                 } while (cp-- != s);
1456                 if (!got_mb)
1457                         return NULL;
1458         }
1459
1460         /* String contained a non-ascii char. Slow path. */
1461         {
1462                 wpstring ws;
1463                 pstring s2;
1464                 smb_ucs2_t *p;
1465
1466                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1467                 p = strrchr_w(ws, UCS2_CHAR(c));
1468                 if (!p)
1469                         return NULL;
1470                 *p = 0;
1471                 pull_ucs2_pstring(s2, ws);
1472                 return (char *)(s+strlen(s2));
1473         }
1474 }
1475
1476 /***********************************************************************
1477  Return the equivalent of doing strrchr 'n' times - always going
1478  backwards.
1479 ***********************************************************************/
1480
1481 char *strnrchr_m(const char *s, char c, unsigned int n)
1482 {
1483         wpstring ws;
1484         pstring s2;
1485         smb_ucs2_t *p;
1486
1487         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1488         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1489         if (!p)
1490                 return NULL;
1491         *p = 0;
1492         pull_ucs2_pstring(s2, ws);
1493         return (char *)(s+strlen(s2));
1494 }
1495
1496 /***********************************************************************
1497  strstr_m - We convert via ucs2 for now.
1498 ***********************************************************************/
1499
1500 char *strstr_m(const char *src, const char *findstr)
1501 {
1502         smb_ucs2_t *p;
1503         smb_ucs2_t *src_w, *find_w;
1504         const char *s;
1505         char *s2;
1506         char *retp;
1507
1508         size_t findstr_len = 0;
1509
1510         /* for correctness */
1511         if (!findstr[0]) {
1512                 return (char*)src;
1513         }
1514
1515         /* Samba does single character findstr calls a *lot*. */
1516         if (findstr[1] == '\0')
1517                 return strchr_m(src, *findstr);
1518
1519         /* We optimise for the ascii case, knowing that all our
1520            supported multi-byte character sets are ascii-compatible
1521            (ie. they match for the first 128 chars) */
1522
1523         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1524                 if (*s == *findstr) {
1525                         if (!findstr_len) 
1526                                 findstr_len = strlen(findstr);
1527
1528                         if (strncmp(s, findstr, findstr_len) == 0) {
1529                                 return (char *)s;
1530                         }
1531                 }
1532         }
1533
1534         if (!*s)
1535                 return NULL;
1536
1537 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1538         /* 'make check' fails unless we do this */
1539
1540         /* With compose characters we must restart from the beginning. JRA. */
1541         s = src;
1542 #endif
1543
1544         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1545                 DEBUG(0,("strstr_m: src malloc fail\n"));
1546                 return NULL;
1547         }
1548         
1549         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1550                 SAFE_FREE(src_w);
1551                 DEBUG(0,("strstr_m: find malloc fail\n"));
1552                 return NULL;
1553         }
1554
1555         p = strstr_w(src_w, find_w);
1556
1557         if (!p) {
1558                 SAFE_FREE(src_w);
1559                 SAFE_FREE(find_w);
1560                 return NULL;
1561         }
1562         
1563         *p = 0;
1564         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1565                 SAFE_FREE(src_w);
1566                 SAFE_FREE(find_w);
1567                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1568                 return NULL;
1569         }
1570         retp = (char *)(s+strlen(s2));
1571         SAFE_FREE(src_w);
1572         SAFE_FREE(find_w);
1573         SAFE_FREE(s2);
1574         return retp;
1575 }
1576
1577 /**
1578  Convert a string to lower case.
1579 **/
1580
1581 void strlower_m(char *s)
1582 {
1583         size_t len;
1584         int errno_save;
1585
1586         /* this is quite a common operation, so we want it to be
1587            fast. We optimise for the ascii case, knowing that all our
1588            supported multi-byte character sets are ascii-compatible
1589            (ie. they match for the first 128 chars) */
1590
1591         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1592                 *s = tolower_ascii((unsigned char)*s);
1593                 s++;
1594         }
1595
1596         if (!*s)
1597                 return;
1598
1599         /* I assume that lowercased string takes the same number of bytes
1600          * as source string even in UTF-8 encoding. (VIV) */
1601         len = strlen(s) + 1;
1602         errno_save = errno;
1603         errno = 0;
1604         unix_strlower(s,len,s,len);     
1605         /* Catch mb conversion errors that may not terminate. */
1606         if (errno)
1607                 s[len-1] = '\0';
1608         errno = errno_save;
1609 }
1610
1611 /**
1612  Convert a string to upper case.
1613 **/
1614
1615 void strupper_m(char *s)
1616 {
1617         size_t len;
1618         int errno_save;
1619
1620         /* this is quite a common operation, so we want it to be
1621            fast. We optimise for the ascii case, knowing that all our
1622            supported multi-byte character sets are ascii-compatible
1623            (ie. they match for the first 128 chars) */
1624
1625         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1626                 *s = toupper_ascii((unsigned char)*s);
1627                 s++;
1628         }
1629
1630         if (!*s)
1631                 return;
1632
1633         /* I assume that lowercased string takes the same number of bytes
1634          * as source string even in multibyte encoding. (VIV) */
1635         len = strlen(s) + 1;
1636         errno_save = errno;
1637         errno = 0;
1638         unix_strupper(s,len,s,len);     
1639         /* Catch mb conversion errors that may not terminate. */
1640         if (errno)
1641                 s[len-1] = '\0';
1642         errno = errno_save;
1643 }
1644
1645 /**
1646  Count the number of UCS2 characters in a string. Normally this will
1647  be the same as the number of bytes in a string for single byte strings,
1648  but will be different for multibyte.
1649 **/
1650
1651 size_t strlen_m(const char *s)
1652 {
1653         size_t count = 0;
1654
1655         if (!s) {
1656                 return 0;
1657         }
1658
1659         while (*s && !(((uint8_t)*s) & 0x80)) {
1660                 s++;
1661                 count++;
1662         }
1663
1664         if (!*s) {
1665                 return count;
1666         }
1667
1668         while (*s) {
1669                 size_t c_size;
1670                 codepoint_t c = next_codepoint(s, &c_size);
1671                 if (c < 0x10000) {
1672                         /* Unicode char fits into 16 bits. */
1673                         count += 1;
1674                 } else {
1675                         /* Double-width unicode char - 32 bits. */
1676                         count += 2;
1677                 }
1678                 s += c_size;
1679         }
1680
1681         return count;
1682 }
1683
1684 /**
1685  Count the number of UCS2 characters in a string including the null
1686  terminator.
1687 **/
1688
1689 size_t strlen_m_term(const char *s)
1690 {
1691         if (!s) {
1692                 return 0;
1693         }
1694         return strlen_m(s) + 1;
1695 }
1696
1697 /*
1698  * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1699  * if a string is there, include the terminator.
1700  */
1701
1702 size_t strlen_m_term_null(const char *s)
1703 {
1704         size_t len;
1705         if (!s) {
1706                 return 0;
1707         }
1708         len = strlen_m(s);
1709         if (len == 0) {
1710                 return 0;
1711         }
1712
1713         return len+1;
1714 }
1715 /**
1716  Return a RFC2254 binary string representation of a buffer.
1717  Used in LDAP filters.
1718  Caller must free.
1719 **/
1720
1721 char *binary_string_rfc2254(char *buf, int len)
1722 {
1723         char *s;
1724         int i, j;
1725         const char *hex = "0123456789ABCDEF";
1726         s = (char *)SMB_MALLOC(len * 3 + 1);
1727         if (!s)
1728                 return NULL;
1729         for (j=i=0;i<len;i++) {
1730                 s[j] = '\\';
1731                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1732                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1733                 j += 3;
1734         }
1735         s[j] = 0;
1736         return s;
1737 }
1738
1739 char *binary_string(char *buf, int len)
1740 {
1741         char *s;
1742         int i, j;
1743         const char *hex = "0123456789ABCDEF";
1744         s = (char *)SMB_MALLOC(len * 2 + 1);
1745         if (!s)
1746                 return NULL;
1747         for (j=i=0;i<len;i++) {
1748                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1749                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1750                 j += 2;
1751         }
1752         s[j] = 0;
1753         return s;
1754 }
1755 /**
1756  Just a typesafety wrapper for snprintf into a pstring.
1757 **/
1758
1759  int pstr_sprintf(pstring s, const char *fmt, ...)
1760 {
1761         va_list ap;
1762         int ret;
1763
1764         va_start(ap, fmt);
1765         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1766         va_end(ap);
1767         return ret;
1768 }
1769
1770
1771 /**
1772  Just a typesafety wrapper for snprintf into a fstring.
1773 **/
1774
1775 int fstr_sprintf(fstring s, const char *fmt, ...)
1776 {
1777         va_list ap;
1778         int ret;
1779
1780         va_start(ap, fmt);
1781         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1782         va_end(ap);
1783         return ret;
1784 }
1785
1786 /**
1787  List of Strings manipulation functions
1788 **/
1789
1790 #define S_LIST_ABS 16 /* List Allocation Block Size */
1791
1792 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1793 {
1794         char **list, **rlist;
1795         const char *str;
1796         char *s;
1797         int num, lsize;
1798         pstring tok;
1799         
1800         if (!string || !*string)
1801                 return NULL;
1802         if (mem_ctx) {
1803                 s = talloc_strdup(mem_ctx, string);
1804         } else {
1805                 s = SMB_STRDUP(string);
1806         }
1807         if (!s) {
1808                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1809                 return NULL;
1810         }
1811         if (!sep) sep = LIST_SEP;
1812         
1813         num = lsize = 0;
1814         list = NULL;
1815         
1816         str = s;
1817         while (next_token(&str, tok, sep, sizeof(tok))) {               
1818                 if (num == lsize) {
1819                         lsize += S_LIST_ABS;
1820                         if (mem_ctx) {
1821                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1822                         } else {
1823                                 /* We need to keep the old list on error so we can free the elements
1824                                    if the realloc fails. */
1825                                 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1826                         }
1827                         if (!rlist) {
1828                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1829                                 str_list_free(&list);
1830                                 if (mem_ctx) {
1831                                         TALLOC_FREE(s);
1832                                 } else {
1833                                         SAFE_FREE(s);
1834                                 }
1835                                 return NULL;
1836                         } else {
1837                                 list = rlist;
1838                         }
1839                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1840                 }
1841
1842                 if (mem_ctx) {
1843                         list[num] = talloc_strdup(mem_ctx, tok);
1844                 } else {
1845                         list[num] = SMB_STRDUP(tok);
1846                 }
1847                 
1848                 if (!list[num]) {
1849                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1850                         str_list_free(&list);
1851                         if (mem_ctx) {
1852                                 TALLOC_FREE(s);
1853                         } else {
1854                                 SAFE_FREE(s);
1855                         }
1856                         return NULL;
1857                 }
1858         
1859                 num++;  
1860         }
1861
1862         if (mem_ctx) {
1863                 TALLOC_FREE(s);
1864         } else {
1865                 SAFE_FREE(s);
1866         }
1867
1868         return list;
1869 }
1870
1871 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1872 {
1873         return str_list_make_internal(mem_ctx, string, sep);
1874 }
1875
1876 char **str_list_make(const char *string, const char *sep)
1877 {
1878         return str_list_make_internal(NULL, string, sep);
1879 }
1880
1881 BOOL str_list_copy(char ***dest, const char **src)
1882 {
1883         char **list, **rlist;
1884         int num, lsize;
1885         
1886         *dest = NULL;
1887         if (!src)
1888                 return False;
1889         
1890         num = lsize = 0;
1891         list = NULL;
1892                 
1893         while (src[num]) {
1894                 if (num == lsize) {
1895                         lsize += S_LIST_ABS;
1896                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1897                         if (!rlist) {
1898                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1899                                 str_list_free(&list);
1900                                 return False;
1901                         } else {
1902                                 list = rlist;
1903                         }
1904                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1905                 }
1906                 
1907                 list[num] = SMB_STRDUP(src[num]);
1908                 if (!list[num]) {
1909                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1910                         str_list_free(&list);
1911                         return False;
1912                 }
1913
1914                 num++;
1915         }
1916         
1917         *dest = list;
1918         return True;    
1919 }
1920
1921 /**
1922  * Return true if all the elements of the list match exactly.
1923  **/
1924 BOOL str_list_compare(char **list1, char **list2)
1925 {
1926         int num;
1927         
1928         if (!list1 || !list2)
1929                 return (list1 == list2); 
1930         
1931         for (num = 0; list1[num]; num++) {
1932                 if (!list2[num])
1933                         return False;
1934                 if (!strcsequal(list1[num], list2[num]))
1935                         return False;
1936         }
1937         if (list2[num])
1938                 return False; /* if list2 has more elements than list1 fail */
1939         
1940         return True;
1941 }
1942
1943 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1944 {
1945         char **tlist;
1946         
1947         if (!list || !*list)
1948                 return;
1949         tlist = *list;
1950         for(; *tlist; tlist++) {
1951                 if (mem_ctx) {
1952                         TALLOC_FREE(*tlist);
1953                 } else {
1954                         SAFE_FREE(*tlist);
1955                 }
1956         }
1957         if (mem_ctx) {
1958                 TALLOC_FREE(*tlist);
1959         } else {
1960                 SAFE_FREE(*list);
1961         }
1962 }
1963
1964 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1965 {
1966         str_list_free_internal(mem_ctx, list);
1967 }
1968
1969 void str_list_free(char ***list)
1970 {
1971         str_list_free_internal(NULL, list);
1972 }
1973
1974 /******************************************************************************
1975  *****************************************************************************/
1976
1977 int str_list_count( const char **list )
1978 {
1979         int i = 0;
1980
1981         if ( ! list )
1982                 return 0;
1983
1984         /* count the number of list members */
1985         
1986         for ( i=0; *list; i++, list++ );
1987         
1988         return i;
1989 }
1990
1991 /******************************************************************************
1992  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1993  for the work
1994  *****************************************************************************/
1995  
1996 BOOL str_list_sub_basic( char **list, const char *smb_name,
1997                          const char *domain_name )
1998 {
1999         char *s, *tmpstr;
2000         
2001         while ( *list ) {
2002                 s = *list;
2003                 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
2004                 if ( !tmpstr ) {
2005                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
2006                         return False;
2007                 }
2008
2009                 SAFE_FREE(*list);
2010                 *list = tmpstr;
2011                         
2012                 list++;
2013         }
2014
2015         return True;
2016 }
2017
2018 /******************************************************************************
2019  substritute a specific pattern in a string list
2020  *****************************************************************************/
2021  
2022 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
2023 {
2024         char *p, *s, *t;
2025         ssize_t ls, lp, li, ld, i, d;
2026
2027         if (!list)
2028                 return False;
2029         if (!pattern)
2030                 return False;
2031         if (!insert)
2032                 return False;
2033
2034         lp = (ssize_t)strlen(pattern);
2035         li = (ssize_t)strlen(insert);
2036         ld = li -lp;
2037                         
2038         while (*list) {
2039                 s = *list;
2040                 ls = (ssize_t)strlen(s);
2041
2042                 while ((p = strstr_m(s, pattern))) {
2043                         t = *list;
2044                         d = p -t;
2045                         if (ld) {
2046                                 t = (char *) SMB_MALLOC(ls +ld +1);
2047                                 if (!t) {
2048                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2049                                         return False;
2050                                 }
2051                                 memcpy(t, *list, d);
2052                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
2053                                 SAFE_FREE(*list);
2054                                 *list = t;
2055                                 ls += ld;
2056                                 s = t +d +li;
2057                         }
2058                         
2059                         for (i = 0; i < li; i++) {
2060                                 switch (insert[i]) {
2061                                         case '`':
2062                                         case '"':
2063                                         case '\'':
2064                                         case ';':
2065                                         case '$':
2066                                         case '%':
2067                                         case '\r':
2068                                         case '\n':
2069                                                 t[d +i] = '_';
2070                                                 break;
2071                                         default:
2072                                                 t[d +i] = insert[i];
2073                                 }
2074                         }       
2075                 }
2076                 
2077                 
2078                 list++;
2079         }
2080         
2081         return True;
2082 }
2083
2084
2085 #define IPSTR_LIST_SEP  ","
2086 #define IPSTR_LIST_CHAR ','
2087
2088 /**
2089  * Add ip string representation to ipstr list. Used also
2090  * as part of @function ipstr_list_make
2091  *
2092  * @param ipstr_list pointer to string containing ip list;
2093  *        MUST BE already allocated and IS reallocated if necessary
2094  * @param ipstr_size pointer to current size of ipstr_list (might be changed
2095  *        as a result of reallocation)
2096  * @param ip IP address which is to be added to list
2097  * @return pointer to string appended with new ip and possibly
2098  *         reallocated to new length
2099  **/
2100
2101 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2102 {
2103         char* new_ipstr = NULL;
2104         
2105         /* arguments checking */
2106         if (!ipstr_list || !service) return NULL;
2107
2108         /* attempt to convert ip to a string and append colon separator to it */
2109         if (*ipstr_list) {
2110                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2111                         inet_ntoa(service->ip), service->port);
2112                 SAFE_FREE(*ipstr_list);
2113         } else {
2114                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2115         }
2116         *ipstr_list = new_ipstr;
2117         return *ipstr_list;
2118 }
2119
2120
2121 /**
2122  * Allocate and initialise an ipstr list using ip adresses
2123  * passed as arguments.
2124  *
2125  * @param ipstr_list pointer to string meant to be allocated and set
2126  * @param ip_list array of ip addresses to place in the list
2127  * @param ip_count number of addresses stored in ip_list
2128  * @return pointer to allocated ip string
2129  **/
2130  
2131 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2132 {
2133         int i;
2134         
2135         /* arguments checking */
2136         if (!ip_list || !ipstr_list) return 0;
2137
2138         *ipstr_list = NULL;
2139         
2140         /* process ip addresses given as arguments */
2141         for (i = 0; i < ip_count; i++)
2142                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2143         
2144         return (*ipstr_list);
2145 }
2146
2147
2148 /**
2149  * Parse given ip string list into array of ip addresses
2150  * (as ip_service structures)  
2151  *    e.g. 192.168.1.100:389,192.168.1.78, ...
2152  *
2153  * @param ipstr ip string list to be parsed 
2154  * @param ip_list pointer to array of ip addresses which is
2155  *        allocated by this function and must be freed by caller
2156  * @return number of succesfully parsed addresses
2157  **/
2158  
2159 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2160 {
2161         fstring token_str;
2162         size_t count;
2163         int i;
2164
2165         if (!ipstr_list || !ip_list) 
2166                 return 0;
2167         
2168         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2169         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2170                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2171                 return 0;
2172         }
2173         
2174         for ( i=0; 
2175                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
2176                 i++ ) 
2177         {
2178                 struct in_addr addr;
2179                 unsigned port = 0;      
2180                 char *p = strchr(token_str, ':');
2181                 
2182                 if (p) {
2183                         *p = 0;
2184                         port = atoi(p+1);
2185                 }
2186
2187                 /* convert single token to ip address */
2188                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2189                         break;
2190                                 
2191                 (*ip_list)[i].ip = addr;
2192                 (*ip_list)[i].port = port;
2193         }
2194         
2195         return count;
2196 }
2197
2198
2199 /**
2200  * Safely free ip string list
2201  *
2202  * @param ipstr_list ip string list to be freed
2203  **/
2204
2205 void ipstr_list_free(char* ipstr_list)
2206 {
2207         SAFE_FREE(ipstr_list);
2208 }
2209
2210
2211 /**
2212  Unescape a URL encoded string, in place.
2213 **/
2214
2215 void rfc1738_unescape(char *buf)
2216 {
2217         char *p=buf;
2218
2219         while (p && *p && (p=strchr_m(p,'%'))) {
2220                 int c1 = p[1];
2221                 int c2 = p[2];
2222
2223                 if (c1 >= '0' && c1 <= '9')
2224                         c1 = c1 - '0';
2225                 else if (c1 >= 'A' && c1 <= 'F')
2226                         c1 = 10 + c1 - 'A';
2227                 else if (c1 >= 'a' && c1 <= 'f')
2228                         c1 = 10 + c1 - 'a';
2229                 else {p++; continue;}
2230
2231                 if (c2 >= '0' && c2 <= '9')
2232                         c2 = c2 - '0';
2233                 else if (c2 >= 'A' && c2 <= 'F')
2234                         c2 = 10 + c2 - 'A';
2235                 else if (c2 >= 'a' && c2 <= 'f')
2236                         c2 = 10 + c2 - 'a';
2237                 else {p++; continue;}
2238                         
2239                 *p = (c1<<4) | c2;
2240
2241                 memmove(p+1, p+3, strlen(p+3)+1);
2242                 p++;
2243         }
2244 }
2245
2246 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2247
2248 /**
2249  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2250  **/
2251 DATA_BLOB base64_decode_data_blob(const char *s)
2252 {
2253         int bit_offset, byte_offset, idx, i, n;
2254         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2255         unsigned char *d = decoded.data;
2256         char *p;
2257
2258         n=i=0;
2259
2260         while (*s && (p=strchr_m(b64,*s))) {
2261                 idx = (int)(p - b64);
2262                 byte_offset = (i*6)/8;
2263                 bit_offset = (i*6)%8;
2264                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2265                 if (bit_offset < 3) {
2266                         d[byte_offset] |= (idx << (2-bit_offset));
2267                         n = byte_offset+1;
2268                 } else {
2269                         d[byte_offset] |= (idx >> (bit_offset-2));
2270                         d[byte_offset+1] = 0;
2271                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2272                         n = byte_offset+2;
2273                 }
2274                 s++; i++;
2275         }
2276
2277         if ((n > 0) && (*s == '=')) {
2278                 n -= 1;
2279         }
2280
2281         /* fix up length */
2282         decoded.length = n;
2283         return decoded;
2284 }
2285
2286 /**
2287  * Decode a base64 string in-place - wrapper for the above
2288  **/
2289 void base64_decode_inplace(char *s)
2290 {
2291         DATA_BLOB decoded = base64_decode_data_blob(s);
2292
2293         if ( decoded.length != 0 ) {
2294                 memcpy(s, decoded.data, decoded.length);
2295
2296                 /* null terminate */
2297                 s[decoded.length] = '\0';
2298         } else {
2299                 *s = '\0';
2300         }
2301
2302         data_blob_free(&decoded);
2303 }
2304
2305 /**
2306  * Encode a base64 string into a malloc()ed string caller to free.
2307  *
2308  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2309  **/
2310 char * base64_encode_data_blob(DATA_BLOB data)
2311 {
2312         int bits = 0;
2313         int char_count = 0;
2314         size_t out_cnt, len, output_len;
2315         char *result;
2316
2317         if (!data.length || !data.data)
2318                 return NULL;
2319
2320         out_cnt = 0;
2321         len = data.length;
2322         output_len = data.length * 2;
2323         result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2324
2325         while (len-- && out_cnt < (data.length * 2) - 5) {
2326                 int c = (unsigned char) *(data.data++);
2327                 bits += c;
2328                 char_count++;
2329                 if (char_count == 3) {
2330                         result[out_cnt++] = b64[bits >> 18];
2331                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2332                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2333             result[out_cnt++] = b64[bits & 0x3f];
2334             bits = 0;
2335             char_count = 0;
2336         } else {
2337             bits <<= 8;
2338         }
2339     }
2340     if (char_count != 0) {
2341         bits <<= 16 - (8 * char_count);
2342         result[out_cnt++] = b64[bits >> 18];
2343         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2344         if (char_count == 1) {
2345             result[out_cnt++] = '=';
2346             result[out_cnt++] = '=';
2347         } else {
2348             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2349             result[out_cnt++] = '=';
2350         }
2351     }
2352     result[out_cnt] = '\0';     /* terminate */
2353     return result;
2354 }
2355
2356 /* read a SMB_BIG_UINT from a string */
2357 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2358 {
2359
2360         SMB_BIG_UINT val = -1;
2361         const char *p = nptr;
2362         
2363         if (!p) {
2364                 if (entptr) {
2365                         *entptr = p;
2366                 }
2367                 return val;
2368         }
2369
2370         while (*p && isspace(*p))
2371                 p++;
2372
2373 #ifdef LARGE_SMB_OFF_T
2374         sscanf(p,"%llu",&val);  
2375 #else /* LARGE_SMB_OFF_T */
2376         sscanf(p,"%lu",&val);
2377 #endif /* LARGE_SMB_OFF_T */
2378         if (entptr) {
2379                 while (*p && isdigit(*p))
2380                         p++;
2381                 *entptr = p;
2382         }
2383
2384         return val;
2385 }
2386
2387 /* Convert a size specification to a count of bytes. We accept the following
2388  * suffixes:
2389  *          bytes if there is no suffix
2390  *      kK  kibibytes
2391  *      mM  mebibytes
2392  *      gG  gibibytes
2393  *      tT  tibibytes
2394  *      pP  whatever the ISO name for petabytes is
2395  *
2396  *  Returns 0 if the string can't be converted.
2397  */
2398 SMB_OFF_T conv_str_size(const char * str)
2399 {
2400         SMB_OFF_T lval;
2401         char * end;
2402
2403         if (str == NULL || *str == '\0') {
2404                 return 0;
2405         }
2406
2407 #ifdef HAVE_STRTOULL
2408         if (sizeof(SMB_OFF_T) == 8) {
2409             lval = strtoull(str, &end, 10 /* base */);
2410         } else {
2411             lval = strtoul(str, &end, 10 /* base */);
2412         }
2413 #else
2414         lval = strtoul(str, &end, 10 /* base */);
2415 #endif
2416
2417         if (end == NULL || end == str) {
2418                 return 0;
2419         }
2420
2421         if (*end) {
2422                 SMB_OFF_T lval_orig = lval;
2423
2424                 if (strwicmp(end, "K") == 0) {
2425                         lval *= (SMB_OFF_T)1024;
2426                 } else if (strwicmp(end, "M") == 0) {
2427                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2428                 } else if (strwicmp(end, "G") == 0) {
2429                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2430                                 (SMB_OFF_T)1024);
2431                 } else if (strwicmp(end, "T") == 0) {
2432                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2433                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2434                 } else if (strwicmp(end, "P") == 0) {
2435                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2436                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2437                                 (SMB_OFF_T)1024);
2438                 } else {
2439                         return 0;
2440                 }
2441
2442                 /* Primitive attempt to detect wrapping on platforms with
2443                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2444                  * a failure than some random number.
2445                  */
2446                 if (lval_orig <= lval) {
2447                         return 0;
2448                 }
2449         }
2450
2451         return lval;
2452 }
2453
2454 void string_append(char **left, const char *right)
2455 {
2456         int new_len = strlen(right) + 1;
2457
2458         if (*left == NULL) {
2459                 *left = (char *)SMB_MALLOC(new_len);
2460                 *left[0] = '\0';
2461         } else {
2462                 new_len += strlen(*left);
2463                 *left = (char *)SMB_REALLOC(*left, new_len);
2464         }
2465
2466         if (*left == NULL) {
2467                 return;
2468         }
2469
2470         safe_strcat(*left, right, new_len-1);
2471 }
2472
2473 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2474                          const char *str, const char ***strings,
2475                          int *num)
2476 {
2477         char *dup_str = talloc_strdup(mem_ctx, str);
2478
2479         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2480
2481         if ((*strings == NULL) || (dup_str == NULL)) {
2482                 *num = 0;
2483                 return False;
2484         }
2485
2486         (*strings)[*num] = dup_str;
2487         *num += 1;
2488         return True;
2489 }
2490
2491 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2492  * error checking in between. The indiation that something weird happened is
2493  * string==NULL */
2494
2495 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2496                     size_t *bufsize, const char *fmt, ...)
2497 {
2498         va_list ap;
2499         char *newstr;
2500         int ret;
2501         BOOL increased;
2502
2503         /* len<0 is an internal marker that something failed */
2504         if (*len < 0)
2505                 goto error;
2506
2507         if (*string == NULL) {
2508                 if (*bufsize == 0)
2509                         *bufsize = 128;
2510
2511                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2512                 if (*string == NULL)
2513                         goto error;
2514         }
2515
2516         va_start(ap, fmt);
2517         ret = vasprintf(&newstr, fmt, ap);
2518         va_end(ap);
2519
2520         if (ret < 0)
2521                 goto error;
2522
2523         increased = False;
2524
2525         while ((*len)+ret >= *bufsize) {
2526                 increased = True;
2527                 *bufsize *= 2;
2528                 if (*bufsize >= (1024*1024*256))
2529                         goto error;
2530         }
2531
2532         if (increased) {
2533                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2534                                                *bufsize);
2535                 if (*string == NULL) {
2536                         goto error;
2537                 }
2538         }
2539
2540         StrnCpy((*string)+(*len), newstr, ret);
2541         (*len) += ret;
2542         free(newstr);
2543         return;
2544
2545  error:
2546         *len = -1;
2547         *string = NULL;
2548 }
2549
2550 /*
2551    Returns the substring from src between the first occurrence of
2552    the char "front" and the first occurence of the char "back".
2553    Mallocs the return string which must be freed.  Not for use
2554    with wide character strings.
2555 */
2556 char *sstring_sub(const char *src, char front, char back)
2557 {
2558         char *temp1, *temp2, *temp3;
2559         ptrdiff_t len;
2560
2561         temp1 = strchr(src, front);
2562         if (temp1 == NULL) return NULL;
2563         temp2 = strchr(src, back);
2564         if (temp2 == NULL) return NULL;
2565         len = temp2 - temp1;
2566         if (len <= 0) return NULL;
2567         temp3 = (char*)SMB_MALLOC(len);
2568         if (temp3 == NULL) {
2569                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2570                 return NULL;
2571         }
2572         memcpy(temp3, temp1+1, len-1);
2573         temp3[len-1] = '\0';
2574         return temp3;
2575 }
2576
2577 /********************************************************************
2578  Check a string for any occurrences of a specified list of invalid
2579  characters.
2580 ********************************************************************/
2581
2582 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2583 {
2584         int i;
2585
2586         for ( i=0; i<max_len && name[i]; i++ ) {
2587                 /* fail if strchr_m() finds one of the invalid characters */
2588                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2589                         return False;
2590                 }
2591         }
2592
2593         return True;
2594 }
2595
2596
2597 /**
2598 return the number of bytes occupied by a buffer in ASCII format
2599 the result includes the null termination
2600 limited by 'n' bytes
2601 **/
2602 size_t ascii_len_n(const char *src, size_t n)
2603 {
2604         size_t len;
2605
2606         len = strnlen(src, n);
2607         if (len+1 <= n) {
2608                 len += 1;
2609         }
2610
2611         return len;
2612 }
2613
2614 /**
2615 return the number of bytes occupied by a buffer in CH_UTF16 format
2616 the result includes the null termination
2617 **/
2618 size_t utf16_len(const void *buf)
2619 {
2620         size_t len;
2621
2622         for (len = 0; SVAL(buf,len); len += 2) ;
2623
2624         return len + 2;
2625 }
2626
2627 /**
2628 return the number of bytes occupied by a buffer in CH_UTF16 format
2629 the result includes the null termination
2630 limited by 'n' bytes
2631 **/
2632 size_t utf16_len_n(const void *src, size_t n)
2633 {
2634         size_t len;
2635
2636         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2637
2638         if (len+2 <= n) {
2639                 len += 2;
2640         }
2641
2642         return len;
2643 }
2644
2645 /*******************************************************************
2646  Add a shell escape character '\' to any character not in a known list
2647  of characters. UNIX charset format.
2648 *******************************************************************/
2649
2650 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2651 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2652
2653 char *escape_shell_string(const char *src)
2654 {
2655         size_t srclen = strlen(src);
2656         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2657         char *dest = ret;
2658         BOOL in_s_quote = False;
2659         BOOL in_d_quote = False;
2660         BOOL next_escaped = False;
2661
2662         if (!ret) {
2663                 return NULL;
2664         }
2665
2666         while (*src) {
2667                 size_t c_size;
2668                 codepoint_t c = next_codepoint(src, &c_size);
2669
2670                 if (c == INVALID_CODEPOINT) {
2671                         SAFE_FREE(ret);
2672                         return NULL;
2673                 }
2674
2675                 if (c_size > 1) {
2676                         memcpy(dest, src, c_size);
2677                         src += c_size;
2678                         dest += c_size;
2679                         next_escaped = False;
2680                         continue;
2681                 }
2682
2683                 /*
2684                  * Deal with backslash escaped state.
2685                  * This only lasts for one character.
2686                  */
2687
2688                 if (next_escaped) {
2689                         *dest++ = *src++;
2690                         next_escaped = False;
2691                         continue;
2692                 }
2693
2694                 /*
2695                  * Deal with single quote state. The
2696                  * only thing we care about is exiting
2697                  * this state.
2698                  */
2699
2700                 if (in_s_quote) {
2701                         if (*src == '\'') {
2702                                 in_s_quote = False;
2703                         }
2704                         *dest++ = *src++;
2705                         continue;
2706                 }
2707
2708                 /* 
2709                  * Deal with double quote state. The most
2710                  * complex state. We must cope with \, meaning
2711                  * possibly escape next char (depending what it
2712                  * is), ", meaning exit this state, and possibly
2713                  * add an \ escape to any unprotected character
2714                  * (listed in INSIDE_DQUOTE_LIST).
2715                  */
2716
2717                 if (in_d_quote) {
2718                         if (*src == '\\') {
2719                                 /* 
2720                                  * Next character might be escaped.
2721                                  * We have to peek. Inside double
2722                                  * quotes only INSIDE_DQUOTE_LIST
2723                                  * characters are escaped by a \.
2724                                  */
2725
2726                                 char nextchar;
2727
2728                                 c = next_codepoint(&src[1], &c_size);
2729                                 if (c == INVALID_CODEPOINT) {
2730                                         SAFE_FREE(ret);
2731                                         return NULL;
2732                                 }
2733                                 if (c_size > 1) {
2734                                         /*
2735                                          * Don't escape the next char.
2736                                          * Just copy the \.
2737                                          */
2738                                         *dest++ = *src++;
2739                                         continue;
2740                                 }
2741
2742                                 nextchar = src[1];
2743
2744                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2745                                         next_escaped = True;
2746                                 }
2747                                 *dest++ = *src++;
2748                                 continue;
2749                         }
2750
2751                         if (*src == '\"') {
2752                                 /* Exit double quote state. */
2753                                 in_d_quote = False;
2754                                 *dest++ = *src++;
2755                                 continue;
2756                         }
2757
2758                         /*
2759                          * We know the character isn't \ or ",
2760                          * so escape it if it's any of the other
2761                          * possible unprotected characters.
2762                          */
2763
2764                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2765                                 *dest++ = '\\';
2766                         }
2767                         *dest++ = *src++;
2768                         continue;
2769                 }
2770
2771                 /* 
2772                  * From here to the end of the loop we're
2773                  * not in the single or double quote state.
2774                  */
2775
2776                 if (*src == '\\') {
2777                         /* Next character must be escaped. */
2778                         next_escaped = True;
2779                         *dest++ = *src++;
2780                         continue;
2781                 }
2782
2783                 if (*src == '\'') {
2784                         /* Go into single quote state. */
2785                         in_s_quote = True;
2786                         *dest++ = *src++;
2787                         continue;
2788                 }
2789
2790                 if (*src == '\"') {
2791                         /* Go into double quote state. */
2792                         in_d_quote = True;
2793                         *dest++ = *src++;
2794                         continue;
2795                 }
2796
2797                 /* Check if we need to escape the character. */
2798
2799                 if (!strchr(INCLUDE_LIST, (int)*src)) {
2800                         *dest++ = '\\';
2801                 }
2802                 *dest++ = *src++;
2803         }
2804         *dest++ = '\0';
2805         return ret;
2806 }