Esempio n. 1
0
static void
send_flow_removed_message(ft_entry_t *entry, indigo_fi_flow_removed_t reason)
{
    of_flow_removed_t *msg;
    int rv = 0;
    uint32_t secs;
    uint32_t nsecs;
    indigo_time_t current;

    current = INDIGO_CURRENT_TIME;

    /* TODO get version from OFConnectionManager */
    if ((msg = of_flow_removed_new(entry->match.version)) == NULL) {
        return;
    }

    calc_duration(current, entry->insert_time, &secs, &nsecs);

    of_flow_removed_xid_set(msg, ind_core_xid_alloc());

    of_flow_removed_cookie_set(msg, entry->cookie);
    of_flow_removed_priority_set(msg, entry->priority);
    of_flow_removed_idle_timeout_set(msg, entry->idle_timeout);

    if (msg->version >= OF_VERSION_1_1) {
        of_flow_removed_table_id_set(msg, entry->table_id);
    }

    if (msg->version >= OF_VERSION_1_2) {
        of_flow_removed_hard_timeout_set(msg, entry->hard_timeout);
    }

    if (of_flow_removed_match_set(msg, &entry->match)) {
        LOG_ERROR("Failed to set match in flow removed message");
        of_object_delete(msg);
        return;
    }

    if (reason > INDIGO_FLOW_REMOVED_DELETE) {
        /* Normalize entry */
        reason = INDIGO_FLOW_REMOVED_DELETE;
    }
    of_flow_removed_reason_set(msg, reason);
    of_flow_removed_duration_sec_set(msg, secs);
    of_flow_removed_duration_nsec_set(msg, nsecs);
    of_flow_removed_packet_count_set(msg, entry->packets);
    of_flow_removed_byte_count_set(msg, entry->bytes);

    /* @fixme hard_timeout and table_id are not in OF 1.0 */

    /* @fixme Should a cxn-id be specified? */
    rv = indigo_cxn_send_controller_message(INDIGO_CXN_ID_UNSPECIFIED, msg);
    if (rv != INDIGO_ERROR_NONE) {
        LOG_ERROR("Error sending flow removed message");
        return;
    }

    return;
}
Esempio n. 2
0
void
read_v23_status()
{
  FILE *fp;
  char buffer[MAX_CHARS_PER_LINE];
  struct status_dot_dat_entry ent;
  int i, host_stamp, service_stamp, eof;

#ifdef _DEBUG_
debug("read_v23_status()...");
debug("status file is %s",STATUS_DAT_FILE);
#endif

  /*--------------------------------------------------------*/
  mvaddstr(LINES-1-pad,pad,"reading status.dat...");
  refresh();

  /*--------------------------------------------------------*/
  if ((fp = fopen(STATUS_DAT_FILE, "r")) == NULL) {
    endwin();
    fprintf(stderr,"fatal error: fopen %s ",STATUS_DAT_FILE);
    perror("failed");
    exit(1);
  }
  line = 0;

  /*--------------------------------------------------------*/
  /* read last update */

  fgets(buffer,sizeof(buffer),fp); line++;
  while ( !feof(fp) && strcmp(buffer,"info {\n") != 0 ) {
    fgets(buffer,sizeof(buffer),fp); line++;
  }
  if ( strcmp(buffer,"info {\n") != 0 ) {
    endwin();
    printf("fatal error: %s: could not find \"info\" stanza\n", STATUS_DAT_FILE);
    exit(1);
  }
  fgets(buffer,sizeof(buffer),fp); line++;
  parse_entry(&ent,buffer);
  while ( !feof(fp) && strcmp(ent.lhs,"created") != 0 ) {
    fgets(buffer,sizeof(buffer),fp); line++;
    parse_entry(&ent,buffer);
  }
  if ( !strcmp(ent.lhs,"created") ) {
    last_update_int = atoi(ent.rhs);
    strncpy(last_update,ctime((time_t *)&last_update_int),19);
    last_update[20] = '\0';
  } else {
    endwin();
    printf("fatal error: %s: could not find \"created\" entry\n", STATUS_DAT_FILE);
    exit(1);
  }
#ifdef _DEBUG_
debug("last update is %s (%d)",last_update,last_update_int);
#endif


  /*--------------------------------------------------------*/
  num_okay = num_warn = num_crit = 0;
  host_list_size = service_list_size = 0;
  num_up = num_down = 0;

  while ( fgets(buffer,sizeof(buffer),fp) != NULL ) { 
    line++;
    parse_entry(&ent,buffer);
    if ( !strcmp(ent.lhs,"fail") ) { continue; }

    /*--------------------------------------------------------*/
    /* HOST object... */
    if ( (!strcmp("host",ent.lhs)) || (!strcmp("hoststatus",ent.lhs)) ) {

      /*--------------------*/
      /* HOST_NAME... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"host_name") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) { 
          endwin();
          printf("fatal error: %s: could not find \"host_name\" for host stanza preceeding line %d\n", 
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"host_name") ) {
        endwin();
        printf("fatal error: %s: could not find \"host_name\" for host stanza preceeding line %d\n", 
          STATUS_DAT_FILE, line);
        exit(1);
      }
      host_list[host_list_size][HOST_NAME] = malloc(strlen(ent.rhs)+1);
      strncpy(host_list[host_list_size][HOST_NAME],ent.rhs,strlen(ent.rhs)+1);
#ifdef _DEBUG_
debug("HOST NUMBER %d...", host_list_size);
debug("  host_name is \"%s\"",host_list[host_list_size][HOST_NAME]);
#endif

      /*--------------------*/
      /* STATUS... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"current_state") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) { 
          endwin();
          printf("fatal error: %s: could not find \"current_state\" for host stanza preceeding line %d\n", 
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"current_state") ) {
        endwin();
        printf("fatal error: %s: could not find \"current_state\" for host stanza preceeding line %d\n", 
          STATUS_DAT_FILE, line);
        exit(1);
      }
      switch(ent.rhs[0]) {
        case NAGIOS_HOST_UP:
          host_list[host_list_size][STATUS] = malloc(3); 
          strncpy(host_list[host_list_size][STATUS],"UP",3);
        break;
        case NAGIOS_HOST_DOWN:
          host_list[host_list_size][STATUS] = malloc(5);
          strncpy(host_list[host_list_size][STATUS],"DOWN",5);
        break;
      }
#ifdef _DEBUG_
debug("  current_state is %s", host_list[host_list_size][STATUS]);
#endif

      /*--------------------*/
      /* PLUGIN_OUTPUT... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"plugin_output") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) { 
          endwin();
          printf("fatal error: %s: could not find \"plugin_output\" for host stanza preceeding line %d\n", 
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"plugin_output") ) {
        endwin();
        printf("fatal error: %s: could not find \"plugin_output\" for host stanza preceeding line %d\n", 
          STATUS_DAT_FILE, line);
        exit(1);
      }
      host_list[host_list_size][PLUGIN_OUTPUT] = malloc(strlen(ent.rhs)+1);
      strncpy(host_list[host_list_size][PLUGIN_OUTPUT],ent.rhs,strlen(ent.rhs)+1);
      perl_hook(HOST_PLUGIN_HOOK,host_list[host_list_size][PLUGIN_OUTPUT]);
#ifdef _DEBUG_
debug("  raw plugin_output is \"%s\"",ent.rhs);
debug("  munged plugin_output is \"%s\"",host_list[host_list_size][PLUGIN_OUTPUT]);
#endif

      /*--------------------*/
      /* LAST_STATE_CHANGE... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"last_state_change") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) { 
          endwin();
          printf("fatal error: %s: could not find \"last_state_change\" for host stanza preceeding line %d\n", 
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"last_state_change") ) {
        endwin();
        printf("fatal error: %s: could not find \"last_state_change\" for host stanza preceeding line %d\n", 
          STATUS_DAT_FILE, line);
        exit(1);
      }
      sscanf(ent.rhs,"%d",&host_stamp);
      if ( (host_stamp == 0) && (host_list[host_list_size][PLUGIN_OUTPUT][0] == '\0') ) {
#ifdef _DEBUG_
debug("  current_state is PENDING, inferred from empty plugin output on Jan 1 1970");
#endif
        /* PENDING... is really UP with NULL plugin output on Jan 1 1970... */
        free(host_list[host_list_size][STATUS]);
        host_list[host_list_size][STATUS] = malloc(8);
        strncpy(host_list[host_list_size][STATUS],"PENDING",8);
        free(host_list[host_list_size][PLUGIN_OUTPUT]);
        host_list[host_list_size][PLUGIN_OUTPUT] = malloc(25);
        strncpy(host_list[host_list_size][PLUGIN_OUTPUT],"(Host assumed to be up)",25);
        perl_hook(HOST_PLUGIN_HOOK,host_list[host_list_size][PLUGIN_OUTPUT]);
        host_stamp = last_update_int;
        host_list[host_list_size][LAST_STATE_CHANGE_INT] = (char *)(last_update_int);
        host_list[host_list_size][LAST_STATE_CHANGE] = malloc(17); 
        strncpy(host_list[host_list_size][LAST_STATE_CHANGE]," not applicable ",16);
      } else { 
        host_list[host_list_size][LAST_STATE_CHANGE_INT] = (char *)host_stamp;
        host_list[host_list_size][LAST_STATE_CHANGE] = malloc(17); /* "DOW Mon DD HH:MM\0" */
        strncpy(host_list[host_list_size][LAST_STATE_CHANGE],ctime((time_t *)&host_stamp),16);
      }
      host_list[host_list_size][LAST_STATE_CHANGE][16] = '\0';
#ifdef _DEBUG_
debug("  last_state_change is \"%s\" (%d)",
  host_list[host_list_size][LAST_STATE_CHANGE],
  (int)host_list[host_list_size][LAST_STATE_CHANGE_INT]);
#endif

      /*--------------------*/
      /* DURATION... */
      host_list[host_list_size][DURATION] = (char *)calc_duration(host_stamp);
#ifdef _DEBUG_
debug("  duration is \"%s\"",host_list[host_list_size][DURATION]);
#endif
 
      /*--------------------*/
      /* Other stuff... */
      host_idx_to_level[host_list_size] = convert_level(host_list[host_list_size][STATUS]);
      switch(host_idx_to_level[host_list_size]) {
        case UP: num_up++;     break;
        case DOWN: num_down++; break;
      }
#if 0
      debug("HOST idx=%d: NAME=%s STATUS=%s LAST_CHANGE=%s",
        host_list_size,
        host_list[host_list_size][HOST_NAME],
        host_list[host_list_size][STATUS],
        host_list[host_list_size][LAST_STATE_CHANGE]
      );
#endif
      host_list_size++;
      if ( host_list_size > MAX_ITEMS ) {
        endwin();
        printf("fatal error: too many hosts!\n");  
        printf("increase MAX_ITEMS in cnagios.h\n");
        exit(1);
      }
      continue;

    }

    /*--------------------------------------------------------*/
    /* SERVICE object... */
    if ( (!strcmp("service",ent.lhs)) || (!strcmp("servicestatus",ent.lhs)) ) {

      /*--------------------*/
      /* HOST_NAME... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"host_name") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) {
          endwin();
          printf("fatal error: %s: could not find \"host_name\" for service stanza preceeding line %d\n",
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"host_name") ) {
        endwin();
        printf("fatal error: %s: could not find \"host_name\" for service stanza preceeding line %d\n",
          STATUS_DAT_FILE, line);
        exit(1);
      }
      service_list[service_list_size][HOST_NAME] = malloc(strlen(ent.rhs)+1);
      strncpy(service_list[service_list_size][HOST_NAME],ent.rhs,strlen(ent.rhs)+1);
#ifdef _DEBUG_
debug("SERVICE NUMBER %d...",service_list_size);
debug("  host_name is \"%s\"",service_list[service_list_size][HOST_NAME]);
#endif

      /*--------------------*/
      /* SERVICE_NAME... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"service_description") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) {
          endwin();
          printf("fatal error: %s: could not find \"service_description\" for service stanza preceeding line %d\n",
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"service_description") ) {
        endwin();
        printf("fatal error: %s: could not find \"service_description\" for service stanza preceeding line %d\n",
          STATUS_DAT_FILE, line);
        exit(1);
      }
      service_list[service_list_size][SERVICE_NAME] =
        malloc(strlen(ent.rhs)+1+strlen(service_list[service_list_size][HOST_NAME])+1);
      snprintf(service_list[service_list_size][SERVICE_NAME],(strlen(ent.rhs)+1+strlen(service_list[service_list_size][HOST_NAME])+1),"%s %s ",
        service_list[service_list_size][HOST_NAME],ent.rhs);
      perl_hook(SERVICE_PLUGIN_HOOK,service_list[service_list_size][SERVICE_NAME]);
#ifdef _DEBUG_
debug("  raw service_description is \"%s\"",ent.rhs);
debug("  munged service_description is \"%s\"",service_list[service_list_size][SERVICE_NAME]);
#endif

      /*--------------------*/
      /* STATUS... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"current_state") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) {
          endwin();
          printf("fatal error: %s: could not find \"current_state\" for service stanza preceeding line %d\n",
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"current_state") ) {
        endwin();
        printf("fatal error: %s: could not find \"current_state\" for service stanza preceeding line %d\n",
          STATUS_DAT_FILE, line);
        exit(1);
      }
      switch(ent.rhs[0]) {
        case NAGIOS_STATE_OK:
          service_list[service_list_size][STATUS] = malloc(5);
          strncpy(service_list[service_list_size][STATUS],"OKAY",5);
        break;
        case NAGIOS_STATE_WARNING:
          service_list[service_list_size][STATUS] = malloc(8);
          strncpy(service_list[service_list_size][STATUS],"WARNING",8);
        break;
        case NAGIOS_STATE_CRITICAL:
          service_list[service_list_size][STATUS] = malloc(9);
          strncpy(service_list[service_list_size][STATUS],"CRITICAL",9);
        break;
        case NAGIOS_STATE_UNKNOWN:
          service_list[service_list_size][STATUS] = malloc(8);
          strncpy(service_list[service_list_size][STATUS],"UNKNOWN",8);
        break;
      }
#ifdef _DEBUG_
debug("  current_state is %s",service_list[service_list_size][STATUS]);
#endif

      /*--------------------*/
      /* LAST_STATE_CHANGE... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"last_state_change") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) {
          endwin();
          printf("fatal error: %s: could not find \"last_state_change\" for service stanza preceeding line %d\n",
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"last_state_change") ) {
        endwin();
        printf("fatal error: %s: could not find \"last_state_change\" for service stanza preceeding line %d\n",
          STATUS_DAT_FILE, line);
        exit(1);
      }

      sscanf(ent.rhs,"%d",&service_stamp);
      service_list[service_list_size][LAST_STATE_CHANGE_INT] = (char *)service_stamp;
      service_list[service_list_size][LAST_STATE_CHANGE] = malloc(17); /* "DOW Mon DD HH:MM\0" */
      strncpy(service_list[service_list_size][LAST_STATE_CHANGE],ctime((time_t *)&service_stamp),16);
      service_list[service_list_size][LAST_STATE_CHANGE][16] = '\0';
#ifdef _DEBUG_
debug("  last_state_change is \"%s\" (%d)",
  service_list[service_list_size][LAST_STATE_CHANGE],
  (int)service_list[service_list_size][LAST_STATE_CHANGE_INT]);
#endif

      /*--------------------*/
      /* DURATION... */
      service_list[service_list_size][DURATION] = (char *)calc_duration(service_stamp);
#ifdef _DEBUG_
debug("  duration is \"%s\"",service_list[service_list_size][DURATION]);
#endif

      /*--------------------*/
      /* PLUGIN_OUTPUT... */
      fgets(buffer,sizeof(buffer),fp); line++;
      parse_entry(&ent,buffer);
      while ( !feof(fp) && strcmp(ent.lhs,"plugin_output") != 0 ) {
        fgets(buffer,sizeof(buffer),fp); line++;
        parse_entry(&ent,buffer);
        if ( !strcmp(ent.lhs,"fail") ) {
          endwin();
          printf("fatal error: %s: could not find \"plugin_output\" for service stanza preceeding line %d\n",
            STATUS_DAT_FILE, line);
          exit(1);
        }
      }
      if ( strcmp(ent.lhs,"plugin_output") ) {
        endwin();
        printf("fatal error: %s: could not find \"plugin_output\" for service stanza preceeding line %d\n",
          STATUS_DAT_FILE, line);
        exit(1);
      }
      service_list[service_list_size][PLUGIN_OUTPUT] = malloc(strlen(ent.rhs)+1);
      strncpy(service_list[service_list_size][PLUGIN_OUTPUT],ent.rhs,strlen(ent.rhs)+1);
      perl_hook(SERVICE_PLUGIN_HOOK,service_list[service_list_size][PLUGIN_OUTPUT]);
#ifdef _DEBUG_
debug("  raw plugin_output is \"%s\"",ent.rhs);
debug("  munged plugin_output is \"%s\"",service_list[service_list_size][PLUGIN_OUTPUT]);
#endif
      /* PENDING is really OKAY w/ "(Service assumed to be ok)" on Jan 1 1970... */
      if ( (service_stamp == 0) && (!strcmp("(Service assumed to be ok)",ent.rhs)) ) {
#ifdef _DEBUG_
debug("  current_state is PENDING, inferred from \"(Service assumed to be ok)\" on Jan 1 1970");
#endif
        free(service_list[service_list_size][STATUS]);
        service_list[service_list_size][STATUS] = malloc(8);
        strncpy(service_list[service_list_size][STATUS],"PENDING",8);
        service_stamp = last_update_int;
        service_list[service_list_size][LAST_STATE_CHANGE_INT] = (char *)service_stamp;
        service_list[service_list_size][LAST_STATE_CHANGE] = malloc(17); /* "DOW Mon DD HH:MM\0" */
        strncpy(service_list[service_list_size][LAST_STATE_CHANGE]," not applicable ",17);
        service_list[service_list_size][DURATION] = (char *)calc_duration(service_stamp);
      }

      /*--------------------*/
      /* Other stuff... */
      service_idx_to_level[service_list_size] = 
         convert_level(service_list[service_list_size][STATUS]);
      switch(service_idx_to_level[service_list_size]) {
        case 0: num_okay++;  break;
        case 1: num_warn++;  break;
        case 2: num_crit++;  break;
      }
#if 0
      debug("SERVICE idx=%d: NAME=%s SERVICE=%s STATUS=%s LAST_CHANGE=%s",
        service_list_size,
        service_list[service_list_size][HOST_NAME],
        service_list[service_list_size][SERVICE_NAME],
        service_list[service_list_size][STATUS],
        service_list[service_list_size][LAST_STATE_CHANGE]
      );
#endif
      service_list_size++;
      if ( service_list_size > MAX_ITEMS ) { 
        endwin();
        printf("fatal error: too many services!\n");
        printf("increase MAX_ITEMS in cnagios.h\n");
        exit(1);
      }
      continue;

    }

  }

  /*--------------------------------------------------------*/

  fclose(fp);

