idirt-1.82d/
idirt-1.82d/bin/
idirt-1.82d/data/LOGS/
idirt-1.82d/data/POLICY/
idirt-1.82d/data/WIZ_ZONES/
idirt-1.82d/doc/
idirt-1.82d/doc/info/
idirt-1.82d/doc/manual/
idirt-1.82d/src/Ident/
idirt-1.82d/src/utils/
idirt-1.82d/utils/

/************************************************************************
 * iDiRT Exit Handler 1.02.00						*
 * 1995 by Illusion							*
 ************************************************************************/

/************************************************************************
 * The following functions handle all exit() calls from the MUD and 	*
 * handle them itself making sure that the MUD shuts down nicely and 	*
 * with as little problems as possible.					*
 ************************************************************************/

#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <a.out.h>
#include "kernel.h"
#include "mobile.h"
#include "sendsys.h"
#include "timing.h"
#include "time.h"
#include "exit.h"
#include "mudmacros.h"
#include "pflags.h"
#include "log.h"
#include "reboot.h"
#include "commands.h"
#include "bprintf.h"
#include "mud.h"
#include "uaf.h"
#include "parse.h"

typedef struct __DB__Info {
  unsigned long symsize;
  unsigned long symcount;
  unsigned long strsize;
  unsigned long symoffset;
  unsigned long stroffset;
}

_DB_Info;

_DB_Info DB_Info;
char *DB_Binary;
char *Syms, *Names;

/* __exit(): Handles the shutdown of the MUD. */
void
__exit (int status)
{
  mudlog ("SYSTEM: __exit(%d) called", status);

  send_msg (DEST_ALL, 0, LVL_MIN, LVL_MAX, NOBODY, NOBODY,
	    "&+Y[&+RInternal error has occured&+Y]\n");

  autosave ();
  debug ();

#ifndef NOCATCH
  run_reboot (True, True);
#endif
  _exit (1);
}

/* sig_exit(): Handles the shutdown of the MUD due to signal error. */
void
sig_exit (char *sig, int signal)
{

  if (signal == SIGUSR1) {
    send_msg (DEST_ALL, 0, LVL_MIN, LVL_MAX, NOBODY, NOBODY,
	      "\001f" SIGNAL1 "\003");
  } else if (signal == SIGUSR2) {
    send_msg (DEST_ALL, 0, LVL_MIN, LVL_MAX, NOBODY, NOBODY,
	      "\001f" SIGNAL2 "\003");
  } else {
    send_msg (DEST_ALL, 0, LVL_WIZARD, LVL_MAX, NOBODY, NOBODY,
	      "&+Y[&+RSignal Error: &+W%s&+Y]\n", sig);

    send_msg (DEST_ALL, 0, LVL_GUEST, (LVL_WIZARD - 1), NOBODY, NOBODY,
	      "&+Y[&+RInternal error has occured&+Y]\n");
  }

  autosave ();
  debug ();
#ifndef NOCATCH
  run_reboot (True, True);
#endif
  _exit (2);
}

/* autosave(): Saves all players. */
void
autosave (void)
{
  int plx;
  PERSONA d;

  for (plx = 0; plx < max_players; ++plx) {
    if (is_in_game (plx)) {
      if (!fclose (players[plx].Mailer.mailbox))
	sendf (plx, "&+R[&+WClosing Mailbox&+R]\n");
      if (!fclose (players[plx].Mailer.output)) {
	sendf (plx, "&+R[&+WAborting Message&+R]\n");
	unlink (players[plx].Mailer.outputname);
      }
      if (players[plx].aliased || players[plx].polymorphed >= 0) {
	unalias (plx);
	unpolymorph (plx);
	setup_globals (plx);
	sendf (plx, "&+R[&+WUnaliasing You&+R]\n");
      }
      sendf (plx, "&+R[&+WSaving Character&+R]\n");
      player2pers (&d, &global_clock, plx);
      bflush ();
      putuaf (&d);
    }
  }
}

/* debug(): Write last commands entered to system logs */
void
debug (void)
{
  int plx;
  int i;
  char *t;
  char nt[100];

  for (plx = 0; plx < max_players; ++plx)
    if (is_in_game (plx)) {
      t = ctime (&prlast_cmd (plx));

      t[19] = '\0';
      for (i = 0; i < 8; ++i)
	nt[i] = t[i + 11];

      nt[8] = '\0';

      mudlog ("DEBUG: Last Command (%s) %s: %s",
	      nt, pname (plx), players[plx].prev_com);
    }
}

void
signalcom (void)
{
  static char *SigTable[] =
  {"list", "sigsegv", "sigterm", "sigbus",
   "sigint", "sigusr1", "sigusr2", TABLE_END};

  int sig = 0, x = 0;

  if (!ptstflg (mynum, PFL_SIGNAL)) {
    erreval ();
    return;
  }
  if (brkword () == -1) {
    bprintf ("Send what signal?\n");
    return;
  }
  if ((x = tlookup (wordbuf, SigTable)) < 0) {
    bprintf ("Invalid signal.\n");
  }
  switch (x) {
  case 0:
    sig = -1;
    break;
  case 1:
    sig = SIGSEGV;
    break;
  case 2:
    sig = SIGTERM;
    break;
  case 3:
    sig = SIGBUS;
    break;
  case 4:
    sig = SIGINT;
    break;
  case 5:
    sig = SIGUSR1;
    break;
  case 6:
    sig = SIGUSR2;
    break;
  }

  if (sig == -1) {
    bprintf ("Signals: SIGSEGV, SIGTERM, SIGBUS, SIGINT, SIGUSR1, SIGUSR2.\n");
    return;
  }
  send_msg (DEST_ALL, 0, LVL_MIN, LVL_MAX, mynum, NOBODY,
	    "&+B[&+CSignal &*has been called: &+W%s&+B]\n",
	    SigTable[x]);

  mudlog ("SIGNAL: %s has called signal %s", pname (mynum), SigTable[x]);
  kill (getpid (), sig);
}