2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
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.
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 ****************************************************************************/
30 BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
36 if (!ptr) return(False);
40 /* default to simple separators */
41 if (!sep) sep = " \t\n\r";
43 /* find the first non sep char */
44 while (*s && strchr_m(sep,*s)) s++;
47 if (! *s) return(False);
49 /* copy over the token */
50 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
59 *ptr = (*s) ? s+1 : s;
67 /****************************************************************************
68 This is like next_token but is not re-entrant and "remembers" the first
69 parameter so you can pass NULL. This is useful for user interface code
70 but beware the fact that it is not re-entrant!
71 ****************************************************************************/
72 static char *last_ptr=NULL;
74 BOOL next_token_nr(char **ptr,char *buff,char *sep, size_t bufsize)
77 if (!ptr) ptr = &last_ptr;
79 ret = next_token(ptr, buff, sep, bufsize);
84 static uint16 tmpbuf[sizeof(pstring)];
86 void set_first_token(char *ptr)
92 /****************************************************************************
93 Convert list of tokens to array; dependent on above routine.
94 Uses last_ptr from above - bit of a hack.
95 ****************************************************************************/
96 char **toktocliplist(int *ctok, char *sep)
102 if (!sep) sep = " \t\n\r";
104 while(*s && strchr_m(sep,*s)) s++;
107 if (!*s) return(NULL);
111 while(*s && (!strchr_m(sep,*s))) s++;
112 while(*s && strchr_m(sep,*s)) *s++=0;
118 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
129 /*******************************************************************
130 case insensitive string compararison
131 ********************************************************************/
132 int StrCaseCmp(const char *s, const char *t)
135 unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1));
136 unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2));
137 return strcmp(buf1,buf2);
140 /*******************************************************************
141 case insensitive string compararison, length limited
142 ********************************************************************/
143 int StrnCaseCmp(const char *s, const char *t, size_t n)
146 unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1));
147 unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2));
148 return strncmp(buf1,buf2,n);
151 /*******************************************************************
153 ********************************************************************/
154 BOOL strequal(const char *s1, const char *s2)
156 if (s1 == s2) return(True);
157 if (!s1 || !s2) return(False);
159 return(StrCaseCmp(s1,s2)==0);
162 /*******************************************************************
163 compare 2 strings up to and including the nth char.
164 ******************************************************************/
165 BOOL strnequal(const char *s1,const char *s2,size_t n)
167 if (s1 == s2) return(True);
168 if (!s1 || !s2 || !n) return(False);
170 return(StrnCaseCmp(s1,s2,n)==0);
173 /*******************************************************************
174 compare 2 strings (case sensitive)
175 ********************************************************************/
176 BOOL strcsequal(const char *s1,const char *s2)
178 if (s1 == s2) return(True);
179 if (!s1 || !s2) return(False);
181 return(strcmp(s1,s2)==0);
184 /***************************************************************************
185 Do a case-insensitive, whitespace-ignoring string compare.
186 ***************************************************************************/
187 int strwicmp(char *psz1, char *psz2)
189 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
190 /* appropriate value. */
193 else if (psz1 == NULL)
195 else if (psz2 == NULL)
198 /* sync the strings on first non-whitespace */
201 while (isspace(*psz1))
203 while (isspace(*psz2))
205 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
211 return (*psz1 - *psz2);
215 /*******************************************************************
216 convert a string to "normal" form
217 ********************************************************************/
218 void strnorm(char *s)
220 extern int case_default;
221 if (case_default == CASE_UPPER)
227 /*******************************************************************
228 check if a string is in "normal" case
229 ********************************************************************/
230 BOOL strisnormal(char *s)
232 extern int case_default;
233 if (case_default == CASE_UPPER)
234 return(!strhaslower(s));
236 return(!strhasupper(s));
240 /****************************************************************************
242 NOTE: oldc and newc must be 7 bit characters
243 ****************************************************************************/
244 void string_replace(char *s,char oldc,char newc)
247 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
248 for(ptr=tmpbuf;*ptr;ptr++) {
249 if(*ptr==UCS2_CHAR(oldc)) *ptr = UCS2_CHAR(newc);
251 pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
255 /*******************************************************************
256 skip past some strings in a buffer
257 ********************************************************************/
258 char *skip_string(char *buf,size_t n)
261 buf += strlen(buf) + 1;
265 /*******************************************************************
266 Count the number of characters in a string. Normally this will
267 be the same as the number of bytes in a string for single byte strings,
268 but will be different for multibyte.
269 ********************************************************************/
270 size_t str_charnum(const char *s)
272 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
273 return strlen_w(tmpbuf);
276 /*******************************************************************
277 trim the specified elements off the front and back of a string
278 ********************************************************************/
280 BOOL trim_string(char *s,const char *front,const char *back)
287 /* Ignore null or empty strings. */
288 if (!s || (s[0] == '\0'))
291 front_len = front? strlen(front) : 0;
292 back_len = back? strlen(back) : 0;
297 while (len && strncmp(s, front, front_len)==0) {
298 memcpy(s, s+front_len, (len-front_len)+1);
305 while (strncmp(s+len-back_len,back,back_len)==0) {
306 s[len-back_len]='\0';
315 /****************************************************************************
316 does a string have any uppercase chars in it?
317 ****************************************************************************/
318 BOOL strhasupper(const char *s)
321 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
322 for(ptr=tmpbuf;*ptr;ptr++)
323 if(isupper_w(*ptr)) return True;
327 /****************************************************************************
328 does a string have any lowercase chars in it?
329 ****************************************************************************/
330 BOOL strhaslower(const char *s)
333 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
334 for(ptr=tmpbuf;*ptr;ptr++)
335 if(islower_w(*ptr)) return True;
339 /****************************************************************************
340 find the number of 'c' chars in a string
341 ****************************************************************************/
342 size_t count_chars(const char *s,char c)
346 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
347 for(count=0,ptr=tmpbuf;*ptr;ptr++) if(*ptr==UCS2_CHAR(c)) count++;
351 /*******************************************************************
352 Return True if a string consists only of one particular character.
353 ********************************************************************/
355 BOOL str_is_all(const char *s,char c)
359 if(s == NULL) return False;
360 if(!*s) return False;
362 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
363 for(ptr=tmpbuf;*ptr;ptr++) if(*ptr!=UCS2_CHAR(c)) return False;
368 /*******************************************************************
369 safe string copy into a known length string. maxlength does not
370 include the terminating zero.
371 ********************************************************************/
373 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
378 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
389 if (len > maxlength) {
390 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
391 (int)(len-maxlength), src));
395 memmove(dest, src, len);
400 /*******************************************************************
401 safe string cat into a string. maxlength does not
402 include the terminating zero.
403 ********************************************************************/
405 char *safe_strcat(char *dest, const char *src, size_t maxlength)
407 size_t src_len, dest_len;
410 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
418 src_len = strlen(src);
419 dest_len = strlen(dest);
421 if (src_len + dest_len > maxlength) {
422 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
423 (int)(src_len + dest_len - maxlength), src));
424 src_len = maxlength - dest_len;
427 memcpy(&dest[dest_len], src, src_len);
428 dest[dest_len + src_len] = 0;
432 /*******************************************************************
433 Paranoid strcpy into a buffer of given length (includes terminating
434 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
435 and replaces with '_'. Deliberately does *NOT* check for multibyte
436 characters. Don't change it !
437 ********************************************************************/
439 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
444 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
454 if (len >= maxlength)
457 if (!other_safe_chars)
458 other_safe_chars = "";
460 for(i = 0; i < len; i++) {
461 int val = (src[i] & 0xff);
462 if(isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
473 /****************************************************************************
474 Like strncpy but always null terminates. Make sure there is room!
475 The variable n should always be one less than the available size.
476 ****************************************************************************/
478 char *StrnCpy(char *dest,const char *src,size_t n)
481 if (!dest) return(NULL);
486 while (n-- && (*d++ = *src++)) ;
491 /****************************************************************************
492 like strncpy but copies up to the character marker. always null terminates.
493 returns a pointer to the character marker in the source string (src).
494 ****************************************************************************/
495 char *strncpyn(char *dest, const char *src,size_t n, char c)
500 p = strchr_m(src, c);
503 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
507 str_len = PTR_DIFF(p, src);
508 strncpy(dest, src, MIN(n, str_len));
509 dest[str_len] = '\0';
515 /*************************************************************
516 Routine to get hex characters and turn them into a 16 byte array.
517 the array can be variable length, and any non-hex-numeric
518 characters are skipped. "0xnn" or "0Xnn" is specially catered
521 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
523 **************************************************************/
524 size_t strhex_to_str(char *p, size_t len, const char *strhex)
527 size_t num_chars = 0;
528 unsigned char lonybble, hinybble;
529 char *hexchars = "0123456789ABCDEF";
530 char *p1 = NULL, *p2 = NULL;
532 for (i = 0; i < len && strhex[i] != 0; i++)
534 if (strnequal(hexchars, "0x", 2))
536 i++; /* skip two chars */
540 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
545 i++; /* next hex digit */
547 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
552 /* get the two nybbles */
553 hinybble = PTR_DIFF(p1, hexchars);
554 lonybble = PTR_DIFF(p2, hexchars);
556 p[num_chars] = (hinybble << 4) | lonybble;
565 /****************************************************************************
566 check if a string is part of a list
567 ****************************************************************************/
568 BOOL in_list(char *s,char *list,BOOL casesensitive)
573 if (!list) return(False);
575 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
577 if (strcmp(tok,s) == 0)
580 if (StrCaseCmp(tok,s) == 0)
587 /* this is used to prevent lots of mallocs of size 1 */
588 static char *null_string = NULL;
590 /****************************************************************************
591 set a string value, allocing the space for the string
592 ****************************************************************************/
593 static BOOL string_init(char **dest,const char *src)
604 if((null_string = (char *)malloc(1)) == NULL) {
605 DEBUG(0,("string_init: malloc fail for null_string.\n"));
614 (*dest) = (char *)malloc(l+1);
615 if ((*dest) == NULL) {
616 DEBUG(0,("Out of memory in string_init\n"));
625 /****************************************************************************
627 ****************************************************************************/
628 void string_free(char **s)
630 if (!s || !(*s)) return;
631 if (*s == null_string)
636 /****************************************************************************
637 set a string value, allocing the space for the string, and deallocating any
639 ****************************************************************************/
640 BOOL string_set(char **dest,const char *src)
644 return(string_init(dest,src));
648 /****************************************************************************
649 substitute a string for a pattern in another string. Make sure there is
652 This routine looks for pattern in s and replaces it with
653 insert. It may do multiple replacements.
655 any of " ; ' $ or ` in the insert string are replaced with _
656 if len==0 then no length check is performed
657 ****************************************************************************/
658 void string_sub(char *s,const char *pattern,const char *insert, size_t len)
663 if (!insert || !pattern || !s) return;
665 ls = (ssize_t)strlen(s);
666 lp = (ssize_t)strlen(pattern);
667 li = (ssize_t)strlen(insert);
669 if (!*pattern) return;
671 while (lp <= ls && (p = strstr(s,pattern))) {
672 if (len && (ls + (li-lp) >= len)) {
673 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
674 (int)(ls + (li-lp) - len),
679 memmove(p+li,p+lp,strlen(p+lp)+1);
702 void fstring_sub(char *s,const char *pattern,const char *insert)
704 string_sub(s, pattern, insert, sizeof(fstring));
707 void pstring_sub(char *s,const char *pattern,const char *insert)
709 string_sub(s, pattern, insert, sizeof(pstring));
712 /****************************************************************************
713 similar to string_sub() but allows for any character to be substituted.
715 if len==0 then no length check is performed
716 ****************************************************************************/
717 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
722 if (!insert || !pattern || !s) return;
724 ls = (ssize_t)strlen(s);
725 lp = (ssize_t)strlen(pattern);
726 li = (ssize_t)strlen(insert);
728 if (!*pattern) return;
730 while (lp <= ls && (p = strstr(s,pattern))) {
731 if (len && (ls + (li-lp) >= len)) {
732 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
733 (int)(ls + (li-lp) - len),
738 memmove(p+li,p+lp,strlen(p+lp)+1);
740 memcpy(p, insert, li);
746 /****************************************************************************
747 splits out the front and back at a separator.
748 ****************************************************************************/
749 void split_at_last_component(char *path, char *front, char sep, char *back)
751 char *p = strrchr_m(path, sep);
759 pstrcpy(front, path);
779 /****************************************************************************
780 write an octal as a string
781 ****************************************************************************/
782 char *octal_string(int i)
788 slprintf(ret, sizeof(ret)-1, "0%o", i);
793 /****************************************************************************
794 truncate a string at a specified length
795 ****************************************************************************/
796 char *string_truncate(char *s, int length)
798 if (s && strlen(s) > length) {
805 /****************************************************************************
806 strchr and strrchr_m are very hard to do on general multi-byte strings.
807 we convert via ucs2 for now
808 ****************************************************************************/
809 char *strchr_m(const char *s, char c)
815 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
816 p = strchr_wa(ws, c);
819 pull_ucs2_pstring(s2, ws);
820 return (char *)(s+strlen(s2));
823 char *strrchr_m(const char *s, char c)
829 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
830 p = strrchr_wa(ws, c);
833 pull_ucs2_pstring(s2, ws);
834 return (char *)(s+strlen(s2));
837 /*******************************************************************
838 convert a string to lower case
839 ********************************************************************/
840 void strlower_m(char *s)
842 /* I assume that lowercased string takes the same number of bytes
843 * as source string even in UTF-8 encoding. (VIV) */
844 unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
847 /*******************************************************************
848 convert a string to upper case
849 ********************************************************************/
850 void strupper_m(char *s)
852 /* I assume that lowercased string takes the same number of bytes
853 * as source string even in multibyte encoding. (VIV) */
854 unix_strupper(s,strlen(s)+1,s,strlen(s)+1);