r15295: Fix some dependencies
[bbaumbach/samba-autobuild/.git] / source4 / lib / util / 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     2005
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 2 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 #include "smb.h"
27 #include "pstring.h"
28 #include "lib/ldb/include/ldb.h"
29 #include "system/iconv.h"
30
31 /**
32  * @file
33  * @brief String utilities.
34  **/
35
36
37 /**
38  Trim the specified elements off the front and back of a string.
39 **/
40 _PUBLIC_ BOOL trim_string(char *s,const char *front,const char *back)
41 {
42         BOOL ret = False;
43         size_t front_len;
44         size_t back_len;
45         size_t len;
46
47         /* Ignore null or empty strings. */
48         if (!s || (s[0] == '\0'))
49                 return False;
50
51         front_len       = front? strlen(front) : 0;
52         back_len        = back? strlen(back) : 0;
53
54         len = strlen(s);
55
56         if (front_len) {
57                 while (len && strncmp(s, front, front_len)==0) {
58                         /* Must use memmove here as src & dest can
59                          * easily overlap. Found by valgrind. JRA. */
60                         memmove(s, s+front_len, (len-front_len)+1);
61                         len -= front_len;
62                         ret=True;
63                 }
64         }
65         
66         if (back_len) {
67                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
68                         s[len-back_len]='\0';
69                         len -= back_len;
70                         ret=True;
71                 }
72         }
73         return ret;
74 }
75
76 /**
77  Find the number of 'c' chars in a string
78 **/
79 _PUBLIC_ size_t count_chars(const char *s, char c)
80 {
81         size_t count = 0;
82
83         while (*s) {
84                 size_t size;
85                 codepoint_t c2 = next_codepoint(s, &size);
86                 if (c2 == c) count++;
87                 s += size;
88         }
89
90         return count;
91 }
92
93 /**
94  Safe string copy into a known length string. maxlength does not
95  include the terminating zero.
96 **/
97 _PUBLIC_ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
98 {
99         size_t len;
100
101         if (!dest) {
102                 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
103                 return NULL;
104         }
105
106 #ifdef DEVELOPER
107         /* We intentionally write out at the extremity of the destination
108          * string.  If the destination is too short (e.g. pstrcpy into mallocd
109          * or fstring) then this should cause an error under a memory
110          * checker. */
111         dest[maxlength] = '\0';
112         if (PTR_DIFF(&len, dest) > 0) {  /* check if destination is on the stack, ok if so */
113                 log_suspicious_usage("safe_strcpy", src);
114         }
115 #endif
116
117         if (!src) {
118                 *dest = 0;
119                 return dest;
120         }  
121
122         len = strlen(src);
123
124         if (len > maxlength) {
125                 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
126                          (uint_t)(len-maxlength), (unsigned)len, (unsigned)maxlength, src));
127                 len = maxlength;
128         }
129       
130         memmove(dest, src, len);
131         dest[len] = 0;
132         return dest;
133 }  
134
135 /**
136  Safe string cat into a string. maxlength does not
137  include the terminating zero.
138 **/
139 _PUBLIC_ char *safe_strcat(char *dest, const char *src, size_t maxlength)
140 {
141         size_t src_len, dest_len;
142
143         if (!dest) {
144                 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
145                 return NULL;
146         }
147
148         if (!src)
149                 return dest;
150         
151 #ifdef DEVELOPER
152         if (PTR_DIFF(&src_len, dest) > 0) {  /* check if destination is on the stack, ok if so */
153                 log_suspicious_usage("safe_strcat", src);
154         }
155 #endif
156         src_len = strlen(src);
157         dest_len = strlen(dest);
158
159         if (src_len + dest_len > maxlength) {
160                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
161                          (int)(src_len + dest_len - maxlength), src));
162                 if (maxlength > dest_len) {
163                         memcpy(&dest[dest_len], src, maxlength - dest_len);
164                 }
165                 dest[maxlength] = 0;
166                 return NULL;
167         }
168         
169         memcpy(&dest[dest_len], src, src_len);
170         dest[dest_len + src_len] = 0;
171         return dest;
172 }
173
174 /**
175  Like strncpy but always null terminates. Make sure there is room!
176  The variable n should always be one less than the available size.
177 **/
178
179 _PUBLIC_ char *StrnCpy(char *dest,const char *src,size_t n)
180 {
181         char *d = dest;
182         if (!dest)
183                 return(NULL);
184         if (!src) {
185                 *dest = 0;
186                 return(dest);
187         }
188         while (n-- && (*d++ = *src++))
189                 ;
190         *d = 0;
191         return(dest);
192 }
193
194
195 /**
196  Routine to get hex characters and turn them into a 16 byte array.
197  the array can be variable length, and any non-hex-numeric
198  characters are skipped.  "0xnn" or "0Xnn" is specially catered
199  for.
200
201  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
202
203
204 **/
205 _PUBLIC_ size_t strhex_to_str(char *p, size_t len, const char *strhex)
206 {
207         size_t i;
208         size_t num_chars = 0;
209         uint8_t   lonybble, hinybble;
210         const char     *hexchars = "0123456789ABCDEF";
211         char           *p1 = NULL, *p2 = NULL;
212
213         for (i = 0; i < len && strhex[i] != 0; i++) {
214                 if (strncasecmp(hexchars, "0x", 2) == 0) {
215                         i++; /* skip two chars */
216                         continue;
217                 }
218
219                 if (!(p1 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
220                         break;
221
222                 i++; /* next hex digit */
223
224                 if (!(p2 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
225                         break;
226
227                 /* get the two nybbles */
228                 hinybble = PTR_DIFF(p1, hexchars);
229                 lonybble = PTR_DIFF(p2, hexchars);
230
231                 p[num_chars] = (hinybble << 4) | lonybble;
232                 num_chars++;
233
234                 p1 = NULL;
235                 p2 = NULL;
236         }
237         return num_chars;
238 }
239
240 /** 
241  * Parse a hex string and return a data blob. 
242  */
243 _PUBLIC_ DATA_BLOB strhex_to_data_blob(const char *strhex) 
244 {
245         DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
246
247         ret_blob.length = strhex_to_str((char *)ret_blob.data,  
248                                         strlen(strhex), 
249                                         strhex);
250
251         return ret_blob;
252 }
253
254
255 /**
256  * Routine to print a buffer as HEX digits, into an allocated string.
257  */
258 _PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
259 {
260         int i;
261         char *hex_buffer;
262
263         *out_hex_buffer = smb_xmalloc((len*2)+1);
264         hex_buffer = *out_hex_buffer;
265
266         for (i = 0; i < len; i++)
267                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
268 }
269
270 /**
271  Check if a string is part of a list.
272 **/
273 _PUBLIC_ BOOL in_list(const char *s, const char *list, BOOL casesensitive)
274 {
275         pstring tok;
276         const char *p=list;
277
278         if (!list)
279                 return(False);
280
281         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
282                 if (casesensitive) {
283                         if (strcmp(tok,s) == 0)
284                                 return(True);
285                 } else {
286                         if (strcasecmp_m(tok,s) == 0)
287                                 return(True);
288                 }
289         }
290         return(False);
291 }
292
293 /**
294  Set a string value, allocing the space for the string
295 **/
296 static BOOL string_init(char **dest,const char *src)
297 {
298         if (!src) src = "";
299
300         (*dest) = strdup(src);
301         if ((*dest) == NULL) {
302                 DEBUG(0,("Out of memory in string_init\n"));
303                 return False;
304         }
305         return True;
306 }
307
308 /**
309  Free a string value.
310 **/
311 _PUBLIC_ void string_free(char **s)
312 {
313         if (s) SAFE_FREE(*s);
314 }
315
316 /**
317  Set a string value, deallocating any existing space, and allocing the space
318  for the string
319 **/
320 _PUBLIC_ BOOL string_set(char **dest, const char *src)
321 {
322         string_free(dest);
323         return string_init(dest,src);
324 }
325
326 /**
327  Substitute a string for a pattern in another string. Make sure there is 
328  enough room!
329
330  This routine looks for pattern in s and replaces it with 
331  insert. It may do multiple replacements.
332
333  Any of " ; ' $ or ` in the insert string are replaced with _
334  if len==0 then the string cannot be extended. This is different from the old
335  use of len==0 which was for no length checks to be done.
336 **/
337
338 _PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t len)
339 {
340         char *p;
341         ssize_t ls,lp,li, i;
342
343         if (!insert || !pattern || !*pattern || !s)
344                 return;
345
346         ls = (ssize_t)strlen(s);
347         lp = (ssize_t)strlen(pattern);
348         li = (ssize_t)strlen(insert);
349
350         if (len == 0)
351                 len = ls + 1; /* len is number of *bytes* */
352
353         while (lp <= ls && (p = strstr(s,pattern))) {
354                 if (ls + (li-lp) >= len) {
355                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
356                                  (int)(ls + (li-lp) - len),
357                                  pattern, (int)len));
358                         break;
359                 }
360                 if (li != lp) {
361                         memmove(p+li,p+lp,strlen(p+lp)+1);
362                 }
363                 for (i=0;i<li;i++) {
364                         switch (insert[i]) {
365                         case '`':
366                         case '"':
367                         case '\'':
368                         case ';':
369                         case '$':
370                         case '%':
371                         case '\r':
372                         case '\n':
373                                 p[i] = '_';
374                                 break;
375                         default:
376                                 p[i] = insert[i];
377                         }
378                 }
379                 s = p + li;
380                 ls += (li-lp);
381         }
382 }
383
384
385 /**
386  Similar to string_sub() but allows for any character to be substituted. 
387  Use with caution!
388  if len==0 then the string cannot be extended. This is different from the old
389  use of len==0 which was for no length checks to be done.
390 **/
391
392 _PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
393 {
394         char *p;
395         ssize_t ls,lp,li;
396
397         if (!insert || !pattern || !s)
398                 return;
399
400         ls = (ssize_t)strlen(s);
401         lp = (ssize_t)strlen(pattern);
402         li = (ssize_t)strlen(insert);
403
404         if (!*pattern)
405                 return;
406         
407         if (len == 0)
408                 len = ls + 1; /* len is number of *bytes* */
409         
410         while (lp <= ls && (p = strstr(s,pattern))) {
411                 if (ls + (li-lp) >= len) {
412                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
413                                  (int)(ls + (li-lp) - len),
414                                  pattern, (int)len));
415                         break;
416                 }
417                 if (li != lp) {
418                         memmove(p+li,p+lp,strlen(p+lp)+1);
419                 }
420                 memcpy(p, insert, li);
421                 s = p + li;
422                 ls += (li-lp);
423         }
424 }
425
426
427
428 /**
429  Unescape a URL encoded string, in place.
430 **/
431
432 _PUBLIC_ void rfc1738_unescape(char *buf)
433 {
434         char *p=buf;
435
436         while ((p=strchr_m(p,'+')))
437                 *p = ' ';
438
439         p = buf;
440
441         while (p && *p && (p=strchr_m(p,'%'))) {
442                 int c1 = p[1];
443                 int c2 = p[2];
444
445                 if (c1 >= '0' && c1 <= '9')
446                         c1 = c1 - '0';
447                 else if (c1 >= 'A' && c1 <= 'F')
448                         c1 = 10 + c1 - 'A';
449                 else if (c1 >= 'a' && c1 <= 'f')
450                         c1 = 10 + c1 - 'a';
451                 else {p++; continue;}
452
453                 if (c2 >= '0' && c2 <= '9')
454                         c2 = c2 - '0';
455                 else if (c2 >= 'A' && c2 <= 'F')
456                         c2 = 10 + c2 - 'A';
457                 else if (c2 >= 'a' && c2 <= 'f')
458                         c2 = 10 + c2 - 'a';
459                 else {p++; continue;}
460                         
461                 *p = (c1<<4) | c2;
462
463                 memmove(p+1, p+3, strlen(p+3)+1);
464                 p++;
465         }
466 }
467
468 #ifdef VALGRIND
469 size_t valgrind_strlen(const char *s)
470 {
471         size_t count;
472         for(count = 0; *s++; count++)
473                 ;
474         return count;
475 }
476 #endif
477
478
479 /**
480   format a string into length-prefixed dotted domain format, as used in NBT
481   and in some ADS structures
482 **/
483 _PUBLIC_ const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s)
484 {
485         char *ret;
486         int i;
487         if (!s || !*s) {
488                 return talloc_strdup(mem_ctx, "");
489         }
490         ret = talloc_size(mem_ctx, strlen(s)+2);
491         if (!ret) {
492                 return ret;
493         }
494         
495         memcpy(ret+1, s, strlen(s)+1);
496         ret[0] = '.';
497
498         for (i=0;ret[i];i++) {
499                 if (ret[i] == '.') {
500                         char *p = strchr(ret+i+1, '.');
501                         if (p) {
502                                 ret[i] = p-(ret+i+1);
503                         } else {
504                                 ret[i] = strlen(ret+i+1);
505                         }
506                 }
507         }
508
509         return ret;
510 }
511
512 /**
513  * Add a string to an array of strings.
514  *
515  * num should be a pointer to an integer that holds the current 
516  * number of elements in strings. It will be updated by this function.
517  */
518 _PUBLIC_ BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
519                          const char *str, const char ***strings, int *num)
520 {
521         char *dup_str = talloc_strdup(mem_ctx, str);
522
523         *strings = talloc_realloc(mem_ctx,
524                                     *strings,
525                                     const char *, ((*num)+1));
526
527         if ((*strings == NULL) || (dup_str == NULL))
528                 return False;
529
530         (*strings)[*num] = dup_str;
531         *num += 1;
532
533         return True;
534 }
535
536
537
538 /**
539   varient of strcmp() that handles NULL ptrs
540 **/
541 _PUBLIC_ int strcmp_safe(const char *s1, const char *s2)
542 {
543         if (s1 == s2) {
544                 return 0;
545         }
546         if (s1 == NULL || s2 == NULL) {
547                 return s1?-1:1;
548         }
549         return strcmp(s1, s2);
550 }
551
552
553 /**
554 return the number of bytes occupied by a buffer in ASCII format
555 the result includes the null termination
556 limited by 'n' bytes
557 **/
558 _PUBLIC_ size_t ascii_len_n(const char *src, size_t n)
559 {
560         size_t len;
561
562         len = strnlen(src, n);
563         if (len+1 <= n) {
564                 len += 1;
565         }
566
567         return len;
568 }
569
570
571 /**
572  Return a string representing a CIFS attribute for a file.
573 **/
574 _PUBLIC_ char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
575 {
576         int i, len;
577         const struct {
578                 char c;
579                 uint16_t attr;
580         } attr_strs[] = {
581                 {'V', FILE_ATTRIBUTE_VOLUME},
582                 {'D', FILE_ATTRIBUTE_DIRECTORY},
583                 {'A', FILE_ATTRIBUTE_ARCHIVE},
584                 {'H', FILE_ATTRIBUTE_HIDDEN},
585                 {'S', FILE_ATTRIBUTE_SYSTEM},
586                 {'N', FILE_ATTRIBUTE_NORMAL},
587                 {'R', FILE_ATTRIBUTE_READONLY},
588                 {'d', FILE_ATTRIBUTE_DEVICE},
589                 {'t', FILE_ATTRIBUTE_TEMPORARY},
590                 {'s', FILE_ATTRIBUTE_SPARSE},
591                 {'r', FILE_ATTRIBUTE_REPARSE_POINT},
592                 {'c', FILE_ATTRIBUTE_COMPRESSED},
593                 {'o', FILE_ATTRIBUTE_OFFLINE},
594                 {'n', FILE_ATTRIBUTE_NONINDEXED},
595                 {'e', FILE_ATTRIBUTE_ENCRYPTED}
596         };
597         char *ret;
598
599         ret = talloc_size(mem_ctx, ARRAY_SIZE(attr_strs)+1);
600         if (!ret) {
601                 return NULL;
602         }
603
604         for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {
605                 if (attrib & attr_strs[i].attr) {
606                         ret[len++] = attr_strs[i].c;
607                 }
608         }
609
610         ret[len] = 0;
611
612         return ret;
613 }
614
615 /**
616  Set a boolean variable from the text value stored in the passed string.
617  Returns True in success, False if the passed string does not correctly 
618  represent a boolean.
619 **/
620
621 _PUBLIC_ BOOL set_boolean(const char *boolean_string, BOOL *boolean)
622 {
623         if (strwicmp(boolean_string, "yes") == 0 ||
624             strwicmp(boolean_string, "true") == 0 ||
625             strwicmp(boolean_string, "on") == 0 ||
626             strwicmp(boolean_string, "1") == 0) {
627                 *boolean = True;
628                 return True;
629         } else if (strwicmp(boolean_string, "no") == 0 ||
630                    strwicmp(boolean_string, "false") == 0 ||
631                    strwicmp(boolean_string, "off") == 0 ||
632                    strwicmp(boolean_string, "0") == 0) {
633                 *boolean = False;
634                 return True;
635         }
636         return False;
637 }
638
639 /**
640  * Parse a string containing a boolean value.
641  *
642  * val will be set to the read value.
643  *
644  * @retval True if a boolean value was parsed, False otherwise.
645  */
646 _PUBLIC_ BOOL conv_str_bool(const char * str, BOOL * val)
647 {
648         char *  end = NULL;
649         long    lval;
650
651         if (str == NULL || *str == '\0') {
652                 return False;
653         }
654
655         lval = strtol(str, &end, 10 /* base */);
656         if (end == NULL || *end != '\0' || end == str) {
657                 return set_boolean(str, val);
658         }
659
660         *val = (lval) ? True : False;
661         return True;
662 }
663
664 /**
665  * Convert a size specification like 16K into an integral number of bytes. 
666  **/
667 _PUBLIC_ BOOL conv_str_size(const char * str, uint64_t * val)
668 {
669         char *              end = NULL;
670         unsigned long long  lval;
671
672         if (str == NULL || *str == '\0') {
673                 return False;
674         }
675
676         lval = strtoull(str, &end, 10 /* base */);
677         if (end == NULL || end == str) {
678                 return False;
679         }
680
681         if (*end) {
682                 if (strwicmp(end, "K") == 0) {
683                         lval *= 1024ULL;
684                 } else if (strwicmp(end, "M") == 0) {
685                         lval *= (1024ULL * 1024ULL);
686                 } else if (strwicmp(end, "G") == 0) {
687                         lval *= (1024ULL * 1024ULL * 1024ULL);
688                 } else if (strwicmp(end, "T") == 0) {
689                         lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
690                 } else if (strwicmp(end, "P") == 0) {
691                         lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
692                 } else {
693                         return False;
694                 }
695         }
696
697         *val = (uint64_t)lval;
698         return True;
699 }
700
701 /**
702  * Parse a uint64_t value from a string
703  *
704  * val will be set to the value read.
705  *
706  * @retval True if parsing was successful, False otherwise
707  */
708 _PUBLIC_ BOOL conv_str_u64(const char * str, uint64_t * val)
709 {
710         char *              end = NULL;
711         unsigned long long  lval;
712
713         if (str == NULL || *str == '\0') {
714                 return False;
715         }
716
717         lval = strtoull(str, &end, 10 /* base */);
718         if (end == NULL || *end != '\0' || end == str) {
719                 return False;
720         }
721
722         *val = (uint64_t)lval;
723         return True;
724 }
725
726 /**
727 return the number of bytes occupied by a buffer in CH_UTF16 format
728 the result includes the null termination
729 **/
730 _PUBLIC_ size_t utf16_len(const void *buf)
731 {
732         size_t len;
733
734         for (len = 0; SVAL(buf,len); len += 2) ;
735
736         return len + 2;
737 }
738
739 /**
740 return the number of bytes occupied by a buffer in CH_UTF16 format
741 the result includes the null termination
742 limited by 'n' bytes
743 **/
744 _PUBLIC_ size_t utf16_len_n(const void *src, size_t n)
745 {
746         size_t len;
747
748         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
749
750         if (len+2 <= n) {
751                 len += 2;
752         }
753
754         return len;
755 }
756
757 _PUBLIC_ size_t ucs2_align(const void *base_ptr, const void *p, int flags)
758 {
759         if (flags & (STR_NOALIGN|STR_ASCII))
760                 return 0;
761         return PTR_DIFF(p, base_ptr) & 1;
762 }
763
764 /**
765 Do a case-insensitive, whitespace-ignoring string compare.
766 **/
767 _PUBLIC_ int strwicmp(const char *psz1, const char *psz2)
768 {
769         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
770         /* appropriate value. */
771         if (psz1 == psz2)
772                 return (0);
773         else if (psz1 == NULL)
774                 return (-1);
775         else if (psz2 == NULL)
776                 return (1);
777
778         /* sync the strings on first non-whitespace */
779         while (1) {
780                 while (isspace((int)*psz1))
781                         psz1++;
782                 while (isspace((int)*psz2))
783                         psz2++;
784                 if (toupper((unsigned char)*psz1) != toupper((unsigned char)*psz2) 
785                     || *psz1 == '\0'
786                     || *psz2 == '\0')
787                         break;
788                 psz1++;
789                 psz2++;
790         }
791         return (*psz1 - *psz2);
792 }
793
794 /**
795  String replace.
796 **/
797 _PUBLIC_ void string_replace(char *s, char oldc, char newc)
798 {
799         while (*s) {
800                 s++;
801                 if (*s == oldc) *s = newc;
802         }
803 }
804
805 /**
806  * Compare 2 strings.
807  *
808  * @note The comparison is case-insensitive.
809  **/
810 _PUBLIC_ BOOL strequal(const char *s1, const char *s2)
811 {
812         if (s1 == s2)
813                 return(True);
814         if (!s1 || !s2)
815                 return(False);
816   
817         return strcasecmp(s1,s2) == 0;
818 }