/* File and display logging functions.
   Rick Smereka, Copyright (C) 1992-2004.

   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 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, get a copy via the Internet at
   http://gnu.org/copyleft/gpl.html or write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
   MA 02111-1307 USA

   You can contact the author via email at rsmereka@future-lab.com

   Original version for DOS, Sep/92, Rick Smereka

   Ported to QNX V4.23a. Jan/97, Rick Smereka

   Added functions to communicate with system logger.
   Feb/97, Rick Smereka

   Changed and added 'sys_log_init' routine to activate
   system logging. Changed function 'sys_log' to use the
   'islog' flag. May/97, Rick Smereka

   Created private flags for personal logging and system
   logging and subroutine 'log_file_date'. Jul/97, Rick Smereka

   Added node ID (nid) and process ID (pid) to system logger
   output line. Dec/97, Rick Smereka

   Ported to 32bit Windows under CodeWarrior. Separated personal
   logging from system logging. This file is only for personal
   logging. System logging is now contained in the file
   'sys_log.c' in the 'clib' directory. Dec/98,
   Rick Smereka

   Ported to HP-UX under GNU C 2.8.1. Jan/99, Rick Smereka

   Modified 'log_start' so that it does not delete the log file
   every time the function is called. Changed 'fopen' from write
   to append. Added functions 'is_log_active' and 'log_end'.
   Feb/99, Rick Smereka

   Ported to Red Hat Linux 5.2, Jul/99, Rick Smereka

   Changed function 'log_start' to return a logic flag indicating
   success or failure. Jan/2000, Rick Smereka

   Added global variable 'p_has_init' to indicate whether personal
   logging has been successfully initialized at least once. Added
   function 'log_file_name' to return the name of the current log
   file. Modified 'log_start' to allow a NULL file name parameter
   as long as logging has been successfully started at least once.
   Added global variable 'p_console_output' to control whether
   logging messages will be displayed to the screen. Added
   functions 'log_console' to control display output and
   'log_get_console' to obtain the current value of
   'p_console_output'. Apr/2000, Rick Smereka

   Corrected size of message buffer 'mes' in function
   'log_file_date' to use size 'MAXMES' (defined in
   'logger.h'). Feb/2001, Rick Smereka

   Added function 'log_file_date_nf'. Oct/2001, Rick Smereka

   Ported to Debian Linux. Nov/2002, Rick Smereka

   Changed the name of the function 'log' to 'logger' since the
   C++ compiler has a function defined as 'log'. Dec/2002,
   Rick Smereka

   Changed default value of 'p_console_output' to 'FALSE'.
   Mar/2004, Rick Smereka */

#include "stdhead.h"

char log_fname[128];             /* log file path/name */
int p_islog = FALSE;             /* is personal logging operational? */
int p_has_init = FALSE;          /* has logging been initialized? */
int p_console_output = FALSE;    /* display message to screen? */

int log_start(char *fname)
{
   FILE *fi;

   /* Start logging and register log file name. This function
      is for stand-alone logging use only. If logging has been
      successfully started with the file name at least once, you
      are allowed to pass a NULL string for 'fname' which indicates
      to re-start the same log file. Function returns 'TRUE'
      upon success, 'FALSE' otherwise. */

   if (!p_has_init)
      if (fname == (char *)NULL || !strlen(fname))
         {
         log_fname[0] = EOS;
         return(FALSE);
         }

   if (fname != (char *)NULL && strlen(fname))
      strcpy(log_fname, fname);

   if ((fi = fopen(log_fname, "a")) == (FILE *)NULL)
      return(FALSE);

   fclose(fi);
   p_islog = TRUE;
   p_has_init = TRUE;
   return(TRUE);
}

void logger(char *fmt,...)
{
   /* Send a message to the log file and to the console if the
      console output flag is high. This function
      is for stand-alone logging only. Do not use for system level
      logging. */

   char mes[MAXMES];
   va_list argptr;

   if (!p_islog)
      return;

   va_start(argptr, fmt);
   vsprintf(mes, fmt, argptr);
   log_file(mes);

   if (log_get_console())
      printf("%s\n", mes);
}

