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