]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/journal.c
Update copyright notice
[empserver] / src / lib / subs / journal.c
index fcaa752c58f7e1b225433d61e8da19f782af5081..4012fb7247259067fad4d614d8ffa95ab6fcb4b3 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
- *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- *  related information and legal notices. It is expected that any future
- *  projects/authors will amend these files as needed.
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
  *
  *  ---
  *
  *  journal.c: Log a journal of events to a file
- * 
+ *
  *  Known contributors to this file:
- *     Markus Armbruster, 2004-2008
+ *     Markus Armbruster, 2004-2012
+ *     Ron Koenderink, 2008
  */
 
 /*
@@ -43,7 +43,9 @@
  *     prng NAME SEED
  *     login CNUM HOSTADDR USER
  *     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)
 {
-    return fopen(journal_fname, "a+");
+    return fopen(journal_fname, "a");
 }
 
 static void
-journal_entry(char *fmt, ...)
+journal_entry_vstart(char *fmt, va_list ap)
 {
-    static char buf[1024];
-    va_list ap;
     time_t now;
-    unsigned char *p;
+    empth_t *self;
 
-    if (journal) {
-       time(&now);
-       fprintf(journal, "%.24s %10.10s:", ctime(&now), empth_name());
-       
-       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;
+    time(&now);
+    self = empth_self();
+    fprintf(journal, "%.24s %10.10s ",
+           ctime(&now), self ? empth_name(self) : "Main");
+    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_write(char *s, size_t n)
+{
+    char *p;
+
+    if (!journal)
+       return;
+    for (p = s; p < s + n; p++) {
+       if (*p == '\\')
+           fprintf(journal, "\\\\");
+       else if (isprint(*(unsigned char *)p) || *p == '\t')
+           putc(*p, journal);
+       else
+           fprintf(journal, "\\%03o", *p);
+    }
+}
+
+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)
 {
@@ -165,10 +207,66 @@ 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_write(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_write(buf, bp - buf);
+       journal_entry_write(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_write(buf, bp - buf);
+       journal_entry_write(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_write(input, strlen(input));
+    journal_entry_end(1, 1);
+}
+
+void
+journal_command(char *cmd)
+{
+    char *eptr = strchr(cmd, ' ');
+    journal_entry("command %.*s", eptr ? (int)(eptr - cmd) : -1, cmd);
 }
 
 void