/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * 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 Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */

#include "config.h"

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef HAVE_TIME_H
#include <time.h>
#endif


#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif

#include "monit.h"
#include "alert.h"
#include "event.h"
#include "process.h"


/**
 * Implementation of the event interface.
 *
 * @file
 */


/* ------------------------------------------------------------- Definitions */

EventTable_T Event_Table[]= {
  {Event_Action,     "Action done",             "Action done",                "Action done",              "Action done"},
  {Event_Checksum,   "Checksum failed",         "Checksum succeeded",         "Checksum changed",         "Checksum not changed"},
  {Event_Connection, "Connection failed",       "Connection succeeded",       "Connection changed",       "Connection not changed"},
  {Event_Content,    "Content failed",          "Content succeeded",          "Content match",            "Content doesn't match"},
  {Event_Data,       "Data access error",       "Data access succeeded",      "Data access changed",      "Data access not changed"},
  {Event_Exec,       "Execution failed",        "Execution succeeded",        "Execution changed",        "Execution not changed"},
  {Event_Fsflag,     "Filesystem flags failed", "Filesystem flags succeeded", "Filesystem flags changed", "Filesystem flags not changed"},
  {Event_Gid,        "GID failed",              "GID succeeded",              "GID changed",              "GID not changed"},
  {Event_Heartbeat,  "Heartbeat failed",        "Heartbeat succeeded",        "Heartbeat changed",        "Heartbeat not changed"},
  {Event_Icmp,       "ICMP failed",             "ICMP succeeded",             "ICMP changed",             "ICMP not changed"},
  {Event_Instance,   "Monit instance failed",   "Monit instance succeeded",   "Monit instance changed",   "Monit instance not changed"},
  {Event_Invalid,    "Invalid type",            "Type succeeded",             "Type changed",             "Type not changed"},
  {Event_Nonexist,   "Does not exist",          "Exists",                     "Existence changed",        "Existence not changed"},
  {Event_Permission, "Permission failed",       "Permission succeeded",       "Permission changed",       "Permission not changed"},
  {Event_Pid,        "PID failed",              "PID succeeded",              "PID changed",              "PID not changed"},
  {Event_PPid,       "PPID failed",             "PPID succeeded",             "PPID changed",             "PPID not changed"},
  {Event_Resource,   "Resource limit matched",  "Resource limit succeeded",   "Resource limit changed",   "Resource limit not changed"},
  {Event_Size,       "Size failed",             "Size succeeded",             "Size changed",             "Size not changed"},
  {Event_Status,     "Status failed",           "Status succeeded",           "Status changed",           "Status not changed"},
  {Event_Timeout,    "Timeout",                 "Timeout recovery",           "Timeout changed",          "Timeout not changed"},
  {Event_Timestamp,  "Timestamp failed",        "Timestamp succeeded",        "Timestamp changed",        "Timestamp not changed"},
  {Event_Uid,        "UID failed",              "UID succeeded",              "UID changed",              "UID not changed"},
  {Event_Uptime,     "Uptime failed",           "Uptime succeeded",           "Uptime changed",           "Uptime not changed"},
  /* Virtual events */
  {Event_Null,       "No Event",                "No Event",                   "No Event",                 "No Event"}
};


/* -------------------------------------------------------------- Prototypes */


static void handle_event(Event_T);
static void handle_action(Event_T, Action_T);
static void Event_queue_add(Event_T);
static void Event_queue_update(Event_T, const char *);


/* ------------------------------------------------------------------ Public */


/**
 * Post a new Event
 * @param service The Service the event belongs to
 * @param id The event identification
 * @param state The event state
 * @param action Description of the event action
 * @param s Optional message describing the event
 */
