Logo Search packages:      
Sourcecode: p3scan version File versions  Download package

logger.c

// Abstract logging system used to facilitate multiple modes
// of logging

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <syslog.h>
#endif
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>

#include "logger.h"

#ifndef WIN32
static int _LOGGER_mode = _LOGGER_SYSLOG;
static int _LOGGER_syslog_mode = LOG_MAIL|LOG_INFO;
#else
static int _LOGGER_mode = _LOGGER_STDERR;
static int _LOGGER_syslog_mode = 0;
#endif
static FILE *_LOGGER_outf;

struct LOGGER_globals {
      int wrap;
      int wraplength;
};

      // Create and Initialise the global structure for LOGGER,
      //          we init it to have NO wrapping.

static struct LOGGER_globals LOGGER_glb={ 0, 0 };


/*------------------------------------------------------------------------
Procedure:     LOGGER_get_file ID:1
Purpose:       Returns the pointer to the file being used to output logs to
Input:
Output:
Errors:
------------------------------------------------------------------------*/
FILE *LOGGER_get_file( void )
{
      return _LOGGER_outf;
}


/*------------------------------------------------------------------------
Procedure:     LOGGER_set_output_mode ID:1
Purpose:       Sets the message/log output method, ie, stderr, stdout
or syslog
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_set_output_mode( int modechoice )
{
      _LOGGER_mode = modechoice;
      return 0;
}

/*------------------------------------------------------------------------
Procedure:     LOGGER_set_output_file ID:1
Purpose:       Sets the output file for when _LOGGER_mode is set to
_LOGGER_file
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_set_output_file( FILE *f )
{
      _LOGGER_outf = f;
      return 0;
}

/*------------------------------------------------------------------------
Procedure:     LOGGER_set_syslog_mode ID:1
Purpose:       Sets the mode that messaging to the syslog daemon will
be sent as (ie, LOG_MAIL|LOG_INFO)
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_set_syslog_mode( int syslogmode )
{
      _LOGGER_syslog_mode = syslogmode;
      return 0;
}




/*------------------------------------------------------------------------
Procedure:     LOGGER_set_logfile ID:1
Purpose:       Opens and setups the internal Log file file pointer with the
log file as given by lfname
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_set_logfile( char *lfname )
{
      int result = 0;

      _LOGGER_outf = fopen(lfname,"a");
      if (!_LOGGER_outf)
      {
#ifndef WIN32
            syslog(1,"LOGGER_set_logfile: ERROR - Cannot open logfile '%s' (%s)",lfname,strerror(errno));
#else
            fprintf(stderr, "LOGGER_set_logfile: ERROR - Cannot open logfile '%s' (%s)\n", lfname, strerror(errno));
#endif
            result = -1;
      }

      return result;
}



/*------------------------------------------------------------------------
Procedure:     LOGGER_set_wraplength ID:1
Purpose:       Sets the character count at which LOGGER will break a line
Input:         int length: Positive integer indicating number of chracters at which to wrap at
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_set_wraplength( int length )
{
      if ( length >= 0 )
      {
            LOGGER_glb.wraplength = length;
      }

      return LOGGER_glb.wraplength;
}

/*------------------------------------------------------------------------
Procedure:     LOGGER_set_wrap ID:1
Purpose:       Set log output wrapping to on or off
Input:         int level: 0 = no wrap, > 0 = wrap.
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_set_wrap( int level )
{
      if ( level >= 0 )
      {
            LOGGER_glb.wrap = level;
      }

      return LOGGER_glb.wrap;
}



/*------------------------------------------------------------------------
Procedure:     LOGGER_close_logfile ID:1
Purpose:       Closes the modules log file pointer.
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_close_logfile( void )
{
      int result = 0;

      if (_LOGGER_outf) fclose(_LOGGER_outf);

      return result;
}



/*------------------------------------------------------------------------
Procedure:     LOGGER_clean_output ID:1
Purpose:       Checks through the output string for any characters which could cause
potential 'isssues' with the data writing calls, items such as stray non-escaped
% characters can cause havoc.
Input:         char *string: Raw string
int maxsize: Maximum available buffer size for this string to expand to
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_clean_output( char *string, char **buffer )
{
      char *newstr;
      char *p, *q;
      char *next_space;

      int pc;
      int slen = strlen( string );
      int line_size;
      int maxsize = slen *2;

      // First up, allocate maxsize bytes for a temporary new string.
      newstr = malloc(slen *2 +1); 
      if ( newstr == NULL )
      {
            // FIXME - Report an error here ... to -somewhere-
            return -1;
      }

      p = newstr;
      q = string;
      pc = 0;
      line_size = 0;

      while (slen--)
      {

            // Do we need to apply any wrapping to the output? If so then we
            //          shall embark on a journey of strange space and distance
            //          evaluations to determine if we should wrap now or later

            if ( LOGGER_glb.wrap > 0 )
            {
                  if (isspace((int)*q))
                  {
                        next_space = strpbrk( (q+1), "\t\r\n\v " );
                        if (next_space != NULL)
                        {
                              if ((line_size +(next_space -q)) >= LOGGER_glb.wraplength)
                              {
                                    *p = '\n';
                                    p++;
                                    pc++;
                                    line_size = 0;
                              }
                        }
                  }

                  if ( line_size >= LOGGER_glb.wraplength )
                  {
                        *p = '\n';
                        p++;
                        pc++;
                        line_size = 0;
                  }
            }

            // If the string has a % in it, then we need to encode it as
            //    a DOUBLE % symbol.

            if (*q == '%') {
//                if (strchr("fdlsxXn",*(q+1)))
//                {
                        *p = '%';
                        p++;
                        pc++;
//                }
            }

            // Copy the character of the string in
            *p = *q;

            // Move everything along.
            q++;
            p++;
            pc++;
            line_size++;

            if ( pc > (maxsize -1) ) {
                  break;
            }
      }

      *p = '\0';

      // This will have to be deallocated later!
      if (newstr) *buffer = newstr;

      return 0;
}

/*------------------------------------------------------------------------
Procedure:     LOGGER_log ID:1
Purpose:       Logs the params as supplied to the required
output as defined by LOGGER_set_output
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int LOGGER_log( char *format, ...)
{
      va_list ptr;
      char tmpoutput[10240];
      char linebreak[]="\n";
      char nolinebreak[]="";
      char *lineend;
      char *output;


      // get our variable arguments
      va_start(ptr,format);

      // produce output, and spit to the log file
#ifdef NO_SNPRINTF
      vsprintf(tmpoutput, format, ptr);
#else
      vsnprintf(tmpoutput,10240,format,ptr);
#endif

      LOGGER_clean_output( tmpoutput, &output );

      if ( output[strlen(output)-1] == '\n' ) {
            lineend = nolinebreak;
      }
      else {
            lineend = linebreak;
      }

      if ( output[strlen(output)-1] == '\n' ) { lineend = nolinebreak; } else { lineend = linebreak; }

      // Send the output to the appropriate output destination
      switch (_LOGGER_mode) {
            case _LOGGER_STDERR:
                  fprintf(stderr,"%s%s",output, lineend );
                  break;
            case _LOGGER_SYSLOG:
                  syslog(_LOGGER_syslog_mode,output);
                  break;
            case _LOGGER_STDOUT:
                  fprintf(stdout,"%s%s",output, lineend);
                  fflush(stdout);
                  break;
            case _LOGGER_FILE:
                  fprintf(_LOGGER_outf,"%s%s",output,lineend);
                  fflush(_LOGGER_outf);
                  break;
            default:
                  fprintf(stdout,"LOGGER-Default: %s%s",output,lineend);
      }


      if (output) free(output);

      return 0;
}





Generated by  Doxygen 1.6.0   Back to index