diff -urN proftpd-1.2.10/modules/mod_codeconv.c proftpd-1.2.10-iconv/modules/mod_codeconv.c --- proftpd-1.2.10/modules/mod_codeconv.c 1970-01-01 09:00:00.000000000 +0900 +++ proftpd-1.2.10-iconv/modules/mod_codeconv.c 2004-09-25 21:44:05.000000000 +0900 @@ -0,0 +1,229 @@ +/* + * ProFTPD: mod_codeconv -- local <-> remote charset conversion + * + * Copyright (c) 2004 by TSUJIKAWA Tohru / All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + */ + + +#include "conf.h" +#include + + +// +// directive +// +#define DIRECTIVE_CHARSETLOCAL "CharsetLocal" +#define DIRECTIVE_CHARSETREMOTE "CharsetRemote" + + +// +// initialization +// +static int codeconv_init(void) +{ + return 0; +} + +static int codeconv_sess_init(void) +{ + return 0; +} + + +char* remote2local(struct pool* pool, char* remote) +{ + iconv_t ic; + char* local; + char* in_ptr; + char* out_ptr; + size_t inbytesleft, outbytesleft; + + config_rec* conf_l = NULL; + config_rec* conf_r = NULL; + + conf_l = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETLOCAL, FALSE); + conf_r = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETREMOTE, FALSE); + if (!conf_l || !conf_r) return NULL; + + ic = iconv_open(conf_l->argv[0], conf_r->argv[0]); + if (ic == (iconv_t)(-1)) return NULL; + + iconv(ic, NULL, NULL, NULL, NULL); + + inbytesleft = strlen(remote); + outbytesleft = inbytesleft*3; + local = palloc(pool, outbytesleft+1); + + in_ptr = remote; out_ptr = local; + while (inbytesleft) { + if (iconv(ic, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft) == -1) { + *out_ptr = '?'; out_ptr++; outbytesleft--; + in_ptr++; inbytesleft--; + break; + } + } + *out_ptr = 0; + + iconv_close(ic); + + return local; +} + + +char* local2remote(char* local) +{ + iconv_t ic; + char* remote; + char* in_ptr; + char* out_ptr; + size_t inbytesleft, outbytesleft; + + config_rec* conf_l = NULL; + config_rec* conf_r = NULL; + + conf_l = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETLOCAL, FALSE); + conf_r = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETREMOTE, FALSE); + if (!conf_l || !conf_r) return NULL; + + ic = iconv_open(conf_r->argv[0], conf_l->argv[0]); + if (ic == (iconv_t)(-1)) return NULL; + + iconv(ic, NULL, NULL, NULL, NULL); + + inbytesleft = strlen(local); + outbytesleft = inbytesleft*3; + remote = malloc(outbytesleft+1); + + in_ptr = local; out_ptr = remote; + while (inbytesleft) { + if (iconv(ic, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft) == -1) { + *out_ptr = '?'; out_ptr++; outbytesleft--; + in_ptr++; inbytesleft--; + break; + } + } + *out_ptr = 0; + + iconv_close(ic); + + return remote; +} + + +// +// module handler +// +MODRET codeconv_pre_any(cmd_rec* cmd) +{ + char* p; + int i; + + p = remote2local(cmd->pool, cmd->arg); + if (p) cmd->arg = p; + + for (i = 0; i < cmd->argc; i++) { + p = remote2local(cmd->pool, cmd->argv[i]); + if (p) cmd->argv[i] = p; + } + + return DECLINED(cmd); +} + + +// +// local charset directive "CharsetLocal" +// +MODRET set_charsetlocal(cmd_rec *cmd) { + config_rec *c = NULL; + + /* Syntax: CharsetLocal iconv-charset-name */ + + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); + + c = add_config_param_str(DIRECTIVE_CHARSETLOCAL, 1, cmd->argv[1]); + + return HANDLED(cmd); +} + +// +// remote charset directive "CharsetRemote" +// +MODRET set_charsetremote(cmd_rec *cmd) { + config_rec *c = NULL; + + /* Syntax: CharsetRemote iconv-charset-name */ + + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); + + c = add_config_param_str(DIRECTIVE_CHARSETREMOTE, 1, cmd->argv[1]); + + return HANDLED(cmd); +} + + +// +// module 用 directive +// +static conftable codeconv_conftab[] = { + { DIRECTIVE_CHARSETLOCAL, set_charsetlocal, NULL }, + { DIRECTIVE_CHARSETREMOTE, set_charsetremote, NULL }, + { NULL, NULL, NULL } +}; + + +// +// trap するコマンド一覧 +// +static cmdtable codeconv_cmdtab[] = { + { PRE_CMD, C_ANY, G_NONE, codeconv_pre_any, FALSE, FALSE }, + { 0, NULL } +}; + + +// +// module 情報 +// +module codeconv_module = { + + /* Always NULL */ + NULL, NULL, + + /* Module API version (2.0) */ + 0x20, + + /* Module name */ + "codeconv", + + /* Module configuration directive handlers */ + codeconv_conftab, + + /* Module command handlers */ + codeconv_cmdtab, + + /* Module authentication handlers (none in this case) */ + NULL, + + /* Module initialization */ + codeconv_init, + + /* Session initialization */ + codeconv_sess_init + +}; diff -urN proftpd-1.2.10/modules/mod_df.c proftpd-1.2.10-iconv/modules/mod_df.c --- proftpd-1.2.10/modules/mod_df.c 1970-01-01 09:00:00.000000000 +0900 +++ proftpd-1.2.10-iconv/modules/mod_df.c 2004-09-25 21:43:57.000000000 +0900 @@ -0,0 +1,127 @@ +/* + * ProFTPD: mod_df -- ディスク空き容量通知モジュール + * + * Copyright (c) 2002 by TSUJIKAWA Tohru + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + */ + + /* + **** for Linux only **** + + CWD/CDUP コマンドのリザルトで当該ディレクトリでのディスク空き容量を通知するモジュールです。 + + statfs() の仕様上,64bit 用にコンパイルしない場合は 2TB 以上のディスクの時に + 正常な値を返さないことが期待されます。 + + */ + + +#include "conf.h" +#include + + +// +// 初期化 +// +static int df_init(void) +{ + return 0; +} + +static int df_sess_init(void) +{ + return 0; +} + + +// +// module handler +// +MODRET df_post_cwd(cmd_rec* cmd) +{ + char buf[PATH_MAX+1]; + struct statfs sfs; + + if (getcwd(buf, sizeof(buf)) && statfs(buf, &sfs) == 0) { + long long f = (long long)sfs.f_bavail * (long long)sfs.f_bsize; + if (f >= ((long long)1 << 10)*1000000000L) { + sprintf(buf, "Disk free space at this directory is %lld,%03lld,%03lld MB.", + (f >> 20)/1000000, (f >> 20)/1000%1000, (f >> 20)%1000); + } else if (f >= ((long long)1 << 10)*1000000) { + sprintf(buf, "Disk free space at this directory is %lld,%03lld,%03lld KB.", + (f >> 10)/1000000, (f >> 10)/1000%1000, (f >> 10)%1000); + } else if (f >= ((long long)1 << 10)*1000) { + sprintf(buf, "DISK FREE SPACE AT THIS DIRECTORY IS ONLY %lld,%03lld KB.", (f >> 10)/1000, (f >> 10)%1000); + } else if (f >= 1000) { + sprintf(buf, "DISK FREE SPACE AT THIS DIRECTORY IS ONLY %lld,%03lld Bytes.", f/1000, f%1000); + } else { + sprintf(buf, "DISK FREE SPACE AT THIS DIRECTORY IS ONLY %lld Bytes.", f); + } + pr_response_send_raw("250-%s", buf); + } + return HANDLED(cmd); +} + + +// +// module 用 directive +// +static conftable df_conftab[] = { + { NULL } // directive はサポートしない +}; + + +// +// trap するコマンド一覧 +// +static cmdtable df_cmdtab[] = { + { POST_CMD, C_CWD, G_NONE, df_post_cwd, FALSE, FALSE }, + { POST_CMD, C_CDUP, G_NONE, df_post_cwd, FALSE, FALSE }, + { 0, NULL } +}; + + +// +// module 情報 +// +module df_module = { + + /* Always NULL */ + NULL, NULL, + + /* Module API version (2.0) */ + 0x20, + + /* Module name */ + "df", + + /* Module configuration directive handlers */ + df_conftab, + + /* Module command handlers */ + df_cmdtab, + + /* Module authentication handlers (none in this case) */ + NULL, + + /* Module initialization */ + df_init, + + /* Session initialization */ + df_sess_init + +}; diff -urN proftpd-1.2.10/modules/mod_ls.c proftpd-1.2.10-iconv/modules/mod_ls.c --- proftpd-1.2.10/modules/mod_ls.c 2004-05-08 06:31:30.000000000 +0900 +++ proftpd-1.2.10-iconv/modules/mod_ls.c 2004-09-25 21:43:53.000000000 +0900 @@ -232,12 +232,15 @@ return res; } +extern char* local2remote(char*); + /* sendline() now has an internal buffer, to help speed up LIST output. */ static int sendline(int flags, char *fmt, ...) { static char listbuf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; va_list msg; char buf[PR_TUNABLE_BUFFER_SIZE+1] = {'\0'}; int res = 0; + char* buf2; /* A NULL fmt argument is the signal to flush the buffer */ if (!fmt) { @@ -255,6 +258,13 @@ buf[sizeof(buf)-1] = '\0'; + if (buf[0]) { + buf2 = local2remote(buf); + if (buf2) { + strcpy(buf, buf2); free(buf2); + } + } + /* If buf won't fit completely into listbuf, flush listbuf */ if (strlen(buf) >= (sizeof(listbuf) - strlen(listbuf))) { if ((res = pr_data_xfer(listbuf, strlen(listbuf))) < 0) diff -urN proftpd-1.2.10/src/netio.c proftpd-1.2.10-iconv/src/netio.c --- proftpd-1.2.10/src/netio.c 2004-06-16 01:45:21.000000000 +0900 +++ proftpd-1.2.10-iconv/src/netio.c 2004-09-25 21:42:59.000000000 +0900 @@ -467,9 +467,12 @@ return -1; } +extern char* local2remote(char* local); + int pr_netio_printf(pr_netio_stream_t *nstrm, const char *fmt, ...) { va_list msg; char buf[PR_RESPONSE_BUFFER_SIZE] = {'\0'}; + char* p; if (!nstrm) { errno = EINVAL; @@ -481,6 +484,13 @@ va_end(msg); buf[sizeof(buf)-1] = '\0'; + if (buf[0]) { + p = local2remote(buf); + if (p) { + strcpy(buf, p); free(p); + } + } + return pr_netio_write(nstrm, buf, strlen(buf)); }