void Event_post(Service_T service, long id, short state, EventAction_T action, char *s, ...) {
  Event_T e;

  ASSERT(service);
  ASSERT(action);
  ASSERT(state == STATE_FAILED || state == STATE_SUCCEEDED || state == STATE_CHANGED || state == STATE_CHANGEDNOT);

  if ((e = service->eventlist) == NULL) {
    /* Only first failed/changed event can initialize the queue for given event type,
     * thus succeeded events are ignored until first error. */
    if (state == STATE_SUCCEEDED || state == STATE_CHANGEDNOT)
      return;

    /* Initialize event list and add first event. The manadatory informations
     * are cloned so the event is as standalone as possible and may be saved
     * to the queue without the dependency on the original service, thus
     * persistent and managable across monit restarts */
    NEW(e);
    e->id = id;
    gettimeofday(&e->collected, NULL);
    e->source = Str_dup(service->name);
    e->mode = service->mode;
    e->type = service->type;
    e->state = STATE_INIT;
    e->state_map = 1;
    e->action = action;
    if (s) {
      va_list ap;
      va_start(ap, s);
      e->message = Str_vcat(s, ap);
      va_end(ap);
    }
    service->eventlist = e;
  } else {
    /* Try to find the event with the same origin and type identification.
     * Each service and each test have its own custom actions object, so
     * we share actions object address to identify event source. */
    do {
      if (e->action == action && e->id == id) {
        gettimeofday(&e->collected, NULL);

        /* Shift the existing event flags to the left
         * and set the first bit based on actual state */
        e->state_map <<= 1;
        e->state_map |= ((state == STATE_SUCCEEDED || state == STATE_CHANGEDNOT) ? 0 : 1);

        /* Update the message */
        if (s) {
          va_list ap;
          FREE(e->message);
          va_start(ap, s);
          e->message = Str_vcat(s, ap);
          va_end(ap);
        }
	break;
      }
      e = e->next;
    } while (e);

    if (!e) {
      /* Only first failed/changed event can initialize the queue for given event type,
       * thus succeeded events are ignored until first error. */
      if (state == STATE_SUCCEEDED || state == STATE_CHANGEDNOT)
        return;

      /* Event was not found in the pending events list, we will add it.
       * The manadatory informations are cloned so the event is as standalone
       * as possible and may be saved to the queue without the dependency on
       * the original service, thus persistent and managable across monit
       * restarts */
      NEW(e);
      e->id = id;
      gettimeofday(&e->collected, NULL);
      e->source = Str_dup(service->name);
      e->mode = service->mode;
      e->type = service->type;
      e->state = STATE_INIT;
      e->state_map = 1;
      e->action = action;
      if (s) {
        va_list ap;
        va_start(ap, s);
        e->message = Str_vcat(s, ap);
        va_end(ap);
      }
      e->next = service->eventlist;
      service->eventlist = e;
    }
  }

  e->state_changed = Event_check_state(e, state);

  /* In the case that the state changed, update it and reset the counter */
  if (e->state_changed) {
    e->state = state;
    e->count = 1;
  } else
    e->count++;

  handle_event(e);
}


/* -------------------------------------------------------------- Properties */


/**
 * Get the Service where the event orginated
 * @param E An event object
 * @return The Service where the event orginated
 */
Service_T Event_get_source(Event_T E) {
  Service_T s = NULL;

  ASSERT(E);

  if (!(s = Util_getService(E->source)))
    LogError("Service %s not found in monit configuration\n", E->source);

  return s;
}


/**
 * Get the Service name where the event orginated
 * @param E An event object
 * @return The Service name where the event orginated
 */
char *Event_get_source_name(Event_T E) {
  ASSERT(E);
  return (E->source);
}


/**
 * Get the service type of the service where the event orginated
 * @param E An event object
 * @return The service type of the service where the event orginated
 */
int Event_get_source_type(Event_T E) {
  ASSERT(E);
  return (E->type);
}


/**
 * Get the Event timestamp
 * @param E An event object
 * @return The Event timestamp
 */
struct timeval *Event_get_collected(Event_T E) {
  ASSERT(E);
  return &E->collected;
}


/**
 * Get the Event raw state
 * @param E An event object
 * @return The Event raw state
 */
short Event_get_state(Event_T E) {
  ASSERT(E);
  return E->state;
}


/**
 * Return the actual event state based on event state bitmap
 * and event ratio needed to trigger the state change
 * @param E An event object
 * @param S Actual posted state
 * @return The Event raw state
 */
