Revert that stupid one line change.
[Samba.git] / source3 / lib / util_str.c
blob6d1f8fe023b137991b6c4f15d7f6940aef20f864
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-2001
5 Copyright (C) Simo Sorce 2001-2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /****************************************************************************
25 Get the next token from a string, return False if none found.
26 Handles double-quotes.
27 Based on a routine by GJC@VILLAGE.COM.
28 Extensively modified by Andrew.Tridgell@anu.edu.au
29 ****************************************************************************/
31 BOOL next_token(char **ptr,char *buff, const char *sep, size_t bufsize)
33 char *s;
34 BOOL quoted;
35 size_t len=1;
37 if (!ptr)
38 return(False);
40 s = *ptr;
42 /* default to simple separators */
43 if (!sep)
44 sep = " \t\n\r";
46 /* find the first non sep char */
47 while (*s && strchr_m(sep,*s))
48 s++;
50 /* nothing left? */
51 if (! *s)
52 return(False);
54 /* copy over the token */
55 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
56 if (*s == '\"') {
57 quoted = !quoted;
58 } else {
59 len++;
60 *buff++ = *s;
64 *ptr = (*s) ? s+1 : s;
65 *buff = 0;
67 return(True);
70 /****************************************************************************
71 This is like next_token but is not re-entrant and "remembers" the first
72 parameter so you can pass NULL. This is useful for user interface code
73 but beware the fact that it is not re-entrant!
74 ****************************************************************************/
76 static char *last_ptr=NULL;
78 BOOL next_token_nr(char **ptr,char *buff, const char *sep, size_t bufsize)
80 BOOL ret;
81 if (!ptr)
82 ptr = &last_ptr;
84 ret = next_token(ptr, buff, sep, bufsize);
85 last_ptr = *ptr;
86 return ret;
89 static uint16 tmpbuf[sizeof(pstring)];
91 void set_first_token(char *ptr)
93 last_ptr = ptr;
96 /****************************************************************************
97 Convert list of tokens to array; dependent on above routine.
98 Uses last_ptr from above - bit of a hack.
99 ****************************************************************************/
101 char **toktocliplist(int *ctok, const char *sep)
103 char *s=last_ptr;
104 int ictok=0;
105 char **ret, **iret;
107 if (!sep)
108 sep = " \t\n\r";
110 while(*s && strchr_m(sep,*s))
111 s++;
113 /* nothing left? */
114 if (!*s)
115 return(NULL);
117 do {
118 ictok++;
119 while(*s && (!strchr_m(sep,*s)))
120 s++;
121 while(*s && strchr_m(sep,*s))
122 *s++=0;
123 } while(*s);
125 *ctok=ictok;
126 s=last_ptr;
128 if (!(ret=iret=malloc(ictok*sizeof(char *))))
129 return NULL;
131 while(ictok--) {
132 *iret++=s;
133 while(*s++)
135 while(!*s)
136 s++;
139 return ret;
142 /*******************************************************************
143 Case insensitive string compararison.
144 ********************************************************************/
146 int StrCaseCmp(const char *s, const char *t)
148 pstring buf1, buf2;
149 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
150 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
151 return strcmp(buf1,buf2);
154 /*******************************************************************
155 Case insensitive string compararison, length limited.
156 ********************************************************************/
158 int StrnCaseCmp(const char *s, const char *t, size_t n)
160 pstring buf1, buf2;
161 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
162 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
163 return strncmp(buf1,buf2,n);
166 /*******************************************************************
167 Compare 2 strings.
168 ********************************************************************/
170 BOOL strequal(const char *s1, const char *s2)
172 if (s1 == s2)
173 return(True);
174 if (!s1 || !s2)
175 return(False);
177 return(StrCaseCmp(s1,s2)==0);
180 /*******************************************************************
181 Compare 2 strings up to and including the nth char.
182 ******************************************************************/
184 BOOL strnequal(const char *s1,const char *s2,size_t n)
186 if (s1 == s2)
187 return(True);
188 if (!s1 || !s2 || !n)
189 return(False);
191 return(StrnCaseCmp(s1,s2,n)==0);
194 /*******************************************************************
195 Compare 2 strings (case sensitive).
196 ********************************************************************/
198 BOOL strcsequal(const char *s1,const char *s2)
200 if (s1 == s2)
201 return(True);
202 if (!s1 || !s2)
203 return(False);
205 return(strcmp(s1,s2)==0);
208 /***************************************************************************
209 Do a case-insensitive, whitespace-ignoring string compare.
210 ***************************************************************************/
212 int strwicmp(const char *psz1, const char *psz2)
214 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
215 /* appropriate value. */
216 if (psz1 == psz2)
217 return (0);
218 else if (psz1 == NULL)
219 return (-1);
220 else if (psz2 == NULL)
221 return (1);
223 /* sync the strings on first non-whitespace */
224 while (1) {
225 while (isspace((int)*psz1))
226 psz1++;
227 while (isspace((int)*psz2))
228 psz2++;
229 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
230 || *psz2 == '\0')
231 break;
232 psz1++;
233 psz2++;
235 return (*psz1 - *psz2);
239 /*******************************************************************
240 Convert a string to upper case, but don't modify it.
241 ********************************************************************/
243 char *strupper_static(const char *s)
245 static pstring str;
247 pstrcpy(str, s);
248 strupper(str);
250 return str;
253 /*******************************************************************
254 Convert a string to "normal" form.
255 ********************************************************************/
257 void strnorm(char *s)
259 extern int case_default;
260 if (case_default == CASE_UPPER)
261 strupper(s);
262 else
263 strlower(s);
266 /*******************************************************************
267 Check if a string is in "normal" case.
268 ********************************************************************/
270 BOOL strisnormal(const char *s)
272 extern int case_default;
273 if (case_default == CASE_UPPER)
274 return(!strhaslower(s));
276 return(!strhasupper(s));
280 /****************************************************************************
281 String replace.
282 NOTE: oldc and newc must be 7 bit characters
283 ****************************************************************************/
285 void string_replace(char *s,char oldc,char newc)
287 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
288 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
289 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
292 /*******************************************************************
293 Skip past some strings in a buffer.
294 ********************************************************************/
296 char *skip_string(char *buf,size_t n)
298 while (n--)
299 buf += strlen(buf) + 1;
300 return(buf);
303 /*******************************************************************
304 Count the number of characters in a string. Normally this will
305 be the same as the number of bytes in a string for single byte strings,
306 but will be different for multibyte.
307 ********************************************************************/
309 size_t str_charnum(const char *s)
311 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
312 return strlen_w(tmpbuf);
315 /*******************************************************************
316 Trim the specified elements off the front and back of a string.
317 ********************************************************************/
319 BOOL trim_string(char *s,const char *front,const char *back)
321 BOOL ret = False;
322 size_t front_len;
323 size_t back_len;
324 size_t len;
326 /* Ignore null or empty strings. */
327 if (!s || (s[0] == '\0'))
328 return False;
330 front_len = front? strlen(front) : 0;
331 back_len = back? strlen(back) : 0;
333 len = strlen(s);
335 if (front_len) {
336 while (len && strncmp(s, front, front_len)==0) {
337 memcpy(s, s+front_len, (len-front_len)+1);
338 len -= front_len;
339 ret=True;
343 if (back_len) {
344 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
345 s[len-back_len]='\0';
346 len -= back_len;
347 ret=True;
350 return ret;
353 /****************************************************************************
354 Does a string have any uppercase chars in it?
355 ****************************************************************************/
357 BOOL strhasupper(const char *s)
359 smb_ucs2_t *ptr;
360 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
361 for(ptr=tmpbuf;*ptr;ptr++)
362 if(isupper_w(*ptr))
363 return True;
364 return(False);
367 /****************************************************************************
368 Does a string have any lowercase chars in it?
369 ****************************************************************************/
371 BOOL strhaslower(const char *s)
373 smb_ucs2_t *ptr;
374 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
375 for(ptr=tmpbuf;*ptr;ptr++)
376 if(islower_w(*ptr))
377 return True;
378 return(False);
381 /****************************************************************************
382 Find the number of 'c' chars in a string
383 ****************************************************************************/
385 size_t count_chars(const char *s,char c)
387 smb_ucs2_t *ptr;
388 int count;
389 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
390 for(count=0,ptr=tmpbuf;*ptr;ptr++)
391 if(*ptr==UCS2_CHAR(c))
392 count++;
393 return(count);
396 /*******************************************************************
397 Return True if a string consists only of one particular character.
398 ********************************************************************/
400 BOOL str_is_all(const char *s,char c)
402 smb_ucs2_t *ptr;
404 if(s == NULL)
405 return False;
406 if(!*s)
407 return False;
409 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
410 for(ptr=tmpbuf;*ptr;ptr++)
411 if(*ptr!=UCS2_CHAR(c))
412 return False;
414 return True;
417 /*******************************************************************
418 Safe string copy into a known length string. maxlength does not
419 include the terminating zero.
420 ********************************************************************/
422 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
424 size_t len;
426 if (!dest) {
427 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
428 return NULL;
431 if (!src) {
432 *dest = 0;
433 return dest;
436 len = strlen(src);
438 if (len > maxlength) {
439 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
440 (int)(len-maxlength), src));
441 len = maxlength;
444 memmove(dest, src, len);
445 dest[len] = 0;
446 return dest;
449 /*******************************************************************
450 Safe string cat into a string. maxlength does not
451 include the terminating zero.
452 ********************************************************************/
454 char *safe_strcat(char *dest, const char *src, size_t maxlength)
456 size_t src_len, dest_len;
458 if (!dest) {
459 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
460 return NULL;
463 if (!src)
464 return dest;
466 src_len = strlen(src);
467 dest_len = strlen(dest);
469 if (src_len + dest_len > maxlength) {
470 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
471 (int)(src_len + dest_len - maxlength), src));
472 src_len = maxlength - dest_len;
475 memcpy(&dest[dest_len], src, src_len);
476 dest[dest_len + src_len] = 0;
477 return dest;
480 /*******************************************************************
481 Paranoid strcpy into a buffer of given length (includes terminating
482 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
483 and replaces with '_'. Deliberately does *NOT* check for multibyte
484 characters. Don't change it !
485 ********************************************************************/
487 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
489 size_t len, i;
491 if (!dest) {
492 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
493 return NULL;
496 if (!src) {
497 *dest = 0;
498 return dest;
501 len = strlen(src);
502 if (len >= maxlength)
503 len = maxlength - 1;
505 if (!other_safe_chars)
506 other_safe_chars = "";
508 for(i = 0; i < len; i++) {
509 int val = (src[i] & 0xff);
510 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
511 dest[i] = src[i];
512 else
513 dest[i] = '_';
516 dest[i] = '\0';
518 return dest;
521 /****************************************************************************
522 Like strncpy but always null terminates. Make sure there is room!
523 The variable n should always be one less than the available size.
524 ****************************************************************************/
526 char *StrnCpy(char *dest,const char *src,size_t n)
528 char *d = dest;
529 if (!dest)
530 return(NULL);
531 if (!src) {
532 *dest = 0;
533 return(dest);
535 while (n-- && (*d++ = *src++))
537 *d = 0;
538 return(dest);
541 /****************************************************************************
542 Like strncpy but copies up to the character marker. always null terminates.
543 returns a pointer to the character marker in the source string (src).
544 ****************************************************************************/
546 char *strncpyn(char *dest, const char *src, size_t n, char c)
548 char *p;
549 size_t str_len;
551 p = strchr_m(src, c);
552 if (p == NULL) {
553 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
554 return NULL;
557 str_len = PTR_DIFF(p, src);
558 strncpy(dest, src, MIN(n, str_len));
559 dest[str_len] = '\0';
561 return p;
564 /*************************************************************
565 Routine to get hex characters and turn them into a 16 byte array.
566 the array can be variable length, and any non-hex-numeric
567 characters are skipped. "0xnn" or "0Xnn" is specially catered
568 for.
570 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
572 **************************************************************/
574 size_t strhex_to_str(char *p, size_t len, const char *strhex)
576 size_t i;
577 size_t num_chars = 0;
578 unsigned char lonybble, hinybble;
579 char *hexchars = "0123456789ABCDEF";
580 char *p1 = NULL, *p2 = NULL;
582 for (i = 0; i < len && strhex[i] != 0; i++) {
583 if (strnequal(hexchars, "0x", 2)) {
584 i++; /* skip two chars */
585 continue;
588 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
589 break;
591 i++; /* next hex digit */
593 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
594 break;
596 /* get the two nybbles */
597 hinybble = PTR_DIFF(p1, hexchars);
598 lonybble = PTR_DIFF(p2, hexchars);
600 p[num_chars] = (hinybble << 4) | lonybble;
601 num_chars++;
603 p1 = NULL;
604 p2 = NULL;
606 return num_chars;
609 /****************************************************************************
610 Check if a string is part of a list.
611 ****************************************************************************/
613 BOOL in_list(char *s,char *list,BOOL casesensitive)
615 pstring tok;
616 char *p=list;
618 if (!list)
619 return(False);
621 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
622 if (casesensitive) {
623 if (strcmp(tok,s) == 0)
624 return(True);
625 } else {
626 if (StrCaseCmp(tok,s) == 0)
627 return(True);
630 return(False);
633 /* this is used to prevent lots of mallocs of size 1 */
634 static char *null_string = NULL;
636 /****************************************************************************
637 Set a string value, allocing the space for the string
638 ****************************************************************************/
640 static BOOL string_init(char **dest,const char *src)
642 size_t l;
643 if (!src)
644 src = "";
646 l = strlen(src);
648 if (l == 0) {
649 if (!null_string) {
650 if((null_string = (char *)malloc(1)) == NULL) {
651 DEBUG(0,("string_init: malloc fail for null_string.\n"));
652 return False;
654 *null_string = 0;
656 *dest = null_string;
657 } else {
658 (*dest) = (char *)malloc(l+1);
659 if ((*dest) == NULL) {
660 DEBUG(0,("Out of memory in string_init\n"));
661 return False;
664 pstrcpy(*dest,src);
666 return(True);
669 /****************************************************************************
670 Free a string value.
671 ****************************************************************************/
673 void string_free(char **s)
675 if (!s || !(*s))
676 return;
677 if (*s == null_string)
678 *s = NULL;
679 SAFE_FREE(*s);
682 /****************************************************************************
683 Set a string value, deallocating any existing space, and allocing the space
684 for the string
685 ****************************************************************************/
687 BOOL string_set(char **dest,const char *src)
689 string_free(dest);
690 return(string_init(dest,src));
693 /****************************************************************************
694 Substitute a string for a pattern in another string. Make sure there is
695 enough room!
697 This routine looks for pattern in s and replaces it with
698 insert. It may do multiple replacements.
700 Any of " ; ' $ or ` in the insert string are replaced with _
701 if len==0 then the string cannot be extended. This is different from the old
702 use of len==0 which was for no length checks to be done.
703 ****************************************************************************/
705 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
707 char *p;
708 ssize_t ls,lp,li, i;
710 if (!insert || !pattern || !*pattern || !s)
711 return;
713 ls = (ssize_t)strlen(s);
714 lp = (ssize_t)strlen(pattern);
715 li = (ssize_t)strlen(insert);
717 if (len == 0)
718 len = ls + 1; /* len is number of *bytes* */
720 while (lp <= ls && (p = strstr(s,pattern))) {
721 if (ls + (li-lp) >= len) {
722 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
723 (int)(ls + (li-lp) - len),
724 pattern, (int)len));
725 break;
727 if (li != lp) {
728 memmove(p+li,p+lp,strlen(p+lp)+1);
730 for (i=0;i<li;i++) {
731 switch (insert[i]) {
732 case '`':
733 case '"':
734 case '\'':
735 case ';':
736 case '$':
737 case '%':
738 case '\r':
739 case '\n':
740 p[i] = '_';
741 break;
742 default:
743 p[i] = insert[i];
746 s = p + li;
747 ls += (li-lp);
751 void fstring_sub(char *s,const char *pattern,const char *insert)
753 string_sub(s, pattern, insert, sizeof(fstring));
756 void pstring_sub(char *s,const char *pattern,const char *insert)
758 string_sub(s, pattern, insert, sizeof(pstring));
761 /****************************************************************************
762 Similar to string_sub, but it will accept only allocated strings
763 and may realloc them so pay attention at what you pass on no
764 pointers inside strings, no pstrings or const may be passed
765 as string.
766 ****************************************************************************/
768 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
770 char *p, *in;
771 char *s;
772 ssize_t ls,lp,li,ld, i;
774 if (!insert || !pattern || !*pattern || !string || !*string)
775 return NULL;
777 s = string;
779 in = strdup(insert);
780 if (!in) {
781 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
782 return NULL;
784 ls = (ssize_t)strlen(s);
785 lp = (ssize_t)strlen(pattern);
786 li = (ssize_t)strlen(insert);
787 ld = li - lp;
788 for (i=0;i<li;i++) {
789 switch (in[i]) {
790 case '`':
791 case '"':
792 case '\'':
793 case ';':
794 case '$':
795 case '%':
796 case '\r':
797 case '\n':
798 in[i] = '_';
799 default:
800 /* ok */
801 break;
805 while ((p = strstr(s,pattern))) {
806 if (ld > 0) {
807 char *t = Realloc(string, ls + ld + 1);
808 if (!t) {
809 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
810 SAFE_FREE(in);
811 return NULL;
813 string = t;
814 p = t + (p - s);
816 if (li != lp) {
817 memmove(p+li,p+lp,strlen(p+lp)+1);
819 memcpy(p, in, li);
820 s = p + li;
821 ls += ld;
823 SAFE_FREE(in);
824 return string;
827 /****************************************************************************
828 Similar to string_sub() but allows for any character to be substituted.
829 Use with caution!
830 if len==0 then the string cannot be extended. This is different from the old
831 use of len==0 which was for no length checks to be done.
832 ****************************************************************************/
834 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
836 char *p;
837 ssize_t ls,lp,li;
839 if (!insert || !pattern || !s)
840 return;
842 ls = (ssize_t)strlen(s);
843 lp = (ssize_t)strlen(pattern);
844 li = (ssize_t)strlen(insert);
846 if (!*pattern)
847 return;
849 if (len == 0)
850 len = ls + 1; /* len is number of *bytes* */
852 while (lp <= ls && (p = strstr(s,pattern))) {
853 if (ls + (li-lp) >= len) {
854 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
855 (int)(ls + (li-lp) - len),
856 pattern, (int)len));
857 break;
859 if (li != lp) {
860 memmove(p+li,p+lp,strlen(p+lp)+1);
862 memcpy(p, insert, li);
863 s = p + li;
864 ls += (li-lp);
868 /****************************************************************************
869 Similar to all_string_sub but for unicode strings.
870 Return a new allocated unicode string.
871 similar to string_sub() but allows for any character to be substituted.
872 Use with caution!
873 ****************************************************************************/
875 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
876 const smb_ucs2_t *insert)
878 smb_ucs2_t *r, *rp;
879 const smb_ucs2_t *sp;
880 size_t lr, lp, li, lt;
882 if (!insert || !pattern || !*pattern || !s)
883 return NULL;
885 lt = (size_t)strlen_w(s);
886 lp = (size_t)strlen_w(pattern);
887 li = (size_t)strlen_w(insert);
889 if (li > lp) {
890 const smb_ucs2_t *st = s;
891 int ld = li - lp;
892 while ((sp = strstr_w(st, pattern))) {
893 st = sp + lp;
894 lt += ld;
898 r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
899 if (!r) {
900 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
901 return NULL;
904 while ((sp = strstr_w(s, pattern))) {
905 memcpy(rp, s, (sp - s));
906 rp += ((sp - s) / sizeof(smb_ucs2_t));
907 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
908 s = sp + lp;
909 rp += li;
911 lr = ((rp - r) / sizeof(smb_ucs2_t));
912 if (lr < lt) {
913 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
914 rp += (lt - lr);
916 *rp = 0;
918 return r;
921 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
922 const char *insert)
924 wpstring p, i;
926 if (!insert || !pattern || !s)
927 return NULL;
928 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
929 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
930 return all_string_sub_w(s, p, i);
933 /****************************************************************************
934 Splits out the front and back at a separator.
935 ****************************************************************************/
937 void split_at_last_component(char *path, char *front, char sep, char *back)
939 char *p = strrchr_m(path, sep);
941 if (p != NULL)
942 *p = 0;
944 if (front != NULL)
945 pstrcpy(front, path);
947 if (p != NULL) {
948 if (back != NULL)
949 pstrcpy(back, p+1);
950 *p = '\\';
951 } else {
952 if (back != NULL)
953 back[0] = 0;
957 /****************************************************************************
958 Write an octal as a string.
959 ****************************************************************************/
961 char *octal_string(int i)
963 static char ret[64];
964 if (i == -1)
965 return "-1";
966 slprintf(ret, sizeof(ret)-1, "0%o", i);
967 return ret;
971 /****************************************************************************
972 Truncate a string at a specified length.
973 ****************************************************************************/
975 char *string_truncate(char *s, int length)
977 if (s && strlen(s) > length)
978 s[length] = 0;
979 return s;
982 /****************************************************************************
983 Strchr and strrchr_m are very hard to do on general multi-byte strings.
984 We convert via ucs2 for now.
985 ****************************************************************************/
987 char *strchr_m(const char *s, char c)
989 wpstring ws;
990 pstring s2;
991 smb_ucs2_t *p;
993 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
994 p = strchr_w(ws, UCS2_CHAR(c));
995 if (!p)
996 return NULL;
997 *p = 0;
998 pull_ucs2_pstring(s2, ws);
999 return (char *)(s+strlen(s2));
1002 char *strrchr_m(const char *s, char c)
1004 wpstring ws;
1005 pstring s2;
1006 smb_ucs2_t *p;
1008 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1009 p = strrchr_w(ws, UCS2_CHAR(c));
1010 if (!p)
1011 return NULL;
1012 *p = 0;
1013 pull_ucs2_pstring(s2, ws);
1014 return (char *)(s+strlen(s2));
1017 /*******************************************************************
1018 Convert a string to lower case.
1019 ********************************************************************/
1021 void strlower_m(char *s)
1023 /* this is quite a common operation, so we want it to be
1024 fast. We optimise for the ascii case, knowing that all our
1025 supported multi-byte character sets are ascii-compatible
1026 (ie. they match for the first 128 chars) */
1028 while (*s && !(((unsigned char)s[0]) & 0x7F))
1029 *s++ = tolower((unsigned char)*s);
1031 if (!*s)
1032 return;
1034 /* I assume that lowercased string takes the same number of bytes
1035 * as source string even in UTF-8 encoding. (VIV) */
1036 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
1039 /*******************************************************************
1040 Duplicate convert a string to lower case.
1041 ********************************************************************/
1043 char *strdup_lower(const char *s)
1045 char *t = strdup(s);
1046 if (t == NULL) {
1047 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1048 return NULL;
1050 strlower_m(t);
1051 return t;
1054 /*******************************************************************
1055 Convert a string to upper case.
1056 ********************************************************************/
1058 void strupper_m(char *s)
1060 /* this is quite a common operation, so we want it to be
1061 fast. We optimise for the ascii case, knowing that all our
1062 supported multi-byte character sets are ascii-compatible
1063 (ie. they match for the first 128 chars) */
1065 while (*s && !(((unsigned char)s[0]) & 0x7F))
1066 *s++ = toupper((unsigned char)*s);
1068 if (!*s)
1069 return;
1071 /* I assume that lowercased string takes the same number of bytes
1072 * as source string even in multibyte encoding. (VIV) */
1073 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
1076 /*******************************************************************
1077 Convert a string to upper case.
1078 ********************************************************************/
1080 char *strdup_upper(const char *s)
1082 char *t = strdup(s);
1083 if (t == NULL) {
1084 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1085 return NULL;
1087 strupper_m(t);
1088 return t;
1091 /*******************************************************************
1092 Return a RFC2254 binary string representation of a buffer.
1093 Used in LDAP filters.
1094 Caller must free.
1095 ********************************************************************/
1097 char *binary_string(char *buf, int len)
1099 char *s;
1100 int i, j;
1101 const char *hex = "0123456789ABCDEF";
1102 s = malloc(len * 3 + 1);
1103 if (!s)
1104 return NULL;
1105 for (j=i=0;i<len;i++) {
1106 s[j] = '\\';
1107 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1108 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1109 j += 3;
1111 s[j] = 0;
1112 return s;
1115 /*******************************************************************
1116 Just a typesafety wrapper for snprintf into a pstring.
1117 ********************************************************************/
1119 int pstr_sprintf(pstring s, const char *fmt, ...)
1121 va_list ap;
1122 int ret;
1124 va_start(ap, fmt);
1125 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1126 va_end(ap);
1127 return ret;
1130 /*******************************************************************
1131 Just a typesafety wrapper for snprintf into a fstring.
1132 ********************************************************************/
1134 int fstr_sprintf(fstring s, const char *fmt, ...)
1136 va_list ap;
1137 int ret;
1139 va_start(ap, fmt);
1140 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1141 va_end(ap);
1142 return ret;
1145 #ifndef HAVE_STRNDUP
1146 /*******************************************************************
1147 Some platforms don't have strndup.
1148 ********************************************************************/
1150 char *strndup(const char *s, size_t n)
1152 char *ret;
1154 n = strnlen(s, n);
1155 ret = malloc(n+1);
1156 if (!ret)
1157 return NULL;
1158 memcpy(ret, s, n);
1159 ret[n] = 0;
1161 return ret;
1163 #endif
1165 #ifndef HAVE_STRNLEN
1166 /*******************************************************************
1167 Some platforms don't have strnlen
1168 ********************************************************************/
1170 size_t strnlen(const char *s, size_t n)
1172 int i;
1173 for (i=0; s[i] && i<n; i++)
1174 /* noop */ ;
1175 return i;
1177 #endif
1179 /***********************************************************
1180 List of Strings manipulation functions
1181 ***********************************************************/
1183 #define S_LIST_ABS 16 /* List Allocation Block Size */
1185 char **str_list_make(const char *string, const char *sep)
1187 char **list, **rlist;
1188 char *str, *s;
1189 int num, lsize;
1190 pstring tok;
1192 if (!string || !*string)
1193 return NULL;
1194 s = strdup(string);
1195 if (!s) {
1196 DEBUG(0,("str_list_make: Unable to allocate memory"));
1197 return NULL;
1199 if (!sep) sep = LIST_SEP;
1201 num = lsize = 0;
1202 list = NULL;
1204 str = s;
1205 while (next_token(&str, tok, sep, sizeof(tok))) {
1206 if (num == lsize) {
1207 lsize += S_LIST_ABS;
1208 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1209 if (!rlist) {
1210 DEBUG(0,("str_list_make: Unable to allocate memory"));
1211 str_list_free(&list);
1212 SAFE_FREE(s);
1213 return NULL;
1214 } else
1215 list = rlist;
1216 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1219 list[num] = strdup(tok);
1220 if (!list[num]) {
1221 DEBUG(0,("str_list_make: Unable to allocate memory"));
1222 str_list_free(&list);
1223 SAFE_FREE(s);
1224 return NULL;
1227 num++;
1230 SAFE_FREE(s);
1231 return list;
1234 BOOL str_list_copy(char ***dest, char **src)
1236 char **list, **rlist;
1237 int num, lsize;
1239 *dest = NULL;
1240 if (!src)
1241 return False;
1243 num = lsize = 0;
1244 list = NULL;
1246 while (src[num]) {
1247 if (num == lsize) {
1248 lsize += S_LIST_ABS;
1249 rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1250 if (!rlist) {
1251 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1252 str_list_free(&list);
1253 return False;
1254 } else
1255 list = rlist;
1256 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1259 list[num] = strdup(src[num]);
1260 if (!list[num]) {
1261 DEBUG(0,("str_list_copy: Unable to allocate memory"));
1262 str_list_free(&list);
1263 return False;
1266 num++;
1269 *dest = list;
1270 return True;
1273 /***********************************************************
1274 Return true if all the elements of the list match exactly.
1275 ***********************************************************/
1277 BOOL str_list_compare(char **list1, char **list2)
1279 int num;
1281 if (!list1 || !list2)
1282 return (list1 == list2);
1284 for (num = 0; list1[num]; num++) {
1285 if (!list2[num])
1286 return False;
1287 if (!strcsequal(list1[num], list2[num]))
1288 return False;
1290 if (list2[num])
1291 return False; /* if list2 has more elements than list1 fail */
1293 return True;
1296 void str_list_free(char ***list)
1298 char **tlist;
1300 if (!list || !*list)
1301 return;
1302 tlist = *list;
1303 for(; *tlist; tlist++)
1304 SAFE_FREE(*tlist);
1305 SAFE_FREE(*list);
1308 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1310 char *p, *s, *t;
1311 ssize_t ls, lp, li, ld, i, d;
1313 if (!list)
1314 return False;
1315 if (!pattern)
1316 return False;
1317 if (!insert)
1318 return False;
1320 lp = (ssize_t)strlen(pattern);
1321 li = (ssize_t)strlen(insert);
1322 ld = li -lp;
1324 while (*list) {
1325 s = *list;
1326 ls = (ssize_t)strlen(s);
1328 while ((p = strstr(s, pattern))) {
1329 t = *list;
1330 d = p -t;
1331 if (ld) {
1332 t = (char *) malloc(ls +ld +1);
1333 if (!t) {
1334 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1335 return False;
1337 memcpy(t, *list, d);
1338 memcpy(t +d +li, p +lp, ls -d -lp +1);
1339 SAFE_FREE(*list);
1340 *list = t;
1341 ls += ld;
1342 s = t +d +li;
1345 for (i = 0; i < li; i++) {
1346 switch (insert[i]) {
1347 case '`':
1348 case '"':
1349 case '\'':
1350 case ';':
1351 case '$':
1352 case '%':
1353 case '\r':
1354 case '\n':
1355 t[d +i] = '_';
1356 break;
1357 default:
1358 t[d +i] = insert[i];
1363 list++;
1366 return True;