musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/* 
 * MusicMUD Daemon, version 1.0
 * Copyright (C) 1998-2003 Abigail Brady
 * 
 * This program 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 (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 */
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/wait.h>
#include <fcntl.h>

#include "musicmud.h"
#include "magic.h"
#include "pflags.h"
#include "hooks.h"

int g_sigpower;
int g_sigint;

jmp_buf sig11trap;
pid_t child;

// Signals behaviours
//    TERM  -> shutdown now, saving players and vars
//    POWER -> shutdown in 20 seconds, with message
//    INT   -> shutdown next cycle, saving players vars and zones

#ifdef SIGPWR
void sigpower(int) {
    g_sigpower = 1;
    log(PFL_SEEINFO, 0, "event", "got a sigpwr");
    signal(SIGPWR, &sigpower);
}
#endif

void sigterm(int) {
    log(PFL_SEEINFO, 0, "event", "got a sigterm");
    mud->interpret("shutdown quick");
}

void sigint(int i) {
    if (g_sigint)
      sigterm(i);
    log(PFL_SEEINFO, 0, "event", "got a sigint");
    g_sigint = 1;
}

static int volatile la=0;

void flush() {
  Player *p;
  int i;
  foreach(players, p, i) {
    p->send_data();
  }
}

extern const char *current_command;

void sigsegv(int) {
  if (la) {
    while (1) {
      sleep(1000);
    }
  }
  la++;
  log(PFL_SEEINFO, 0, "event", "got a sigsegv. pid == %i", (int)getpid());
  if (current_command)
    log(PFL_SEEINFO, LEV_INTERNAL, "event", "command : '%s'", current_command);
  la--;
  flush();
  while (1) {
      sleep(1000);
  }
}

int sc_wait=1;

void sigchld(int a, int b) {
    int status;
    if (sc_wait) {
      wait(&status);
    }
    signal(SIGCHLD, (void(*)(int))&sigchld);
}

void sigpipe(int) {
    signal(SIGPIPE, &sigpipe);
}

extern bool is_test();

void signals_start() {
  signal(SIGPIPE, &sigpipe);
#ifdef SIGPWR
  signal(SIGPWR, &sigpower);
#endif
  signal(SIGTERM, &sigterm);
  signal(SIGINT, &sigint);
  signal(SIGSEGV, &sigsegv);
  signal(SIGCHLD, (void(*)(int))&sigchld);
}