static char rcsid[] = "@(#)$Id: cancel.c,v 1.6 2006/07/24 18:45:00 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.6 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
*****************************************************************************/
#include "headers.h"
#include "s_me.h"
DEBUG_VAR(Debug,__FILE__,"ui");
static void cancel_set_ttysig_d P_((void));
static void cancel_set_ttysig_d()
{
/* NULL */
}
static cancel_set_ttysig_f * SET_TTYSIG = &cancel_set_ttysig_d;
static void cancel_reset_ttysig_d P_((void));
static void cancel_reset_ttysig_d()
{
/* NULL */
}
static cancel_reset_ttysig_f * RESET_TTYSIG = &cancel_reset_ttysig_d;
static void cancel_transient_d P_((struct string *x));
static void cancel_transient_d(x)
struct string *x;
{
lib_transient(FRM("%S"),x);
}
static cancel_transient_f * TRANSIENT = &cancel_transient_d;
static void cancel_clear_d P_((void));
static void cancel_clear_d()
{
lib_transient(FRM(""));
}
static cancel_clear_f * CLEAR = &cancel_clear_d;
extern void setup_cancel_cb(cancel_set_ttysig,cancel_reset_ttysig,
cancel_transient,cancel_clear)
cancel_set_ttysig_f *cancel_set_ttysig;
cancel_reset_ttysig_f *cancel_reset_ttysig;
cancel_transient_f *cancel_transient;
cancel_clear_f *cancel_clear;
{
SET_TTYSIG = cancel_set_ttysig;
RESET_TTYSIG = cancel_reset_ttysig;
TRANSIENT = cancel_transient;
CLEAR = cancel_clear;
}
#define CANCEL_magic 0xF903
struct chancel_data {
unsigned short magic; /* CANCEL_magic */
struct string *msg;
VOLATILE int is_canceled;
struct chancel_data * previous;
} * new_cancel P_((const char * format, const char *msg, ...));
static struct chancel_data * VOLATILE current = NULL;
#ifdef POSIX_SIGNALS
static struct sigaction saved_state;
static int state_set = 0;
static void SA_HANDLER P_((int sig));
static void SA_HANDLER(sig)
int sig;
{
SIGDPRINT(Debug,1,(&Debug,"Got SIGINT ...\n"));
if (!current) {
panic("CANCEL PANIC",__FILE__,__LINE__,
"SA_HANDLER",
"current pointer is not set",1);
return;
}
if (CANCEL_magic != current->magic)
panic("CANCEL PANIC",__FILE__,__LINE__,
"SA_HANDLER",
"Bad current pointer",1);
current->is_canceled = 1;
}
#endif
struct chancel_data * new_cancel (
#if ANSI_C
const char * format,
const char *msg,
...
#else
format,msg, va_alist
#endif
)
#if !ANSI_C
CONST char * format;
CONST char *msg;
va_dcl
#endif
{
va_list vl;
struct string *store;
struct chancel_data *ret;
Va_start(vl, msg); /* defined in defs.h */
store = elm_smessage(160,format,msg,vl);
va_end(vl);
TRANSIENT(store);
ret = safe_malloc(sizeof (*ret));
bzero((void *)ret,sizeof (*ret));
ret->magic = CANCEL_magic;
ret->msg = store;
ret->is_canceled = 0;
ret->previous = NULL;
if (current) {
if (CANCEL_magic != current->magic)
panic("CANCEL PANIC",__FILE__,__LINE__,
"new_cancel",
"Bad current pointer",0);
ret->previous = current;
} else {
#ifdef POSIX_SIGNALS
struct sigaction act;
bzero((void *)&act,sizeof (act));
act.sa_handler = &SA_HANDLER;
sigemptyset(&(act.sa_mask)); /* No signal to mask while in handler */
act.sa_flags = 0;
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS */
#endif
state_set = 0;
bzero((void *)&saved_state,sizeof (saved_state));
current = ret;
if (0 == sigaction(SIGINT,&act,&saved_state)) {
DPRINT(Debug,10,(&Debug,"SIGINT handler installed\n"));
state_set = 1;
} else {
DPRINT(Debug,10,(&Debug,"Failed to set SIGINT handler\n"));
}
#endif
SET_TTYSIG();
}
current = ret;
return ret;
}
int is_canceled(cd)
struct chancel_data *cd;
{
int ret;
if (CANCEL_magic != cd->magic)
panic("CANCEL PANIC",__FILE__,__LINE__,
"is_canceled",
"Bad pointer (magic)",0);
ret = cd->is_canceled;
if (ret) {
struct string * X =
format_string(CATGETS(elm_msg_cat, MeSet, MeCanceled,
"%S canceled"),
cd->msg);
TRANSIENT(X);
free_string(&X);
}
return ret;
}
void free_cancel(cd)
struct chancel_data **cd;
{
struct chancel_data *x = *cd;
if (CANCEL_magic != x->magic)
panic("CANCEL PANIC",__FILE__,__LINE__,
"free_cancel",
"Bad pointer (magic)",0);
if (current != x)
panic("CANCEL PANIC",__FILE__,__LINE__,
"free_cancel",
"pointer not current",0);
if (x->previous &&
CANCEL_magic != x->previous->magic)
panic("CANCEL PANIC",__FILE__,__LINE__,
"free_cancel",
"bad previous pointer",0);
if (x->previous) {
TRANSIENT(x->previous->msg);
} else {
RESET_TTYSIG();
CLEAR();
#ifdef POSIX_SIGNALS
if (!state_set) {
DPRINT(Debug,10,(&Debug,"SIGINT was not handler installed\n"));
} else if (0 == sigaction(SIGINT,&saved_state,NULL)) {
DPRINT(Debug,10,(&Debug,"SIGINT handler is reset\n"));
} else {
DPRINT(Debug,1,(&Debug,"failed to reset SIGINT handler\n"));
}
state_set = 0;
#endif
}
current = x->previous;
free_string (& (x->msg) );
x->magic = 0;
free(x);
x = NULL;
*cd = x;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1