/*
**
** Copyright (C) 1994 Swedish University Network (SUNET)
**
**
** This program is developed by UDAC, Uppsala University by commission
** of the Swedish University Network (SUNET). 
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
** 
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
**
**                                        Martin.Wendel@udac.uu.se
**                                        Torbjorn.Wictorin@udac.uu.se
**
**                                        UDAC	
**                                        P.O. Box 174
**                                        S-751 04 Uppsala
**                                        Sweden
**
*/


#include "emil.h"

#ifndef	HAVE_GETHOSTNAME
#include <sys/utsname.h>
#endif

#define	LOG_MAX	50	/* Max number of logged lines  */

struct	log_s {
	struct	log_s	* f;	/* points to next in chain */
	struct	log_s	* b;	/* points to previous */
	char	*	m;	/* Message text */
	int	l;
};
static	struct	log_s  * log_f = NULL, * log_b = NULL;
static	int	log_n			= 0;
static	int	open_log		= 0;


extern	int	syslog_logging;	/* defined in main() */
extern	int	header_logging;	/* defined in main() */
extern	int	syslog_facility;/* defined in main() */

extern	FILE	* out_fd;

void logger(int level, char * data)
{
	/* One could argue that va_lst should have been used. */
	/* But varargs seems to bee at bit unstable sometimes */

	char	* buf;
	int	dosys, doheader;
	struct	log_s	* s;
	int	l;


	switch (syslog_logging) {
	case	0:	dosys	= 0;			break;
	case	1:	dosys	= (level <= LOG_ERR);	break;
	case	2:	dosys	= (level <= LOG_NOTICE);break;
	case	3:	dosys	= (level <= LOG_INFO);	break;
	default  :	dosys	= 1;
	}
	switch (header_logging) {
	case	0:	doheader = 0;			break;
	case	1:	doheader = (level <= LOG_ERR);	break;
	case	2:	doheader = (level <= LOG_NOTICE);break;
	case	3:	doheader = (level <= LOG_INFO);	break;
	default  :	doheader = 1;
	}

	if ((dosys==0) && (doheader==0))return;
	if ((++log_n) >= LOG_MAX)	return;

	l	= strlen(data);
	if ((buf=malloc(l+1)) == NULL) {
		syslog(LOG_ERR,"Cannot get memory");
		return;
	}
	strcpy(buf,data);

	if (dosys) {
		if (log_n == 1) {
#ifdef			ultrix
			openlog("emil",0);
#else
			openlog("emil",LOG_CONS,syslog_facility);
#endif
		}
		syslog(level, "%s", buf);
	}

	if (doheader) {
		if ((s = malloc(sizeof(struct log_s)))==NULL) {
			syslog(LOG_ERR,"Cannot get memory");
			return;
		}
		if (log_f == NULL) {
			/* first element */
			log_f 	= s;
		}
		else {
			s->b	= log_b; /* add to end */
			log_b->f= s;
		}
		log_b	= s;	/* last  in chain */
		s->f	= NULL;
		s->m	= buf;
		s->l	= level;
	}
}

void	print_log()
{
	/* Print headerlog on stdout */

	struct	log_s	* s;
	char	* h;
	char	hn[255];
	time_t	t;
#ifndef	HAVE_GETHOSTNAME
	struct	utsname	uts;
#endif

	if (log_f != NULL) {
#ifdef	HAVE_GETHOSTNAME
		if (gethostname(hn,sizeof(hn)-1) < 0)
			strcpy(hn,"unknown");
#else
		if (uname(&uts)==0) strcpy(hn,uts.nodename);
		else		    strcpy(hn,"unknown");
#endif
		time(&t);
		fprintf(out_fd,"Emil-server: %s v.%s %s", hn,EMIL_VERSION,ctime(&t));
	}
	for (s = log_f; s != NULL; s = s->f) {
		switch (s->l) {
		case	LOG_EMERG:	h = "EMERGENCY"; break;
		case	LOG_ALERT:	h = "ALERT"; break;
		case	LOG_CRIT:	h = "CRITICAL"; break;
		case	LOG_ERR:	h = "Error"; break;
		case	LOG_WARNING:	h = "Warning"; break;
		case	LOG_NOTICE:	h = "info"; break;
		case	LOG_INFO:	h = "notice"; break;
		case	LOG_DEBUG:	h = "debug"; break;
		default:		h = "x";
		}
		fprintf(out_fd,"Emil-%s-message: %s\n",h,s->m);
	}
	header_logging = 0;
}
