/************************************************************************ * 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); }