Some comments about the format of the on-disk reg file, as well as
[Samba/gebeck_regimport.git] / source3 / lib / util_str.c
blobe561d15f61b64b1d196b8d43790f7509975e005f
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) Simo Sorce 2001-2002
7 Copyright (C) Martin Pool 2003
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 /**
27 * @file
28 * @brief String utilities.
29 **/
31 /**
32 * Get the next token from a string, return False if none found.
33 * Handles double-quotes.
35 * Based on a routine by GJC@VILLAGE.COM.
36 * Extensively modified by Andrew.Tridgell@anu.edu.au
37 **/
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
40 const char *s;
41 BOOL quoted;
42 size_t len=1;
44 if (!ptr)
45 return(False);
47 s = *ptr;
49 /* default to simple separators */
50 if (!sep)
51 sep = " \t\n\r";
53 /* find the first non sep char */
54 while (*s && strchr_m(sep,*s))
55 s++;
57 /* nothing left? */
58 if (! *s)
59 return(False);
61 /* copy over the token */
62 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
63 if (*s == '\"') {
64 quoted = !quoted;
65 } else {
66 len++;
67 *buff++ = *s;
71 *ptr = (*s) ? s+1 : s;
72 *buff = 0;
74 return(True);
77 /**
78 This is like next_token but is not re-entrant and "remembers" the first
79 parameter so you can pass NULL. This is useful for user interface code
80 but beware the fact that it is not re-entrant!
81 **/
83 static const char *last_ptr=NULL;
85 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
87 BOOL ret;
88 if (!ptr)
89 ptr = (const char **)&last_ptr;
91 ret = next_token(ptr, buff, sep, bufsize);
92 last_ptr = *ptr;
93 return ret;
96 static uint16 tmpbuf[sizeof(pstring)];
98 void set_first_token(char *ptr)
100 last_ptr = ptr;
104 Convert list of tokens to array; dependent on above routine.
105 Uses last_ptr from above - bit of a hack.
108 char **toktocliplist(int *ctok, const char *sep)
110 char *s=last_ptr;
111 int ictok=0;
112 char **ret, **iret;
114 if (!sep)
115 sep = " \t\n\r";
117 while(*s && strchr_m(sep,*s))
118 s++;
120 /* nothing left? */
121 if (!*s)
122 return(NULL);
124 do {
125 ictok++;
126 while(*s && (!strchr_m(sep,*s)))
127 s++;
128 while(*s && strchr_m(sep,*s))
129 *s++=0;
130 } while(*s);
132 *ctok=ictok;
133 s=last_ptr;
135 if (!(ret=iret=malloc(ictok*sizeof(char *))))
136 return NULL;
138 while(ictok--) {
139 *iret++=s;
140 while(*s++)
142 while(!*s)
143 s++;
146 return ret;
150 * Case insensitive string compararison.
152 * iconv does not directly give us a way to compare strings in
153 * arbitrary unix character sets -- all we can is convert and then
154 * compare. This is expensive.
156 * As an optimization, we do a first pass that considers only the
157 * prefix of the strings that is entirely 7-bit. Within this, we
158 * check whether they have the same value.
160 * Hopefully this will often give the answer without needing to copy.
161 * In particular it should speed comparisons to literal ascii strings
162 * or comparisons of strings that are "obviously" different.
164 * If we find a non-ascii character we fall back to converting via
165 * iconv.
167 * This should never be slower than convering the whole thing, and
168 * often faster.
170 * A different optimization would be to compare for bitwise equality
171 * in the binary encoding. (It would be possible thought hairy to do
172 * both simultaneously.) But in that case if they turn out to be
173 * different, we'd need to restart the whole thing.
175 * Even better is to implement strcasecmp for each encoding and use a
176 * function pointer.
178 int StrCaseCmp(const char *s, const char *t)
181 const char * ps, * pt;
182 pstring buf1, buf2;
184 for (ps = s, pt = t; ; ps++, pt++) {
185 char us, ut;
187 if (!*ps && !*pt)
188 return 0; /* both ended */
189 else if (!*ps)
190 return -1; /* s is a prefix */
191 else if (!*pt)
192 return +1; /* t is a prefix */
193 else if ((*ps & 0x80) || (*pt & 0x80))
194 /* not ascii anymore, do it the hard way from here on in */
195 break;
197 us = toupper(*ps);
198 ut = toupper(*pt);
199 if (us == ut)
200 continue;
201 else if (us < ut)
202 return -1;
203 else if (us > ut)
204 return +1;
207 /* TODO: Don't do this with a fixed-length buffer. This could
208 * still be much more efficient. */
209 /* TODO: Hardcode a char-by-char comparison for UTF-8, which
210 * can be much faster. */
211 /* TODO: Test case for this! */
213 unix_strupper(ps, strlen(ps)+1, buf1, sizeof(buf1));
214 unix_strupper(pt, strlen(pt)+1, buf2, sizeof(buf2));
216 return strcmp(buf1, buf2);
221 Case insensitive string compararison, length limited.
223 int StrnCaseCmp(const char *s, const char *t, size_t n)
225 pstring buf1, buf2;
226 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
227 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
228 return strncmp(buf1,buf2,n);
232 * Compare 2 strings.
234 * @note The comparison is case-insensitive.
236 BOOL strequal(const char *s1, const char *s2)
238 if (s1 == s2)
239 return(True);
240 if (!s1 || !s2)
241 return(False);
243 return(StrCaseCmp(s1,s2)==0);
247 * Compare 2 strings up to and including the nth char.
249 * @note The comparison is case-insensitive.
251 BOOL strnequal(const char *s1,const char *s2,size_t n)
253 if (s1 == s2)
254 return(True);
255 if (!s1 || !s2 || !n)
256 return(False);
258 return(StrnCaseCmp(s1,s2,n)==0);
262 Compare 2 strings (case sensitive).
265 BOOL strcsequal(const char *s1,const char *s2)
267 if (s1 == s2)
268 return(True);
269 if (!s1 || !s2)
270 return(False);
272 return(strcmp(s1,s2)==0);
276 Do a case-insensitive, whitespace-ignoring string compare.
279 int strwicmp(const char *psz1, const char *psz2)
281 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
282 /* appropriate value. */
283 if (psz1 == psz2)
284 return (0);
285 else if (psz1 == NULL)
286 return (-1);
287 else if (psz2 == NULL)
288 return (1);
290 /* sync the strings on first non-whitespace */
291 while (1) {
292 while (isspace((int)*psz1))
293 psz1++;
294 while (isspace((int)*psz2))
295 psz2++;
296 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
297 || *psz2 == '\0')
298 break;
299 psz1++;
300 psz2++;
302 return (*psz1 - *psz2);
307 Convert a string to upper case, but don't modify it.
310 char *strupper_static(const char *s)
312 static pstring str;
314 pstrcpy(str, s);
315 strupper(str);
317 return str;
321 Convert a string to "normal" form.
324 void strnorm(char *s)
326 extern int case_default;
327 if (case_default == CASE_UPPER)
328 strupper(s);
329 else
330 strlower(s);
334 Check if a string is in "normal" case.
337 BOOL strisnormal(const char *s)
339 extern int case_default;
340 if (case_default == CASE_UPPER)
341 return(!strhaslower(s));
343 return(!strhasupper(s));
348 String replace.
349 NOTE: oldc and newc must be 7 bit characters
352 void string_replace(char *s,char oldc,char newc)
354 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
355 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
356 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
360 Skip past some strings in a buffer.
363 char *skip_string(char *buf,size_t n)
365 while (n--)
366 buf += strlen(buf) + 1;
367 return(buf);
371 Count the number of characters in a string. Normally this will
372 be the same as the number of bytes in a string for single byte strings,
373 but will be different for multibyte.
376 size_t str_charnum(const char *s)
378 uint16 tmpbuf2[sizeof(pstring)];
379 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
380 return strlen_w(tmpbuf2);
384 Count the number of characters in a string. Normally this will
385 be the same as the number of bytes in a string for single byte strings,
386 but will be different for multibyte.
389 size_t str_ascii_charnum(const char *s)
391 pstring tmpbuf2;
392 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
393 return strlen(tmpbuf2);
397 Trim the specified elements off the front and back of a string.
400 BOOL trim_string(char *s,const char *front,const char *back)
402 BOOL ret = False;
403 size_t front_len;
404 size_t back_len;
405 size_t len;
407 /* Ignore null or empty strings. */
408 if (!s || (s[0] == '\0'))
409 return False;
411 front_len = front? strlen(front) : 0;
412 back_len = back? strlen(back) : 0;
414 len = strlen(s);
416 if (front_len) {
417 while (len && strncmp(s, front, front_len)==0) {
418 memcpy(s, s+front_len, (len-front_len)+1);
419 len -= front_len;
420 ret=True;
424 if (back_len) {
425 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
426 s[len-back_len]='\0';
427 len -= back_len;
428 ret=True;
431 return ret;
435 Does a string have any uppercase chars in it?
438 BOOL strhasupper(const char *s)
440 smb_ucs2_t *ptr;
441 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
442 for(ptr=tmpbuf;*ptr;ptr++)
443 if(isupper_w(*ptr))
444 return True;
445 return(False);
449 Does a string have any lowercase chars in it?
452 BOOL strhaslower(const char *s)
454 smb_ucs2_t *ptr;
455 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
456 for(ptr=tmpbuf;*ptr;ptr++)
457 if(islower_w(*ptr))
458 return True;
459 return(False);
463 Find the number of 'c' chars in a string
466 size_t count_chars(const char *s,char c)
468 smb_ucs2_t *ptr;
469 int count;
470 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
471 for(count=0,ptr=tmpbuf;*ptr;ptr++)
472 if(*ptr==UCS2_CHAR(c))
473 count++;
474 return(count);
478 Safe string copy into a known length string. maxlength does not
479 include the terminating zero.
482 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
484 size_t len;
486 if (!dest) {
487 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
488 return NULL;
491 clobber_region(fn,line,dest, maxlength+1);
493 if (!src) {
494 *dest = 0;
495 return dest;
498 len = strnlen(src, maxlength+1);
500 if (len > maxlength) {
501 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
502 (unsigned int)(len-maxlength), len, maxlength, src));
503 len = maxlength;
506 memmove(dest, src, len);
507 dest[len] = 0;
508 return dest;
512 Safe string cat into a string. maxlength does not
513 include the terminating zero.
515 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
517 size_t src_len, dest_len;
519 if (!dest) {
520 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
521 return NULL;
524 if (!src)
525 return dest;
527 src_len = strnlen(src, maxlength + 1);
528 dest_len = strnlen(dest, maxlength + 1);
530 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
532 if (src_len + dest_len > maxlength) {
533 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
534 (int)(src_len + dest_len - maxlength), src));
535 if (maxlength > dest_len) {
536 memcpy(&dest[dest_len], src, maxlength - dest_len);
538 dest[maxlength] = 0;
539 return NULL;
542 memcpy(&dest[dest_len], src, src_len);
543 dest[dest_len + src_len] = 0;
544 return dest;
548 Paranoid strcpy into a buffer of given length (includes terminating
549 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
550 and replaces with '_'. Deliberately does *NOT* check for multibyte
551 characters. Don't change it !
553 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
555 size_t len, i;
557 clobber_region(fn, line, dest, maxlength);
559 if (!dest) {
560 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
561 return NULL;
564 if (!src) {
565 *dest = 0;
566 return dest;
569 len = strlen(src);
570 if (len >= maxlength)
571 len = maxlength - 1;
573 if (!other_safe_chars)
574 other_safe_chars = "";
576 for(i = 0; i < len; i++) {
577 int val = (src[i] & 0xff);
578 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
579 dest[i] = src[i];
580 else
581 dest[i] = '_';
584 dest[i] = '\0';
586 return dest;
590 Like strncpy but always null terminates. Make sure there is room!
591 The variable n should always be one less than the available size.
593 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
595 char *d = dest;
597 clobber_region(fn, line, dest, n+1);
599 if (!dest)
600 return(NULL);
602 if (!src) {
603 *dest = 0;
604 return(dest);
607 while (n-- && (*d = *src)) {
608 d++;
609 src++;
612 *d = 0;
613 return(dest);
616 #if 0
618 Like strncpy but copies up to the character marker. always null terminates.
619 returns a pointer to the character marker in the source string (src).
622 static char *strncpyn(char *dest, const char *src, size_t n, char c)
624 char *p;
625 size_t str_len;
627 clobber_region(dest, n+1);
629 p = strchr_m(src, c);
630 if (p == NULL) {
631 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
632 return NULL;
635 str_len = PTR_DIFF(p, src);
636 strncpy(dest, src, MIN(n, str_len));
637 dest[str_len] = '\0';
639 return p;
641 #endif
644 Routine to get hex characters and turn them into a 16 byte array.
645 the array can be variable length, and any non-hex-numeric
646 characters are skipped. "0xnn" or "0Xnn" is specially catered
647 for.
649 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
653 size_t strhex_to_str(char *p, size_t len, const char *strhex)
655 size_t i;
656 size_t num_chars = 0;
657 unsigned char lonybble, hinybble;
658 const char *hexchars = "0123456789ABCDEF";
659 char *p1 = NULL, *p2 = NULL;
661 for (i = 0; i < len && strhex[i] != 0; i++) {
662 if (strnequal(hexchars, "0x", 2)) {
663 i++; /* skip two chars */
664 continue;
667 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
668 break;
670 i++; /* next hex digit */
672 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
673 break;
675 /* get the two nybbles */
676 hinybble = PTR_DIFF(p1, hexchars);
677 lonybble = PTR_DIFF(p2, hexchars);
679 p[num_chars] = (hinybble << 4) | lonybble;
680 num_chars++;
682 p1 = NULL;
683 p2 = NULL;
685 return num_chars;
689 * Routine to print a buffer as HEX digits, into an allocated string.
692 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
694 int i;
695 char *hex_buffer;
697 *out_hex_buffer = smb_xmalloc((len*2)+1);
698 hex_buffer = *out_hex_buffer;
700 for (i = 0; i < len; i++)
701 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
705 Check if a string is part of a list.
708 BOOL in_list(char *s,char *list,BOOL casesensitive)
710 pstring tok;
711 const char *p=list;
713 if (!list)
714 return(False);
716 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
717 if (casesensitive) {
718 if (strcmp(tok,s) == 0)
719 return(True);
720 } else {
721 if (StrCaseCmp(tok,s) == 0)
722 return(True);
725 return(False);
728 /* this is used to prevent lots of mallocs of size 1 */
729 static char *null_string = NULL;
732 Set a string value, allocing the space for the string
735 static BOOL string_init(char **dest,const char *src)
737 size_t l;
738 if (!src)
739 src = "";
741 l = strlen(src);
743 if (l == 0) {
744 if (!null_string) {
745 if((null_string = (char *)malloc(1)) == NULL) {
746 DEBUG(0,("string_init: malloc fail for null_string.\n"));
747 return False;
749 *null_string = 0;
751 *dest = null_string;
752 } else {
753 (*dest) = strdup(src);
754 if ((*dest) == NULL) {
755 DEBUG(0,("Out of memory in string_init\n"));
756 return False;
759 return(True);
763 Free a string value.
766 void string_free(char **s)
768 if (!s || !(*s))
769 return;
770 if (*s == null_string)
771 *s = NULL;
772 SAFE_FREE(*s);
776 Set a string value, deallocating any existing space, and allocing the space
777 for the string
780 BOOL string_set(char **dest,const char *src)
782 string_free(dest);
783 return(string_init(dest,src));
787 Substitute a string for a pattern in another string. Make sure there is
788 enough room!
790 This routine looks for pattern in s and replaces it with
791 insert. It may do multiple replacements.
793 Any of " ; ' $ or ` in the insert string are replaced with _
794 if len==0 then the string cannot be extended. This is different from the old
795 use of len==0 which was for no length checks to be done.
798 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
800 char *p;
801 ssize_t ls,lp,li, i;
803 if (!insert || !pattern || !*pattern || !s)
804 return;
806 ls = (ssize_t)strlen(s);
807 lp = (ssize_t)strlen(pattern);
808 li = (ssize_t)strlen(insert);
810 if (len == 0)
811 len = ls + 1; /* len is number of *bytes* */
813 while (lp <= ls && (p = strstr(s,pattern))) {
814 if (ls + (li-lp) >= len) {
815 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
816 (int)(ls + (li-lp) - len),
817 pattern, (int)len));
818 break;
820 if (li != lp) {
821 memmove(p+li,p+lp,strlen(p+lp)+1);
823 for (i=0;i<li;i++) {
824 switch (insert[i]) {
825 case '`':
826 case '"':
827 case '\'':
828 case ';':
829 case '$':
830 case '%':
831 case '\r':
832 case '\n':
833 p[i] = '_';
834 break;
835 default:
836 p[i] = insert[i];
839 s = p + li;
840 ls += (li-lp);
844 void fstring_sub(char *s,const char *pattern,const char *insert)
846 string_sub(s, pattern, insert, sizeof(fstring));
849 void pstring_sub(char *s,const char *pattern,const char *insert)
851 string_sub(s, pattern, insert, sizeof(pstring));
855 Similar to string_sub, but it will accept only allocated strings
856 and may realloc them so pay attention at what you pass on no
857 pointers inside strings, no pstrings or const may be passed
858 as string.
861 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
863 char *p, *in;
864 char *s;
865 ssize_t ls,lp,li,ld, i;
867 if (!insert || !pattern || !*pattern || !string || !*string)
868 return NULL;
870 s = string;
872 in = strdup(insert);
873 if (!in) {
874 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
875 return NULL;
877 ls = (ssize_t)strlen(s);
878 lp = (ssize_t)strlen(pattern);
879 li = (ssize_t)strlen(insert);
880 ld = li - lp;
881 for (i=0;i<li;i++) {
882 switch (in[i]) {
883 case '`':
884 case '"':
885 case '\'':
886 case ';':
887 case '$':
888 case '%':
889 case '\r':
890 case '\n':
891 in[i] = '_';
892 default:
893 /* ok */
894 break;
898 while ((p = strstr(s,pattern))) {
899 if (ld > 0) {
900 char *t = Realloc(string, ls + ld + 1);
901 if (!t) {
902 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
903 SAFE_FREE(in);
904 return NULL;
906 string = t;
907 p = t + (p - s);
909 if (li != lp) {
910 memmove(p+li,p+lp,strlen(p+lp)+1);
912 memcpy(p, in, li);
913 s = p + li;
914 ls += ld;
916 SAFE_FREE(in);
917 return string;
921 Similar to string_sub() but allows for any character to be substituted.
922 Use with caution!
923 if len==0 then the string cannot be extended. This is different from the old
924 use of len==0 which was for no length checks to be done.
927 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
929 char *p;
930 ssize_t ls,lp,li;
932 if (!insert || !pattern || !s)
933 return;
935 ls = (ssize_t)strlen(s);
936 lp = (ssize_t)strlen(pattern);
937 li = (ssize_t)strlen(insert);
939 if (!*pattern)
940 return;
942 if (len == 0)
943 len = ls + 1; /* len is number of *bytes* */
945 while (lp <= ls && (p = strstr(s,pattern))) {
946 if (ls + (li-lp) >= len) {
947 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
948 (int)(ls + (li-lp) - len),
949 pattern, (int)len));
950 break;
952 if (li != lp) {
953 memmove(p+li,p+lp,strlen(p+lp)+1);
955 memcpy(p, insert, li);
956 s = p + li;
957 ls += (li-lp);
962 Similar to all_string_sub but for unicode strings.
963 Return a new allocated unicode string.
964 similar to string_sub() but allows for any character to be substituted.
965 Use with caution!
968 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
969 const smb_ucs2_t *insert)
971 smb_ucs2_t *r, *rp;
972 const smb_ucs2_t *sp;
973 size_t lr, lp, li, lt;
975 if (!insert || !pattern || !*pattern || !s)
976 return NULL;
978 lt = (size_t)strlen_w(s);
979 lp = (size_t)strlen_w(pattern);
980 li = (size_t)strlen_w(insert);
982 if (li > lp) {
983 const smb_ucs2_t *st = s;
984 int ld = li - lp;
985 while ((sp = strstr_w(st, pattern))) {
986 st = sp + lp;
987 lt += ld;
991 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
992 if (!r) {
993 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
994 return NULL;
997 while ((sp = strstr_w(s, pattern))) {
998 memcpy(rp, s, (sp - s));
999 rp += ((sp - s) / sizeof(smb_ucs2_t));
1000 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1001 s = sp + lp;
1002 rp += li;
1004 lr = ((rp - r) / sizeof(smb_ucs2_t));
1005 if (lr < lt) {
1006 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1007 rp += (lt - lr);
1009 *rp = 0;
1011 return r;
1014 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1015 const char *insert)
1017 wpstring p, i;
1019 if (!insert || !pattern || !s)
1020 return NULL;
1021 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1022 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1023 return all_string_sub_w(s, p, i);
1026 #if 0
1028 Splits out the front and back at a separator.
1031 static void split_at_last_component(char *path, char *front, char sep, char *back)
1033 char *p = strrchr_m(path, sep);
1035 if (p != NULL)
1036 *p = 0;
1038 if (front != NULL)
1039 pstrcpy(front, path);
1041 if (p != NULL) {
1042 if (back != NULL)
1043 pstrcpy(back, p+1);
1044 *p = '\\';
1045 } else {
1046 if (back != NULL)
1047 back[0] = 0;
1050 #endif
1053 Write an octal as a string.
1056 const char *octal_string(int i)
1058 static char ret[64];
1059 if (i == -1)
1060 return "-1";
1061 slprintf(ret, sizeof(ret)-1, "0%o", i);
1062 return ret;
1067 Truncate a string at a specified length.
1070 char *string_truncate(char *s, unsigned int length)
1072 if (s && strlen(s) > length)
1073 s[length] = 0;
1074 return s;
1078 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1079 We convert via ucs2 for now.
1082 char *strchr_m(const char *s, char c)
1084 wpstring ws;
1085 pstring s2;
1086 smb_ucs2_t *p;
1088 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1089 p = strchr_w(ws, UCS2_CHAR(c));
1090 if (!p)
1091 return NULL;
1092 *p = 0;
1093 pull_ucs2_pstring(s2, ws);
1094 return (char *)(s+strlen(s2));
1097 char *strrchr_m(const char *s, char c)
1099 wpstring ws;
1100 pstring s2;
1101 smb_ucs2_t *p;
1103 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1104 p = strrchr_w(ws, UCS2_CHAR(c));
1105 if (!p)
1106 return NULL;
1107 *p = 0;
1108 pull_ucs2_pstring(s2, ws);
1109 return (char *)(s+strlen(s2));
1113 Convert a string to lower case.
1116 void strlower_m(char *s)
1118 /* this is quite a common operation, so we want it to be
1119 fast. We optimise for the ascii case, knowing that all our
1120 supported multi-byte character sets are ascii-compatible
1121 (ie. they match for the first 128 chars) */
1123 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1124 *s = tolower((unsigned char)*s);
1125 s++;
1128 if (!*s)
1129 return;
1131 /* I assume that lowercased string takes the same number of bytes
1132 * as source string even in UTF-8 encoding. (VIV) */
1133 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1137 Duplicate convert a string to lower case.
1140 char *strdup_lower(const char *s)
1142 char *t = strdup(s);
1143 if (t == NULL) {
1144 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1145 return NULL;
1147 strlower_m(t);
1148 return t;
1152 Convert a string to upper case.
1155 void strupper_m(char *s)
1157 /* this is quite a common operation, so we want it to be
1158 fast. We optimise for the ascii case, knowing that all our
1159 supported multi-byte character sets are ascii-compatible
1160 (ie. they match for the first 128 chars) */
1162 while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1163 *s = toupper((unsigned char)*s);
1164 s++;
1167 if (!*s)
1168 return;
1170 /* I assume that lowercased string takes the same number of bytes
1171 * as source string even in multibyte encoding. (VIV) */
1172 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1176 Convert a string to upper case.
1179 char *strdup_upper(const char *s)
1181 char *t = strdup(s);
1182 if (t == NULL) {
1183 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1184 return NULL;
1186 strupper_m(t);
1187 return t;
1191 Return a RFC2254 binary string representation of a buffer.
1192 Used in LDAP filters.
1193 Caller must free.
1196 char *binary_string(char *buf, int len)
1198 char *s;
1199 int i, j;
1200 const char *hex = "0123456789ABCDEF";
1201 s = malloc(len * 3 + 1);
1202 if (!s)
1203 return NULL;
1204 for (j=i=0;i<len;i++) {
1205 s[j] = '\\';
1206 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1207 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1208 j += 3;
1210 s[j] = 0;
1211 return s;
1215 Just a typesafety wrapper for snprintf into a pstring.
1218 int pstr_sprintf(pstring s, const char *fmt, ...)
1220 va_list ap;
1221 int ret;
1223 va_start(ap, fmt);
1224 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1225 va_end(ap);
1226 return ret;
1231 Just a typesafety wrapper for snprintf into a fstring.
1234 int fstr_sprintf(fstring s, const char *fmt, ...)
1236 va_list ap;
1237 int ret;
1239 va_start(ap, fmt);
1240 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1241 va_end(ap);
1242 return ret;
1246 #ifndef HAVE_STRNDUP
1248 Some platforms don't have strndup.
1251 char *strndup(const char *s, size_t n)
1253 char *ret;
1255 n = strnlen(s, n);
1256 ret = malloc(n+1);
1257 if (!ret)
1258 return NULL;
1259 memcpy(ret, s, n);
1260 ret[n] = 0;
1262 return ret;
1264 #endif
1266 #ifndef HAVE_STRNLEN
1268 Some platforms don't have strnlen
1271 size_t strnlen(const char *s, size_t n)
1273 int i;
1274 for (i=0; s[i] && i<n; i++)
1275 /* noop */ ;
1276 return i;
1278 #endif
1281 List of Strings manipulation functions
1284 #define S_LIST_ABS 16 /* List Allocation Block Size */
1286 char **str_list_make(const char *string, const char *sep)
1288 char **list, **rlist;
1289 const char *str;
1290 char *s;
1291 int num, lsize;
1292 pstring tok;
1294 if (!string || !*string)
1295 return NULL;
1296 s = strdup(string);
1297 if (!s) {
1298 DEBUG(0,("str_list_make: Unable to allocate memory"));
1299 return NULL;
1301 if (!sep) sep = LIST_SEP;
1303 num = lsize = 0;
1304 list = NULL;
1306 str = s;
1307 while (next_token(&str, tok, sep, sizeof(tok))) {
1308 if (num == lsize) {
1309 lsize += S_LIST_ABS;
1310 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1311 if (!rlist) {
1312 DEBUG(0,("str_list_make: Unable to allocate memory"));
1313 str_list_free(&list);
1314 SAFE_FREE(s);
1315 return NULL;
1316 } else
1317 list = rlist;
1318 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1321 list[num] = strdup(tok);
1322 if (!list[num]) {
1323 DEBUG(0,("str_list_make: Unable to allocate memory"));
1324 str_list_free(&list);
1325 SAFE_FREE(s);
1326 return NULL;
1329 num++;
1332 SAFE_FREE(s);
1333 return list;
1336 BOOL str_list_copy(char ***dest, const char **src)
1338 char **list, **rlist;
1339 int num, lsize;
1341 *dest = NULL;
1342 if (!src)
1343 return False;
1345 num = lsize = 0;
1346 list = NULL;
1348 while (src[num]) {
1349 if (num == lsize) {
1350 lsize += S_LIST_ABS;
1351 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1352 if (!rlist) {
1353 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1354 str_list_free(&list);
1355 return False;
1356 } else
1357 list = rlist;
1358 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1361 list[num] = strdup(src[num]);
1362 if (!list[num]) {
1363 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1364 str_list_free(&list);
1365 return False;
1368 num++;
1371 *dest = list;
1372 return True;
1376 * Return true if all the elements of the list match exactly.
1378 BOOL str_list_compare(char **list1, char **list2)
1380 int num;
1382 if (!list1 || !list2)
1383 return (list1 == list2);
1385 for (num = 0; list1[num]; num++) {
1386 if (!list2[num])
1387 return False;
1388 if (!strcsequal(list1[num], list2[num]))
1389 return False;
1391 if (list2[num])
1392 return False; /* if list2 has more elements than list1 fail */
1394 return True;
1397 void str_list_free(char ***list)
1399 char **tlist;
1401 if (!list || !*list)
1402 return;
1403 tlist = *list;
1404 for(; *tlist; tlist++)
1405 SAFE_FREE(*tlist);
1406 SAFE_FREE(*list);
1409 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1411 char *p, *s, *t;
1412 ssize_t ls, lp, li, ld, i, d;
1414 if (!list)
1415 return False;
1416 if (!pattern)
1417 return False;
1418 if (!insert)
1419 return False;
1421 lp = (ssize_t)strlen(pattern);
1422 li = (ssize_t)strlen(insert);
1423 ld = li -lp;
1425 while (*list) {
1426 s = *list;
1427 ls = (ssize_t)strlen(s);
1429 while ((p = strstr(s, pattern))) {
1430 t = *list;
1431 d = p -t;
1432 if (ld) {
1433 t = (char *) malloc(ls +ld +1);
1434 if (!t) {
1435 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1436 return False;
1438 memcpy(t, *list, d);
1439 memcpy(t +d +li, p +lp, ls -d -lp +1);
1440 SAFE_FREE(*list);
1441 *list = t;
1442 ls += ld;
1443 s = t +d +li;
1446 for (i = 0; i < li; i++) {
1447 switch (insert[i]) {
1448 case '`':
1449 case '"':
1450 case '\'':
1451 case ';':
1452 case '$':
1453 case '%':
1454 case '\r':
1455 case '\n':
1456 t[d +i] = '_';
1457 break;
1458 default:
1459 t[d +i] = insert[i];
1464 list++;
1467 return True;
1471 #define IPSTR_LIST_SEP ","
1474 * Add ip string representation to ipstr list. Used also
1475 * as part of @function ipstr_list_make
1477 * @param ipstr_list pointer to string containing ip list;
1478 * MUST BE already allocated and IS reallocated if necessary
1479 * @param ipstr_size pointer to current size of ipstr_list (might be changed
1480 * as a result of reallocation)
1481 * @param ip IP address which is to be added to list
1482 * @return pointer to string appended with new ip and possibly
1483 * reallocated to new length
1486 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1488 char* new_ipstr = NULL;
1490 /* arguments checking */
1491 if (!ipstr_list || !ip) return NULL;
1493 /* attempt to convert ip to a string and append colon separator to it */
1494 if (*ipstr_list) {
1495 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1496 SAFE_FREE(*ipstr_list);
1497 } else {
1498 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1500 *ipstr_list = new_ipstr;
1501 return *ipstr_list;
1506 * Allocate and initialise an ipstr list using ip adresses
1507 * passed as arguments.
1509 * @param ipstr_list pointer to string meant to be allocated and set
1510 * @param ip_list array of ip addresses to place in the list
1511 * @param ip_count number of addresses stored in ip_list
1512 * @return pointer to allocated ip string
1515 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1517 int i;
1519 /* arguments checking */
1520 if (!ip_list && !ipstr_list) return 0;
1522 *ipstr_list = NULL;
1524 /* process ip addresses given as arguments */
1525 for (i = 0; i < ip_count; i++)
1526 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1528 return (*ipstr_list);
1533 * Parse given ip string list into array of ip addresses
1534 * (as in_addr structures)
1536 * @param ipstr ip string list to be parsed
1537 * @param ip_list pointer to array of ip addresses which is
1538 * allocated by this function and must be freed by caller
1539 * @return number of succesfully parsed addresses
1542 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1544 fstring token_str;
1545 int count;
1547 if (!ipstr_list || !ip_list) return 0;
1549 for (*ip_list = NULL, count = 0;
1550 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1551 count++) {
1553 struct in_addr addr;
1555 /* convert single token to ip address */
1556 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1557 break;
1559 /* prepare place for another in_addr structure */
1560 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1561 if (!*ip_list) return -1;
1563 (*ip_list)[count] = addr;
1566 return count;
1571 * Safely free ip string list
1573 * @param ipstr_list ip string list to be freed
1576 void ipstr_list_free(char* ipstr_list)
1578 SAFE_FREE(ipstr_list);
1583 Unescape a URL encoded string, in place.
1586 void rfc1738_unescape(char *buf)
1588 char *p=buf;
1590 while ((p=strchr_m(p,'+')))
1591 *p = ' ';
1593 p = buf;
1595 while (p && *p && (p=strchr_m(p,'%'))) {
1596 int c1 = p[1];
1597 int c2 = p[2];
1599 if (c1 >= '0' && c1 <= '9')
1600 c1 = c1 - '0';
1601 else if (c1 >= 'A' && c1 <= 'F')
1602 c1 = 10 + c1 - 'A';
1603 else if (c1 >= 'a' && c1 <= 'f')
1604 c1 = 10 + c1 - 'a';
1605 else {p++; continue;}
1607 if (c2 >= '0' && c2 <= '9')
1608 c2 = c2 - '0';
1609 else if (c2 >= 'A' && c2 <= 'F')
1610 c2 = 10 + c2 - 'A';
1611 else if (c2 >= 'a' && c2 <= 'f')
1612 c2 = 10 + c2 - 'a';
1613 else {p++; continue;}
1615 *p = (c1<<4) | c2;
1617 memmove(p+1, p+3, strlen(p+3)+1);
1618 p++;
1622 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1625 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1627 DATA_BLOB base64_decode_data_blob(const char *s)
1629 int bit_offset, byte_offset, idx, i, n;
1630 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1631 unsigned char *d = decoded.data;
1632 char *p;
1634 n=i=0;
1636 while (*s && (p=strchr_m(b64,*s))) {
1637 idx = (int)(p - b64);
1638 byte_offset = (i*6)/8;
1639 bit_offset = (i*6)%8;
1640 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1641 if (bit_offset < 3) {
1642 d[byte_offset] |= (idx << (2-bit_offset));
1643 n = byte_offset+1;
1644 } else {
1645 d[byte_offset] |= (idx >> (bit_offset-2));
1646 d[byte_offset+1] = 0;
1647 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1648 n = byte_offset+2;
1650 s++; i++;
1653 /* fix up length */
1654 decoded.length = n;
1655 return decoded;
1659 * Decode a base64 string in-place - wrapper for the above
1661 void base64_decode_inplace(char *s)
1663 DATA_BLOB decoded = base64_decode_data_blob(s);
1664 memcpy(s, decoded.data, decoded.length);
1665 /* null terminate */
1666 s[decoded.length] = '\0';
1668 data_blob_free(&decoded);
1672 * Encode a base64 string into a malloc()ed string caller to free.
1674 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1676 char * base64_encode_data_blob(DATA_BLOB data)
1678 int bits = 0;
1679 int char_count = 0;
1680 size_t out_cnt = 0;
1681 size_t len = data.length;
1682 size_t output_len = data.length * 2;
1683 char *result = malloc(output_len); /* get us plenty of space */
1685 while (len-- && out_cnt < (data.length * 2) - 5) {
1686 int c = (unsigned char) *(data.data++);
1687 bits += c;
1688 char_count++;
1689 if (char_count == 3) {
1690 result[out_cnt++] = b64[bits >> 18];
1691 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1692 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1693 result[out_cnt++] = b64[bits & 0x3f];
1694 bits = 0;
1695 char_count = 0;
1696 } else {
1697 bits <<= 8;
1700 if (char_count != 0) {
1701 bits <<= 16 - (8 * char_count);
1702 result[out_cnt++] = b64[bits >> 18];
1703 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1704 if (char_count == 1) {
1705 result[out_cnt++] = '=';
1706 result[out_cnt++] = '=';
1707 } else {
1708 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1709 result[out_cnt++] = '=';
1712 result[out_cnt] = '\0'; /* terminate */
1713 return result;