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

📄 charcnv.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				retval += 2;				if (!lastp)					break;			} else {#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS				goto general_case;#else				return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);#endif			}		}		if (!dlen) {			/* Even if we fast path we should note if we ran out of room. */			if (((slen != (size_t)-1) && slen) ||					((slen == (size_t)-1) && lastp)) {				errno = E2BIG;			}		}		return retval;	}#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS  general_case:#endif	return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv);}/** * Convert between character sets, allocating a new buffer for the result. * * @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc. * @param srclen length of source buffer. * @param dest always set at least to NULL * @note -1 is not accepted for srclen. * * @returns Size in bytes of the converted string; or -1 in case of error. * * Ensure the srclen contains the terminating zero. *  * I hate the goto's in this function. It's embarressing..... * There has to be a cleaner way to do this. JRA. **/size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,			       void const *src, size_t srclen, void **dest, BOOL allow_bad_conv){	size_t i_len, o_len, destlen = MAX(srclen, 512);	size_t retval;	const char *inbuf = (const char *)src;	char *outbuf = NULL, *ob = NULL;	smb_iconv_t descriptor;	*dest = NULL;	if (src == NULL || srclen == (size_t)-1)		return (size_t)-1;	if (srclen == 0)		return 0;	lazy_initialize_conv();	descriptor = conv_handles[from][to];	if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {		if (!conv_silent)			DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));		return (size_t)-1;	}  convert:	if ((destlen*2) < destlen) {		/* wrapped ! abort. */		if (!conv_silent)			DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));		if (!ctx)			SAFE_FREE(outbuf);		return (size_t)-1;	} else {		destlen = destlen * 2;	}	if (ctx)		ob = (char *)TALLOC_REALLOC(ctx, ob, destlen);	else		ob = (char *)SMB_REALLOC(ob, destlen);	if (!ob) {		DEBUG(0, ("convert_string_allocate: realloc failed!\n"));		if (!ctx)			SAFE_FREE(outbuf);		return (size_t)-1;	} else {		outbuf = ob;	}	i_len = srclen;	o_len = destlen; again:	retval = smb_iconv(descriptor,			   &inbuf, &i_len,			   &outbuf, &o_len);	if(retval == (size_t)-1) 		{	    	const char *reason="unknown error";		switch(errno) {			case EINVAL:				reason="Incomplete multibyte sequence";				if (!conv_silent)					DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));				if (allow_bad_conv)					goto use_as_is;				break;			case E2BIG:				goto convert;					case EILSEQ:				reason="Illegal multibyte sequence";				if (!conv_silent)					DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));				if (allow_bad_conv)					goto use_as_is;				break;		}		if (!conv_silent)			DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));		/* smb_panic(reason); */		return (size_t)-1;	}  out:	destlen = destlen - o_len;	if (ctx)		*dest = (char *)TALLOC_REALLOC(ctx,ob,destlen);	else		*dest = (char *)SMB_REALLOC(ob,destlen);	if (destlen && !*dest) {		DEBUG(0, ("convert_string_allocate: out of memory!\n"));		if (!ctx)			SAFE_FREE(ob);		return (size_t)-1;	}	return destlen; use_as_is:	/* 	 * Conversion not supported. This is actually an error, but there are so	 * many misconfigured iconv systems and smb.conf's out there we can't just	 * fail. Do a very bad conversion instead.... JRA.	 */	{		if (o_len == 0 || i_len == 0)			goto out;		if (from == CH_UCS2 && to != CH_UCS2) {			/* Can't convert from ucs2 to multibyte. Just use the default fail char. */			if (i_len < 2)				goto out;			if (i_len >= 2) {				*outbuf = lp_failed_convert_char();				outbuf++;				o_len--;				inbuf += 2;				i_len -= 2;			}			if (o_len == 0 || i_len == 0)				goto out;			/* Keep trying with the next char... */			goto again;		} else if (from != CH_UCS2 && to == CH_UCS2) {			/* Can't convert to ucs2 - just widen by adding the default fail char then zero. */			if (o_len < 2)				goto out;			outbuf[0] = lp_failed_convert_char();			outbuf[1] = '\0';			inbuf++;			i_len--;			outbuf += 2;			o_len -= 2;			if (o_len == 0 || i_len == 0)				goto out;			/* Keep trying with the next char... */			goto again;		} else if (from != CH_UCS2 && to != CH_UCS2) {			/* Failed multibyte to multibyte. Just copy the default fail char and				try again. */			outbuf[0] = lp_failed_convert_char();			inbuf++;			i_len--;			outbuf++;			o_len--;			if (o_len == 0 || i_len == 0)				goto out;			/* Keep trying with the next char... */			goto again;		} else {			/* Keep compiler happy.... */			goto out;		}	}}/** * Convert between character sets, allocating a new buffer using talloc for the result. * * @param srclen length of source buffer. * @param dest always set at least to NULL  * @note -1 is not accepted for srclen. * * @returns Size in bytes of the converted string; or -1 in case of error. **/static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,		      		void const *src, size_t srclen, void **dest, BOOL allow_bad_conv){	size_t dest_len;	*dest = NULL;	dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest, allow_bad_conv);	if (dest_len == (size_t)-1)		return (size_t)-1;	if (*dest == NULL)		return (size_t)-1;	return dest_len;}size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen){	size_t size;	smb_ucs2_t *buffer;		size = push_ucs2_allocate(&buffer, src);	if (size == (size_t)-1) {		smb_panic("failed to create UCS2 buffer");	}	if (!strupper_w(buffer) && (dest == src)) {		free(buffer);		return srclen;	}		size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True);	free(buffer);	return size;}/** strdup() a unix string to upper case. Max size is pstring.**/char *strdup_upper(const char *s){	pstring out_buffer;	const unsigned char *p = (const unsigned char *)s;	unsigned char *q = (unsigned char *)out_buffer;	/* 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) */	while (1) {		if (*p & 0x80)			break;		*q++ = toupper_ascii(*p);		if (!*p)			break;		p++;		if (p - ( const unsigned char *)s >= sizeof(pstring))			break;	}	if (*p) {		/* MB case. */		size_t size;		wpstring buffer;		size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer), True);		if (size == (size_t)-1) {			return NULL;		}		strupper_w(buffer);			size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True);		if (size == (size_t)-1) {			return NULL;		}	}	return SMB_STRDUP(out_buffer);}size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen){	size_t size;	smb_ucs2_t *buffer = NULL;		size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,				       (void **)(void *)&buffer, True);	if (size == (size_t)-1 || !buffer) {		smb_panic("failed to create UCS2 buffer");	}	if (!strlower_w(buffer) && (dest == src)) {		SAFE_FREE(buffer);		return srclen;	}	size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True);	SAFE_FREE(buffer);	return size;}/** strdup() a unix string to lower case.**/char *strdup_lower(const char *s){	size_t size;	smb_ucs2_t *buffer = NULL;	char *out_buffer;		size = push_ucs2_allocate(&buffer, s);	if (size == -1 || !buffer) {		return NULL;	}	strlower_w(buffer);		size = pull_ucs2_allocate(&out_buffer, buffer);	SAFE_FREE(buffer);	if (size == (size_t)-1) {		return NULL;	}		return out_buffer;}static size_t ucs2_align(const void *base_ptr, const void *p, int flags){	if (flags & (STR_NOALIGN|STR_ASCII))		return 0;	return PTR_DIFF(p, base_ptr) & 1;}/** * Copy a string from a char* unix src to a dos codepage string destination. * * @return the number of bytes occupied by the string in the destination. * * @param flags can include * <dl> * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd> * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd> * </dl> * * @param dest_len the maximum length in bytes allowed in the * destination.  If @p dest_len is -1 then no maximum is used. **/size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags){	size_t src_len = strlen(src);	pstring tmpbuf;	/* treat a pstring as "unlimited" length */	if (dest_len == (size_t)-1)		dest_len = sizeof(pstring);	if (flags & STR_UPPER) {		pstrcpy(tmpbuf, src);		strupper_m(tmpbuf);		src = tmpbuf;	}	if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))		src_len++;	return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);}size_t push_ascii_fstring(void *dest, const char *src){	return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);}size_t push_ascii_pstring(void *dest, const char *src){	return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);}/******************************************************************** Push an nstring - ensure null terminated. Written by moriyama@miraclelinux.com (MORIYAMA Masayuki).********************************************************************/size_t push_ascii_nstring(void *dest, const char *src){	size_t i, buffer_len, dest_len;	smb_ucs2_t *buffer;	conv_silent = True;	buffer_len = push_ucs2_allocate(&buffer, src);	if (buffer_len == (size_t)-1) {		smb_panic("failed to create UCS2 buffer");	}	/* We're using buffer_len below to count ucs2 characters, not bytes. */	buffer_len /= sizeof(smb_ucs2_t);	dest_len = 0;	for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) {		unsigned char mb[10];		/* Convert one smb_ucs2_t character at a time. */		size_t mb_len = convert_string(CH_UCS2, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False);		if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) {			memcpy((char *)dest + dest_len, mb, mb_len);			dest_len += mb_len;		} else {			errno = E2BIG;			break;		}	}	((char *)dest)[dest_len] = '\0';	SAFE_FREE(buffer);	conv_silent = False;	return dest_len;}/** * Copy a string from a dos codepage source to a unix char* destination. * * The resulting string in "dest" is always null terminated. * * @param flags can have: * <dl> * <dt>STR_TERMINATE</dt> * <dd>STR_TERMINATE means the string in @p src * is null terminated, and src_len is ignored.</dd> * </dl> * * @param src_len is the length of the source area in bytes. * @returns the number of bytes occupied by the string in @p src. **/size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags){

⌨️ 快捷键说明

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