/*
 * $Header: /home/gene/library/website/docsrc/wel/src/RCS/log.c,v 395.1 2008/04/20 17:25:48 gene Exp $
 *
 * Copyright (c) 2005 Gene Michael Stover.  All rights reserved.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

/*
 * Save events which happen within this suite of programs.
 */

#include "this.h"

/*
 */
char *LOG_eventSource = "Gene's Generic Log";
char *LOG_eventMessageFile = "%SystemRoot%\\System32\\printinc-phone-log.dll";
char *LOG_pathname = "C://temp//log.txt";

/*
 */
void
LOG_Shutdown ()
{
}

/*
 */
int
LOG_Startup ()
{
  int rc = 0;
  char regpath[1024];
  HKEY hkey;
  LONG n;
  DWORD disposition, dw;

  sprintf (regpath,
	   "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
	   LOG_eventSource);
  /*
   * Create the new key or open the existing key.
   */
  n = RegCreateKeyEx (HKEY_LOCAL_MACHINE, regpath, 0, NULL,
		      REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey,
		      &disposition);
  if (n == ERROR_SUCCESS) {
    if (disposition == REG_OPENED_EXISTING_KEY) {
      /*
       * We opened an existing key, so we'll assume that the
       * values within it (namely, the type mask & the
       * pathname of the messages file) already exist.
       */
    } else if (disposition == REG_CREATED_NEW_KEY) {
      /*
       * We created a new key, so we'll also create the
       * fields within it.
       */
      /*
       * Set the name of the message file.
       */
      n = RegSetValueEx (hkey, "EventMessageFile", 0, REG_EXPAND_SZ,
			 LOG_eventMessageFile, strlen (LOG_eventMessageFile));
      if (n == ERROR_SUCCESS) {
	/*
	 * Set the supported event types.  We support all types.
	 */
	dw = EVENTLOG_AUDIT_FAILURE | EVENTLOG_AUDIT_SUCCESS |
	  EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE |
	  EVENTLOG_WARNING_TYPE;
	n = RegSetValueEx (hkey, "TypesSupported", 0, REG_DWORD,
			   (BYTE *) &dw, sizeof dw);
	if (n == ERROR_SUCCESS) {
	  /* good */
	} else {
	  printf("Could not set the supported types."); 
	  rc = 51;
	}
      } else {
	printf("Could not set the event message file."); 
	rc = -9;
      }
    } else {
      /*
       * Disposition isn't either of the values we expect.
       * This is weird.
       */
      fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__);
      fprintf (stderr, " RegCreateKeyEx returned");
      fprintf (stderr, " %lu in the disposition", (unsigned long) disposition);
      fprintf (stderr, " field.  This is not one of the two values which");
      fprintf (stderr, " are expected in that field.");
      rc = 9;
    }
    RegCloseKey(hkey); 
  } else {
    printf("Could not create the registry key."); 
    rc = 5;
  }
  return rc;
}

/*
 * Handle for inserting events into the Winders Event Log.
 * Don't access this variable directly.  It is shared between
 * S_Open & S_Close.
 */
static HANDLE S_handle = NULL;

/*
 */
static void
S_Close ()
{
  if (S_handle != NULL) {
    DeregisterEventSource (S_handle);
    S_handle = NULL;
  }
}

/*
 * Return a handle for inserting events into the Winders Event Log.
 * Saves the handle in a global variable, so the handle stays
 * open until you call S_Close, which you should do.  Don't call
 * DeregisterEventSource on the handle that
 * this function returns.  Instead, call S_Close.
 */
static HANDLE
S_Open ()
{
  if (S_handle == NULL) {
    S_handle = RegisterEventSource (NULL, LOG_eventSource);
  }
  return S_handle;
}

/*
 */
static void
S_ErrorToEventLog (DWORD error, char fn[], char file[], int line)
{
#if 0
  char line_str[10];
  char *lst[4];

  sprintf (line_str, "%d", line);
  lst[0] = hostname;
  lst[1] = port_str;
  lst[2] = file;
  lst[3] = line_str;
  ReportEvent (S_Open (),
	       EVENTLOG_ERROR_TYPE,
	       0, /* category */
	       LOG_IdConnectFailed,
	       NULL, /* user SID */
	       4, /* number of strings */
	       0, /* size of binary data */
	       lst,
	       NULL);
  S_Close ();
#endif
}

/*
 */
static void
S_ErrorToStdio (DWORD error, char fn[], char file[], int line, FILE *strm)
{
  fprintf (strm, "\n%s:%d: %s: error is %lu.", __FILE__, __LINE__, fn,
           (long unsigned) error);
}

/*
 */
static void
S_ErrorToFile (DWORD error, char fn[], char file[], int line)
{
  FILE *fp;

  fp = fopen (LOG_pathname, "a");
  if (fp != NULL) {
    S_ErrorToStdio (error, fn, file, line, fp);
    fclose (fp);
  } else {
    fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__);
    fprintf (stderr, " Can't open the log file, \"%s\",", LOG_pathname);
    fprintf (stderr, " to append.");
  }
}

/*
 */
void
LOG_Error (DWORD error, char fn[], char file[], int line)
{
  S_ErrorToStdio (error, fn, file, line, stderr);
  S_ErrorToFile (error, fn, file, line);
  S_ErrorToEventLog (error, fn, file, line);
}

/*
 */
void
LOG_LastError (char fn[], char file[], int line)
{
  LOG_Error (GetLastError (), fn, file, line);
}

/* --- end of file --- */

