From: hadley@cad.ics.uci.edu (Tedd Hadley)
Subject: Re: Nasty server/client "Feature"
Newsgroups: rec.games.netrek
Organization: UC Irvine Department of ICS
Date: 5 Oct 92 20:29:40 GMT

In <1aop64INNmmc@agate.berkeley.edu> beorn@elk.Berkeley.EDU (Beorn Johnson) writes:

>The kill and bombing messages were what I was referring to.  I couldn't
>tell if someone had declared peace before or after being killed, so I
>couldn't be positive.

   Oh, right.  I also found out those are needed for William Katz's statistics
   program.

>I still want the full message log, by the way, if it's available.

   It isn't, I'm sorry.  The INL server does not keep a message log, and
   watchmes <arg> doesn't record kill or bombing messages.

>Oh, and the times are nice, but one minute resolution

   I've made some minor changes to a version of watchmes.c to be used with the
   INL server.  It functions just like 'watchmes > file' (i.e. all messages
   recorded) but prepends hour:minute:sec to each message.  It also quits
   automatically when the daemon quits (meaning the daemon can actually
   fork it on startup, but there's a few things that need to be ironed out
   for that..)

   Here 'tis if anyone's interested.  (put logmes.c in INL<3.x>/ntserv and
   do 'make logmes'.)

/*
 * logmes.c
 *
 * Usage: logmes <output file>
 * If no output file specified, messages are sent to standard output.
 * Program will automatically quit when the daemon quits.
 */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/file.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "defs.h"
#include "struct.h"

struct player  *players;
struct player  *me;
struct torp    *torps;
struct ship    *myship;
struct stats   *mystats;
struct planet  *planets;
struct phaser  *phasers;
struct message *messages;
struct mctl    *mctl;
struct team    *teams;

int             shmid;

openmem()
{
   extern int      errno;
   int             shmemKey = PKEY;
   struct memory  *sharedMemory;

   errno = 0;
   shmid = shmget(shmemKey, 0, 0);
   if (shmid < 0) {
      if (errno != ENOENT) {
	 perror("shmget");
	 exit(1);
      }
      shmid = shmget(shmemKey, 0, 0);
      if (shmid < 0) {
	 fprintf(stderr, "logmes: Daemon not running\n");
	 exit(1);
      }
   }
   sharedMemory = (struct memory *) shmat(shmid, 0, 0);
   if (sharedMemory == (struct memory *) - 1) {
      perror("shmat");
      exit(1);
   }
   players = sharedMemory->players;
   torps = sharedMemory->torps;
   planets = sharedMemory->planets;
   phasers = sharedMemory->phasers;
   mctl = sharedMemory->mctl;
   messages = sharedMemory->messages;
   teams = sharedMemory->teams;
}

main(argc, argv)
   int             argc;
   char           *argv[];
{
   int             i;
   int             oldmctl;
   FILE           *fo = stdout;
   struct shmid_ds smbuf;
   struct stat	   lstat;
   char		   buf[256];

   openmem();

   if (argc > 1) {
      /* keep backup */
      if(stat(argv[1], &lstat) == 0){
	 sprintf(buf, "%s~", argv[1]);
	 link(argv[1], buf);
	 unlink(argv[1]);
      }
      fo = fopen(argv[1], "w");
      if (!fo) {
	 perror(argv[0]);
	 exit(1);
      }
   }

   oldmctl = mctl->mc_current;
   for (i = 0; i <= oldmctl; i++){
      log(fo, &(messages[i]));	/* times slightly off here .. can't be helped */
      fflush(fo);
   }

   for (;;) {

      sleep(1);
      /* make sure daemonII is still running */
      if (shmctl(shmid, IPC_STAT, &smbuf) < 0) {
	 fclose(fo);
	 exit(0);
      }
      while (oldmctl != mctl->mc_current) {
	 oldmctl++;
	 if (oldmctl == 50)
	    oldmctl = 0;
	 log(fo, &(messages[oldmctl]));
      }
   }
}

log(fo, m)
   FILE           *fo;
   struct message *m;
{
   long            curtime;
   struct tm      *tmstruct;
   char            buf[40];
   int             hour;

   time(&curtime);
   tmstruct = localtime(&curtime);
   if (!(hour = tmstruct->tm_hour % 12))
      hour = 12;
   fprintf(fo, "%02d:%02d:%02d %-70.70s\n", hour, tmstruct->tm_min,
	   tmstruct->tm_sec, m->m_data);
   fflush(fo);
}