/*
 * nblog.c  -  Message and error logging for netboot programs
 *
 * Copyright (C) 2003-2007 Gero Kuhlmann <gero@gkminix.han.de>
 *
 *  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
 *  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 FITNESS 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.
 *
 * $Id: nblog.c,v 1.9 2007/01/06 18:31:38 gkminix Exp $
 */

#include <common.h>
#include <nblib.h>
#include "privlib.h"



/*
 * Local variables
 */
static FILE *logfile = NULL;			/* output log file */
static int isinit = FALSE;			/* initialization flag */



/*
 * Function to be called upon program termination
 */
static void closelog __F_NOARGS
{
  if (logfile != NULL) {
	(void)fclose(logfile);
	logfile = NULL;
  }
}



/*
 * Initialize module
 *
 * Note that this routine has to be called as early as possible.
 */
void nblib_init_log __F_NOARGS
{
  int ret;

  /* Setup the exit function */
  if (!isinit) {
	if ((ret = nbatexit(&closelog)) != 0) {
		/* Don't use prnerr here! */
		if (!quiet)
			fprintf(stderr,
				"%s: unable to set log file exit function",
				progname);
		nbexit(EXIT_LOGFILE);
	}
	isinit = TRUE;
  }

  /* Open the log file for appending */
  if (logfile == NULL && nblogname != NULL) {
	logfile = fopen(nblogname, "a");
	if (logfile == NULL) {
		if (!quiet)
			fprintf(stderr, "%s: unable to open log file %s",
							progname, nblogname);
		nbexit(EXIT_LOGFILE);
	}
	fprintf(logfile, "\n---------- start logging of %s ----------\n\n",
							progname);
  }
}



/*
 * Determine where to print a log message
 */
FILE *logfd __F((level), int level)
{
  FILE *fd;

  fd = NULL;
  if (verbose >= level) {
	if (logfile != NULL)
		fd = logfile;
	else if (!quiet)
		fd = stdout;
  }
  return(fd);
}



/*
 * Write a message into the log file. This routine only writes something
 * if the current verbosity level is at or above the level parameter. Also,
 * if a log file has been opened, it writes only into that log file. Other-
 * wise, it writes to stdout.
 */
void prnvlog __F((level, msg, args),
			int level AND
			const char *msg AND
			va_list args)
{
  FILE *fd;

  if ((fd = logfd(level)) != NULL) {
	if (level >= LOGLEVEL_DEBUG)
		fprintf(fd, "DBG: ");
	vfprintf(fd, msg, args);
  }
}



/*
 * Write a message into the log file using variadic arguments
 */
#if defined(HAVE_ANSI_CC)
void prnlog(int level, const char *msg, ...)
#else
void prnlog(va_list) va_dcl
#endif
{
  va_list args;
#if !defined(HAVE_ANSI_CC)
  char *msg;
  int level;
#endif

  /* Startup variadic argument handling */
#if defined(HAVE_ANSI_CC)
  va_start(args, msg);
#else
  va_start(args);
  level = va_arg(args, int);
  msg = va_arg(args, char *);
#endif

  /* Now print the message */
  prnvlog(level, msg, args);

  /* Terminate variadic argument handling */
  va_end(args);
}



/*
 * Write an error message into the log file. This routine writes to stderr
 * in any case (except when the quiet flag is set). In addition, it writes
 * to the log file if it has been opened.
 */
void prnverr __F((msg, args), const char *msg AND va_list args)
{
  if (!quiet || !isinit) {
	fprintf(stderr, "%s: ", progname);
	vfprintf(stderr, msg, args);
	fprintf(stderr, "\n");
  }
  if (logfile != NULL) {
	vfprintf(logfile, msg, args);
	fprintf(logfile, "\n");
  }
}



/*
 * Write an error message using variadic arguments
 */
#if defined(HAVE_ANSI_CC)
void prnerr(const char *msg, ...)
#else
void prnerr(va_list) va_dcl
#endif
{
  va_list args;
#if !defined(HAVE_ANSI_CC)
  char *msg;
#endif

  /* Startup variadic argument handling */
#if defined(HAVE_ANSI_CC)
  va_start(args, msg);
#else
  va_start(args);
  msg = va_arg(args, char *);
#endif

  /* Check if we have to print something, and where to print it */
  prnverr(msg, args);

  /* Terminate variadic argument handling */
  va_end(args);
}

