/* ************************************************************************
*  file: signals.c , trapping of signals from Unix.       Part of DIKUMUD *
*  Usage : Signal Trapping.                                               *
*  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
************************************************************************* */

#include <signal.h>
#include <stdio.h>
#include <sys/time.h>

#include "structs.h"
#include "utils.h"
#include "interpreter.h"

extern int process_output(struct descriptor_data *t);

int checkpointing(void);
int shutdown_request(void);
int logsig(void);
int hupsig(void);
int shutdownsave(void);

void signal_setup(void)
{
	struct itimerval itime;
	struct timeval interval;

	signal(SIGUSR2, shutdown_request);

	/* just to be on the safe side: */

	signal(SIGHUP, hupsig);
	signal(SIGPIPE, SIG_IGN);
	signal(SIGINT, hupsig);
	signal(SIGALRM, logsig);
	signal(SIGTERM, hupsig);

	/* set up the deadlock-protection */

	interval.tv_sec = 900;    /* 15 minutes */
	interval.tv_usec = 0;
	itime.it_interval = interval;
	itime.it_value = interval;
	setitimer(ITIMER_VIRTUAL, &itime, 0);
	signal(SIGVTALRM, checkpointing);
}



int checkpointing(void)
{
	extern int tics;
	
	if (!tics)
	{
		log("CHECKPOINT shutdown: tics not updated");
		abort();
	}
	else
		tics = 0;
}




int shutdown_request(void)
{
	extern int shutdown;

	log("Received USR2 - shutdown request");
	shutdown = 1;
}

/* kick out players etc */
int hupsig(void)
{
	extern int shutdown;
	log("Received SIGHUP, SIGINT, or SIGTERM. Shutting down");
	shutdownsave();
	exit(0);   /* something more elegant should perhaps be substituted */
}

/* Save all players before shutting down */
int shutdownsave(void)
{
	void do_save(struct char_data *ch, char *argument, int cmd);
	extern struct descriptor_data *descriptor_list;
	extern struct char_data *character_list;
	struct descriptor_data *i;
	struct char_data *vict;
	static char buf[]=
	 "\n\rThe Copper SAVE Daemon has forced you to 'save.' Good-bye!\n\r";
	static char to_force[]=
	 "save";

	for(i=descriptor_list; i; i=i->next){
		if(!i->connected){
			vict=i->character;
			write_to_descriptor(i->descriptor, buf);
			do_save(vict, "", 0);
		}
	}
	log("SAVE Daemon invoked to save all players.");
}

int logsig(void)
{
	log("Signal received. Ignoring.");
}