|
|
a04ae28 |
--- include/proftpd.h
|
|
|
a04ae28 |
+++ include/proftpd.h
|
|
|
a04ae28 |
@@ -133,7 +133,7 @@ typedef struct {
|
|
|
a04ae28 |
struct config_struc *anon_config; /* Anonymous FTP configuration */
|
|
|
a04ae28 |
char *anon_user; /* E-mail address sent to us */
|
|
|
a04ae28 |
|
|
|
a04ae28 |
- char *curr_cmd; /* Current FTP command */
|
|
|
a04ae28 |
+ const char *curr_cmd; /* Current FTP command */
|
|
|
a04ae28 |
int curr_phase; /* Current handler phase */
|
|
|
a04ae28 |
|
|
|
a04ae28 |
off_t restart_pos; /* Restart marked position */
|
|
|
a04ae28 |
--- src/data.c
|
|
|
a04ae28 |
+++ src/data.c
|
|
|
a04ae28 |
@@ -653,7 +653,7 @@ void pr_data_close(int quiet) {
|
|
|
a04ae28 |
*/
|
|
|
a04ae28 |
void pr_data_cleanup(void) {
|
|
|
a04ae28 |
/* sanity check */
|
|
|
a04ae28 |
- if (session.d) {
|
|
|
a04ae28 |
+ if (session.d != NULL) {
|
|
|
a04ae28 |
pr_inet_lingering_close(session.pool, session.d, timeout_linger);
|
|
|
a04ae28 |
session.d = NULL;
|
|
|
a04ae28 |
}
|
|
|
a04ae28 |
@@ -675,7 +675,7 @@ void pr_data_abort(int err, int quiet) {
|
|
|
a04ae28 |
int true_abort = XFER_ABORTED;
|
|
|
a04ae28 |
nstrm = NULL;
|
|
|
a04ae28 |
|
|
|
a04ae28 |
- if (session.d) {
|
|
|
a04ae28 |
+ if (session.d != NULL) {
|
|
|
a04ae28 |
if (!true_abort)
|
|
|
a04ae28 |
pr_inet_lingering_close(session.pool, session.d, timeout_linger);
|
|
|
a04ae28 |
|
|
|
a04ae28 |
@@ -856,6 +856,11 @@ void pr_data_abort(int err, int quiet) {
|
|
|
a04ae28 |
*/
|
|
|
a04ae28 |
if (!true_abort)
|
|
|
a04ae28 |
pr_response_add_err(respcode, _("Transfer aborted. %s"), msg ? msg : "");
|
|
|
a04ae28 |
+
|
|
|
a04ae28 |
+ /* Forcibly clear the data-transfer instigating command pool from the
|
|
|
a04ae28 |
+ * Response API.
|
|
|
a04ae28 |
+ */
|
|
|
a04ae28 |
+ pr_response_set_pool(NULL);
|
|
|
a04ae28 |
}
|
|
|
a04ae28 |
|
|
|
a04ae28 |
if (true_abort)
|
|
|
a04ae28 |
@@ -939,8 +944,8 @@ int pr_data_xfer(char *cl_buf, int cl_si
|
|
|
a04ae28 |
|
|
|
a04ae28 |
pr_response_flush(&resp_err_list);
|
|
|
a04ae28 |
|
|
|
a04ae28 |
- destroy_pool(cmd->pool);
|
|
|
a04ae28 |
pr_response_set_pool(resp_pool);
|
|
|
a04ae28 |
+ destroy_pool(cmd->pool);
|
|
|
a04ae28 |
|
|
|
a04ae28 |
/* We don't want to actually dispatch the NOOP command, since that
|
|
|
a04ae28 |
* would overwrite the scoreboard with the NOOP state; admins probably
|
|
|
a04ae28 |
@@ -965,13 +970,13 @@ int pr_data_xfer(char *cl_buf, int cl_si
|
|
|
a04ae28 |
|
|
|
a04ae28 |
pr_response_flush(&resp_list);
|
|
|
a04ae28 |
|
|
|
a04ae28 |
- destroy_pool(cmd->pool);
|
|
|
a04ae28 |
pr_response_set_pool(resp_pool);
|
|
|
a04ae28 |
+ destroy_pool(cmd->pool);
|
|
|
a04ae28 |
|
|
|
a04ae28 |
} else {
|
|
|
a04ae28 |
char *title_buf = NULL;
|
|
|
a04ae28 |
int title_len = -1;
|
|
|
a04ae28 |
- const char *sce_cmd = NULL, *sce_cmd_arg = NULL;
|
|
|
a04ae28 |
+ const char *curr_cmd = NULL, *sce_cmd = NULL, *sce_cmd_arg = NULL;
|
|
|
a04ae28 |
|
|
|
a04ae28 |
pr_trace_msg(trace_channel, 5,
|
|
|
a04ae28 |
"client sent '%s' command during data transfer, dispatching",
|
|
|
a04ae28 |
@@ -983,6 +988,7 @@ int pr_data_xfer(char *cl_buf, int cl_si
|
|
|
a04ae28 |
pr_proctitle_get(title_buf, title_len + 1);
|
|
|
a04ae28 |
}
|
|
|
a04ae28 |
|
|
|
a04ae28 |
+ curr_cmd = session.curr_cmd;
|
|
|
a04ae28 |
sce_cmd = pr_scoreboard_entry_get(PR_SCORE_CMD);
|
|
|
a04ae28 |
sce_cmd_arg = pr_scoreboard_entry_get(PR_SCORE_CMD_ARG);
|
|
|
a04ae28 |
|
|
|
a04ae28 |
@@ -998,6 +1004,7 @@ int pr_data_xfer(char *cl_buf, int cl_si
|
|
|
a04ae28 |
}
|
|
|
a04ae28 |
|
|
|
a04ae28 |
destroy_pool(cmd->pool);
|
|
|
a04ae28 |
+ session.curr_cmd = curr_cmd;
|
|
|
a04ae28 |
}
|
|
|
a04ae28 |
|
|
|
a04ae28 |
} else {
|
|
|
a04ae28 |
--- src/main.c
|
|
|
a04ae28 |
+++ src/main.c
|
|
|
a04ae28 |
@@ -940,9 +940,10 @@ static void cmd_loop(server_rec *server,
|
|
|
a04ae28 |
pr_timer_reset(PR_TIMER_IDLE, ANY_MODULE);
|
|
|
a04ae28 |
}
|
|
|
a04ae28 |
|
|
|
a04ae28 |
- if (cmd) {
|
|
|
a04ae28 |
+ if (cmd != NULL) {
|
|
|
a04ae28 |
pr_cmd_dispatch(cmd);
|
|
|
a04ae28 |
destroy_pool(cmd->pool);
|
|
|
a04ae28 |
+ session.curr_cmd = NULL;
|
|
|
a04ae28 |
|
|
|
a04ae28 |
} else {
|
|
|
a04ae28 |
pr_response_send(R_500, _("Invalid command: try being more creative"));
|
|
|
a04ae28 |
--- src/response.c
|
|
|
a04ae28 |
+++ src/response.c
|
|
|
a04ae28 |
@@ -194,6 +194,16 @@ void pr_response_add_err(const char *num
|
|
|
a04ae28 |
pr_response_t *resp = NULL, **head = NULL;
|
|
|
a04ae28 |
va_list msg;
|
|
|
a04ae28 |
|
|
|
a04ae28 |
+ if (fmt == NULL) {
|
|
|
a04ae28 |
+ return;
|
|
|
a04ae28 |
+ }
|
|
|
a04ae28 |
+
|
|
|
a04ae28 |
+ if (resp_pool == NULL) {
|
|
|
a04ae28 |
+ pr_trace_msg(trace_channel, 1,
|
|
|
a04ae28 |
+ "no response pool set, ignoring added %s error response", numeric);
|
|
|
a04ae28 |
+ return;
|
|
|
a04ae28 |
+ }
|
|
|
a04ae28 |
+
|
|
|
a04ae28 |
va_start(msg, fmt);
|
|
|
a04ae28 |
vsnprintf(resp_buf, sizeof(resp_buf), fmt, msg);
|
|
|
a04ae28 |
va_end(msg);
|
|
|
a04ae28 |
@@ -239,6 +249,16 @@ void pr_response_add(const char *numeric
|
|
|
a04ae28 |
pr_response_t *resp = NULL, **head = NULL;
|
|
|
a04ae28 |
va_list msg;
|
|
|
a04ae28 |
|
|
|
a04ae28 |
+ if (fmt == NULL) {
|
|
|
a04ae28 |
+ return;
|
|
|
a04ae28 |
+ }
|
|
|
a04ae28 |
+
|
|
|
a04ae28 |
+ if (resp_pool == NULL) {
|
|
|
a04ae28 |
+ pr_trace_msg(trace_channel, 1,
|
|
|
a04ae28 |
+ "no response pool set, ignoring added %s response", numeric);
|
|
|
a04ae28 |
+ return;
|
|
|
a04ae28 |
+ }
|
|
|
a04ae28 |
+
|
|
|
a04ae28 |
va_start(msg, fmt);
|
|
|
a04ae28 |
vsnprintf(resp_buf, sizeof(resp_buf), fmt, msg);
|
|
|
a04ae28 |
va_end(msg);
|