Blob Blame History Raw
--- 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);