short Event_check_state(Event_T E, short S) {
  int       i;
  int       count = 0;
  short     state = (S == STATE_SUCCEEDED || S == STATE_CHANGEDNOT) ? 0 : 1; /* translate to 0/1 class */
  Action_T  action;
  Service_T service;
  long long flag;

  ASSERT(E);

  if (!(service = Event_get_source(E)))
    return TRUE;

  /* Only true failed/changed state condition can change the initial state */
  if (!state && E->state == STATE_INIT && !(service->error & E->id))
    return FALSE;

  action = !state ? E->action->succeeded : E->action->failed;

  /* Compare as many bits as cycles able to trigger the action */
  for (i = 0; i < action->cycles; i++) {
    /* Check the state of the particular cycle given by the bit position */
    flag = (E->state_map >> i) & 0x1;

    /* Count occurences of the posted state */
    if (flag == state)
      count++;
  }

  /* the internal instance and action events are handled as changed any time since we need to deliver alert whenever it occurs */
  if (E->id == Event_Instance || E->id == Event_Action || (count >= action->count && (S != E->state || S == STATE_CHANGED)))
    return TRUE;
  
  return FALSE;
}


/**
 * Get the Event type
 * @param E An event object
 * @return The Event type
 */
long Event_get_id(Event_T E) {
  ASSERT(E);
  return E->id;
}


/**
 * Get the optionally Event message describing why the event was
 * fired.
 * @param E An event object
 * @return The Event message. May be NULL
 */
const char *Event_get_message(Event_T E) {
  ASSERT(E);
  return E->message;
}


/**
 * Get a textual description of actual event type.
 * @param E An event object
 * @return A string describing the event type in clear text. If the
 * event type is not found NULL is returned.
 */
const char *Event_get_description(Event_T E) {
  EventTable_T *et= Event_Table;

  ASSERT(E);

  while ((*et).id) {
    if (E->id == (*et).id) {
      switch (E->state) {
        case STATE_SUCCEEDED:
          return (*et).description_succeeded;
        case STATE_FAILED:
          return (*et).description_failed;
        case STATE_INIT:
          return (*et).description_failed;
        case STATE_CHANGED:
          return (*et).description_changed;
        case STATE_CHANGEDNOT:
          return (*et).description_changednot;
        default:
          break;
      }
    }
    et++;
  }
  
  return NULL;
}


/**
 * Get an event action id.
 * @param E An event object
 * @return An action id
 */
short Event_get_action(Event_T E) {
  Action_T A = NULL;

  ASSERT(E);

  switch (E->state) {
    case STATE_SUCCEEDED:
    case STATE_CHANGEDNOT:
      A = E->action->succeeded;
      break;
    case STATE_FAILED:
    case STATE_CHANGED:
    case STATE_INIT:
      A = E->action->failed;
      break;
    default:
      break;
  }

  if (! A)
    return ACTION_IGNORE;

  /* In the case of passive mode we replace the description of start, stop
   * or restart action for alert action, because these actions are passive in
   * this mode */
  return (E->mode == MODE_PASSIVE && ((A->id == ACTION_START) || (A->id == ACTION_STOP) || (A->id == ACTION_RESTART))) ? ACTION_ALERT : A->id;
}


/**
 * Get a textual description of actual event action. For instance if the
 * event type is possitive Event_Nonexist, the textual description of
 * failed state related action is "restart". Likewise if the event type is
 * negative Event_Checksumthe textual description of recovery related action
 * is "alert" and so on.
 * @param E An event object
 * @return A string describing the event type in clear text. If the
 * event type is not found NULL is returned.
 */
const char *Event_get_action_description(Event_T E) {
  ASSERT(E);
  return actionnames[Event_get_action(E)];
}


/**
 * Reprocess the partially handled event queue
 */