void log_file(char *fmt,...)
{
   /* Function to output to the log file name 'log_fname'.
      No output is sent to the console. This
      function is for stand-alone use only. Do not use for system
      level logging. */

   va_list argptr;
   FILE *fi;

   if (!p_islog)
      return;

   if (!strlen(log_fname))
      return;

   va_start(argptr, fmt);

   if ((fi = fopen(log_fname, "a")) == (FILE *)NULL)
      {
      printf("logger:log_file:Unable to open %s for append\n",
             log_fname);
      return;
      }

   vfprintf(fi, fmt, argptr);
   fclose(fi);
}

void log_file_date(char *fmt,...)
{
   /* Function to output to the log file name 'log_fname' with the
      current date and time as a prefix. Message is also output to
      the screen if the console output flag is high. This function
      is for stand-alone use only. Do not use for system level
      logging. */

   va_list argptr;
   FILE *fi;
   char tmch[26], mes[MAXMES];

   if (!p_islog)
      return;

   if (!strlen(log_fname))
      return;

   va_start(argptr, fmt);

   if ((fi = fopen(log_fname, "a")) == (FILE *)NULL)
      {
      printf("logger:log_file_date:Unable to open %s for append\n",
             log_fname);
      return;
      }

   get_time(tmch);
   vsprintf(mes, fmt, argptr);
   fprintf(fi, "[%s]%s\n", tmch, mes);

   if (log_get_console())
      printf("[%s]%s\n", tmch, mes);

   fclose(fi);
}

void log_file_date_nf(char *mes)
{
   /* Log a message with a date/time prefix. Function behaves
      like 'log_file_date' except that there are no variable
      number of arguments. */

   FILE *fi;
   char tmch[26];

   if (!p_islog)
      return;

   if (!strlen(log_fname))
      return;

   if ((fi = fopen(log_fname, "a")) == (FILE *)NULL)
      {
      printf("logger:log_file_date_nf:Unable to open %s for append\n",
             log_fname);
      return;
      }

   get_time(tmch);
   fprintf(fi, "[%s]%s\n", tmch, mes);

   if (log_get_console())
      printf("[%s]%s\n", tmch, mes);

   fclose(fi);
}

void log_disp(char *fmt,...)
{
   /* Function to output to the display. Console output will
      be display regardless of the value of 'p_console_output'.
      This function is for stand-alone logging only. Do not
      use for system level logging. */

   va_list argptr;

   if (!p_islog)
      return;

   va_start(argptr, fmt);
   vprintf(fmt, argptr);
}

int is_log_active(void)
{
   /* Return the value of the 'p_islog' flag. */

   return(p_islog);
}

void log_end(void)
{
   /* Stop personal logging by changing the 'p_islog' flag. */

   p_islog = FALSE;
}

int log_file_name(char *lfname)
{
   /* Get and return the current log file name.
      Personal logging must have successfully been
      initialized at least once. Function returns
      'TRUE' upon success with the log file name
      loaded into 'lfname' which must already be
      allocated to sufficient size. Function returns
      'FALSE' upon failure. */

   if (lfname == (char *)NULL)
      return(FALSE);

   lfname[0] = EOS;

   if (!p_has_init)
      return(FALSE);

   strcpy(lfname, log_fname);
   return(TRUE);
}

void log_console(int flag)
{
   /* Set whether logging output will be sent
      to the console/screen. Output will be
      turned off if 'flag' is zero. Any other
      value will cause console output to be
      turned on. */

   p_console_output = flag ? 1 : 0;
}

int log_get_console(void)
{
   /* Return the current value of the
      console/screen output flag
      ('p_console_output') */

   return(p_console_output);
}

/* this version of 'sys_log'
   and 'sys_log_nf' is for DOS
   it is a stub, just returns */

#ifdef OS_DOS
int sys_log(char *fmt,...)
{
   return(FALSE);
}

int sys_log_nf(char *mes)
{
   return(FALSE);
}
#endif
