LINUX.ORG.RU

Патч к proftpd 1.3.1 для перекодировки CP1251<>UTF-8


0

0

В proftpd 1.3.1 сделали поддержку UTF-8 (т.е. она светится в FEAT, а имена файлов в UTF и раньше были), но под оффтопом дофига FTP-клиентов с ним не дружат, признавая только CP1251. Чтобы исправить ситуацию был на скорую руку написан костыль, позволяющий включить перекодировку имен файлов в win1251.

http://www.everfall.com/paste/id.php?cu7w232wyvze

Перекодировка включается командой OPTS UTF8 OFF.

З.Ы. Раньше пользовался патчем mod_codeconv, но если его наложить на 1.3.1, то сервер умирает когда кто-либо посылает команду OPTS UTF8 ON...

Патч этот тоже не рулил, т.к. тупо перекодировал все, соответственно при входе с линуха крякозябры.

anonymous

Сам использую vsftpd, но если ваш патч рабочий, то вам спасибо.

andreyu ★★★★★
()
Ответ на: комментарий от free4net

Немного помудрив с вышеуказынным патчем и с http://linuxportal.vrn.ru/file/proftpd-1.3.0-rus.patch.gz получил следующий патч для proftpd-1.3.1:

#
diff -ur proftpd-1.3.1/include/utf8.h proftpd-1.3.1/include/utf8.h
#
--- proftpd-1.3.1/include/utf8.h        2006-05-25 22:55:34.000000000 +0600
#
+++ proftpd-1.3.1/include/utf8.h        2007-10-25 00:50:10.000000000 +0600
#
@@ -31,11 +31,11 @@
#
 
#
 /*
#
  */
#
-char *pr_utf8_decode(pool *p, const char *in, size_t inlen, size_t *outlen);
#
+char *pr_utf8_decode(pool *p, const char *in, size_t inlen, size_t *outlen, int legacy);
#
 
#
 /*
#
  */
#
-char *pr_utf8_encode(pool *p, const char *in, size_t inlen, size_t *outlen);
#
+char *pr_utf8_encode(pool *p, const char *in, size_t inlen, size_t *outlen, int legacy);
#
 
#
 /* Internal use only. */
#
 int utf8_init(void);
#
diff -ur proftpd-1.3.1/src/fsio.c proftpd-1.3.1/src/fsio.c
#
--- proftpd-1.3.1/src/fsio.c    2007-08-22 20:50:23.000000000 +0600
#
+++ proftpd-1.3.1/src/fsio.c    2007-10-25 01:22:42.000000000 +0600
#
@@ -1912,11 +1912,7 @@
#
   size_t outlen;
#
   char *res;
#
 