void Event_queue_process() {
  DIR           *dir = NULL;
  FILE          *file = NULL;
  struct dirent *de = NULL;
  EventAction_T  ea = NULL;
  Action_T       a = NULL;

  /* return in the case that the eventqueue is not enabled or empty */
  if (! Run.eventlist_dir || (! Run.handler_init && ! Run.handler_queue[HANDLER_ALERT] && ! Run.handler_queue[HANDLER_MMONIT]))
    return;

  if (! (dir = opendir(Run.eventlist_dir)) ) {
    if (errno != ENOENT)
      LogError("%s: cannot open the directory %s -- %s\n", prog, Run.eventlist_dir, STRERROR);
    return;
  }

  if ((de = readdir(dir)))
    DEBUG("Processing postponed events queue\n");

  NEW(ea);
  NEW(a);

  while (de) {
    size_t         size;
    int            handlers_passed = 0;
    int           *version = NULL;
    short         *action = NULL;
    Event_T        e = NULL;
    struct stat    st;
    char           file_name[STRLEN];

    /* In the case that all handlers failed, skip the further processing in
     * this cycle. Alert handler is currently defined anytime (either
     * explicitly or localhost by default) */
    if ( (Run.mmonits && FLAG(Run.handler_flag, HANDLER_MMONIT) && FLAG(Run.handler_flag, HANDLER_ALERT)) || FLAG(Run.handler_flag, HANDLER_ALERT))
      break;

    snprintf(file_name, STRLEN, "%s/%s", Run.eventlist_dir, de->d_name);

    if (!stat(file_name, &st) && S_ISREG(st.st_mode)) {
      DEBUG("%s: processing queued event %s\n", prog, file_name);

      if (! (file = fopen(file_name, "r")) ) {
        LogError("%s: queued event processing failed - cannot open the file %s -- %s\n", prog, file_name, STRERROR);
        goto error1;
      }

      /* read event structure version */
      if (!(version = file_readQueue(file, &size))) {
        LogError("skipping queued event %s - unknown data format\n", file_name);
        goto error2;
      }
      if (size != sizeof(int)) {
        LogError("Aborting queued event %s - invalid size %d\n", file_name, size);
        goto error3;
      }
      if (*version != EVENT_VERSION) {
        LogError("Aborting queued event %s - incompatible data format version %d\n", file_name, *version);
        goto error3;
      }

      /* read event structure */
      if (!(e = file_readQueue(file, &size)))
        goto error3;
      if (size != sizeof(*e))
        goto error4;

      /* read source */
      if (!(e->source = file_readQueue(file, &size)))
        goto error4;

      /* read message */
      if (!(e->message = file_readQueue(file, &size)))
        goto error5;

      /* read event action */
      if (!(action = file_readQueue(file, &size)))
        goto error6;
      if (size != sizeof(short))
        goto error7;
      a->id = *action;
      if (e->state == STATE_FAILED)
        ea->failed = a;
      else
        ea->succeeded = a;
      e->action = ea;

      /* Retry all remaining handlers */

      /* alert */
      if (e->flag & HANDLER_ALERT) {
        if (Run.handler_init)
          Run.handler_queue[HANDLER_ALERT]++;
        if ((Run.handler_flag & HANDLER_ALERT) != HANDLER_ALERT) {
          if ( handle_alert(e) != HANDLER_ALERT ) {
            e->flag &= ~HANDLER_ALERT;
            Run.handler_queue[HANDLER_ALERT]--;
            handlers_passed++;
          } else {
            LogError("Alert handler failed, retry scheduled for next cycle\n");
            Run.handler_flag |= HANDLER_ALERT;
          }
        }
      }

      /* mmonit */
      if (e->flag & HANDLER_MMONIT) {
        if (Run.handler_init)
          Run.handler_queue[HANDLER_MMONIT]++;
        if ((Run.handler_flag & HANDLER_MMONIT) != HANDLER_MMONIT) {
          if ( handle_mmonit(e) != HANDLER_MMONIT ) {
            e->flag &= ~HANDLER_MMONIT;
            Run.handler_queue[HANDLER_MMONIT]--;
            handlers_passed++;
          } else {
            LogError("M/Monit handler failed, retry scheduled for next cycle\n");
            Run.handler_flag |= HANDLER_MMONIT;
          }
        }
      }

      /* If no error persists, remove it from the queue */
      if (e->flag == HANDLER_SUCCEEDED) {
        DEBUG("Removing queued event %s\n", file_name);
        if (unlink(file_name) < 0)
          LogError("Failed to remove queued event file '%s' -- %s\n", file_name, STRERROR);
      } else if (handlers_passed > 0) {
        DEBUG("Updating queued event %s (some handlers passed)\n", file_name);
        Event_queue_update(e, file_name);
      }

error7:
      FREE(action);
error6:
      FREE(e->message);
error5:
      FREE(e->source);
error4:
      FREE(e);
error3:
      FREE(version);
error2:
      fclose(file);
    }
error1:
    de = readdir(dir);
  }
  Run.handler_init = FALSE;
  closedir(dir);
  FREE(a);
  FREE(ea);
  return;
}


