diff -Nru proftpd.orig/Makefile proftpd/Makefile
--- proftpd.orig/Makefile	2008-03-04 01:12:52.000000000 +0300
+++ proftpd/Makefile	2008-03-23 23:49:00.000000000 +0300
@@ -85,7 +85,8 @@
 		CYRFIX "Patch to fix cyrillic encoding" off \
 		CLAMAV "Include mod_clamav" off \
 		DIGEST "Include mod_digest" off \
-		COMB "Include mod_comb (multistream upload)" off
+		COMB "Include mod_comb (multistream upload)" off \
+		ICONV "Convert local and remote charset" off
 
 MODULES?=
 LIBDIRS?=
@@ -152,6 +153,14 @@
 CONFIGURE_ARGS+=	--disable-ipv6
 .endif
 
+.if defined (WITH_ICONV)
+USE_ICONV=	yes
+WITH_NLS=	yes
+INCLUDEDIRS:=${INCLUDEDIRS}:${LOCALBASE}/include
+PROFTPD_LIBS+=	-liconv -L${LOCALBASE}/lib
+EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-iconv.patch
+.endif
+
 .if defined(WITH_NLS)
 INCLUDEDIRS:=${INCLUDEDIRS}:${LOCALBASE}/include
 LIBDIRS:=${LIBDIRS}:${LOCALBASE}/lib