#if _DEBUG_
  debug("done with read_v23_status()");
#endif

}
Esempio n. 3
0
void
read_v1_status()
{
  FILE *fp;
  int i, k;
  int line_num;
  int stamp;
  char buffer[MAX_CHARS_PER_LINE];
  char *str_match; 
  char entry_type[MAX_STATUS_TYPE_LEN];

#if _DEBUG_
debug("read_v1_status()...");
debug("status file is %s",STATUS_FILE);
#endif

  /*--------------------------------------------------------*/
  mvaddstr(LINES-1-pad,pad,"reading status.log...");
  refresh();

  /*--------------------------------------------------------*/
  if ((fp = fopen(STATUS_FILE, "r")) == NULL) {
    endwin();
    fprintf(stderr,"fatal error: fopen %s ",STATUS_FILE);
    perror("failed");
    exit(1);
  }

  /*--------------------------------------------------------*/
  /* ignore "Nagios 1.x Status File" line... */
  fgets(buffer,sizeof(buffer),fp);

  /*--------------------------------------------------------*/
  /* last update from PROGRAM line... */
  fgets(buffer,sizeof(buffer),fp);
  if ( sscanf(buffer,"[%d]",&last_update_int) != 1 ) {
    endwin();
    printf("fatal error: could not parse last update from 2nd line of %s\n",
      STATUS_FILE);
    exit(1);
  }
  strncpy(last_update,ctime((time_t *)&last_update_int),20);
  last_update[21] = '\0';

  /*--------------------------------------------------------*/
  num_okay = num_warn = num_crit = 0;
  host_list_size = service_list_size = 0;
  num_up = num_down = 0;
  for ( i=0, line_num=1; fgets(buffer,sizeof(buffer),fp) != NULL; i++, line_num++ ) {

    if ( (str_match = (char *)strtok(buffer,";")) == NULL ) {
      endwin();
      fprintf(stderr,"warning: ignoring %s line %d: could not parse entry\r\n",
        STATUS_FILE,line_num);
      refresh();
      continue;
    }

    if ( sscanf(str_match,"[%ld] %s",&stamp,entry_type) != 2 ) {
      endwin();
      fprintf(stderr,"warning: ignoring %s line %d: could not parse entry\r\n",
        STATUS_FILE,line_num);
      refresh();
      continue;
    }
    host_list[i][LAST_UPDATE] = (char *)stamp;

    if (strcmp(entry_type,"HOST") == 0) {
      /*--------------------------------------------------------*/
      /* host objects... */
      for ( k=1; k < NUM_HOST_ENTRY_ATTRS+1; k++ ) {
        if ( (str_match = (char *)strtok(NULL,";")) == NULL ) {
          endwin();
          fprintf(stderr,"warning: ignoring %s line %d: could not parse entry\r\n",
            STATUS_FILE,line_num);
          refresh();
          continue;
        }
        switch(k) {
          case 1:
            host_list[host_list_size][HOST_NAME] = malloc(strlen(str_match)+1);
            strncpy(host_list[host_list_size][HOST_NAME],str_match,strlen(str_match)+1);
          break;
          case 2:
            host_list[host_list_size][STATUS] = malloc(strlen(str_match)+1);
            strncpy(host_list[host_list_size][STATUS],str_match,strlen(str_match)+1);
          break;
          case 4:
            if (strcmp(host_list[host_list_size][STATUS],"PENDING") == 0) {
              host_list[host_list_size][LAST_STATE_CHANGE_INT] = (char *)(last_update_int + 1);
              host_list[host_list_size][LAST_STATE_CHANGE] = malloc(17); /* "DOW Mon DD HH:MM\0" */
              strncpy(host_list[host_list_size][LAST_STATE_CHANGE]," not applicable ",strlen(str_match)+1);
              host_list[host_list_size][DURATION] = (char *)calc_duration(stamp);
            } else {
              sscanf(str_match,"%d",&stamp);
              host_list[host_list_size][LAST_STATE_CHANGE_INT] = (char *)stamp;
              host_list[host_list_size][LAST_STATE_CHANGE] = malloc(17); /* "DOW Mon DD HH:MM\0" */
              strncpy(host_list[host_list_size][LAST_STATE_CHANGE],ctime((time_t *)&stamp),16);
              host_list[host_list_size][DURATION] = (char *)calc_duration(stamp);
            }
          break;
          case 20:
            host_list[host_list_size][PLUGIN_OUTPUT] = malloc(strlen(str_match)+1);
            strncpy(host_list[host_list_size][PLUGIN_OUTPUT],str_match,strlen(str_match)+1);
            host_list[host_list_size][PLUGIN_OUTPUT][strlen(str_match)-1] = '\0'; /* nix \n */
            perl_hook(HOST_PLUGIN_HOOK,host_list[host_list_size][PLUGIN_OUTPUT]);
          break;
        }
      }
      host_idx_to_level[host_list_size] = convert_level(host_list[host_list_size][STATUS]);
      switch(host_idx_to_level[host_list_size]) {
        case UP: num_up++;     break;
        case DOWN: num_down++; break;
      }
#if _DEBUG_
      debug("READ HOST: idx=%d -> NAME=%s STATUS=%s LAST_CHANGE=%s",
        host_list_size,
        host_list[host_list_size][HOST_NAME],
        host_list[host_list_size][STATUS],
        host_list[host_list_size][LAST_STATE_CHANGE]
      );
#endif
      host_list_size++;
      /* end of host entries */

    } else if (strcmp(entry_type,"SERVICE") == 0) {
      /*--------------------------------------------------------*/
      /* service objects... */
      for ( k=1; k < NUM_SERVICE_ENTRY_ATTRS+1; k++ ) {
        if ( (str_match = (char *)strtok(NULL,";")) == NULL ) {
          endwin();
          fprintf(stderr,"warning: ignoring %s line %d: could not parse entry\r\n",
            STATUS_FILE,line_num);
          refresh();
          continue;
        }
        switch(k) {
          case 1: 
            service_list[service_list_size][HOST_NAME] = malloc(strlen(str_match)+1);
            strncpy(service_list[service_list_size][HOST_NAME],str_match,strlen(str_match)+1);
          break;
          case 2:
            service_list[service_list_size][SERVICE_NAME] = 
              malloc(strlen(str_match)+1+strlen(service_list[service_list_size][HOST_NAME])+3);
            snprintf(service_list[service_list_size][SERVICE_NAME],strlen(str_match)+1+strlen(service_list[service_list_size][HOST_NAME])+3,"%s %s ",
              service_list[service_list_size][HOST_NAME],str_match);
            perl_hook(SERVICE_PLUGIN_HOOK,service_list[service_list_size][SERVICE_NAME]);
          break;
          case 3:
            if (strcmp(str_match,"OK") == 0) { 
              service_list[service_list_size][STATUS] = malloc(5);
              strncpy(service_list[service_list_size][STATUS],"OKAY",5);
            } else {
              service_list[service_list_size][STATUS] = malloc(strlen(str_match)+1);
              strncpy(service_list[service_list_size][STATUS],str_match,strlen(str_match)+1);
            }
          break;
          case 12:
            service_list[service_list_size][LAST_STATE_CHANGE] = malloc(17); 
            if (strcmp(service_list[service_list_size][STATUS],"PENDING") == 0) { 
              service_list[service_list_size][LAST_STATE_CHANGE_INT] = (char *)(last_update_int + 1);
              strncpy(service_list[service_list_size][LAST_STATE_CHANGE]," not applicable ",strlen(str_match)+1);
              service_list[service_list_size][DURATION] = malloc(1);
              service_list[service_list_size][DURATION] = (char *)calc_duration(stamp);
            } else {
              sscanf(str_match,"%d",&stamp);
              service_list[service_list_size][LAST_STATE_CHANGE_INT] = (char *)stamp;
              strncpy(service_list[service_list_size][LAST_STATE_CHANGE],ctime((time_t *)&stamp),16);
              service_list[service_list_size][DURATION] = (char *)calc_duration(stamp);
            }
          break;
          case 31:
            service_list[service_list_size][PLUGIN_OUTPUT] = malloc(strlen(str_match)+1);
            strncpy(service_list[service_list_size][PLUGIN_OUTPUT],str_match,strlen(str_match)+1);
            service_list[service_list_size][PLUGIN_OUTPUT][strlen(str_match)-1] = '\0'; 
            perl_hook(SERVICE_PLUGIN_HOOK,service_list[service_list_size][PLUGIN_OUTPUT]);
          break;
        }
      }
      service_idx_to_level[service_list_size] = 
         convert_level(service_list[service_list_size][STATUS]);
      switch(service_idx_to_level[service_list_size]) {
        case 0: num_okay++;  break;
        case 1: num_warn++;  break;
        case 2: num_crit++;  break;
      }
#if _DEBUG_
      debug("READ SERVICE: idx=%d -> NAME=%s SERVICE=%s STATUS=%s LAST_CHANGE=%s",
        service_list_size,
        service_list[service_list_size][HOST_NAME],
        service_list[service_list_size][SERVICE_NAME],
        service_list[service_list_size][STATUS],
        service_list[service_list_size][LAST_STATE_CHANGE]
      );
#endif
      service_list_size++;
      /* end of service entries */
    } else {
      /*--------------------------------------------------------*/
      /* there are no known unknown entries */
    }
  }
  fclose(fp);

#if _DEBUG_
  debug("done with read_v1_status()");
#endif


}