⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util_str.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    Unix SMB/CIFS implementation.   Samba utility functions      Copyright (C) Andrew Tridgell 1992-2001   Copyright (C) Simo Sorce      2001-2002   Copyright (C) Martin Pool     2003      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"/** * @file * @brief String utilities. **//** * Get the next token from a string, return False if none found. * Handles double-quotes. *  * Based on a routine by GJC@VILLAGE.COM.  * Extensively modified by Andrew.Tridgell@anu.edu.au **/BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize){	char *s;	char *pbuf;	BOOL quoted;	size_t len=1;	if (!ptr)		return(False);	s = (char *)*ptr;	/* default to simple separators */	if (!sep)		sep = " \t\n\r";	/* find the first non sep char */	while (*s && strchr_m(sep,*s))		s++;		/* nothing left? */	if (! *s)		return(False);		/* copy over the token */	pbuf = buff;	for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {		if ( *s == '\"' ) {			quoted = !quoted;		} else {			len++;			*pbuf++ = *s;		}	}		*ptr = (*s) ? s+1 : s;  	*pbuf = 0;		return(True);}/**This is like next_token but is not re-entrant and "remembers" the first parameter so you can pass NULL. This is useful for user interface codebut beware the fact that it is not re-entrant!**/static const char *last_ptr=NULL;BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize){	BOOL ret;	if (!ptr)		ptr = &last_ptr;	ret = next_token(ptr, buff, sep, bufsize);	last_ptr = *ptr;	return ret;	}static uint16 tmpbuf[sizeof(pstring)];void set_first_token(char *ptr){	last_ptr = ptr;}/** Convert list of tokens to array; dependent on above routine. Uses last_ptr from above - bit of a hack.**/char **toktocliplist(int *ctok, const char *sep){	char *s=(char *)last_ptr;	int ictok=0;	char **ret, **iret;	if (!sep)		sep = " \t\n\r";	while(*s && strchr_m(sep,*s))		s++;	/* nothing left? */	if (!*s)		return(NULL);	do {		ictok++;		while(*s && (!strchr_m(sep,*s)))			s++;		while(*s && strchr_m(sep,*s))			*s++=0;	} while(*s);		*ctok=ictok;	s=(char *)last_ptr;		if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))		return NULL;		while(ictok--) {    		*iret++=s;		if (ictok > 0) {			while(*s++)				;			while(!*s)				s++;		}	}	ret[*ctok] = NULL;	return ret;}/** * Case insensitive string compararison. * * iconv does not directly give us a way to compare strings in * arbitrary unix character sets -- all we can is convert and then * compare.  This is expensive. * * As an optimization, we do a first pass that considers only the * prefix of the strings that is entirely 7-bit.  Within this, we * check whether they have the same value. * * Hopefully this will often give the answer without needing to copy. * In particular it should speed comparisons to literal ascii strings * or comparisons of strings that are "obviously" different. * * If we find a non-ascii character we fall back to converting via * iconv. * * This should never be slower than convering the whole thing, and * often faster. * * A different optimization would be to compare for bitwise equality * in the binary encoding.  (It would be possible thought hairy to do * both simultaneously.)  But in that case if they turn out to be * different, we'd need to restart the whole thing. * * Even better is to implement strcasecmp for each encoding and use a * function pointer.  **/int StrCaseCmp(const char *s, const char *t){	const char *ps, *pt;	size_t size;	smb_ucs2_t *buffer_s, *buffer_t;	int ret;	for (ps = s, pt = t; ; ps++, pt++) {		char us, ut;		if (!*ps && !*pt)			return 0; /* both ended */ 		else if (!*ps)			return -1; /* s is a prefix */		else if (!*pt)			return +1; /* t is a prefix */		else if ((*ps & 0x80) || (*pt & 0x80))			/* not ascii anymore, do it the hard way from here on in */			break;		us = toupper_ascii(*ps);		ut = toupper_ascii(*pt);		if (us == ut)			continue;		else if (us < ut)			return -1;		else if (us > ut)			return +1;	}	size = push_ucs2_allocate(&buffer_s, ps);	if (size == (size_t)-1) {		return strcmp(ps, pt); 		/* Not quite the right answer, but finding the right one		   under this failure case is expensive, and it's pretty close */	}		size = push_ucs2_allocate(&buffer_t, pt);	if (size == (size_t)-1) {		SAFE_FREE(buffer_s);		return strcmp(ps, pt); 		/* Not quite the right answer, but finding the right one		   under this failure case is expensive, and it's pretty close */	}		ret = strcasecmp_w(buffer_s, buffer_t);	SAFE_FREE(buffer_s);	SAFE_FREE(buffer_t);	return ret;}/** Case insensitive string compararison, length limited.**/int StrnCaseCmp(const char *s, const char *t, size_t n){	pstring buf1, buf2;	unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));	unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));	return strncmp(buf1,buf2,n);}/** * Compare 2 strings. * * @note The comparison is case-insensitive. **/BOOL strequal(const char *s1, const char *s2){	if (s1 == s2)		return(True);	if (!s1 || !s2)		return(False);  	return(StrCaseCmp(s1,s2)==0);}/** * Compare 2 strings up to and including the nth char. * * @note The comparison is case-insensitive. **/BOOL strnequal(const char *s1,const char *s2,size_t n){	if (s1 == s2)		return(True);	if (!s1 || !s2 || !n)		return(False);  	return(StrnCaseCmp(s1,s2,n)==0);}/** Compare 2 strings (case sensitive).**/BOOL strcsequal(const char *s1,const char *s2){	if (s1 == s2)		return(True);	if (!s1 || !s2)		return(False);  	return(strcmp(s1,s2)==0);}/**Do a case-insensitive, whitespace-ignoring string compare.**/int strwicmp(const char *psz1, const char *psz2){	/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */	/* appropriate value. */	if (psz1 == psz2)		return (0);	else if (psz1 == NULL)		return (-1);	else if (psz2 == NULL)		return (1);	/* sync the strings on first non-whitespace */	while (1) {		while (isspace((int)*psz1))			psz1++;		while (isspace((int)*psz2))			psz2++;		if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'		    || *psz2 == '\0')			break;		psz1++;		psz2++;	}	return (*psz1 - *psz2);}/** Convert a string to upper case, but don't modify it.**/char *strupper_static(const char *s){	static pstring str;	pstrcpy(str, s);	strupper_m(str);	return str;}/** Convert a string to "normal" form.**/void strnorm(char *s, int case_default){	if (case_default == CASE_UPPER)		strupper_m(s);	else		strlower_m(s);}/** Check if a string is in "normal" case.**/BOOL strisnormal(const char *s, int case_default){	if (case_default == CASE_UPPER)		return(!strhaslower(s));		return(!strhasupper(s));}/** String replace. NOTE: oldc and newc must be 7 bit characters**/void string_replace( pstring s, char oldc, char newc ){	char *p;	/* this is quite a common operation, so we want it to be	   fast. We optimise for the ascii case, knowing that all our	   supported multi-byte character sets are ascii-compatible	   (ie. they match for the first 128 chars) */	for (p = s; *p; p++) {		if (*p & 0x80) /* mb string - slow path. */			break;		if (*p == oldc)			*p = newc;	}	if (!*p)		return;	/* Slow (mb) path. */#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS	/* With compose characters we must restart from the beginning. JRA. */	p = s;#endif	push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);	string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));	pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);}/** Skip past some strings in a buffer.**/char *skip_string(char *buf,size_t n){	while (n--)		buf += strlen(buf) + 1;	return(buf);}/** Count the number of characters in a string. Normally this will be the same as the number of bytes in a string for single byte strings, but will be different for multibyte.**/size_t str_charnum(const char *s){	uint16 tmpbuf2[sizeof(pstring)];	push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);	return strlen_w(tmpbuf2);}/** Count the number of characters in a string. Normally this will be the same as the number of bytes in a string for single byte strings, but will be different for multibyte.**/size_t str_ascii_charnum(const char *s){	pstring tmpbuf2;	push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);	return strlen(tmpbuf2);}BOOL trim_char(char *s,char cfront,char cback){	BOOL ret = False;	char *ep;	char *fp = s;	/* Ignore null or empty strings. */	if (!s || (s[0] == '\0'))		return False;	if (cfront) {		while (*fp && *fp == cfront)			fp++;		if (!*fp) {			/* We ate the string. */			s[0] = '\0';			return True;		}		if (fp != s)			ret = True;	}	ep = fp + strlen(fp) - 1;	if (cback) {		/* Attempt ascii only. Bail for mb strings. */		while ((ep >= fp) && (*ep == cback)) {			ret = True;			if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {				/* Could be mb... bail back to tim_string. */				char fs[2], bs[2];				if (cfront) {					fs[0] = cfront;					fs[1] = '\0';				}				bs[0] = cback;				bs[1] = '\0';				return trim_string(s, cfront ? fs : NULL, bs);			} else {				ep--;			}		}		if (ep < fp) {			/* We ate the string. */			s[0] = '\0';			return True;		}	}	ep[1] = '\0';	memmove(s, fp, ep-fp+2);	return ret;}/** Trim the specified elements off the front and back of a string.**/BOOL trim_string(char *s,const char *front,const char *back){	BOOL ret = False;	size_t front_len;	size_t back_len;	size_t len;	/* Ignore null or empty strings. */	if (!s || (s[0] == '\0'))		return False;	front_len	= front? strlen(front) : 0;	back_len	= back? strlen(back) : 0;	len = strlen(s);	if (front_len) {		while (len && strncmp(s, front, front_len)==0) {			/* Must use memmove here as src & dest can			 * easily overlap. Found by valgrind. JRA. */			memmove(s, s+front_len, (len-front_len)+1);			len -= front_len;			ret=True;		}	}		if (back_len) {		while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {			s[len-back_len]='\0';			len -= back_len;			ret=True;		}	}	return ret;}/** Does a string have any uppercase chars in it?**/BOOL strhasupper(const char *s){	smb_ucs2_t *ptr;	push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);	for(ptr=tmpbuf;*ptr;ptr++)		if(isupper_w(*ptr))			return True;	return(False);}/** Does a string have any lowercase chars in it?**/BOOL strhaslower(const char *s){	smb_ucs2_t *ptr;	push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);	for(ptr=tmpbuf;*ptr;ptr++)		if(islower_w(*ptr))			return True;	return(False);}/** Find the number of 'c' chars in a string**/size_t count_chars(const char *s,char c){	smb_ucs2_t *ptr;	int count;	smb_ucs2_t *alloc_tmpbuf = NULL;	if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {		return 0;	}	for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)		if(*ptr==UCS2_CHAR(c))			count++;	SAFE_FREE(alloc_tmpbuf);	return(count);}/** Safe string copy into a known length string. maxlength does not include the terminating zero.**/char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -