/*
 *      Code to convert a stream input into a dynamic array
 *      that can be parsed as argc and argv.
 *
 *      Authors: Horms <horms@vergenet.net>
 *
 *      Released under the terms of the GNU GPL
 */

#include "config_stream.h"


/**********************************************************************
 * config_stream_read
 * Read in a config file and put elements in a dynamic array
 * pre: stream: stream to read configuration from
 * return: dynamic array whose elements are the space delimited
 *         tokens read from the stream. Result is returned
 *         once a newline is reached so multiple calls
 *         will be required to read an entire stream.
 *         Everthing including and after a hash (#) on a line is 
 *         ignored
 **********************************************************************/

dynamic_array_t *config_stream_read (FILE *stream, const char *first_element){
  char token[MAX_LINE_LENGTH];
  char tail[2];
  char format[MAX_LINE_LENGTH];
  char format_whitespace[MAX_LINE_LENGTH];
  int status;
  int ntoken;
  int comment=0;
  char *s;
  int c;
  int flag;
  dynamic_array_t *a;

  extern int errno;

  if((a=dynamic_array_create((size_t)0))==NULL){
    perror("config_file_read: dynamic_array_create");
    return(NULL);
  }

  /*insert a argv[0] into the dynamic array*/
  if((a=dynamic_array_add_element(
    a, 
    (first_element!=NULL?first_element:""), 
    DESTROY_STR, 
    DUP_STR
  ))==NULL){
    perror("config_file_read: dynamic_array_add_element");
    return(NULL);
  }

  sprintf(format, "%%%d[^ \t\n\r]%%1[ \t\n\r]", MAX_LINE_LENGTH);
  sprintf(format_whitespace, "%%%d[ \t\r]%%1[\n]", MAX_LINE_LENGTH);

  ntoken=0;
  while((status=fscanf(stream, format, token, tail))!=EOF){
    if(status==0) { 
      flag=1;
      while(flag){
        c=fgetc(stream);
        switch(c){
	  case EOF:
	  case '\n':
	    return(a);
          case '\t':
          case '\r':
          case ' ':
	    break;
          default:
	    ungetc(c, stream);
	    flag=0;
        }
      }
      continue;
    }
    if(!comment && strcmp(token, "ipvsadm")){
      ntoken++;
      if((a=dynamic_array_add_element(
        a, 
        token, 
        DESTROY_STR,
        DUP_STR
      ))==NULL){
        perror("config_file_read: dynamic_array_add_element");
	dynamic_array_destroy(a, DESTROY_STR);
        return(NULL);
      }
    }
    if((s=strrchr(tail, '\n'))!=NULL){
      return(a);
    }
    if(!comment){
      comment=(strchr((s!=NULL?s:tail), '#')==NULL)?0:1;
    }
  }

  if(ntoken==0){
    dynamic_array_destroy(a, DESTROY_STR);
    return(NULL);
  }

  return(a);
}
