diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /rfc2045/rfc2045decodemsgtoutf8.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'rfc2045/rfc2045decodemsgtoutf8.c')
| -rw-r--r-- | rfc2045/rfc2045decodemsgtoutf8.c | 148 | 
1 files changed, 148 insertions, 0 deletions
| diff --git a/rfc2045/rfc2045decodemsgtoutf8.c b/rfc2045/rfc2045decodemsgtoutf8.c new file mode 100644 index 0000000..e3c5fe8 --- /dev/null +++ b/rfc2045/rfc2045decodemsgtoutf8.c @@ -0,0 +1,148 @@ +/* +** Copyright 2010-2011 Double Precision, Inc.  See COPYING for +** distribution information. +*/ + +#include	"rfc2045.h" +#include	"rfc822/rfc822.h" +#include	<ctype.h> +#include	<unistd.h> +#include	<string.h> + + + +struct doconvtoutf8_info { + +	struct rfc2045_decodemsgtoutf8_cb *callback; + +	int err_flag; +}; + +static void doconvtoutf8_write(const char *p, size_t n, +			       void *void_arg) +{ +	struct doconvtoutf8_info *ptr= +		(struct doconvtoutf8_info *)void_arg; + +	if (n && ptr->err_flag == 0) +		ptr->err_flag=(*ptr->callback->output_func) +			(p, n, ptr->callback->arg); +} + +static void doconvtoutf8_error(const char *p, int n, +			       void *void_arg) +{ +	struct doconvtoutf8_info *ptr=(struct doconvtoutf8_info *)void_arg; + +	ptr->err_flag= -1; +} + +static int doconvtoutf8_rfc822hdr(const char *header, +				  const char *value, +				  struct rfc2045_decodemsgtoutf8_cb *callback) +{ +	struct doconvtoutf8_info info; + +	info.err_flag=0; +	info.callback=callback; + +	if (callback->headerfilter_func && +	    (*callback->headerfilter_func)(header, value, callback->arg) == 0) +		return 0; + +	if ((callback->flags & RFC2045_DECODEMSG_NOHEADERNAME) == 0) +	{ +		doconvtoutf8_write(header, strlen(header), &info); +		doconvtoutf8_write(": ", 2, &info); +	} +	rfc822_display_hdrvalue(header, value, "utf-8",  +				doconvtoutf8_write, +				doconvtoutf8_error, +				&info); +	doconvtoutf8_write("\n", 1, &info); +	if (callback->headerdone_func && info.err_flag == 0) +	{ +		int rc=(*callback->headerdone_func)(header, callback->arg); + +		if (rc) +			info.err_flag=rc; +	} + +	return info.err_flag; +} + +static int decode_handler(const char *p, size_t n, void *voidarg) +{ +	const struct doconvtoutf8_info *ptr= +		(const struct doconvtoutf8_info *)voidarg; + +	int rc=0; + +	if (n) +		rc=(*ptr->callback->output_func)(p, n, ptr->callback->arg); + +	return rc; +} + +int rfc2045_decodemsgtoutf8(struct rfc2045src *src, +			    struct rfc2045 *p, +			    struct rfc2045_decodemsgtoutf8_cb *callback) +{ +	struct rfc2045headerinfo *hi; +	int rc; + +	hi=rfc2045header_start(src, p); + +	if (hi) +	{ +		char *header; +		char *value; + +		while (rfc2045header_get(hi, &header, &value, +					 RFC2045H_NOLC | +					 RFC2045H_KEEPNL) == 0 && header) +		{ +			if (callback->flags & RFC2045_DECODEMSG_NOHEADERS) +				continue; + +			if (doconvtoutf8_rfc822hdr(header, value, +						   callback) < 0) +				return -1; +		} +		rfc2045header_end(hi); +	} + +	if (p->firstpart) +	{ +		for (p=p->firstpart; p; p=p->next) +		{ +			if (!p->isdummy) +			{ +				if ((rc=rfc2045_decodemsgtoutf8(src, p, +								callback)) +				    != 0) +					return rc; +			} +		} +	} +	else +	{ +		const char *content_type; +		const char *transfer_encoding; +		const char *charset; +		struct doconvtoutf8_info info; + +		info.callback=callback; + +		rfc2045_mimeinfo(p, &content_type, &transfer_encoding, +				 &charset); + +		if (strncmp(content_type, "text/", 5) == 0 && +		    (callback->flags & RFC2045_DECODEMSG_NOBODY) == 0 && +		    (rc=rfc2045_decodetextmimesection(src, p, "utf-8", NULL, +						      decode_handler, +						      &info)) != 0) +			return rc; +	} +	return 0; +} | 
