static int
_legacy_simple_output_compact_record (ipmi_sensors_state_data_t *state_data,
                                      uint16_t record_id,
                                      int event_message_output_type,
                                      uint16_t sensor_event_bitmask,
                                      char **event_message_list,
                                      unsigned int event_message_list_len)
{
  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_legacy_simple_output_header (state_data, record_id) < 0)
    return (-1);

  if (ipmi_sensors_output_event_message_list (state_data,
                                              event_message_output_type,
                                              sensor_event_bitmask,
                                              event_message_list,
                                              event_message_list_len,
                                              NULL,
                                              0) < 0)
    return (-1);

  return (0);
}
int
ipmi_sensors_output_verbose_event_message_list (ipmi_sensors_state_data_t *state_data,
                                                char **event_message_list,
                                                unsigned int event_message_list_len)
{
  assert (state_data);
 
  if (ipmi_sensors_output_event_message_list (state_data,
                                              event_message_list,
                                              event_message_list_len,
                                              "Sensor Status: ",
                                              1) < 0)
    return -1;
  
  return 0;
}
static int
_ipmimonitoring_legacy_simple_output_compact_record (ipmi_sensors_state_data_t *state_data,
                                                     uint16_t record_id,
                                                     int event_message_output_type,
                                                     uint16_t sensor_event_bitmask,
                                                     char **event_message_list,
                                                     unsigned int event_message_list_len)
{
  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_ipmimonitoring_legacy_simple_output_header (state_data, record_id) < 0)
    return (-1);

  if (state_data->prog_data->args->output_sensor_state)
    {
      char *sensor_state_str = NULL;
      
      if (ipmi_sensors_get_sensor_state (state_data,
                                         event_message_output_type,
                                         sensor_event_bitmask,
                                         &sensor_state_str) < 0)
        return (-1);
      
      pstdout_printf (state_data->pstate,
                      " | %s",
                      sensor_state_str);
    }
  
  if (state_data->prog_data->args->quiet_readings)
    return (0);

  pstdout_printf (state_data->pstate,
                  " | %s | ",
                  IPMIMONITORING_NA_STRING_LEGACY);

  if (ipmi_sensors_output_event_message_list (state_data,
                                              event_message_output_type,
                                              sensor_event_bitmask,
                                              event_message_list,
                                              event_message_list_len,
                                              NULL,
                                              0) < 0)
    return (-1);

  return (0);
}
static int
_simple_output_compact_record (ipmi_sensors_state_data_t *state_data,
                               uint16_t record_id,
                               uint8_t sensor_number,
                               int event_message_output_type,
                               uint16_t sensor_event_bitmask,                              
                               char **event_message_list,
                               unsigned int event_message_list_len)
{
  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_simple_output_header (state_data,
                             record_id,
                             sensor_number,
                             event_message_output_type,
                             sensor_event_bitmask) < 0)
    return (-1);

  if (!state_data->prog_data->args->quiet_readings)
    {
      char fmt[IPMI_SENSORS_FMT_BUFLEN + 1];
  
      memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

      if (state_data->prog_data->args->comma_separated_output)
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  ",%%s,%%s");
      else
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  " | %%-10s | %%-%ds",
                  state_data->column_width.sensor_units);

      pstdout_printf (state_data->pstate,
                      fmt,
                      IPMI_SENSORS_NA_STRING,
                      IPMI_SENSORS_NA_STRING);
    }

  if (state_data->prog_data->args->output_sensor_thresholds)
    {
      if (state_data->prog_data->args->comma_separated_output)
        pstdout_printf (state_data->pstate,
                        ",%s,%s,%s,%s,%s,%s",
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING);
      else
        pstdout_printf (state_data->pstate,
                        " | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s",
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING);
    }
 
  if (state_data->prog_data->args->comma_separated_output)
    pstdout_printf (state_data->pstate, ",");
  else
    pstdout_printf (state_data->pstate, " | ");

  if (ipmi_sensors_output_event_message_list (state_data,
                                              event_message_output_type,
                                              sensor_event_bitmask,
                                              event_message_list,
                                              event_message_list_len,
                                              NULL,
                                              0) < 0)
    return (-1);

  return (0);
}
static int
_simple_output_full_record (ipmi_sensors_state_data_t *state_data,
                            uint16_t record_id,
                            uint8_t sensor_number,
                            double *sensor_reading,
                            int event_message_output_type,
                            uint16_t sensor_event_bitmask,
                            char **event_message_list,
                            unsigned int event_message_list_len)
{
  char fmt[IPMI_SENSORS_FMT_BUFLEN + 1];
  uint8_t event_reading_type_code;
  double *lower_non_critical_threshold = NULL;
  double *upper_non_critical_threshold = NULL;
  double *lower_critical_threshold = NULL;
  double *upper_critical_threshold = NULL;
  double *lower_non_recoverable_threshold = NULL;
  double *upper_non_recoverable_threshold = NULL;
  int rv = -1;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_simple_output_header (state_data,
                             record_id,
                             sensor_number,
                             event_message_output_type,
                             sensor_event_bitmask) < 0)
    goto cleanup;

  if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                              NULL,
                                              0,
                                              &event_reading_type_code) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_event_reading_type_code: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }

  switch (ipmi_event_reading_type_code_class (event_reading_type_code))
    {
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD:
      if (!state_data->prog_data->args->quiet_readings)
        {
          char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];

          memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
          if (get_sensor_units_output_string (state_data->pstate,
                                              state_data->sdr_ctx,
                                              sensor_units_buf,
                                              IPMI_SENSORS_UNITS_BUFLEN,
                                              state_data->prog_data->args->non_abbreviated_units) < 0)
            goto cleanup;

          memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

          if (sensor_reading)
            {
              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%.2f,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10.2f | %%-%ds",
                          state_data->column_width.sensor_units);
              
              pstdout_printf (state_data->pstate,
                              fmt,
                              _round_double2 (*sensor_reading),
                              sensor_units_buf);
            }
          else
            {
              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%s,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10s | %%-%ds",
                          state_data->column_width.sensor_units);
              
              pstdout_printf (state_data->pstate,
                              fmt,
                              IPMI_SENSORS_NA_STRING,
                              sensor_units_buf);
            }
        }

      if (state_data->prog_data->args->output_sensor_thresholds)
        {
          char thresholdfmt[IPMI_SENSORS_FMT_BUFLEN + 1];
          char nafmt[IPMI_SENSORS_FMT_BUFLEN + 1];

          if (ipmi_sensors_get_thresholds (state_data,
                                           &lower_non_critical_threshold,
                                           &lower_critical_threshold,
                                           &lower_non_recoverable_threshold,
                                           &upper_non_critical_threshold,
                                           &upper_critical_threshold,
                                           &upper_non_recoverable_threshold) < 0)
            goto cleanup;

          memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

          if (state_data->prog_data->args->comma_separated_output)
            {
              snprintf (thresholdfmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        ",%%.2f");

              snprintf (nafmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        ",%%s");
            }
          else
            {
              snprintf (thresholdfmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        " | %%-10.2f");

              snprintf (nafmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        " | %%-10s");
            }

          if (lower_non_recoverable_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *lower_non_recoverable_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (lower_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *lower_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (lower_non_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *lower_non_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);
                          
          if (upper_non_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *upper_non_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (upper_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *upper_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (upper_non_recoverable_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *upper_non_recoverable_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);
        }

      if (state_data->prog_data->args->comma_separated_output)
        pstdout_printf (state_data->pstate, ",");
      else
        pstdout_printf (state_data->pstate, " | ");

      if (ipmi_sensors_output_event_message_list (state_data,
                                                  event_message_output_type,
                                                  sensor_event_bitmask,
                                                  event_message_list,
                                                  event_message_list_len,
                                                  NULL,
                                                  0) < 0)
        goto cleanup;

      break;
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_OEM:
    default:
      if (!state_data->prog_data->args->quiet_readings)
        {
          if (state_data->prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_DISCRETE_READING
              && sensor_reading)
            {
              char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];

              memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
              if (get_sensor_units_output_string (state_data->pstate,
                                                  state_data->sdr_ctx,
                                                  sensor_units_buf,
                                                  IPMI_SENSORS_UNITS_BUFLEN,
                                                  state_data->prog_data->args->non_abbreviated_units) < 0)
                goto cleanup;
              
              memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%.2f,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10.2f | %%-%ds",
                          state_data->column_width.sensor_units);
                  
              pstdout_printf (state_data->pstate,
                              fmt,
                              _round_double2 (*sensor_reading),
                              sensor_units_buf);
            }
          else
            {
              memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%s,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10s | %%-%ds",
                          state_data->column_width.sensor_units);
              
              pstdout_printf (state_data->pstate,
                              fmt,
                              IPMI_SENSORS_NA_STRING,
                              IPMI_SENSORS_NA_STRING);
            }
        }

      if (state_data->prog_data->args->output_sensor_thresholds)
        {
          if (state_data->prog_data->args->comma_separated_output)
            pstdout_printf (state_data->pstate,
                            ",%s,%s,%s,%s,%s,%s",
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING);
          else
            pstdout_printf (state_data->pstate,
                            " | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s",
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING);
        }
 
      if (state_data->prog_data->args->comma_separated_output)
        pstdout_printf (state_data->pstate, ",");
      else
        pstdout_printf (state_data->pstate, " | ");
      
      if (ipmi_sensors_output_event_message_list (state_data,
                                                  event_message_output_type,
                                                  sensor_event_bitmask,
                                                  event_message_list,
                                                  event_message_list_len,
                                                  NULL,
                                                  0) < 0)
        goto cleanup;
      break;
    }

  rv = 0;
 cleanup:
  free (lower_non_critical_threshold);
  free (upper_non_critical_threshold);
  free (lower_critical_threshold);
  free (upper_critical_threshold);
  free (lower_non_recoverable_threshold);
  free (upper_non_recoverable_threshold);
  return (rv);
}
static int
_ipmimonitoring_legacy_simple_output_full_record (ipmi_sensors_state_data_t *state_data,
                                                  uint16_t record_id,
                                                  double *sensor_reading,
                                                  int event_message_output_type,
                                                  uint16_t sensor_event_bitmask,
                                                  char **event_message_list,
                                                  unsigned int event_message_list_len)
{
  int rv = -1;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_ipmimonitoring_legacy_simple_output_header (state_data, record_id) < 0)
    goto cleanup;

  if (state_data->prog_data->args->output_sensor_state)
    {
      char *sensor_state_str = NULL;
      
      if (ipmi_sensors_get_sensor_state (state_data,
                                         event_message_output_type,
                                         sensor_event_bitmask,
                                         &sensor_state_str) < 0)
        goto cleanup;
      
      pstdout_printf (state_data->pstate,
                      " | %s",
                      sensor_state_str);
    }

  if (!state_data->prog_data->args->quiet_readings)
    {
      uint8_t event_reading_type_code;

      if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                                  NULL,
                                                  0,
                                                  &event_reading_type_code) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "ipmi_sdr_parse_event_reading_type_code: %s\n",
                           ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
          goto cleanup;
        }
      
      switch (ipmi_event_reading_type_code_class (event_reading_type_code))
        {
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD:
          {
            char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];
            
            memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
            if (get_sensor_units_output_string (state_data->pstate,
                                                state_data->sdr_ctx,
                                                sensor_units_buf,
                                                IPMI_SENSORS_UNITS_BUFLEN,
                                                0) < 0)
              goto cleanup;
            
            
            if (sensor_reading)
              pstdout_printf (state_data->pstate,
                              " | %s | %f\n",
                              sensor_units_buf,
                              *sensor_reading);
            else
              pstdout_printf (state_data->pstate,
                              " | %s | %s\n",
                              sensor_units_buf,
                              IPMIMONITORING_NA_STRING_LEGACY);
          }

          break;
          
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE:
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE:
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_OEM:
        default:
          /* sensor units */
          pstdout_printf (state_data->pstate,
                          " | %s | ",
                          IPMIMONITORING_NA_STRING_LEGACY);
          
          if (ipmi_sensors_output_event_message_list (state_data,
                                                      event_message_output_type,
                                                      sensor_event_bitmask,
                                                      event_message_list,
                                                      event_message_list_len,
                                                      NULL,
                                                      0) < 0)
            goto cleanup;
          
          break;
        }
    }
  else
    pstdout_printf (state_data->pstate,
                    "\n");

  rv = 0;
 cleanup:
  return (rv);
}
static int
_legacy_simple_output_full_record (ipmi_sensors_state_data_t *state_data,
                                   uint16_t record_id,
                                   double *sensor_reading,
                                   int event_message_output_type,
                                   uint16_t sensor_event_bitmask,
                                   char **event_message_list,
                                   unsigned int event_message_list_len)
{
  uint8_t event_reading_type_code;
  double *lower_non_critical_threshold = NULL;
  double *upper_non_critical_threshold = NULL;
  double *lower_critical_threshold = NULL;
  double *upper_critical_threshold = NULL;
  double *lower_non_recoverable_threshold = NULL;
  double *upper_non_recoverable_threshold = NULL;
  int rv = -1;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_legacy_simple_output_header (state_data, record_id) < 0)
    goto cleanup;

  if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                              NULL,
                                              0,
                                              &event_reading_type_code) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_event_reading_type_code: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }

  switch (ipmi_event_reading_type_code_class (event_reading_type_code))
    {
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD:
      if (!state_data->prog_data->args->quiet_readings)
        {
          char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];
          double *lower_output_threshold = NULL;
          double *upper_output_threshold = NULL;

          memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
          if (get_sensor_units_output_string (state_data->pstate,
                                              state_data->sdr_ctx,
                                              sensor_units_buf,
                                              IPMI_SENSORS_UNITS_BUFLEN,
                                              0) < 0)
            goto cleanup;

          if (ipmi_sensors_get_thresholds (state_data,
                                           &lower_non_critical_threshold,
                                           &lower_critical_threshold,
                                           &lower_non_recoverable_threshold,
                                           &upper_non_critical_threshold,
                                           &upper_critical_threshold,
                                           &upper_non_recoverable_threshold) < 0)
            goto cleanup;

          if (sensor_reading)
            pstdout_printf (state_data->pstate,
                            "%.2f %s ",
                            _round_double2 (*sensor_reading),
                            sensor_units_buf);
          else
            pstdout_printf (state_data->pstate,
                            "%s ",
                            IPMI_SENSORS_NA_STRING_LEGACY);
          
          /* default output is critical thresholds, if those aren't
           * available, move to non-recoverable, and if those aren't
           * available, move on to non-critical.
           */
          
          if (lower_critical_threshold || upper_critical_threshold)
            {
              lower_output_threshold = lower_critical_threshold;
              upper_output_threshold = upper_critical_threshold;
            }
          else if (lower_non_recoverable_threshold || upper_non_recoverable_threshold)
            {
              lower_output_threshold = lower_non_recoverable_threshold;
              upper_output_threshold = upper_non_recoverable_threshold;
            }
          else if (lower_non_critical_threshold || upper_non_critical_threshold)
            {
              lower_output_threshold = lower_non_critical_threshold;
              upper_output_threshold = upper_non_critical_threshold;
            }
          
          if (lower_output_threshold)
            pstdout_printf (state_data->pstate,
                            "(%.2f/",
                            _round_double2 (*lower_output_threshold));
          else
            pstdout_printf (state_data->pstate, "(%s/", IPMI_SENSORS_NA_STRING_LEGACY);
          
          if (upper_output_threshold)
            pstdout_printf (state_data->pstate,
                            "%.2f): ",
                            _round_double2 (*upper_output_threshold));
          else
            pstdout_printf (state_data->pstate, "%s): ", IPMI_SENSORS_NA_STRING_LEGACY);
        }
      /* fall through and also output event messages */
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_OEM:
    default:
      if (ipmi_sensors_output_event_message_list (state_data,
                                                  event_message_output_type,
                                                  sensor_event_bitmask,
                                                  event_message_list,
                                                  event_message_list_len,
                                                  NULL,
                                                  0) < 0)
        goto cleanup;
      break;
    }

  rv = 0;
 cleanup:
  free (lower_non_critical_threshold);
  free (upper_non_critical_threshold);
  free (lower_critical_threshold);
  free (upper_critical_threshold);
  free (lower_non_recoverable_threshold);
  free (upper_non_recoverable_threshold);
  return (rv);
}