/*
 * W-NEWS       A simple NEWS processing package.
 *		logmsg - is the function that logs the messages to
 *		the various log files as wanted.  Taken from inews.c.
 *		Probably similar to all files using logmsg().
 *
 * Version:     @(#)logmsg.c	4.50	03-Feb-1995
 *
 * Authors:	Fred N. van Kempen, <waltje@Infomagic.COM>
 *		Miquel van Smoorenburg, <miquels@drinkel.ow.org>
 *		Edvard Tuinder, <ed@ow.org>
 *		Copyright 1988-1993 MicroWalt Corporation
 *		Copyright 1994,1995 Cistron Software C.V.
 *
 *		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.
 *
 */
#include "libwnews.h"
#if HAVE_SYSLOG
#   include <syslog.h>
#endif
#if USE_STDARG
#   include <stdarg.h>
#endif
#if USE_VARARGS
#   include <varargs.h>
#endif

int debug;
extern char *program;

char *months[] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

static FILE *logfp;
static FILE *errlogfp;
static int keepopen = 0;
static int syslog_open = 0;

#define lfp ((level & LOGERR) ? errlogfp : logfp)

/* Indicate that we want to keep the logfile opened. */
void log_open()
{
  keepopen = 1;
}

void log_close()
{
  if (logfp) fclose(logfp);
  if (errlogfp) fclose(errlogfp);
  if (syslog_open) closelog();
  syslog_open = 0;
  logfp = (FILE *)0;
  errlogfp = (FILE *)0;
  keepopen = 0;
}

#if defined(USE_STDARG) || defined(USE_VARARGS)


#ifdef __STDC__
void
logmsg(int level, char *fmt, ...)
#else
#  if USE_STDARG
void
logmsg(level, fmt)
int level;
char *fmt;
#  else
void
logmsg(level, fmt, va_alist)
int level;
char *fmt;
va_dcl
#  endif
#endif
{
  char buff[1024];
  struct tm *mydate;
  va_list args;
  time_t now;
  static int tty = -1;
  static int wr_err = 0;
  FILE *fp;

  if (tty < 0) tty = isatty(2);

  /* See which file we want to use. */
  if (level & LOGERR) sprintf (buff, "%s/%s", VARDIR, ERRLOG);
    else sprintf (buff, "%s/%s", VARDIR, INFOLOG);

#if USE_STDARG
  va_start(args, fmt);
#endif
#if USE_VARARGS
  va_start(args);
#endif

  /* Open log file if needed. */
  if (!wr_err && lfp == (FILE *)0) {
	fp = fopen(buff, "a");
	if (level & LOGERR)
		errlogfp = fp;
	else
		logfp = fp;
  } else
	fp = lfp;

  /* Error opening log file? Complain only once. */
  if (!wr_err && fp == (FILE *)NULL) {
	wr_err = 1;
	if (debug || tty > 0)
	    	fprintf(stderr, "%s: cannot append to %s\n", program, buff);
#if HAVE_SYSLOG
	if (level & LOGSYS) {
		if (!syslog_open) {
			openlog(program, LOG_CONS, LOG_NEWS);
			syslog_open = keepopen;
		}
		syslog(LOGERR, "cannot append to %s", buff);
		if (!keepopen) closelog();
	}
#endif
  }

  /* Create message. */
  bzero(buff, 1024);
  (void) time(&now);
  mydate = localtime(&now);
  sprintf(buff, "%s %02d %02d:%02d:%02d %s: ",
	months[mydate->tm_mon], mydate->tm_mday,
	mydate->tm_hour, mydate->tm_min, mydate->tm_sec, program);

  /* Log message to file. */
  if (fp) {
	fprintf(fp, buff);
	vfprintf(fp, fmt, args);
  }
  va_end(args);

  /* See if we need to be verbose (on stderr) */
  if (debug != 0) {
	fprintf(stderr, buff);
	vfprintf(stderr, fmt, args);
  } else if (tty && (level & LOGERR)) {
	fprintf(stderr, "%s: ", program);
	vfprintf(stderr, fmt, args);
  }

#if HAVE_SYSLOG
  /* Need to log to syslog? */
  if (level & LOGSYS) {
    if (!syslog_open) {
	openlog(program, LOG_CONS, LOG_NEWS);
	syslog_open = keepopen;
    }
    vsyslog(level == LOGERR?LOG_ERR:LOG_NOTICE, fmt, args);
    if (!keepopen) closelog();
  }
#endif
  /* Close file if needed. */
  if (!wr_err && fp && !keepopen) {
	(void) fclose(fp);
	if (level & LOGERR)
		errlogfp = NULL;
	else
		logfp = NULL;
  }
}


#else /* NOT USE_STDARGS && NOT USE_VARARS */

/* Give compiler error */
............

void
logmsg(level, fmt)
int level;
char *fmt;
{
  /*
   * ET:  Not implemented... 
   * We just print the fmt and that's all. Can't emulate varargs
   * if the compiler doesn't support it... Should make some
   * function with fixed no off int and char's as arguments and
   * fprintf accordingly. This requires changes in ALL sources !
   */
  char buff[1024];
  FILE *fp;
  struct tm *mydate;
  time_t now;
  static int tty = -1;

  if (tty < 0) tty = isatty(2);

  if (level == LOGERR) sprintf (buff, "%s/%s", VARDIR, ERRLOG);
    else sprintf (buff, "%s/%s", VARDIR, INFOLOG);

  if ((fp = fopen(buff, "a")) == (FILE *)NULL) {
    	fprintf(stderr, "%s: cannot append to %s\n", program,
				level == LOGERR?ERRLOG:INFOLOG);
	return;
  }

  bzero(buff, 1024);
  (void) time(&now);
  mydate = localtime(&now);
  sprintf(buff, "%s %02d %02d:%02d %s",
	months[mydate->tm_mon], mydate->tm_mday,
			mydate->tm_hour, mydate->tm_min, fmt);
  fprintf(fp, buff);

  if (debug != 0 || (tty && (level & LOGERR))) fprintf(stderr, buff);
  (void) fclose(fp);
}

#endif /* NOT STDARG && ! VARARGS */
