--- 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(session.pool);
}
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);