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

📄 ttodata.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * convert from text form of arbitrary data (e.g., keys) to binary * Copyright (C) 2000  Henry Spencer. *  * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>. *  * This library 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 Library General Public * License for more details. * * RCSID $Id: ttodata.c,v 1.12 2004/04/09 18:00:37 mcr Exp $ */#include "internal.h"#include "openswan.h"/* converters and misc */static int unhex(const char *, char *, size_t);static int unb64(const char *, char *, size_t);static int untext(const char *, char *, size_t);static const char *badch(const char *, int, char *, size_t);/* internal error codes for converters */#define	SHORT	(-2)		/* internal buffer too short */#define	BADPAD	(-3)		/* bad base64 padding */#define	BADCH0	(-4)		/* invalid character 0 */#define	BADCH1	(-5)		/* invalid character 1 */#define	BADCH2	(-6)		/* invalid character 2 */#define	BADCH3	(-7)		/* invalid character 3 */#define	BADOFF(code) (BADCH0-(code))/* - ttodatav - convert text to data, with verbose error reports * If some of this looks slightly odd, it's because it has changed * repeatedly (from the original atodata()) without a major rewrite. */const char *			/* NULL on success, else literal or errp */ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags)const char *src;size_t srclen;			/* 0 means apply strlen() */int base;			/* 0 means figure it out */char *dst;			/* need not be valid if dstlen is 0 */size_t dstlen;size_t *lenp;			/* where to record length (NULL is nowhere) */char *errp;			/* error buffer */size_t errlen;unsigned int flags;{	size_t ingroup;	/* number of input bytes converted at once */	char buf[4];		/* output from conversion */	int nbytes;		/* size of output */	int (*decode)(const char *, char *, size_t);	char *stop;	int ndone;	int i;	int underscoreok;	int skipSpace = 0;	if (srclen == 0)		srclen = strlen(src);	if (dstlen == 0)		dst = buf;	/* point it somewhere valid */	stop = dst + dstlen;	if (base == 0) {		if (srclen < 2)			return "input too short to be valid";		if (*src++ != '0')			return "input does not begin with format prefix";		switch (*src++) {		case 'x':		case 'X':			base = 16;			break;		case 's':		case 'S':			base = 64;			break;		case 't':		case 'T':			base = 256;			break;		default:			return "unknown format prefix";		}		srclen -= 2;	}	switch (base) {	case 16:		decode = unhex;		underscoreok = 1;		ingroup = 2;		break;	case 64:		decode = unb64;		underscoreok = 0;		ingroup = 4;		if(flags & TTODATAV_IGNORESPACE) {			skipSpace = 1;		}		break;	case 256:		decode = untext;		ingroup = 1;		underscoreok = 0;		break;	default:		return "unknown base";	}	/* proceed */	ndone = 0;	while (srclen > 0) {		char stage[4];	/* staging area for group */		size_t sl = 0;		/* Grab ingroup characters into stage,		 * squeezing out blanks if we are supposed to ignore them.		 */		for (sl = 0; sl < ingroup; src++, srclen--) {			if (srclen == 0)				return "input ends in mid-byte, perhaps truncated";			else if (!(skipSpace && (*src == ' ' || *src == '\t')))				stage[sl++] = *src;		}				nbytes = (*decode)(stage, buf, sizeof(buf));		switch (nbytes) {		case BADCH0:		case BADCH1:		case BADCH2:		case BADCH3:			return badch(stage, nbytes, errp, errlen);		case SHORT:			return "internal buffer too short (\"can't happen\")";		case BADPAD:			return "bad (non-zero) padding at end of base64 input";		}		if (nbytes <= 0)			return "unknown internal error";		for (i = 0; i < nbytes; i++) {			if (dst < stop)				*dst++ = buf[i];			ndone++;		}		while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){			src++;			srclen--;		}		if (underscoreok && srclen > 1 && *src == '_') {			/* srclen > 1 means not last character */			src++;			srclen--;		}	}	if (ndone == 0)		return "no data bytes specified by input";	if (lenp != NULL)		*lenp = ndone;	return NULL;}/* - ttodata - convert text to data */const char *			/* NULL on success, else literal */ttodata(src, srclen, base, dst, dstlen, lenp)const char *src;size_t srclen;			/* 0 means apply strlen() */int base;			/* 0 means figure it out */char *dst;			/* need not be valid if dstlen is 0 */size_t dstlen;size_t *lenp;			/* where to record length (NULL is nowhere) */{	return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,			(size_t)0, TTODATAV_SPACECOUNTS);}/* - atodata - convert ASCII to data * backward-compatibility interface */size_t				/* 0 for failure, true length for success */atodata(src, srclen, dst, dstlen)const char *src;size_t srclen;char *dst;size_t dstlen;{	size_t len;	const char *err;	err = ttodata(src, srclen, 0, dst, dstlen, &len);	if (err != NULL)		return 0;	return len;}/* - atobytes - convert ASCII to data bytes * another backward-compatibility interface */const char *atobytes(src, srclen, dst, dstlen, lenp)const char *src;size_t srclen;char *dst;size_t dstlen;size_t *lenp;{	return ttodata(src, srclen, 0, dst, dstlen, lenp);}/* - unhex - convert two ASCII hex digits to byte */static int		/* number of result bytes, or error code */unhex(src, dst, dstlen)const char *src;	/* known to be full length */char *dst;size_t dstlen;		/* not large enough is a failure */{	char *p;	unsigned byte;	static char hex[] = "0123456789abcdef";	if (dstlen < 1)		return SHORT;		p = strchr(hex, *src);	if (p == NULL)		p = strchr(hex, tolower(*src));	if (p == NULL)		return BADCH0;	byte = (p - hex) << 4;	src++;	p = strchr(hex, *src);	if (p == NULL)		p = strchr(hex, tolower(*src));	if (p == NULL)		return BADCH1;	byte |= (p - hex);	*dst = byte;	return 1;}/* - unb64 - convert four ASCII base64 digits to three bytes * Note that a base64 digit group is padded out with '=' if it represents * less than three bytes:  one byte is dd==, two is ddd=, three is dddd. */static int		/* number of result bytes, or error code */unb64(src, dst, dstlen)const char *src;	/* known to be full length */char *dst;size_t dstlen;{	char *p;	unsigned byte1;	unsigned byte2;	static char base64[] =	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";	if (dstlen < 3)		return SHORT;	p = strchr(base64, *src++);	if (p == NULL)		return BADCH0;	byte1 = (p - base64) << 2;	/* first six bits */	p = strchr(base64, *src++);	if (p == NULL) {		return BADCH1;	}	byte2 = p - base64;		/* next six:  two plus four */	*dst++ = byte1 | (byte2 >> 4);	byte1 = (byte2 & 0xf) << 4;	p = strchr(base64, *src++);	if (p == NULL) {		if (*(src-1) == '=' && *src == '=') {			if (byte1 != 0)		/* bad padding */				return BADPAD;			return 1;		}		return BADCH2;	}	byte2 = p - base64;		/* next six:  four plus two */	*dst++ = byte1 | (byte2 >> 2);	byte1 = (byte2 & 0x3) << 6;	p = strchr(base64, *src++);	if (p == NULL) {		if (*(src-1) == '=') {			if (byte1 != 0)		/* bad padding */				return BADPAD;			return 2;		}		return BADCH3;	}	byte2 = p - base64;		/* last six */	*dst++ = byte1 | byte2;	return 3;}/* - untext - convert one ASCII character to byte */static int		/* number of result bytes, or error code */untext(src, dst, dstlen)const char *src;	/* known to be full length */char *dst;size_t dstlen;		/* not large enough is a failure */{	if (dstlen < 1)		return SHORT;	*dst = *src;	return 1;}/* - badch - produce a nice complaint about an unknown character * * If the compiler complains that the array bigenough[] has a negative * size, that means the TTODATAV_BUF constant has been set too small. */static const char *		/* literal or errp */badch(src, errcode, errp, errlen)const char *src;int errcode;char *errp;			/* might be NULL */size_t errlen;{	static const char pre[] = "unknown character (`";	static const char suf[] = "') in input";	char buf[5];#	define	REQD	(sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))	struct sizecheck {		char bigenough[TTODATAV_BUF - REQD];	/* see above */	};	char ch;	if (errp == NULL || errlen < REQD)		return "unknown character in input";	strcpy(errp, pre);	ch = *(src + BADOFF(errcode));	if (isprint(ch)) {		buf[0] = ch;		buf[1] = '\0';

⌨️ 快捷键说明

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