/* ----------------------------------------------------------------- Private */


/*
 * Handle the event
 * @param E An event
 */
static void handle_event(Event_T E) {
  Service_T S;

  ASSERT(E);
  ASSERT(E->action);
  ASSERT(E->action->failed);
  ASSERT(E->action->succeeded);

  /* We will handle only first succeeded event, recurrent succeeded events
   * or insufficient succeeded events during failed service state are
   * ignored. Failed events are handled each time. */
  if (!E->state_changed && (E->state == STATE_SUCCEEDED || E->state == STATE_CHANGEDNOT || ((E->state_map & 0x1) ^ 0x1)))
    return;

  S = Event_get_source(E);
  if (!S) {
    LogError("Event handling aborted\n");
    return;
  }

  if (E->message) {
    /* In the case that the service state is initializing yet and error
     * occured, log it and exit. Succeeded events in init state are not
     * logged. Instance and action events are logged always with priority
     * info. */
    if (E->state != STATE_INIT || E->state_map & 0x1) {
      if (E->state == STATE_SUCCEEDED || E->state == STATE_CHANGEDNOT || E->id == Event_Instance || E->id == Event_Action)
        LogInfo("'%s' %s\n", S->name, E->message);
      else
        LogError("'%s' %s\n", S->name, E->message);
    }
    if (E->state == STATE_INIT)
      return;
  }

  if (E->state == STATE_FAILED || E->state == STATE_CHANGED) {
    if (E->id != Event_Instance && E->id != Event_Action) { // We are not interested in setting error flag for instance and action events
      S->error |= E->id;
      /* The error hint provides second dimension for error bitmap and differentiates between failed/changed event states (failed=0, chaged=1) */
      if (E->state == STATE_CHANGED)
        S->error_hint |= E->id;
      else
        S->error_hint &= ~E->id;
    }
    handle_action(E, E->action->failed);
  } else {
    S->error &= ~E->id;
    handle_action(E, E->action->succeeded);
  }

  /* Possible event state change was handled so we will reset the flag. */
  E->state_changed = FALSE;
}


static void handle_action(Event_T E, Action_T A) {
  Service_T s;

  ASSERT(E);
  ASSERT(A);

  E->flag = HANDLER_SUCCEEDED;

  if (A->id == ACTION_IGNORE)
    return;

  /* Alert and mmonit event notification are common actions */
  E->flag |= handle_mmonit(E);
  E->flag |= handle_alert(E);

  /* In the case that some subhandler failed, enqueue the event for
   * partial reprocessing */
  if (E->flag != HANDLER_SUCCEEDED) {
    if (Run.eventlist_dir)
      Event_queue_add(E);
    else
      LogError("Aborting event\n");
  }

  if (!(s = Event_get_source(E))) {
    LogError("Event action handling aborted\n");
    return;
  }

  /* Action event is handled already. For Instance events
   * we don't want actions like stop to be executed
   * to prevent the disabling of system service monitoring */
  if (A->id == ACTION_ALERT || E->id == Event_Instance) {
    return;
  } else if (A->id == ACTION_EXEC) {
    LogInfo("'%s' exec: %s\n", s->name, A->exec->arg[0]);
    spawn(s, A->exec, E);
    return;
  } else {
    if (s->actionratelist && (A->id == ACTION_START || A->id == ACTION_RESTART))
      s->nstart++;

    if (s->mode == MODE_PASSIVE && (A->id == ACTION_START || A->id == ACTION_STOP  || A->id == ACTION_RESTART))
      return;

    control_service(s->name, A->id);
  }
}


/**
 * Add the partialy handled event to the global queue
 * @param E An event object
 */
