// Copyright, 2001-2003, Astra Network Inc.  All Rights Reserved

// This source code has been published by Astra Network Inc. However, any
// use, reproduction, modification, distribution or transfer of this
// software, or any software which includes or is based upon any of this
// code, is only permitted if expressly authorized by a written license
// agreement from Astra. Contact your Astra representative directly for
// more information.


#include <olmod.h>
#include <stdio.h>
#include <string.h>

typedef struct logf1_data_s
{
  pid_t process;
  int logtype;
  FILE *fp;;
  int debug_level;		/* level at which we stop recording errors */
  char *format;
}
logf1_data_t;


olmod_error_t
logf1_module_init ()
{
  return kMod_OK;
}

olmod_blackbox_t *
logf1_module_inst (pid_t process, olmod_arglist_t * static_args)
{
  logf1_data_t *blackbox;

  if (!(blackbox = (logf1_data_t *) malloc (sizeof (logf1_data_t))))
    {
      printf ("mod_logf1: malloc failed\n");
      return NULL;
    }
  blackbox->process = process;
  blackbox->logtype = QTOL (*(int64_t *) static_args[0]);
  blackbox->format = (char *) static_args[2];
  if (blackbox->logtype == 1)
    {
      blackbox->fp = fopen ((char *) static_args[1], "a+");
      if (blackbox->fp == NULL)
	blackbox->fp = stderr;
    }
  else if (blackbox == 0)
    blackbox->fp = stderr;
  else
    blackbox->fp = stderr;

  /* FIXME: highest level, change this to something dynamic later */
  blackbox->debug_level = 10;

  return blackbox;
}

olmod_error_t
logf1_module_set (olmod_blackbox_t * data, int64_t var)
{
  return kMod_OK;
}

#define TMPLEN 255

int64_t
logf1_module_get (olmod_blackbox_t * data, olmod_arglist_t * dynamic_args)
{
  logf1_data_t *blackbox = (logf1_data_t *) data;
  int severity = QTOL (*(int64_t *) dynamic_args[0]);
  char output[TMPLEN];
  /* Only record log message of a severity greater than the debug level */
  if (severity > blackbox->debug_level)
    return (LTOQ (0L));

  /* If the format string is too large then fail */
  /* FIXME - do this more graceful, ie truncate the string */
  if (strlen (blackbox->format) > (TMPLEN - QUAD_STR_SIZE - 1))
    return (LTOQ (0L));

  sprintf (output, blackbox->format, QTOSTR (*(int64_t *) dynamic_args[1]));

  if (blackbox->logtype == 0 || blackbox->logtype == 1)
    {
      fprintf (blackbox->fp, "%ld:%d:%s\n", (long) blackbox->process,	/* pid (or 0 for global context) */
	       severity,	/* severity level */
	       output);		/* log message */
    }
  else
    {
      fprintf (stderr, "mod_logf1: logtype not supported\n");
    }

  return (LTOQ (0l));
}

void
logf1_module_deinst (olmod_blackbox_t * data)
{
  logf1_data_t *blackbox = (logf1_data_t *) data;

  if (blackbox->fp != stderr)
    fclose (blackbox->fp);
  free (data);
}

void
logf1_module_deinit ()
{
}
