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