Fix `puttygen-unix-perms': f_open(), PuTTY's wrapper on fopen, now
[u/mdw/putty] / logging.c
index a54b167..bd5705c 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -1,3 +1,7 @@
+/*
+ * Session logging.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -10,7 +14,7 @@
 /* log session to file stuff ... */
 struct LogContext {
     FILE *lgfp;
-    enum { CLOSED, OPENING, OPEN, ERROR } state;
+    enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state;
     bufchain queue;
     Filename currlogfilename;
     void *frontend;
@@ -28,19 +32,19 @@ static void xlatlognam(Filename *d, Filename s, char *hostname, struct tm *tm);
 static void logwrite(struct LogContext *ctx, void *data, int len)
 {
     /*
-     * In state CLOSED, we call logfopen, which will set the state
-     * to one of OPENING, OPEN or ERROR. Hence we process all of
-     * those three _after_ processing CLOSED.
+     * In state L_CLOSED, we call logfopen, which will set the state
+     * to one of L_OPENING, L_OPEN or L_ERROR. Hence we process all of
+     * those three _after_ processing L_CLOSED.
      */
-    if (ctx->state == CLOSED)
+    if (ctx->state == L_CLOSED)
        logfopen(ctx);
 
-    if (ctx->state == OPENING) {
+    if (ctx->state == L_OPENING) {
        bufchain_add(&ctx->queue, data, len);
-    } else if (ctx->state == OPEN) {
+    } else if (ctx->state == L_OPEN) {
        assert(ctx->lgfp);
        fwrite(data, 1, len, ctx->lgfp);
-    }                                 /* else ERROR, so ignore the write */
+    }                                 /* else L_ERROR, so ignore the write */
 }
 
 /*
@@ -66,7 +70,7 @@ static void logprintf(struct LogContext *ctx, const char *fmt, ...)
 void logflush(void *handle) {
     struct LogContext *ctx = (struct LogContext *)handle;
     if (ctx->cfg.logtype > 0)
-       if (ctx->state == OPEN)
+       if (ctx->state == L_OPEN)
            fflush(ctx->lgfp);
 }
 
@@ -78,17 +82,17 @@ static void logfopen_callback(void *handle, int mode)
     const char *fmode;
 
     if (mode == 0) {
-       ctx->state = ERROR;            /* disable logging */
+       ctx->state = L_ERROR;          /* disable logging */
     } else {
-       fmode = (mode == 1 ? "a" : "w");
-       ctx->lgfp = f_open(ctx->currlogfilename, fmode);
+       fmode = (mode == 1 ? "ab" : "wb");
+       ctx->lgfp = f_open(ctx->currlogfilename, fmode, TRUE);
        if (ctx->lgfp)
-           ctx->state = OPEN;
+           ctx->state = L_OPEN;
        else
-           ctx->state = ERROR;
+           ctx->state = L_ERROR;
     }
 
-    if (ctx->state == OPEN) {
+    if (ctx->state == L_OPEN) {
        /* Write header line into log file. */
        tm = ltime();
        strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm);
@@ -102,6 +106,7 @@ static void logfopen_callback(void *handle, int mode)
                      (ctx->cfg.logtype == LGTYP_ASCII ? "ASCII" :
                       ctx->cfg.logtype == LGTYP_DEBUG ? "raw" :
                       ctx->cfg.logtype == LGTYP_PACKETS ? "SSH packets" :
+                      ctx->cfg.logtype == LGTYP_SSHRAW ? "SSH raw data" :
                       "unknown"),
                      filename_to_str(&ctx->currlogfilename));
     logevent(ctx->frontend, event);
@@ -111,7 +116,7 @@ static void logfopen_callback(void *handle, int mode)
      * Having either succeeded or failed in opening the log file,
      * we should write any queued data out.
      */
-    assert(ctx->state != OPENING);     /* make _sure_ it won't be requeued */
+    assert(ctx->state != L_OPENING);   /* make _sure_ it won't be requeued */
     while (bufchain_size(&ctx->queue)) {
        void *data;
        int len;
@@ -133,7 +138,7 @@ void logfopen(void *handle)
     int mode;
 
     /* Prevent repeat calls */
-    if (ctx->state != CLOSED)
+    if (ctx->state != L_CLOSED)
        return;
 
     if (!ctx->cfg.logtype)
@@ -144,7 +149,7 @@ void logfopen(void *handle)
     /* substitute special codes in file name */
     xlatlognam(&ctx->currlogfilename, ctx->cfg.logfilename,ctx->cfg.host, &tm);
 
-    ctx->lgfp = f_open(ctx->currlogfilename, "r");  /* file already present? */
+    ctx->lgfp = f_open(ctx->currlogfilename, "r", FALSE);  /* file already present? */
     if (ctx->lgfp) {
        fclose(ctx->lgfp);
        if (ctx->cfg.logxfovr != LGXF_ASK) {
@@ -156,7 +161,7 @@ void logfopen(void *handle)
        mode = 2;                      /* create == overwrite */
 
     if (mode < 0)
-       ctx->state = OPENING;
+       ctx->state = L_OPENING;
     else
        logfopen_callback(ctx, mode);  /* open the file */
 }
@@ -168,7 +173,7 @@ void logfclose(void *handle)
        fclose(ctx->lgfp);
        ctx->lgfp = NULL;
     }
-    ctx->state = CLOSED;
+    ctx->state = L_CLOSED;
 }
 
 /*
@@ -199,9 +204,14 @@ void log_eventlog(void *handle, const char *event)
        fprintf(stderr, "%s\n", event);
        fflush(stderr);
     }
-    if (ctx->cfg.logtype != LGTYP_PACKETS)
+    /* If we don't have a context yet (eg winnet.c init) then skip entirely */
+    if (!ctx)
+       return;
+    if (ctx->cfg.logtype != LGTYP_PACKETS &&
+       ctx->cfg.logtype != LGTYP_SSHRAW)
        return;
     logprintf(ctx, "Event Log: %s\r\n", event);
+    logflush(ctx);
 }
 
 /*
@@ -218,13 +228,18 @@ void log_packet(void *handle, int direction, int type,
     int p = 0, b = 0, omitted = 0;
     int output_pos = 0; /* NZ if pending output in dumpdata */
 
-    if (ctx->cfg.logtype != LGTYP_PACKETS)
+    if (!(ctx->cfg.logtype == LGTYP_SSHRAW ||
+          (ctx->cfg.logtype == LGTYP_PACKETS && texttype)))
        return;
 
     /* Packet header. */
-    logprintf(ctx, "%s packet type %d / 0x%02x (%s)\r\n",
-             direction == PKT_INCOMING ? "Incoming" : "Outgoing",
-             type, type, texttype);
+    if (texttype)
+        logprintf(ctx, "%s packet type %d / 0x%02x (%s)\r\n",
+                  direction == PKT_INCOMING ? "Incoming" : "Outgoing",
+                  type, type, texttype);
+    else
+        logprintf(ctx, "%s raw data\r\n",
+                  direction == PKT_INCOMING ? "Incoming" : "Outgoing");
 
     /*
      * Output a hex/ASCII dump of the packet body, blanking/omitting
@@ -300,7 +315,7 @@ void *log_init(void *frontend, Config *cfg)
 {
     struct LogContext *ctx = snew(struct LogContext);
     ctx->lgfp = NULL;
-    ctx->state = CLOSED;
+    ctx->state = L_CLOSED;
     ctx->frontend = frontend;
     ctx->cfg = *cfg;                  /* STRUCTURE COPY */
     bufchain_init(&ctx->queue);
@@ -340,7 +355,7 @@ void log_reconfig(void *handle, Config *cfg)
  * translate format codes into time/date strings
  * and insert them into log file name
  *
- * "&Y":YYYY   "&m":MM   "&d":DD   "&T":hhmm   "&h":<hostname>   "&&":&
+ * "&Y":YYYY   "&m":MM   "&d":DD   "&T":hhmmss   "&h":<hostname>   "&&":&
  */
 static void xlatlognam(Filename *dest, Filename src,
                       char *hostname, struct tm *tm) {