static char rcsid[] = "@(#)$Id: signals.c,v 1.29.40.1 2007/08/24 20:01:56 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.29.40.1 $   $State: Exp $
 *
 *  Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                           (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  The Elm Mail System 
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/** This set of routines traps various signals and informs the
    user of the error, leaving the program in a nice, graceful
    manner.

**/

#include "def_elm.h"
#include "s_elm.h"

DEBUG_VAR(Debug,__FILE__,"signal");

VOLATILE int pipe_abort;		/* set to TRUE if receive SIGPIPE */

SIGHAND_TYPE
quit_signal(sig)
     int sig;
{
    SIGDPRINT(Debug,1, (&Debug, 	      
			"\n\n** Received SIGQUIT **\n\n\n\n"));
    leave(!wait_can_signal);
}

SIGHAND_TYPE
hup_signal(sig)
     int sig;
{
    SIGDPRINT(Debug,1, (&Debug, 	      
			"\n\n** Received SIGHUP **\n\n\n\n"));
    leave(!wait_can_signal);
}

SIGHAND_TYPE
term_signal(sig) 
     int sig;
{
    SIGDPRINT(Debug,1, (&Debug, 	      
			"\n\n** Received SIGTERM **\n\n\n\n"));
    leave(!wait_can_signal);
}

char * Ill_Text = "\n\nIllegal Instruction signal!\n\n";

SIGHAND_TYPE
ill_signal(sig)
     int sig;
{
    SIGDPRINT(Debug,1, (&Debug, 	       
			"\n\n** Received SIGILL **\n\n\n\n"));
    
    panic("SIGNAL PANIC",
	  __FILE__,__LINE__,"ill_signal",
	  Ill_Text,
	  !wait_can_signal);
}

char * Fpe_Text = "\n\nFloating Point Exception signal!\n\n";

SIGHAND_TYPE
fpe_signal(sig)  
     int sig;
{   
    SIGDPRINT(Debug,1, (&Debug, "\n\n** Received SIGFPE **\n\n\n\n"));
    
    panic("SIGNAL PANIC",
	  __FILE__,__LINE__,"fpe_signal",
	  Fpe_Text,
	  !wait_can_signal);
}

char * Bus_Text = "\n\nBus Error signal!\n\n";

#ifdef SIGBUS
SIGHAND_TYPE
bus_signal(sig)
     int sig;
{
    SIGDPRINT(Debug,1, (&Debug, "\n\n** Received SIGBUS **\n\n\n\n"));
    
    panic("SIGNAL PANIC",
	  __FILE__,__LINE__,"bus_signal",
	  Bus_Text,
	  !wait_can_signal);
}
#endif

char * Segv_Text = "\n\nSegment Violation signal!\n\n";

SIGHAND_TYPE
segv_signal(sig)
     int sig;
{    
    SIGDPRINT(Debug,1, (&Debug, "\n\n** Received SIGSEGV **\n\n\n\n"));
    
    panic("SIGNAL PANIC",
	  __FILE__,__LINE__,"segv_signal",
	  Segv_Text,
	  !wait_can_signal);
}

SIGHAND_TYPE
alarm_signal(sig)
     int sig;
{	
    signal(SIGALRM, alarm_signal);

    SIGDPRINT(Debug,4, (&Debug, "\n SIGALRM signal\n"));
    
    /** silently process alarm signal for timeouts... **/
    if (InGetPrompt && wait_can_signal) {
#ifdef HASSIGHOLD
	sigrelse(SIGALRM);
#endif
	LONGJMP(GetPromptBuf, 1);
    }
}

SIGHAND_TYPE
pipe_signal(sig)
     int sig;
{
    /** silently process pipe signal... **/
    SIGDPRINT(Debug,2, (&Debug, "*** received SIGPIPE ***\n\n"));
	
    pipe_abort = TRUE;	/* internal signal ... wheeee!  */
    
    signal(SIGPIPE, pipe_signal);
}

char * Stopped_Text = "\nSTOPPED\n";   /* Initialized by init.c */
char * Back_Text = "\nBack in ELM\n";  /* Initialized by init.c */

#ifdef SIGTSTP
int was_in_raw_state;

SIGHAND_TYPE
sig_user_stop(sig)
     int sig;
{
    SIGDPRINT(Debug,1, (&Debug,  "\n\n** Received SIGTSTP **\n\n\n\n"));
    /* This is called when the user presses a ^Z to stop the
       process within BSD 
    */
    
    menu_context_redraw();
    
    signal(SIGTSTP, SIG_DFL);
    
    was_in_raw_state = RawState();
    Raw(OFF|RAW_FROM_SIGNAL);	    /* turn it off regardless */
    
    switch_title(0);

    WriteRaw(Stopped_Text);
    
    kill(getpid(), SIGSTOP);
}

SIGHAND_TYPE
sig_return_from_user_stop(sig)
     int sig;
{  
    /** this is called when returning from a ^Z stop **/
    SIGDPRINT(Debug,1, (&Debug, "\n\n** Received SIGCONT **\n\n\n\n"));
    
    menu_context_redraw();
    
    signal(SIGCONT, sig_return_from_user_stop);
    signal(SIGTSTP, sig_user_stop);
    
    CarriageReturn();  /* Reset column counter? ... */
    
    WriteRaw(Back_Text);
    
    if (was_in_raw_state)
	Raw(ON|RAW_FROM_SIGNAL);

    if (InGetPrompt && wait_can_signal) {
#ifdef HASSIGHOLD
	sigrelse(SIGTSTP);
	sigrelse(SIGCONT);
#endif
	LONGJMP(GetPromptBuf, 1);
    }
}
#endif

#ifdef SIGWINCH
SIGHAND_TYPE
winch_signal(sig)
     int sig;
{
    signal(SIGWINCH, winch_signal);
    
    SIGDPRINT(Debug,2, (&Debug, "*** received SIGWINCH ***\n\n"));

    menu_context_resize();

    if (InGetPrompt && wait_can_signal) {
#ifdef HASSIGHOLD
	sigrelse(SIGWINCH);
#endif
	LONGJMP(GetPromptBuf, 1);
    }
}
#endif

SIGHAND_TYPE
usr1_signal(sig)
     int sig;
{
    int result = 0;
    struct MailboxView *m;
    int idx2 = 0;
    
    SIGDPRINT(Debug,1, (&Debug, "\n\n** Received SIGUSR1 **\n\n\n\n"));
    if (!InGetPrompt || !wait_can_signal) {
	SIGDPRINT(Debug,1, (&Debug, "-- can't leave folder\n"));
	return;
    }

    question_me = FALSE;


    while (NULL != (m = give_next_open_mailbox(&idx2,!InGetPrompt))) {

	while (m &&
	       (result = sync_mbox(TRUE, FALSE, TRUE, NULL, m,
				   default_context))
	       == -1) {
	    int idx;
	    int mbxcount = get_storage_count(m);
	    
	    for (idx = 0 ; idx < mbxcount; idx++) {
		
		struct current_storage * storage = get_storage(m,idx);
	    
		if (!storage ||
		    !storage->current_folder)
		    continue;

		read_new_mails(storage, default_context);
	    }   
	}
	if (result < 0)
	    break;
    }

    if (result >= 0) 
	leave(!InGetPrompt);
}

SIGHAND_TYPE
usr2_signal(sig)
     int sig;
{
    int result = 0;
    struct MailboxView *m;
    int idx2 = 0;

    SIGDPRINT(Debug,1, (&Debug, "\n\n** Received SIGUSR2 **\n\n\n\n"));
    
    if (!InGetPrompt || !wait_can_signal) {
	SIGDPRINT(Debug,1, (&Debug,  "-- can't leave folder\n"));
	return;
    }

    while (NULL != (m = give_next_open_mailbox(&idx2,!InGetPrompt))) {
    
	while (m &&
	       (result = sync_mbox(FALSE, TRUE, FALSE, NULL,
				   m,
				   default_context)) == -1) {
	    int idx;
	    int mbxcount = get_storage_count(m);
	    
	    for (idx = 0 ; idx < mbxcount; idx++) {
		
		struct current_storage * storage = get_storage(m,idx);
		
		if (!storage ||
		    !storage->current_folder)
		    continue;
		
		read_new_mails(storage, default_context);
	    }   
	}
	if (result < 0)
	    break;
    }
    if (result >= 0)
	leave(!InGetPrompt);
}

void init_signals()
{

    DPRINT(Debug,4, (&Debug, "Initializing terminating signals\n"));

    signal(SIGQUIT, quit_signal);		/* Quit signal 	            */
    signal(SIGTERM, term_signal); 	/* Terminate signal         */
    signal(SIGILL,  ill_signal);		/* Illegal instruction      */
    signal(SIGFPE,  fpe_signal);		/* Floating point exception */
#ifdef SIGBUS
    signal(SIGBUS,  bus_signal);		/* Bus error  		    */
#endif
    signal(SIGSEGV, segv_signal);		/* Segmentation Violation   */
    signal(SIGHUP,  hup_signal);		/* HangUp (line dropped)    */
    signal(SIGUSR1, usr1_signal);		/* User request 1	    */
    signal(SIGUSR2, usr2_signal);		/* User request 2	    */
}

void init_signals1() {
#if defined(SIGVEC) & defined(SV_INTERRUPT)
    struct sigvec alarm_vec;
#endif /* defined(SIGVEC) & defined(SV_INTERRUPT) */

    DPRINT(Debug,4, (&Debug, "Initializing operating signals\n"));

#if !defined(POSIX_SIGNALS) & defined(SIGVEC) & defined(SV_INTERRUPT)
    bzero((char *) &alarm_vec, sizeof(alarm_vec));
    alarm_vec.sv_handler = alarm_signal;
    alarm_vec.sv_flags = SV_INTERRUPT;
    sigvec (SIGALRM, &alarm_vec, (struct sigvec *)0);	/* Process Timer Alarm	    */
#else /* defined(SIGVEC) & defined(SV_INTERRUPT) */
    signal(SIGALRM, alarm_signal);		/* Process Timer Alarm      */
#endif /* defined(SIGVEC) & defined(SV_INTERRUPT) */
    signal(SIGPIPE, pipe_signal);		/* Illegal Pipe Operation   */
#ifdef SIGTSTP
    signal(SIGTSTP, sig_user_stop);		/* Suspend signal from tty  */
    signal(SIGCONT, sig_return_from_user_stop);	/* Continue Process */
#endif
#ifdef SIGWINCH
    signal(SIGWINCH, winch_signal);		/* change screen size */
#endif

}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1