int
event_load_event_state_config_file (pstdout_state_t pstate,
                                    ipmi_interpret_ctx_t interpret_ctx,
                                    const char *event_state_config_file)
{
  if (event_state_config_file)
    {
      if (ipmi_interpret_load_sel_config (interpret_ctx,
                                          event_state_config_file) < 0)
        {
          if (ipmi_interpret_ctx_errnum (interpret_ctx) == IPMI_INTERPRET_ERR_SEL_CONFIG_FILE_DOES_NOT_EXIST)
            PSTDOUT_FPRINTF (pstate,
                             stderr,
                             "event state config file '%s' does not exist\n",
                             event_state_config_file);
          else if (ipmi_interpret_ctx_errnum (interpret_ctx) == IPMI_INTERPRET_ERR_SEL_CONFIG_FILE_PARSE)
            PSTDOUT_FPRINTF (pstate,
                             stderr,
                             "event state config file '%s' parse error\n",
                             event_state_config_file);
          else
            PSTDOUT_FPRINTF (pstate,
                             stderr,
                             "ipmi_interpret_load_sel_config: %s\n",
                             ipmi_interpret_ctx_errormsg (interpret_ctx));
          return (-1);
        }
    }
  else
    {
      if (ipmi_interpret_load_sel_config (interpret_ctx, NULL) < 0)
        {
          if (ipmi_interpret_ctx_errnum (interpret_ctx) == IPMI_INTERPRET_ERR_SEL_CONFIG_FILE_PARSE)
            PSTDOUT_FPRINTF (pstate,
                             stderr,
                             "event state config file parse error\n");
          else
            PSTDOUT_FPRINTF (pstate,
                             stderr,
                             "ipmi_interpret_load_sel_config: %s\n",
                             ipmi_interpret_ctx_errormsg (interpret_ctx));
          return (-1);
        }
    }
  
  return (0);
}
static int
_store_sel_record (ipmi_monitoring_ctx_t c, unsigned int sel_flags)
{
  struct ipmi_monitoring_sel_record *s = NULL;
  uint8_t sel_record[IPMI_SEL_RECORD_MAX_RECORD_LENGTH];
  int sel_record_len;
  uint16_t record_id;
  uint8_t record_type;
  int record_type_class;
  unsigned int sel_state;

  assert (c);
  assert (c->magic == IPMI_MONITORING_MAGIC);
  assert (c->sel_records);
  
  if (!(s = (struct ipmi_monitoring_sel_record *)malloc (sizeof (struct ipmi_monitoring_sel_record))))
    {
      IPMI_MONITORING_DEBUG (("malloc: %s", strerror (errno)));
      c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY;
      goto cleanup;
    }

  memset (s, '\0', sizeof (struct ipmi_monitoring_sel_record));

  if ((sel_record_len = ipmi_sel_parse_read_record (c->sel_parse_ctx,
                                                    sel_record,
                                                    IPMI_SEL_RECORD_MAX_RECORD_LENGTH)) < 0)
    {
      IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record: %s",
                              ipmi_sel_ctx_errnum (c->sel_parse_ctx)));
      _sel_parse_ctx_error_convert (c);
      goto cleanup;
    }
  
  if (ipmi_sel_parse_read_record_id (c->sel_parse_ctx,
				     NULL,
				     0,
				     &record_id) < 0)
    {
      IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_id: %s",
                              ipmi_sel_ctx_errnum (c->sel_parse_ctx)));
      _sel_parse_ctx_error_convert (c);
      goto cleanup;
    }

  if (ipmi_sel_parse_read_record_type (c->sel_parse_ctx,
				       NULL,
				       0,
				       &record_type) < 0)
    {
      IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_id: %s",
                              ipmi_sel_ctx_errnum (c->sel_parse_ctx)));
      _sel_parse_ctx_error_convert (c);
      goto cleanup;
    }

  /* IPMI Workaround
   *
   * HP DL 380 G5
   *
   * Motherboard is reporting SEL Records of record type 0x00, which
   * is not a valid record type.
   */
  if (sel_flags & IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD
      && !IPMI_SEL_RECORD_TYPE_VALID (record_type))
    record_type = IPMI_SEL_RECORD_TYPE_SYSTEM_EVENT_RECORD;

  s->record_id = record_id;
  s->record_type = record_type;

  if (ipmi_interpret_sel (c->interpret_ctx,
                          sel_record,
                          sel_record_len,
                          &sel_state) < 0)
    {
      IPMI_MONITORING_DEBUG (("ipmi_interpret_sel: %s",
                              ipmi_interpret_ctx_errormsg (c->interpret_ctx)));
      c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR;
      goto cleanup;
    }

  if (sel_state == IPMI_INTERPRET_STATE_NOMINAL)
    s->sel_state = IPMI_MONITORING_STATE_NOMINAL;
  else if (sel_state == IPMI_INTERPRET_STATE_WARNING)
    s->sel_state = IPMI_MONITORING_STATE_WARNING;
  else if (sel_state == IPMI_INTERPRET_STATE_CRITICAL)
    s->sel_state = IPMI_MONITORING_STATE_CRITICAL;
  else if (sel_state == IPMI_INTERPRET_STATE_UNKNOWN)
    s->sel_state = IPMI_MONITORING_STATE_UNKNOWN;

  record_type_class = ipmi_sel_record_type_class (record_type);

  if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD)
    {
      s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD;

      if (_ipmi_monitoring_sel_parse_system_event_record (c, s, sel_flags) < 0)
        goto cleanup;
    }
  else if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
    {
      s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD;

      if (_ipmi_monitoring_sel_parse_timestamped_oem_record (c, s) < 0)
        goto cleanup;
    }
  else if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD)
    {
      s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD;

      if (_ipmi_monitoring_sel_parse_non_timestamped_oem_record (c, s) < 0)
        goto cleanup;
    }
  else
    s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_UNKNOWN;
  

  /* achu: should come before list_append to avoid having a freed entry on the list */
  if (c->callback)
    {
      c->callback_sel_record = s;
      if ((*c->callback)(c, c->callback_data) < 0)
        {
          IPMI_MONITORING_DEBUG (("callback error"));
          c->errnum = IPMI_MONITORING_ERR_CALLBACK_ERROR;
          goto cleanup;
        }
    }

  if (!list_append (c->sel_records, s))
    {
      IPMI_MONITORING_DEBUG (("list_append: %s", strerror (errno)));
      c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR;
      goto cleanup;
    }

  return (0);

 cleanup:
  if (s)
    {
      free (s->event_offset_string);
      free (s);
    }
  return (-1);
}