static char rcsid[] = "@(#)$Id: panic.c,v 1.13 2006/04/09 07:37:07 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.13 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
 *****************************************************************************/

#include "headers.h"
#include "s_me.h"

static void def_panic_prepare P_((CONST int interrupt, 
				  CONST char * title,
				  CONST char * ms));

static void def_panic_prepare(interrupt,title,ms)
     CONST int interrupt;
     CONST char * title;
     CONST char * ms;
{
    /* NULL */
}

static panic_prepare *prepare = &def_panic_prepare;
void set_panic_prepare(fn)
     panic_prepare *fn;
{
    prepare = fn;
}

static void def_panic_exit P_((CONST int interrupt));
static void def_panic_exit(interrupt)
     CONST int interrupt;
{
    if (interrupt)
	abort();
    exit(127);
}

static panic_exit *exit_rut = &def_panic_exit;
void set_panic_exit(fn)
     panic_exit *fn;
{
    exit_rut = fn;
}

static void print_str_err P_((const char * ptr));
static void print_str_err(ptr)
     CONST char * ptr;
{
    int l = strlen(ptr);
    write(2,ptr,l);
}

static void print_num_err P_((unsigned int num));
static void print_num_err(num)
     unsigned int num;
{
    char buffer[100];    
    int x = sizeof buffer;
    
    do {	
	buffer[--x] = "0123456789"[num % 10];
	num /= 10;
    } while (num != 0 && x > 0);

    write (2, buffer + x, sizeof buffer -x);
}

void panic(title,f,ln,pr,ms,interrupt) 
     CONST char * title;     
     CONST char * f;
     CONST int ln;
     CONST char * pr;
     CONST char * ms;
     CONST int interrupt;
{

    static VOLATILE int in_panic  = 0;
    static char ABORTING[] = "ABORTING...\n";

#if DEBUG
    int level;
 
    panic_dprint ("\n%s in %s:%d:%s\n",title,f,ln,pr);
    panic_dprint (">>%s\n",ms);
        
    level = panic_dprint ("\n** in_panic = %d\n** interrupt = %d\n** wait_can_signal = %d\n",
			  in_panic,interrupt,wait_can_signal);
#endif

    switch (in_panic) {

    case 0: in_panic++;
	prepare(interrupt,title,ms);

    case 1: in_panic++;
	
	print_str_err("\n");
	print_str_err(title);
	print_str_err(" in ");
	print_str_err(f);
	print_str_err(":");
	print_num_err(ln);
	print_str_err(":");
	print_str_err(pr);
	print_str_err("\n>>>");
	print_str_err(ms);
	print_str_err("\n");

    case 2: in_panic++;	
#if DEBUG
	if (level > 10) {
	    write(2,ABORTING,sizeof ABORTING);
	    abort();
	}
#endif
	exit_rut(interrupt);
    case 3: in_panic++;	

	write(2,ABORTING,sizeof ABORTING);
	abort();
    default:
	abort();
    }
}

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


syntax highlighted by Code2HTML, v. 0.9.1