diff -Nru proftpd.orig/files/extra-patch-iconv.patch proftpd/files/extra-patch-iconv.patch
--- proftpd.orig/files/extra-patch-iconv.patch	1970-01-01 03:00:00.000000000 +0300
+++ proftpd/files/extra-patch-iconv.patch	2008-03-23 23:49:00.000000000 +0300
@@ -0,0 +1,230 @@
+diff -ur proftpd-1.3.1/include/utf8.h proftpd-1.3.1.iconv/include/utf8.h
+--- proftpd-1.3.1/include/utf8.h	2006-05-25 18:55:34.000000000 +0200
++++ ./include/utf8.h	2008-03-23 15:08:54.000000000 +0100
+@@ -37,6 +37,12 @@
+  */
+ char *pr_utf8_encode(pool *p, const char *in, size_t inlen, size_t *outlen);
+ 
++char *pr_charset_decode(pool *p, const char *in, size_t inlen, size_t *outlen, 
++	const char *, const char *);
++	
++char *pr_charset_encode(pool *p, const char *in, size_t inlen, size_t *outlen,
++	const char *, const char *);
++
+ /* Internal use only. */
+ int utf8_init(void);
+ int utf8_free(void);
+diff -ur proftpd-1.3.1/modules/mod_core.c ./modules/mod_core.c
+--- proftpd-1.3.1/modules/mod_core.c	2007-09-14 18:08:40.000000000 +0200
++++ ./modules/mod_core.c	2008-03-23 21:40:57.000000000 +0100
+@@ -1160,6 +1160,28 @@
+   return PR_HANDLED(cmd);
+ }
+ 
++MODRET set_localcharset(cmd_rec *cmd) {
++  config_rec *c;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  c=add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
++  c->flags |= CF_MERGEDOWN;
++  return PR_HANDLED(cmd);
++}
++
++MODRET set_clientcharset(cmd_rec *cmd) {
++  config_rec *c;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  c=add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
++  c->flags |= CF_MERGEDOWN;
++  return PR_HANDLED(cmd);
++}
++
+ MODRET set_rlimitcpu(cmd_rec *cmd) {
+ #ifdef RLIMIT_CPU
+   /* Make sure the directive has between 1 and 3 parameters */
+@@ -4741,6 +4763,8 @@
+   { "WtmpLog",			set_wtmplog,			NULL },
+   { "tcpBackLog",		set_tcpbacklog,			NULL },
+   { "tcpNoDelay",		set_tcpnodelay,			NULL },
++  { "LocalCharset",		set_localcharset,		NULL },
++  { "ClientCharset",		set_clientcharset,		NULL },
+ 
+   /* Deprecated */
+   { "DisplayFirstChdir",	set_displayfirstchdir,		NULL },
+diff -ur proftpd-1.3.1/src/fsio.c ./src/fsio.c
+--- proftpd-1.3.1/src/fsio.c	2007-08-22 16:50:23.000000000 +0200
++++ ./src/fsio.c	2008-03-23 21:39:04.000000000 +0100
+@@ -1911,11 +1911,25 @@
+ #ifdef PR_USE_NLS
+   size_t outlen;
+   char *res;
++  
++  char *localcharset;
++  char *clientcharset;
++  
++  localcharset=get_param_ptr(CURRENT_CONF,"LocalCharset",FALSE);
++  clientcharset=get_param_ptr(CURRENT_CONF,"ClientCharset",FALSE);
++  
++  if(localcharset && clientcharset) {
++	  res = pr_charset_encode(p, path, strlen(path) + 1, &outlen,clientcharset,localcharset);
++	  pr_trace_msg("utf8", 5, "Charset-decoded '%s' into '%s' using '%s'-> %s",
++	  path, res, clientcharset,localcharset);
++	  return res;
++  }
+ 
++  
+   if (!use_utf8) {
+     return (char *) path;
+   }
+-
++  
+   res = pr_utf8_decode(p, path, strlen(path) + 1, &outlen);
+   if (!res) {
+     pr_trace_msg("utf8", 0, "error UTF8 decoding path '%s': %s", path,
+@@ -1932,9 +1946,25 @@
+ 
+ char *pr_fs_encode_path(pool *p, const char *path) {
+ #ifdef PR_USE_NLS
++    
+   size_t outlen;
+   char *res;
++  
++  char *localcharset;
++  char *clientcharset;
+ 
++  localcharset=get_param_ptr(CURRENT_CONF,"LocalCharset",FALSE);
++  clientcharset=get_param_ptr(CURRENT_CONF,"ClientCharset",FALSE);
++  
++  if(localcharset && clientcharset) {
++	  res = pr_charset_encode(p, path, strlen(path) + 1, &outlen,localcharset,clientcharset);
++	  pr_trace_msg("utf8", 5, "Charset-encoded '%s' into '%s' using '%s'-> %s",
++	  	path, res, localcharset,clientcharset);
++	  return res;
++  }
++  
++  
++  
+   if (!use_utf8) {
+     return (char *) path;
+   }
+diff -ur proftpd-1.3.1/src/utf8.c ./src/utf8.c
+--- proftpd-1.3.1/src/utf8.c	2006-12-15 19:51:50.000000000 +0100
++++ ./src/utf8.c	2008-03-23 15:28:52.000000000 +0100
+@@ -69,6 +69,38 @@
+ }
+ #endif /* !HAVE_ICONV_H */
+ 
++static int charset_convert(char *inbuf, size_t *inbuflen,
++    char *outbuf, size_t *outbuflen, const char* localcharset,const char* clientcharset) {
++# ifdef HAVE_ICONV
++  char *start = inbuf;
++ 
++  iconv_t recode_conv = (iconv_t) -1;
++
++  recode_conv = iconv_open(clientcharset,localcharset);
++  if (recode_conv == (iconv_t) -1)
++	  return -1;
++
++  while (inbuflen > 0) {
++    size_t nconv = iconv(recode_conv, &inbuf, inbuflen, &outbuf, outbuflen);
++    if (nconv == (size_t) -1) {
++      if (errno == EINVAL) {
++        memmove(start, inbuf, *inbuflen);
++        continue;
++
++      } else
++        return -1;
++    }
++
++    break;
++  }
++  iconv_close(recode_conv);
++  return 0;
++# else
++  errno = ENOSYS;
++  return -1;
++# endif /* HAVE_ICONV */
++}
++
+ int utf8_free(void) {
+ # ifdef HAVE_ICONV
+   int res;
+@@ -114,6 +146,7 @@
+ #endif /* HAVE_NL_LANGINFO */
+ 
+ # ifdef HAVE_ICONV
++ 
+   /* Get the iconv handles. */
+   encode_conv = iconv_open(local_charset, "UTF-8");
+   if (encode_conv == (iconv_t) -1)
+@@ -200,4 +233,66 @@
+ #endif /* !HAVE_ICONV_H */
+ }
+ 
++char *pr_charset_decode(pool *p, const char *in, size_t inlen, size_t *outlen, 
++	const char* localcharset, const char* clientcharset) {
++#ifdef HAVE_ICONV_H
++  size_t inbuflen, outbuflen;
++  char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res = NULL;
++
++  if (!p || !in || !outlen) {
++    errno = EINVAL;
++    return NULL;
++  }
++
++  inbuf = pcalloc(p, inlen);
++  memcpy(inbuf, in, inlen);
++  inbuflen = inlen;
++
++  outbuflen = sizeof(outbuf);
++
++  if (charset_convert(inbuf, &inbuflen, outbuf, &outbuflen, localcharset, clientcharset) < 0)
++    return NULL;
++
++  *outlen = sizeof(outbuf) - outbuflen;
++  res = pcalloc(p, *outlen);
++  memcpy(res, outbuf, *outlen);
++
++  return res;
++#else
++  pr_trace_msg("utf8", 1, "missing iconv support, no charset recoding possible");
++  return pstrdup(p, in);
++#endif /* !HAVE_ICONV_H */
++}
++
++char *pr_charset_encode(pool *p, const char *in, size_t inlen, size_t *outlen,
++	const char* localcharset, const char* clientcharset){
++#ifdef HAVE_ICONV_H
++  size_t inbuflen, outbuflen;
++  char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res;
++
++  if (!p || !in || !outlen) {
++    errno = EINVAL;
++    return NULL;
++  }
++
++  inbuf = pcalloc(p, inlen);
++  memcpy(inbuf, in, inlen);
++  inbuflen = inlen;
++
++  outbuflen = sizeof(outbuf);
++
++  if (charset_convert(inbuf, &inbuflen, outbuf, &outbuflen,localcharset, clientcharset) < 0)
++    return NULL;
++
++  *outlen = sizeof(outbuf) - outbuflen;
++  res = pcalloc(p, *outlen);
++  memcpy(res, outbuf, *outlen);
++
++  return res;
++#else
++  pr_trace_msg("utf8", 1, "missing iconv support, no UTF8 encoding possible");
++  return pstrdup(p, in);
++#endif /* !HAVE_ICONV_H */
++}
++
+ #endif /* PR_USE_NLS */
