/* 
**
*/

#include 	"../include/includes.h"
#include    <stdarg.h>        /* ANSI C header file */
#include    <syslog.h>

static void    LogDoIt(int, void *fp, int, const char *, va_list ap);

int    debug;    /* caller must define and set this:
                   nonzero if interactive, zero if daemon */




/* Initialize syslog(), if running as daemon.  */
void *
OpenLog (const char *prog_name, const char *ident, 
		int option, int facility)
{
	char	*logpath=NULL, filename[100];
	void	*fp = NULL;

	switch(debug) {
	case D_CONSOLE_ONLY:
		fp = stderr;
		break;
	case D_LOG_ONLY:
	case D_CONSOLE_LOG:
		if ((logpath = (char *)getenv("LOG_FILE_PATH")) == NULL) {
			log_ret("%s: %s: getenv", prog_name, FUNCTION_MACRO);
			fp = stderr;
			break;
		}
		sprintf(filename, "%s/%s.log", logpath, prog_name);
		if ((fp = fopen(filename, "w")) == NULL) {
			log_sys("%s: %s: fopen", prog_name, FUNCTION_MACRO);
			fp = stderr;
		}
		break;
	case D_SYSLOG_MODE:
        openlog(ident, option, facility);
		break;
	case D_NO_DEBUG: 
	default:
		break;
	}

	return fp;
}

/*
** Nonfatal error related to a system call.
** Print a message with the system's errno value and return.
*/

void
LogRet(void *fp, const char *fmt, ...)
{
    va_list        ap;
	int            priority = LOG_ERR;

    va_start(ap, fmt);
    LogDoIt(1, fp, priority, fmt, ap);
    va_end(ap);
    return;
}

/*
** Fatal error related to a system call.
** Print a message and terminate.
*/

void
LogSys(void *fp, const char *fmt, ...)
{
    va_list        ap;
	int            priority = LOG_ERR;

    va_start(ap, fmt);
    LogDoIt(1, fp, priority, fmt, ap);
    va_end(ap);
    exit(2);
}

/*
** Nonfatal error unrelated to a system call.
** Print a message and return.
*/

void
LogMsg(void *fp, const char *fmt, ...)
{
    va_list        ap;
	int            priority = LOG_ERR;

	if (fp == NULL) return;
    va_start(ap, fmt);
    LogDoIt(0, fp, priority, fmt, ap);
    va_end(ap);
    return;
}

/*
** Fatal error unrelated to a system call.
** Print a message and terminate.
*/

void
LogQuit(void *fp, const char *fmt, ...)
{
    va_list        ap;
	int            priority = LOG_ERR;

    va_start(ap, fmt);
    LogDoIt(0, fp, priority, fmt, ap);
    va_end(ap);
    exit(2);
}

/*
** Print a message and return to caller.
** Caller specifies "errnoflag" and "priority".
*/

static void
LogDoIt(int errnoflag, void *fp, int priority, 
		const char *fmt, va_list ap)
{
    int        errno_save;
    char       buf[4096];

    errno_save = errno;        /* value caller might want printed */
    vsprintf(buf, fmt, ap);
    if (errnoflag)
        sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
    strcat(buf, "\n");
    switch (debug) {
	case D_CONSOLE_ONLY:
        fflush(stdout);
        fputs(buf, stderr);
        fflush(stderr);
		break;
	case D_CONSOLE_LOG:
        fflush(stdout);
        fputs(buf, stderr);
        fflush(stderr);
		if (fp != stderr) {
        	fputs(buf, fp);
        	fflush(fp);
		}
		break;
	case D_LOG_ONLY:
        fflush(stdout);
        fputs(buf, fp);
        fflush(fp);
		break;
	case D_SYSLOG_MODE:
		syslog(priority, "%s", buf); break;
	case D_NO_DEBUG:
	default:
		break;
    }
      
    return;
}

void
GetErrnoMsg(char *sp, const char *fmt, ...)
{
    va_list        ap;
    int        errno_save;
    char       buf[4096*2];

    errno_save = errno;        /* value caller might want printed */
    va_start(ap, fmt);
    vsprintf(buf, fmt, ap);
    va_end(ap);
    sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
	strcpy(sp, buf);

	return;
}

/* 
** Close log file point.
** Return 0 on success, -1 on failure.
*/
void   
CloseLog (void *fp)
{
	fclose(fp);
	fp = stdout;
}

