/*
 * Configurable Finger Daemon Signal Catcher
 * version 1.04
 *
 * Fixed a bit for POSIX compliance.
 * Removed SIGUNUSED and SIGSTKFLT (since they're never used, anyway)
 */

#include "cfingerd.h"

typedef struct {
    int value;
    char *sigtype;
    char *text;
    int fatal;
} SLIST;

#define NUM_SIGS 25

SLIST siglist[] = {
	{SIGHUP, "SIGHUP", "Hangup", FALSE},
	{SIGINT, "SIGINT", "Interrupt from keyboard", TRUE},
	{SIGQUIT, "SIGQUIT", "Quit from keyboard", TRUE},
	{SIGILL, "SIGILL", "Illegal instruction", TRUE},
	{SIGTRAP, "SIGTRAP", "Trace/Breakpoint reached", FALSE},
	{SIGABRT, "SIGABRT", "Abort", TRUE},
	{SIGFPE, "SIGFPE", "Floating Point Exception", TRUE},
	{SIGKILL, "SIGKILL", "Termination", TRUE},
	{SIGUSR1, "SIGUSR1", "User-defined", FALSE},
	{SIGSEGV, "SIGSEGV", "Segmentation violation", TRUE},
	{SIGUSR2, "SIGUSR2", "User-defined", FALSE},
	{SIGPIPE, "SIGPIPE", "Write to pipe with no headers", FALSE},
	{SIGALRM, "SIGALRM", "Time out", FALSE},
	{SIGTERM, "SIGTERM", "Termination", TRUE},
	{SIGCHLD, "SIGCHLD", "Child terminated", FALSE},
	{SIGCONT, "SIGCONT", "Continued", FALSE},
	{SIGTSTP, "SIGTSTP", "Stopped at tty", FALSE},
	{SIGTTIN, "SIGTTIN", "TTY input for background process", FALSE},
	{SIGTTOU, "SIGTTOU", "TTY output for background process", FALSE},
	{SIGIO, "SIGIO", "I/O Error (Socket/Non-Socket)", TRUE},
	{SIGXCPU, "SIGXCPU", "CPU time limit exceeded", TRUE},
	{SIGXFSZ, "SIGXFSZ", "File size limit exceeded", TRUE},
	{SIGVTALRM, "SIGVTALRM", "Virtual time alarm", FALSE},
	{SIGPROF, "SIGPROF", "Profile", FALSE},
	{SIGWINCH, "SIGWINCH", "Window size change", FALSE}
};

void int_handler(int signo)
{
    int i;
    BOOL caught = FALSE;

#ifdef __bsdi__
    if (signo == SIGCHLD)
	return;
#endif

    for (i = 0; i < NUM_SIGS; i++) {
	if (signo == siglist[i].value) {
	    printf("Signal \"%s\": %s signal\n",
		siglist[i].sigtype, siglist[i].text);
#ifdef	SYSLOG
	    syslog(LOG_ERR, "\"%s\" caught", siglist[i].sigtype);
#endif

	    caught = TRUE;

	    if (siglist[i].fatal) {
		printf("\nPlease report this bug to khollis@bitgate.chatlink.com!\n");
	    } else {
		if (siglist[i].value == SIGALRM) {
		    printf("Ooh, you caught an alarm signal.  This may be a cause from either not\n");
		    printf("having GCC 2.5.8 used with compilation, or your script simply timed\n");
		    printf("out on you.  May want to check this.  :)\n\n");
		}

		printf("Non-fatal; continuing.\n");
	    }

	    (void) fflush(stdout);

	    if (siglist[i].fatal)
		exit(PROGRAM_BUG);
	}
    }

    if (!caught) {
	printf("Whoops, the program crashed.  Could not catch the signal type.\n");
	printf("Please report this to khollis@bitgate.chatlink.com.\n\n");
#ifdef	SYSLOG
	syslog(LOG_ERR, "SIGUNKNOWN caught");
#endif
	(void) fflush(stdout);
	exit(PROGRAM_BUG);
    }
}
