Sebastian Kuschel reports that pfd_closing can be called for a socket
[u/mdw/putty] / logging.c
index b2401c3..fc89db7 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -16,13 +16,13 @@ struct LogContext {
     FILE *lgfp;
     enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state;
     bufchain queue;
-    Filename currlogfilename;
+    Filename *currlogfilename;
     void *frontend;
     Conf *conf;
     int logtype;                      /* cached out of conf */
 };
 
-static void xlatlognam(Filename *d, Filename s, char *hostname, struct tm *tm);
+static Filename *xlatlognam(Filename *s, char *hostname, struct tm *tm);
 
 /*
  * Internal wrapper function which must be called for _all_ output
@@ -116,7 +116,7 @@ static void logfopen_callback(void *handle, int mode)
                       ctx->logtype == LGTYP_PACKETS ? "SSH packets" :
                       ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" :
                       "unknown"),
-                     filename_to_str(&ctx->currlogfilename));
+                     filename_to_str(ctx->currlogfilename));
     logevent(ctx->frontend, event);
     sfree(event);
 
@@ -155,9 +155,11 @@ void logfopen(void *handle)
     tm = ltime();
 
     /* substitute special codes in file name */
-    xlatlognam(&ctx->currlogfilename,
-              *conf_get_filename(ctx->conf, CONF_logfilename),
-              conf_get_str(ctx->conf, CONF_host), &tm);
+    if (ctx->currlogfilename)
+        filename_free(ctx->currlogfilename);
+    ctx->currlogfilename = 
+        xlatlognam(conf_get_filename(ctx->conf, CONF_logfilename),
+                   conf_get_str(ctx->conf, CONF_host), &tm);
 
     ctx->lgfp = f_open(ctx->currlogfilename, "r", FALSE);  /* file already present? */
     if (ctx->lgfp) {
@@ -256,8 +258,21 @@ void log_packet(void *handle, int direction, int type,
                      type, type, texttype);
        }
     } else {
-        logprintf(ctx, "%s raw data\r\n",
-                  direction == PKT_INCOMING ? "Incoming" : "Outgoing");
+        /*
+         * Raw data is logged with a timestamp, so that it's possible
+         * to determine whether a mysterious delay occurred at the
+         * client or server end. (Timestamping the raw data avoids
+         * cluttering the normal case of only logging decrypted SSH
+         * messages, and also adds conceptual rigour in the case where
+         * an SSH message arrives in several pieces.)
+         */
+        char buf[256];
+        struct tm tm;
+       tm = ltime();
+       strftime(buf, 24, "%Y-%m-%d %H:%M:%S", &tm);
+        logprintf(ctx, "%s raw data at %s\r\n",
+                  direction == PKT_INCOMING ? "Incoming" : "Outgoing",
+                  buf);
     }
 
     /*
@@ -338,6 +353,7 @@ void *log_init(void *frontend, Conf *conf)
     ctx->frontend = frontend;
     ctx->conf = conf_copy(conf);
     ctx->logtype = conf_get_int(ctx->conf, CONF_logtype);
+    ctx->currlogfilename = NULL;
     bufchain_init(&ctx->queue);
     return ctx;
 }
@@ -348,6 +364,8 @@ void log_free(void *handle)
 
     logfclose(ctx);
     bufchain_clear(&ctx->queue);
+    if (ctx->currlogfilename)
+        filename_free(ctx->currlogfilename);
     sfree(ctx);
 }
 
@@ -356,8 +374,8 @@ void log_reconfig(void *handle, Conf *conf)
     struct LogContext *ctx = (struct LogContext *)handle;
     int reset_logging;
 
-    if (!filename_equal(*conf_get_filename(ctx->conf, CONF_logfilename),
-                       *conf_get_filename(conf, CONF_logfilename)) ||
+    if (!filename_equal(conf_get_filename(ctx->conf, CONF_logfilename),
+                       conf_get_filename(conf, CONF_logfilename)) ||
        conf_get_int(ctx->conf, CONF_logtype) !=
        conf_get_int(conf, CONF_logtype))
        reset_logging = TRUE;
@@ -382,17 +400,19 @@ void log_reconfig(void *handle, Conf *conf)
  *
  * "&Y":YYYY   "&m":MM   "&d":DD   "&T":hhmmss   "&h":<hostname>   "&&":&
  */
-static void xlatlognam(Filename *dest, Filename src,
-                      char *hostname, struct tm *tm) {
+static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
+{
     char buf[10], *bufp;
     int size;
-    char buffer[FILENAME_MAX];
-    int len = sizeof(buffer)-1;
-    char *d;
+    char *buffer;
+    int buflen, bufsize;
     const char *s;
+    Filename *ret;
 
-    d = buffer;
-    s = filename_to_str(&src);
+    bufsize = FILENAME_MAX;
+    buffer = snewn(bufsize, char);
+    buflen = 0;
+    s = filename_to_str(src);
 
     while (*s) {
        /* Let (bufp, len) be the string to append. */
@@ -428,13 +448,16 @@ static void xlatlognam(Filename *dest, Filename src,
            buf[0] = *s++;
            size = 1;
        }
-       if (size > len)
-           size = len;
-       memcpy(d, bufp, size);
-       d += size;
-       len -= size;
+        if (bufsize <= buflen + size) {
+            bufsize = (buflen + size) * 5 / 4 + 512;
+            buffer = sresize(buffer, bufsize, char);
+        }
+       memcpy(buffer + buflen, bufp, size);
+       buflen += size;
     }
-    *d = '\0';
+    buffer[buflen] = '\0';
 
-    *dest = filename_from_str(buffer);
+    ret = filename_from_str(buffer);
+    sfree(buffer);
+    return ret;
 }