]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/journal.c
New journal event "output"
[empserver] / src / lib / subs / journal.c
index aa27f97e045c0304f00becddbc8014e33e5d05de..8a07fb3d3dafe95cfaa8c91d17f4fd21a85d63e0 100644 (file)
@@ -45,6 +45,7 @@
  *     logout CNUM
  *     command NAME
  *     input INPUT
+ *     output THREAD ID OUTPUT
  *     update ETU
  */
 
 static char journal_fname[] = "journal.log";
 static FILE *journal;
 
+static void journal_entry_start(char *fmt, ...)
+    ATTRIBUTE((format (printf, 1, 2)));
 static void journal_entry(char *fmt, ...)
     ATTRIBUTE((format (printf, 1, 2)));
+static void journal_output_start(struct player *, int);
 
 static FILE *
 journal_open(void)
@@ -75,37 +79,72 @@ journal_open(void)
 }
 
 static void
-journal_entry(char *fmt, ...)
+journal_entry_vstart(char *fmt, va_list ap)
 {
-    static char buf[1024];
-    va_list ap;
     time_t now;
+
+    if (!journal)
+       return;
+    time(&now);
+    fprintf(journal, "%.24s %10.10s ",
+           ctime(&now), empth_name(empth_self()));
+    vfprintf(journal, fmt, ap);
+}
+
+static void
+journal_entry_start(char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    journal_entry_vstart(fmt, ap);
+    va_end(ap);
+}
+
+static void
+journal_entry_pr(char *s, size_t n)
+{
     unsigned char *p;
 
-    if (journal) {
-       time(&now);
-       fprintf(journal, "%.24s %10.10s ",
-               ctime(&now), empth_name(empth_self()));
-
-       va_start(ap, fmt);
-       vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
-       va_end(ap);
-
-       for (p = (unsigned char *)buf; *p; p++) {
-           if (isprint(*p))
-               putc(*p, journal);
-           else
-               fprintf(journal, "\\%03o", *p);
-       }
-       fputs("\n", journal);
-       fflush(journal);
-       if (ferror(journal)) {
-           logerror("Error writing journal (%s)", strerror(errno));
-           clearerr(journal);
-       }
+    if (!journal)
+       return;
+    for (p = (unsigned char *)s; *p && n; p++) {
+       if (*p == '\\')
+           fputs("\\\\", journal);
+       else if (isprint(*p))
+           putc(*p, journal);
+       else
+           fprintf(journal, "\\%03o", *p);
+       n--;
     }
 }
 
+static void
+journal_entry_end(int newline, int flush)
+{
+    if (!journal)
+       return;
+    if (!newline)
+       fputc('\\', journal);
+    fputc('\n', journal);
+    fflush(journal);
+    if (ferror(journal)) {
+       logerror("Error writing journal (%s)", strerror(errno));
+       clearerr(journal);
+    }
+}
+
+static void
+journal_entry(char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    journal_entry_vstart(fmt, ap);
+    va_end(ap);
+    journal_entry_end(1, 1);
+}
+
 int
 journal_startup(void)
 {
@@ -167,10 +206,59 @@ journal_logout(void)
     journal_entry("logout %d", player->cnum);
 }
 
+void
+journal_output(struct player *pl, int id, char *output)
+{
+    static char buf[1024];
+    static char *bp = buf;
+    static struct player *bpl;
+    static int bid;
+    char *s, *e;
+
+    if (keep_journal < 2)
+       return;
+
+    if (bp != buf && (pl != bpl || id != bid)) {
+       journal_output_start(bpl, bid);
+       journal_entry_pr(buf, bp - buf);
+       journal_entry_end(0, 0);
+       bp = buf;
+    }
+
+    for (s = output; (e = strchr(s, '\n')); s = e + 1) {
+       journal_output_start(pl, id);
+       journal_entry_pr(buf, bp - buf);
+       journal_entry_pr(s, e - s);
+       journal_entry_end(1, 0);
+       bp = buf;
+    }
+    e = strchr(s, 0);
+    if (bp + (e - s) <= buf + sizeof(buf)) {
+       memcpy(bp, s, e - s);
+       bp += e - s;
+       bpl = pl;
+       bid = id;
+    } else {
+       journal_output_start(pl, id);
+       journal_entry_pr(buf, bp - buf);
+       journal_entry_pr(s, e - s);
+       journal_entry_end(0, 0);
+       bp = buf;
+    }
+}
+
+static void
+journal_output_start(struct player *pl, int id)
+{
+    journal_entry_start("output %s %d ", empth_name(pl->proc), id);
+}
+
 void
 journal_input(char *input)
 {
-    journal_entry("input %s", input);
+    journal_entry_start("input ");
+    journal_entry_pr(input, -1);
+    journal_entry_end(1, 1);
 }
 
 void