diff options
| author | Sam Varshavchik | 2018-07-14 15:51:42 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2018-07-16 21:20:25 -0400 | 
| commit | 9643d3d5adcbc6357833a818e2928eb8e76717ed (patch) | |
| tree | 367ec86c8ccfb3aa2ab40b2440ebabfea382e0ce /maildir/maildirinfo2.c | |
| parent | 3359e8155147662382d2fd982bcf75a1644901a0 (diff) | |
| download | courier-libs-9643d3d5adcbc6357833a818e2928eb8e76717ed.tar.bz2 | |
Add maidirmake options to convert pre-unicode mailboxes to unicode mailboxes.
Diffstat (limited to 'maildir/maildirinfo2.c')
| -rw-r--r-- | maildir/maildirinfo2.c | 148 | 
1 files changed, 148 insertions, 0 deletions
| diff --git a/maildir/maildirinfo2.c b/maildir/maildirinfo2.c new file mode 100644 index 0000000..fcae14c --- /dev/null +++ b/maildir/maildirinfo2.c @@ -0,0 +1,148 @@ +/* +** Copyright 2018 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if	HAVE_CONFIG_H +#include	"config.h" +#endif +#include	<stdio.h> +#include	<stdlib.h> +#include	<string.h> +#include	<errno.h> +#include	<ctype.h> +#if	HAVE_UNISTD_H +#include	<unistd.h> +#endif + +#include	"maildirinfo.h" +#include	<courier-unicode.h> + + +/* Count the size of the converted filename or foldername string */ +static void count_utf8(const char *str, size_t n, void *arg) +{ +	*(size_t *)arg += n; +} + +/* Save the converted filename or foldername string */ +static void save_utf8(const char *str, size_t n, void *arg) +{ +	char **p=(char **)arg; + +	memcpy( (*p), str, n); +	*p += n; +} + +/* +** Split a string at periods, convert each split range between charsets. +*/ +static int foldername_filename_convert(const char *src_chset, +				       const char *dst_chset, +				       const char *foldername, +				       void (*closure)(const char *, size_t, +						       void *), +				       void *arg) +{ +	unicode_convert_handle_t h; +	char *cbufptr; +	size_t cbufsize; +	size_t l; +	int conversion_error; + +	while (*foldername) +	{ +		if (*foldername == '.') +		{ +			(*closure)(foldername, 1, arg); +			++foldername; +			continue; +		} + +		h=unicode_convert_tocbuf_init(src_chset, +					      dst_chset, +					      &cbufptr, +					      &cbufsize, +					      0); +		if (!h) +		{ +			errno=EINVAL; +			return -1; +		} + +		for (l=0; foldername[l] && foldername[l] != '.'; ++l) +			; + +		unicode_convert(h, foldername, l); + +		if (unicode_convert_deinit(h, &conversion_error) == 0) +		{ +			closure(cbufptr, cbufsize, arg); +			free(cbufptr); +			if (conversion_error) +			{ +				errno=EILSEQ; +				return -1; +			} +		} +		else +			return -1; +		foldername += l; +	} +	return 0; +} + +/* Convert either a foldername or a filename to the other */ + +static char *foldername_filename_convert_tobuf(const char *src_chset, +					       const char *dst_chset, +					       const char *foldername) +{ +	char *utf8, *p; +	size_t l=1; + +	if (foldername_filename_convert(src_chset, +					dst_chset, +					foldername, count_utf8, &l)) +		return NULL; + +	utf8=malloc(l+1); + +	if (!utf8) +		return NULL; + +	p=utf8; +	if (foldername_filename_convert(src_chset, +					dst_chset, +					foldername, save_utf8, &p)) +	{ +		free(utf8); +		return NULL; +	} + +	*p=0; + +	return utf8; +} + +char *imap_foldername_to_filename(int utf8_format, const char *foldername) +{ +	if (utf8_format) +		return strdup(foldername); + +	return foldername_filename_convert_tobuf +		(unicode_x_imap_modutf7, +		 "utf-8", +		 foldername); +} + +char *imap_filename_to_foldername(int utf8_format, const char *filename) +{ +	if (utf8_format) +		return strdup(filename); + +	return foldername_filename_convert_tobuf +		("utf-8", +		 unicode_x_imap_modutf7, +		 filename); +} | 
