Jump to content

Recommended Posts

Posted

все файлы у нас на серваке в UTF-8, а хотелось получить в FTP-клиенте CP1251. Пропатчил vsftpd-2.0.1, использовав iconv.

 

в main.c строки

#define INSIDE_CHARSET "UTF-8"

#define OUTSIDE_CHARSET "CP1251"

задают внутреннюю и внешнюю кодировки.

 

Патч: vsftpd-2.0.1-convertable.diff

diff -uNr vsftpd-2.0.1/ftpcmdio.c vsftpd-2.0.1-convertable/ftpcmdio.c

--- vsftpd-2.0.1/ftpcmdio.c     2004-07-02 15:23:02.000000000 +0400

+++ vsftpd-2.0.1-convertable/ftpcmdio.c 2004-11-16 15:47:19.000000000 +0300

@@ -200,6 +200,7 @@

  ftp_getline(p_sess, p_str, p_sess->p_control_line_buf);

  /* As mandated by the FTP specifications.. */

  str_replace_char(p_str, '0', 'n');

+  str_iconv(p_str, 1);

  /* If the last character is a r, strip it */

  {

    unsigned int len = str_getlen(p_str);

diff -uNr vsftpd-2.0.1/main.c vsftpd-2.0.1-convertable/main.c

--- vsftpd-2.0.1/main.c 2004-07-02 15:23:39.000000000 +0400

+++ vsftpd-2.0.1-convertable/main.c     2004-11-16 15:33:14.000000000 +0300

@@ -5,6 +5,10 @@

 * main.c

 */



+#include <iconv.h>

+#include <string.h>

+#include <errno.h>

+

#include "session.h"

#include "utility.h"

#include "tunables.h"

@@ -31,6 +35,10 @@

static void session_init(struct vsf_session* p_sess);

static void env_init(void);



+#define INSIDE_CHARSET "UTF-8"

+#define OUTSIDE_CHARSET "CP1251"

+iconv_t cd_inside, cd_outside;

+

int

main(int argc, const char* argv[])

{

@@ -68,6 +76,12 @@

  /* Zero or one argument supported. If one argument is passed, it is the

   * path to the config file

   */

+

+  cd_inside = iconv_open(INSIDE_CHARSET, OUTSIDE_CHARSET);

+  if (cd_inside == (iconv_t)(-1)) die(strerror(errno));

+  cd_outside = iconv_open(OUTSIDE_CHARSET, INSIDE_CHARSET);

+  if (cd_outside == (iconv_t)(-1)) die(strerror(errno));

+

  if (argc > 2)

  {

    die("vsftpd: too many arguments (I take an optional config file only)");

diff -uNr vsftpd-2.0.1/str.c vsftpd-2.0.1-convertable/str.c

--- vsftpd-2.0.1/str.c  2004-07-02 15:25:43.000000000 +0400

+++ vsftpd-2.0.1-convertable/str.c      2004-11-16 15:56:33.000000000 +0300

@@ -660,3 +660,24 @@

  }

}



+void

+str_iconv(struct mystr* p_str, int direction)

+{

+  char tmp[MAX_ICONV_STRING+1], *to_buf, *from_buf;

+  size_t sz_from, sz_to, nconv;

+

+  from_buf = (char*)str_strdup(p_str);

+  to_buf = tmp;

+  sz_from = str_getlen(p_str)+1;

+  if (sz_from>MAX_ICONV_STRING) return;

+  sz_to = MAX_ICONV_STRING;

+  if (direction) {

+       nconv = iconv(cd_inside, &from_buf, &sz_from, &to_buf, &sz_to);

+       nconv = iconv(cd_inside, NULL, NULL, NULL, NULL);

+  } else {

+    nconv = iconv(cd_outside, &from_buf, &sz_from, &to_buf, &sz_to);

+       nconv = iconv(cd_inside, NULL, NULL, NULL, NULL);

+  }

+  str_empty(p_str);

+  str_append_text(p_str, tmp);

+}

diff -uNr vsftpd-2.0.1/str.h vsftpd-2.0.1-convertable/str.h

--- vsftpd-2.0.1/str.h  2004-06-04 20:35:00.000000000 +0400

+++ vsftpd-2.0.1-convertable/str.h      2004-11-16 15:52:48.000000000 +0300

@@ -1,12 +1,19 @@

#ifndef VSFTP_STR_H

#define VSFTP_STR_H



+#include <iconv.h>

+#include <string.h>

+#include "sysstr.h"

+#define MAX_ICONV_STRING 2048

+

/* TODO - document these functions;-) */



#ifndef VSF_FILESIZE_H

#include "filesize.h"

#endif



+extern iconv_t cd_inside, cd_outside;

+

struct mystr

{

  char* PRIVATE_HANDS_OFF_p_buf;

@@ -120,5 +127,7 @@

int str_contains_line(const struct mystr* p_str,

                      const struct mystr* p_line_str);



+void str_iconv(struct mystr* p_str, int direction); //  direction: 1 - inside, 0 - outside

+

#endif /* VSFTP_STR_H */



diff -uNr vsftpd-2.0.1/strlist.c vsftpd-2.0.1-convertable/strlist.c

--- vsftpd-2.0.1/strlist.c      2004-07-02 15:25:48.000000000 +0400

+++ vsftpd-2.0.1-convertable/strlist.c  2004-11-16 15:39:25.000000000 +0300

@@ -92,6 +92,7 @@

  p_node = &p_list->p_nodes[p_list->list_len];

  p_node->str = s_null_str;

  p_node->sort_key_str = s_null_str;

+  str_iconv(p_str, 0);

  str_copy(&p_node->str, p_str);

  if (p_sort_key_str)

  {

 

патч применяется как всегда:

cd vsftpd-2.0.1

patch -p1 < ../vsftpd-2.0.1-convertable.diff

[/code]

  • 3 months later...
Posted

я его немного проапгрейдил - в командной строке можно указывать внутреннюю, внешнюю кодировки, и порт, на котором слушать. плюс, видимо, вышел новый релиз под версией 2.0.1, и предыдущий патч на ней не срабатывал. новый патч:

diff -rc vsftpd-2.0.1/ftpcmdio.c vsftpd-2.0.1-convertable-r2/ftpcmdio.c

*** vsftpd-2.0.1/ftpcmdio.c     2004-07-02 15:23:02.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/ftpcmdio.c      2005-02-01 01:17:17.000000000 +0300

***************

*** 200,205 ****

--- 200,206 ----

   ftp_getline(p_sess, p_str, p_sess->p_control_line_buf);

   /* As mandated by the FTP specifications.. */

   str_replace_char(p_str, '0', 'n');

+   if (iconv_enabled) str_iconv(p_str, 1);

   /* If the last character is a r, strip it */

   {

     unsigned int len = str_getlen(p_str);

diff -rc vsftpd-2.0.1/ftpcmdio.h vsftpd-2.0.1-convertable-r2/ftpcmdio.h

*** vsftpd-2.0.1/ftpcmdio.h     2003-09-10 03:11:01.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/ftpcmdio.h      2005-02-01 01:17:00.000000000 +0300

***************

*** 1,6 ****

--- 1,8 ----

 #ifndef VSF_FTPCMDIO_H

 #define VSF_FTPCMDIO_H



+ extern int iconv_enabled;

+

 struct mystr;

 struct vsf_session;



diff -rc vsftpd-2.0.1/main.c vsftpd-2.0.1-convertable-r2/main.c

*** vsftpd-2.0.1/main.c 2004-07-02 15:23:39.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/main.c  2005-02-01 01:33:46.000000000 +0300

***************

*** 5,10 ****

--- 5,15 ----

  * main.c

  */



+ #include <iconv.h>

+ #include <stdlib.h>

+ #include <string.h>

+ #include <errno.h>

+

 #include "session.h"

 #include "utility.h"

 #include "tunables.h"

***************

*** 31,36 ****

--- 36,46 ----

 static void session_init(struct vsf_session* p_sess);

 static void env_init(void);



+ #define INSIDE_CHARSET "UTF-8"

+ #define OUTSIDE_CHARSET "WINDOWS-1251"

+ iconv_t cd_inside, cd_outside;

+ int iconv_enabled=0;

+

 int

 main(int argc, const char* argv[])

 {

***************

*** 68,82 ****

   /* Zero or one argument supported. If one argument is passed, it is the

    * path to the config file

    */

!   if (argc > 2)

   {

!     die("vsftpd: too many arguments (I take an optional config file only)");

   }

   else if (argc == 0)

   {

     die("vsftpd: missing argv[0]");

   }

!   if (argc == 2)

   {

     if (!vsf_sysutil_strcmp(argv[1], "-v"))

     {

--- 78,93 ----

   /* Zero or one argument supported. If one argument is passed, it is the

    * path to the config file

    */

!

!   if (argc > 5 || argc == 3)

   {

!     die("vsftpd: incorrect arguments (usage: vsftpd /path/to/config [inside_charset outside_charset [listen_port]]");

   }

   else if (argc == 0)

   {

     die("vsftpd: missing argv[0]");

   }

!   if (argc >= 2)

   {

     if (!vsf_sysutil_strcmp(argv[1], "-v"))

     {

***************

*** 85,90 ****

--- 96,112 ----

     p_config_name = argv[1];

     config_specified = 1;

   }

+   if (argc >= 4) {

+       cd_inside = iconv_open(argv[2], argv[3]);

+       if (cd_inside == (iconv_t)(-1)) die(strerror(errno));

+       cd_outside = iconv_open(argv[3], argv[2]);

+       if (cd_outside == (iconv_t)(-1)) die(strerror(errno));

+       iconv_enabled = 1;

+   }

+   if (argc == 5) {

+     tunable_listen_port = atoi(argv[4]);

+   }

+

   /* This might need to open /dev/zero on systems lacking MAP_ANON. Needs

    * to be done early (i.e. before config file parse, which may use

    * anonymous pages

diff -rc vsftpd-2.0.1/str.c vsftpd-2.0.1-convertable-r2/str.c

*** vsftpd-2.0.1/str.c  2004-07-02 15:25:43.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/str.c   2005-02-01 01:09:16.000000000 +0300

***************

*** 660,662 ****

--- 660,683 ----

   }

 }



+ void

+ str_iconv(struct mystr* p_str, int direction)

+ {

+   char tmp[MAX_ICONV_STRING+1], *to_buf, *from_buf;

+   size_t sz_from, sz_to, nconv;

+

+   from_buf = (char*)str_strdup(p_str);

+   to_buf = tmp;

+   sz_from = str_getlen(p_str)+1;

+   if (sz_from>MAX_ICONV_STRING) return;

+   sz_to = MAX_ICONV_STRING;

+   if (direction) {

+        nconv = iconv(cd_inside, &from_buf, &sz_from, &to_buf, &sz_to);

+        nconv = iconv(cd_inside, NULL, NULL, NULL, NULL);

+   } else {

+     nconv = iconv(cd_outside, &from_buf, &sz_from, &to_buf, &sz_to);

+        nconv = iconv(cd_inside, NULL, NULL, NULL, NULL);

+   }

+   str_empty(p_str);

+   str_append_text(p_str, tmp);

+ }

diff -rc vsftpd-2.0.1/str.h vsftpd-2.0.1-convertable-r2/str.h

*** vsftpd-2.0.1/str.h  2004-06-04 20:35:00.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/str.h   2005-02-01 01:09:16.000000000 +0300

***************

*** 1,12 ****

--- 1,19 ----

 #ifndef VSFTP_STR_H

 #define VSFTP_STR_H



+ #include <iconv.h>

+ #include <string.h>

+ #include "sysstr.h"

+ #define MAX_ICONV_STRING 2048

+

 /* TODO - document these functions;-) */



 #ifndef VSF_FILESIZE_H

 #include "filesize.h"

 #endif



+ extern iconv_t cd_inside, cd_outside;

+

 struct mystr

 {

   char* PRIVATE_HANDS_OFF_p_buf;

***************

*** 120,124 ****

--- 127,133 ----

 int str_contains_line(const struct mystr* p_str,

                       const struct mystr* p_line_str);



+ void str_iconv(struct mystr* p_str, int direction); //  direction: 1 - inside, 0 - outside

+

 #endif /* VSFTP_STR_H */



diff -rc vsftpd-2.0.1/strlist.c vsftpd-2.0.1-convertable-r2/strlist.c

*** vsftpd-2.0.1/strlist.c      2004-07-02 15:25:48.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/strlist.c       2005-02-01 01:21:12.000000000 +0300

***************

*** 92,97 ****

--- 92,98 ----

   p_node = &p_list->p_nodes[p_list->list_len];

   p_node->str = s_null_str;

   p_node->sort_key_str = s_null_str;

+   if (iconv_enabled) str_iconv((struct mystr*)p_str, 0);

   str_copy(&p_node->str, p_str);

   if (p_sort_key_str)

   {

diff -rc vsftpd-2.0.1/strlist.h vsftpd-2.0.1-convertable-r2/strlist.h

*** vsftpd-2.0.1/strlist.h      2002-07-14 22:27:03.000000000 +0400

--- vsftpd-2.0.1-convertable-r2/strlist.h       2005-02-01 01:17:58.000000000 +0300

***************

*** 1,6 ****

--- 1,8 ----

 #ifndef VSF_STRLIST_H

 #define VSF_STRLIST_H



+ extern int iconv_enabled;

+

 /* Forward declarations */

 struct mystr;

 struct mystr_list_node;

 

запускать можно так:

# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf UTF-8 WINDOWS-1251

# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf UTF-8 UTF-8 2121

# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf UTF-8 KOI8-R 2122

Posted
# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf UTF-8 WINDOWS-1251

# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf UTF-8 UTF-8 2121

# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf UTF-8 KOI8-R 2122

 

всё это конечно хорошо, но не у всех локально utf-8. лучше вынести это дело в конфиг. ну и конечно добится добавления патча на официальном уровне.

Posted

мой патч основан на iconv, так что можно перекодировать хоть из WINDOWS-1251 в CP866, UTF-8 я привел для примера. в конфиг выносить не хочу - хочется запускать несколько vsftpd с указанием одного конфига и разных кодировок и портов.

 

официально думаю не получится - решение не очень красивое, и с безопасностью теоретически могут возникнуть проблемы. у них для работы со строками только свои функции используются, а тут какая-то внешняя библиотека..

Posted
официально думаю не получится - решение не очень красивое, и с безопасностью теоретически могут возникнуть проблемы. у них для работы со строками только свои функции используются, а тут какая-то внешняя библиотека..

а как быть с другими версиями (у меня 1.2.2) ? ну и раз уже взялся делать патчи выкладывай их гденибудь. а то на форуме както несеръёзно.

Posted

с другими версиями - нет времени, тем более на предыдущие... +(

с патчем - подумаю, пока нет стабильного места, где выложить...

Posted
с другими версиями - нет времени, тем более на предыдущие... +(

с патчем - подумаю, пока нет стабильного места, где выложить...

1.2.2 это не предидущая а стабильная ветка.

  • 8 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...
На сайте используются файлы cookie и сервисы аналитики для корректной работы форума и улучшения качества обслуживания. Продолжая использовать сайт, вы соглашаетесь с использованием файлов cookie и с Политикой конфиденциальности.