#
-  if (!use_utf8) {
#
-    return (char *) path;
#
-  }
#
-
#
-  res = pr_utf8_decode(p, path, strlen(path) + 1, &outlen);
#
+  res = pr_utf8_decode(p, path, strlen(path) + 1, &outlen, !use_utf8);
#
   if (!res) {
#
     pr_trace_msg("utf8", 0, "error UTF8 decoding path '%s': %s", path,
#
       strerror(errno));
#
@@ -1935,11 +1931,7 @@
#
   size_t outlen;
#
   char *res;
#
 
#
-  if (!use_utf8) {
#
-    return (char *) path;
#
-  }
#
-
#
-  res = pr_utf8_encode(p, path, strlen(path) + 1, &outlen);
#
+  res = pr_utf8_encode(p, path, strlen(path) + 1, &outlen, !use_utf8);
#
   if (!res) {
#
     pr_trace_msg("utf8", 0, "error UTF8 encoding path '%s': %s", path,
#
       strerror(errno));
#
diff -ur proftpd-1.3.1/src/utf8.c proftpd-1.3.1/src/utf8.c
#
--- proftpd-1.3.1/src/utf8.c    2006-12-15 23:51:50.000000000 +0500
#
+++ proftpd-1.3.1/src/utf8.c    2007-10-25 00:53:18.000000000 +0600
#
@@ -41,6 +41,8 @@
#
 #ifdef HAVE_ICONV_H
#
 static iconv_t decode_conv = (iconv_t) -1;
#
 static iconv_t encode_conv = (iconv_t) -1;
#
+static iconv_t decode_conv_legacy = (iconv_t) -1;
#
+static iconv_t encode_conv_legacy = (iconv_t) -1;
#
 
#
 static int utf8_convert(iconv_t conv, char *inbuf, size_t *inbuflen,
#
     char *outbuf, size_t *outbuflen) {
#
@@ -82,6 +84,14 @@
#
   if (res < 0)
#
     return -1;
#
 
#
+  res = iconv_close(encode_conv_legacy);
#
+  if (res < 0)
#
+    return -1;
#
+
#
+  res = iconv_close(decode_conv_legacy);
#
+  if (res < 0)
#
+    return -1;
#
+
#
   return 0;
#
 # else
#
   errno = ENOSYS;
#
@@ -96,6 +106,7 @@
#
   /* Look up the current charset.  If there's a problem, default to
#
    * UCS-2.
#
    */
#
+  setlocale(LC_CTYPE, "");
#
   local_charset = nl_langinfo(CODESET);
#
   if (!local_charset) {
#
     local_charset = "C";
#
@@ -123,6 +134,14 @@
#
   if (decode_conv == (iconv_t) -1)
#
     return -1;
#
 
#
+  encode_conv_legacy = iconv_open("CP1251", local_charset);
#
+  if (encode_conv_legacy == (iconv_t) -1)
#
+    return -1;
#
+
#
+  decode_conv_legacy = iconv_open(local_charset, "CP1251");
#
+  if (decode_conv_legacy == (iconv_t) -1)
#
+    return -1;
#
+
#
   return 0;
#
 # else
#
   errno = ENOSYS;
#
@@ -130,7 +149,7 @@
#
 # endif /* HAVE_ICONV */
#
 }
#
 
#
-char *pr_utf8_decode(pool *p, const char *in, size_t inlen, size_t *outlen) {
#
+char *pr_utf8_decode(pool *p, const char *in, size_t inlen, size_t *outlen, int legacy) {
#
 #ifdef HAVE_ICONV_H
#
   size_t inbuflen, outbuflen;
#
   char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res = NULL;
#
@@ -140,7 +159,13 @@
#
     return NULL;
#
   }
#
 
#
-  if (decode_conv == (iconv_t) -1) {
#
+  iconv_t conv;
#
+  if (legacy == 0)
#
+    conv = decode_conv;
#
+  else
#
+    conv = decode_conv_legacy;
#
+
#
+  if (conv == (iconv_t) -1) {
#
     errno = EPERM;
#
     return NULL;
#
   }
#
@@ -151,7 +176,7 @@
#
 
#
   outbuflen = sizeof(outbuf);
#
 
#
-  if (utf8_convert(decode_conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0)
#
+  if (utf8_convert(conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0)
#
     return NULL;
#
 
#
   *outlen = sizeof(outbuf) - outbuflen;
#
@@ -165,7 +190,7 @@
#
 #endif /* !HAVE_ICONV_H */
#
 }
#
 
#
-char *pr_utf8_encode(pool *p, const char *in, size_t inlen, size_t *outlen) {
#
+char *pr_utf8_encode(pool *p, const char *in, size_t inlen, size_t *outlen, int legacy) {
#
 #ifdef HAVE_ICONV_H
#
   size_t inbuflen, outbuflen;
#
   char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res;
#
@@ -175,7 +200,13 @@
#
     return NULL;
#
   }
#
 
#
-  if (encode_conv == (iconv_t) -1) {
#
+  iconv_t conv;
#
+  if (legacy == 0)
#
+    conv = encode_conv;
#
+  else
#
+    conv = encode_conv_legacy;
#
+
#
+  if (conv == (iconv_t) -1) {
#
     errno = EPERM;
#
     return NULL;
#
   }
#
@@ -186,7 +217,7 @@
#
 
#
   outbuflen = sizeof(outbuf);
#
 
#
-  if (utf8_convert(encode_conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0)
#
+  if (utf8_convert(conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0)
#
     return NULL;

    *outlen = sizeof(outbuf) - outbuflen;

diff -urN proftpd-1.3.1/src/netio.c proftpd-1.3.1/src/netio.c
--- proftpd-1.3.1/src/netio.c	2004-10-10 00:46:00.000000000 +0900
+++ proftpd-1.3.1/src/netio.c	2006-09-10 01:37:45.000000000 +0900
@@ -523,9 +523,12 @@
   return -1;
 }
 
+
+
 int pr_netio_printf(pr_netio_stream_t *nstrm, const char *fmt, ...) {
   va_list msg;
   char buf[PR_RESPONSE_BUFFER_SIZE] = {'\0'};
+
 
   if (!nstrm) {
     errno = EINVAL;
@@ -537,6 +540,13 @@
   va_end(msg);
   buf[sizeof(buf)-1] = '\0';
 
+
+
+
+
+
+
+
   return pr_netio_write(nstrm, buf, strlen(buf));
 }
 
@@ -901,46 +901,6 @@
       cp = *pbuf->current++;
       pbuf->remaining++;
 
-      switch (mode) {
-        case IAC:
-          switch (cp) {
-            case WILL:
-            case WONT:
-            case DO:
-            case DONT:
-              mode = cp;
-              continue;
-
-            case IAC:
-              mode = 0;
-              break;
-
-            default:
-              /* Ignore */
-              mode = 0;
-              continue;
-          }
-          break;
-
-        case WILL:
-        case WONT:
-          pr_netio_printf(out_nstrm, "%c%c%c", IAC, DONT, cp);
-          mode = 0;
-          continue;
-
-        case DO:
-        case DONT:
-          pr_netio_printf(out_nstrm, "%c%c%c", IAC, WONT, cp);
-          mode = 0;
-          continue;
-
-        default:
-          if (cp == IAC) {
-            mode = cp;
-            continue;
-          }
-          break;
-      }
 
       *bp++ = cp;
       buflen--;

free4net
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.