diff --git a/proftpd-1.3.2a-mlsd.patch b/proftpd-1.3.2a-mlsd.patch index 9cf3ec5..a8148bc 100644 --- a/proftpd-1.3.2a-mlsd.patch +++ b/proftpd-1.3.2a-mlsd.patch @@ -1,166 +1,6 @@ --- proftpd-1.3.2a/modules/mod_facts.c.mlsd 2009-04-28 22:17:45.000000000 +0100 +++ proftpd-1.3.2a/modules/mod_facts.c 2009-09-07 14:17:39.000000000 +0100 -@@ -22,7 +22,7 @@ - * resulting executable, without including the source code for OpenSSL in the - * source distribution. - * -- * $Id: mod_facts.c,v 1.13.2.1 2009/04/28 21:17:45 castaglia Exp $ -+ * $Id: mod_facts.c,v 1.22 2009/04/09 15:59:38 castaglia Exp $ - */ - - #include "conf.h" -@@ -227,7 +227,17 @@ - ptr = buf + buflen; - } - -- snprintf(ptr, bufsz - buflen, " %s\n", info->path); -+ /* MLST entries are not sent via pr_data_xfer(), and thus we do not need -+ * to include an LF at the end; it is appended by pr_response_send_raw(). -+ * But MLSD entries DO need the trailing LF, so that it can be converted -+ * into a CRLF sequence by pr_data_xfer(). -+ */ -+ if (strcmp(session.curr_cmd, C_MLSD) == 0) { -+ snprintf(ptr, bufsz - buflen, " %s\n", info->path); -+ -+ } else { -+ snprintf(ptr, bufsz - buflen, " %s", info->path); -+ } - - buf[bufsz-1] = '\0'; - buflen = strlen(buf); -@@ -244,11 +254,17 @@ - * channel, wherease MLSD's output is sent via a data transfer, much like - * LIST or NLST. - */ --static char mlinfo_buf[PR_TUNABLE_BUFFER_SIZE]; -+static char *mlinfo_buf = NULL; -+static size_t mlinfo_bufsz = 0; - static size_t mlinfo_buflen = 0; - - static void facts_mlinfobuf_init(void) { -- memset(mlinfo_buf, '\0', sizeof(mlinfo_buf)); -+ if (mlinfo_buf == NULL) { -+ mlinfo_bufsz = pr_config_get_xfer_bufsz(); -+ mlinfo_buf = palloc(session.pool, mlinfo_bufsz); -+ } -+ -+ memset(mlinfo_buf, '\0', mlinfo_bufsz); - mlinfo_buflen = 0; - } - -@@ -261,11 +277,11 @@ - /* If this buffer will exceed the capacity of mlinfo_buf, then flush - * mlinfo_buf. - */ -- if (buflen >= (sizeof(mlinfo_buf) - mlinfo_buflen)) { -+ if (buflen >= (mlinfo_bufsz - mlinfo_buflen)) { - (void) facts_mlinfobuf_flush(); - } - -- sstrcat(mlinfo_buf, buf, sizeof(mlinfo_buf)); -+ sstrcat(mlinfo_buf, buf, mlinfo_bufsz); - mlinfo_buflen += buflen; - } - -@@ -358,6 +374,8 @@ - char buf[PR_TUNABLE_BUFFER_SIZE]; - - (void) facts_mlinfo_fmt(info, buf, sizeof(buf)); -+ -+ /* The trailing CRLF will be added by pr_response_send_raw(). */ - pr_response_send_raw("%s", buf); - } - -@@ -595,7 +613,6 @@ - */ - - MODRET facts_mff(cmd_rec *cmd) { -- register unsigned int i; - const char *path, *decoded_path; - char *facts, *ptr; - -@@ -606,18 +623,16 @@ - - facts = cmd->argv[1]; - -- /* The path can contain spaces; it is thus the concatenation of all of the -- * arguments after the timestamp. -+ /* The path can contain spaces. Thus we need to use cmd->arg, not cmd->argv, -+ * to find the path. But cmd->arg contains the facts as well. Thus we -+ * find the FIRST space in cmd->arg; the path is everything past that space. - */ -- path = pstrdup(cmd->tmp_pool, cmd->argv[2]); -- for (i = 3; i < cmd->argc; i++) { -- path = pstrcat(cmd->tmp_pool, path, " ", cmd->argv[i], NULL); -- } -+ ptr = strchr(cmd->arg, ' '); -+ path = pstrdup(cmd->tmp_pool, ptr + 1); - - decoded_path = pr_fs_decode_path(cmd->tmp_pool, path); - -- if (!dir_check(cmd->tmp_pool, cmd->argv[0], cmd->group, (char *) decoded_path, -- NULL)) { -+ if (!dir_check(cmd->tmp_pool, cmd, cmd->group, (char *) decoded_path, NULL)) { - pr_log_debug(DEBUG4, MOD_FACTS_VERSION ": %s command denied by ", - cmd->argv[0]); - pr_response_add_err(R_550, _("Unable to handle command")); -@@ -739,7 +754,6 @@ - } - - MODRET facts_mfmt(cmd_rec *cmd) { -- register unsigned int i; - const char *path, *decoded_path; - char *timestamp, *ptr; - int res; -@@ -751,18 +765,16 @@ - - timestamp = cmd->argv[1]; - -- /* The path can contain spaces; it is thus the concatenation of all of the -- * arguments after the timestamp. -+ /* The path can contain spaces. Thus we need to use cmd->arg, not cmd->argv, -+ * to find the path. But cmd->arg contains the facts as well. Thus we -+ * find the FIRST space in cmd->arg; the path is everything past that space. - */ -- path = pstrdup(cmd->tmp_pool, cmd->argv[2]); -- for (i = 3; i < cmd->argc; i++) { -- path = pstrcat(cmd->tmp_pool, path, " ", cmd->argv[i], NULL); -- } -+ ptr = strchr(cmd->arg, ' '); -+ path = pstrdup(cmd->tmp_pool, ptr + 1); - - decoded_path = pr_fs_decode_path(cmd->tmp_pool, path); - -- if (!dir_check(cmd->tmp_pool, cmd->argv[0], cmd->group, (char *) decoded_path, -- NULL)) { -+ if (!dir_check(cmd->tmp_pool, cmd, cmd->group, (char *) decoded_path, NULL)) { - pr_log_debug(DEBUG4, MOD_FACTS_VERSION ": %s command denied by ", - cmd->argv[0]); - pr_response_add_err(R_550, _("Unable to handle command")); -@@ -820,33 +832,28 @@ - DIR *dirh; - struct dirent *dent; - -- if (cmd->argc > 2) { -- pr_response_add_err(R_501, _("Invalid number of arguments")); -- return PR_ERROR(cmd); -- } -- - if (cmd->argc != 1) { -- path = cmd->argv[1]; -+ path = pstrdup(cmd->tmp_pool, cmd->arg); - decoded_path = pr_fs_decode_path(cmd->tmp_pool, path); - - } else { - decoded_path = path = pr_fs_getcwd(); - } - -- if (!dir_check(cmd->tmp_pool, cmd->argv[0], cmd->group, (char *) decoded_path, -- NULL)) { -+ if (!dir_check(cmd->tmp_pool, cmd, cmd->group, (char *) decoded_path, NULL)) { - pr_log_debug(DEBUG4, MOD_FACTS_VERSION ": %s command denied by ", - cmd->argv[0]); - pr_response_add_err(R_550, _("Unable to handle command")); +@@ -841,12 +841,13 @@ return PR_ERROR(cmd); } @@ -179,67 +19,3 @@ } /* Make sure that the given path is actually a directory. */ -@@ -870,11 +877,11 @@ - int xerrno = errno; - - pr_trace_msg("fileperms", 1, "MLSD, user '%s' (UID %lu, GID %lu): " -- "error reading directory '%s': %s", session.user, -+ "error opening directory '%s': %s", session.user, - (unsigned long) session.uid, (unsigned long) session.gid, - decoded_path, strerror(xerrno)); - -- pr_response_add_err(R_550, _("'%s' cannot be listed"), path); -+ pr_response_add_err(R_550, "%s: %s", path, strerror(xerrno)); - return PR_ERROR(cmd); - } - -@@ -899,16 +906,14 @@ - /* Check that the file can be listed. */ - abs_path = dir_realpath(cmd->tmp_pool, rel_path); - if (abs_path) { -- res = dir_check(cmd->tmp_pool, cmd->argv[0], cmd->group, abs_path, -- &hidden); -+ res = dir_check(cmd->tmp_pool, cmd, cmd->group, abs_path, &hidden); - - } else { - abs_path = dir_canonical_path(cmd->tmp_pool, rel_path); - if (abs_path == NULL) - abs_path = rel_path; - -- res = dir_check_canon(cmd->tmp_pool, cmd->argv[0], cmd->group, abs_path, -- &hidden); -+ res = dir_check_canon(cmd->tmp_pool, cmd, cmd->group, abs_path, &hidden); - } - - if (!res || hidden) { -@@ -955,20 +960,15 @@ - const char *path, *decoded_path; - struct mlinfo info; - -- if (cmd->argc > 2) { -- pr_response_add_err(R_501, _("Invalid number of arguments")); -- return PR_ERROR(cmd); -- } -- - if (cmd->argc != 1) { -- path = cmd->argv[1]; -+ path = pstrdup(cmd->tmp_pool, cmd->arg); - decoded_path = pr_fs_decode_path(cmd->tmp_pool, path); - - } else { - decoded_path = path = pr_fs_getcwd(); - } - -- if (!dir_check(cmd->tmp_pool, cmd->argv[0], cmd->group, (char *) decoded_path, -+ if (!dir_check(cmd->tmp_pool, cmd, cmd->group, (char *) decoded_path, - &hidden)) { - pr_log_debug(DEBUG4, MOD_FACTS_VERSION ": %s command denied by ", - cmd->argv[0]); -@@ -1155,6 +1155,7 @@ - - pr_feat_add("MFF modify;UNIX.group;UNIX.mode;"); - pr_feat_add("MFMT"); -+ pr_feat_add("TVFS"); - - facts_mlst_feat_add(session.pool); -