static void Event_queue_add(Event_T E) {
  FILE        *file = NULL;
  char         file_name[STRLEN];
  int          version = EVENT_VERSION;
  short        action = Event_get_action(E);
  int          rv = FALSE;
  mode_t       mask;

  ASSERT(E);
  ASSERT(E->flag != HANDLER_SUCCEEDED);

  if (!file_checkQueueDirectory(Run.eventlist_dir, 0700)) {
    LogError("%s: Aborting event - cannot access the directory %s\n", prog, Run.eventlist_dir);
    return;
  }
    
  if (!file_checkQueueLimit(Run.eventlist_dir, Run.eventlist_slots)) {
    LogError("%s: Aborting event - queue over quota\n", prog);
    return;
  }
    
  /* compose the file name of actual timestamp and service name */
  snprintf(file_name, STRLEN, "%s/%ld_%lx", Run.eventlist_dir, (long int)time(NULL), (long unsigned)E->source);

  DEBUG("%s: Adding event to the queue file %s for later delivery\n", prog, file_name);

  mask = umask(QUEUEMASK);
  file = fopen(file_name, "w");
  umask(mask);
  if (! file) {
    LogError("%s: Aborting event - cannot open the event file %s -- %s\n", prog, file_name, STRERROR);
    return;
  }

  /* write event structure version */
  if (!(rv = file_writeQueue(file, &version, sizeof(int))))
    goto error;

  /* write event structure */
  if (!(rv = file_writeQueue(file, E, sizeof(*E))))
    goto error;

  /* write source */
  if (!(rv = file_writeQueue(file, E->source, E->source ? strlen(E->source)+1 : 0)))
    goto error;

  /* write message */
  if (!(rv = file_writeQueue(file, E->message, E->message ? strlen(E->message)+1 : 0)))
    goto error;

  /* write event action */
  if (!(rv = file_writeQueue(file, &action, sizeof(short))))
    goto error;

  error:
  fclose(file);
  if (!rv) {
    LogError("%s: Aborting event - unable to save event information to %s\n",  prog, file_name);
    if (unlink(file_name) < 0)
      LogError("Failed to remove event file '%s' -- %s\n", file_name, STRERROR);
  } else {
    if (!Run.handler_init && E->flag & HANDLER_ALERT)
      Run.handler_queue[HANDLER_ALERT]++;
    if (!Run.handler_init && E->flag & HANDLER_MMONIT)
      Run.handler_queue[HANDLER_MMONIT]++;
  }

  return;
}


/**
 * Update the partialy handled event in the global queue
 * @param E An event object
 * @param file_name File name
 */
static void Event_queue_update(Event_T E, const char *file_name) {
  FILE        *file = NULL;
  int          version = EVENT_VERSION;
  short        action = Event_get_action(E);
  int          rv = FALSE;
  mode_t       mask;

  ASSERT(E);
  ASSERT(E->flag != HANDLER_SUCCEEDED);

  if (!file_checkQueueDirectory(Run.eventlist_dir, 0700)) {
    LogError("%s: Aborting event - cannot access the directory %s\n", prog, Run.eventlist_dir);
    return;
  }
    
  DEBUG("%s: Updating event in the queue file %s for later delivery\n", prog, file_name);

  mask = umask(QUEUEMASK);
  file = fopen(file_name, "w");
  umask(mask);
  if (! file)
  {
    LogError("%s: Aborting event - cannot open the event file %s -- %s\n", prog, file_name, STRERROR);
    return;
  }

  /* write event structure version */
  if (!(rv = file_writeQueue(file, &version, sizeof(int))))
    goto error;

  /* write event structure */
  if (!(rv = file_writeQueue(file, E, sizeof(*E))))
    goto error;

  /* write source */
  if (!(rv = file_writeQueue(file, E->source, E->source ? strlen(E->source)+1 : 0)))
    goto error;

  /* write message */
  if (!(rv = file_writeQueue(file, E->message, E->message ? strlen(E->message)+1 : 0)))
    goto error;

  /* write event action */
  if (!(rv = file_writeQueue(file, &action, sizeof(short))))
    goto error;

  error:
  fclose(file);
  if (!rv) {
    LogError("%s: Aborting event - unable to update event information to %s\n",  prog, file_name);
    if (unlink(file_name) < 0)
      LogError("Failed to remove event file '%s' -- %s\n", file_name, STRERROR);
  }

  return;
}

