/*
 *	Copyright (c) 1994, University of Kansas, All Rights Reserved
 */
#include "HTUtils.h"
#include "tcp.h"
#include "LYexit.h"
#ifndef VMS
#include "LYGlobalDefs.h"
#include "LYUtils.h"
#include "LYSignal.h"
#include "LYClean.h"
#ifdef SYSLOG_REQUESTED_URLS
#include <syslog.h>
#endif /* SYSLOG_REQUESTED_URLS */
#endif /* !VMS */

#define FREE(x) if (x) {free(x); x = NULL;}

/*
 *  Stack of functions to call upon exit.
 */
PRIVATE void (*callstack[ATEXITSIZE])();
PRIVATE int topOfStack = 0;

/*
 *  Flag for outofmem macro. - FM
 */
PUBLIC BOOL LYOutOfMemory = FALSE;

/*
 *  Forward declarations.
 */
PRIVATE void LYCompleteExit NOPARAMS;

/*
 *  Purpose:		Terminates program.
 *  Arguments:		status	Exit code.
 *  Return Value:	void
 *  Remarks/Portability/Dependencies/Restrictions:
 *	Function calls stdlib.h exit
 *  Revision History:
 *	06-15-94	created Lynx 2-3-1 Garrett Arch Blythe
 */
PUBLIC void LYexit ARGS1(
	int,		status)
{
#ifndef VMS	/*  On VMS, the VMSexit() handler does these. - FM */
    if (LYOutOfMemory == TRUE) {
	/*
	 *  Ignore further interrupts. - FM
 	 */
	(void) signal (SIGHUP, SIG_IGN);
	(void) signal (SIGTERM, SIG_IGN);
	(void) signal (SIGINT, SIG_IGN);
#ifndef __linux__
	(void) signal(SIGBUS, SIG_IGN);
#endif /* !__linux__ */
	(void) signal(SIGSEGV, SIG_IGN);
	(void) signal(SIGILL, SIG_IGN);

         /*
	  *  Flush all messages. - FM
	  */
	 fflush(stderr);
	 fflush(stdout);

	/*
	 *  Deal with curses, if on, and clean up. - FM
	 */
	if (LYCursesON) {
	    sleep(AlertSecs);
	}
	cleanup_sig(0);
#ifndef __linux__
	signal(SIGBUS, SIG_DFL);
#endif /* !__linux__ */
	signal(SIGSEGV, SIG_DFL);
	signal(SIGILL, SIG_DFL);
    }
#endif /* !VMS */

    /*
     *	Do functions registered with LYatexit. - GAB
     */
    LYCompleteExit();

#ifndef VMS
#ifdef SYSLOG_REQUESTED_URLS
    syslog(LOG_INFO, "Session over");
    closelog();
#endif /* SYSLOG_REQUESTED_URLS */
#endif /* !VMS */

#ifdef exit
/*  Make sure we use stdlib exit and not LYexit. - GAB
*/
#undef exit
#endif /* exit */

#ifndef VMS	/*  On VMS, the VMSexit() handler does these. - FM */
    if (LYOutOfMemory == TRUE) {
	LYOutOfMemory = FALSE;
	printf("\r\n%s\r\n\r\n", MEMORY_EXHAUSTED_ABORT);
	fflush(stdout);
    }
    if (LYTraceLogFP != NULL) {
	fflush(stdout);
	fflush(stderr);
        fclose(LYTraceLogFP);
	LYTraceLogFP = NULL;
	*stderr = LYOrigStderr;
    }
#endif /* !VMS */
    exit(status);
}

/*
 *  Purpose:		Registers termination function.
 *  Arguments:		function	The function to register.
 *  Return Value:	int	0	registered
 *				!0	no more space to register
 *  Remarks/Portability/Dependencies/Restrictions:
 *  Revision History:
 *	06-15-94	created Lynx 2-3-1 Garrett Arch Blythe
 */
#ifdef __STDC__
PUBLIC int LYatexit(void (*function)())
#else /* Not ANSI, ugh! */
PUBLIC int LYatexit(function)
void (*function)();
#endif /* __STDC__ */
{
    /*
     *  Check for available space.
     */
    if (topOfStack == ATEXITSIZE) {
	return(-1);
    }

    /*
     *  Register the function.
     */
    callstack[topOfStack] = function;
    topOfStack++;
    return(0);
}

/*
 *  Purpose:		Call the functions registered with LYatexit
 *  Arguments:		void
 *  Return Value:	void
 *  Remarks/Portability/Dependencies/Restrictions:
 *  Revision History:
 *	06-15-94	created Lynx 2-3-1 Garrett Arch Blythe
 */
PRIVATE void LYCompleteExit NOPARAMS
{
    /*
     *  Just loop through registered functions.
     *  This is reentrant if more exits occur in the registered functions.
     */
    while (--topOfStack >= 0) {
	callstack[topOfStack]();
    }
}
