/***************************************************************************
 *   Copyright (C) 2004-2010 by Giovanni Venturi                           *
 *   giovanni@ksniffer.org                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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 General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 ***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "consts.h"
#include "parseconfig.h"

#define  APPNAME  "[sniff parse] -"

void ParseConfig::parseStandard(xmlNodePtr cur)
{
  int count = 0;

  cur = (cur->xmlChildrenNode)->next;
  if (cur != NULL)
  {
    if (!xmlStrcmp(cur->name, (const xmlChar *)"interface"))
    {
      xmlChar *attr;
      attr = xmlGetProp(cur, (const xmlChar *)"dev");
      if (attr != NULL)
      {
        sprintf(m_strInterface, "%s", attr);
        //printf( "m_strInterface: '%s'\n", m_strInterface);
        count++;
      }

      xmlFree(attr);
      attr = xmlGetProp(cur, (const xmlChar *)"capturefile");
      if (attr != NULL)
      {
        sprintf(m_strSniffFile, "%s", attr);
        //printf( "m_strSniffFile: '%s'\n", m_strSniffFile);
        count++;
      }
      xmlFree(attr);
    }
  }

  // if we found less than 2 attributes there is a syntax error in the XML file
  m_error |= (count < 2);
}


void ParseConfig::parseExtras(xmlNodePtr cur)
{
  char *snifftype;
  char *unit;
  char *quantity;
  xmlChar *attr;
  int count = 0;  // you count the found corrected attributes

  cur = (cur->xmlChildrenNode)->next;
  if (cur != NULL)
  {
    if (!xmlStrcmp(cur->name, (const xmlChar *)"capture"))
    {
      attr = xmlGetProp(cur, (const xmlChar *)"type");
      if (attr != NULL)
      {
        snifftype = (char *)malloc(sizeof(attr)*sizeof(char));
        sprintf(snifftype, "%s", attr);
        if (strcmp(snifftype, "packets") == 0)
          // packets
          m_sniffType = STOP_AFTER_X_PACKETS;
        else if (strcmp(snifftype, "size") == 0)
          // size
          m_sniffType = STOP_AFTER_X_BYTES;
        else if (strcmp(snifftype, "time") == 0)
          // time
          m_sniffType = STOP_AFTER_X_SECONDS;
        count++;
        free(snifftype);
        xmlFree(attr);
      }

      // getting unit
      attr = xmlGetProp(cur, (const xmlChar *)"unit");
      if (attr != NULL)
      {
        unit = (char *)malloc(sizeof(attr)*sizeof(char));
        sprintf(unit, "%s", attr);
        //printf( "unit: '%s'\n", unit);
        m_nUnits = atol(unit);
        count++;
        free(unit);
        xmlFree(attr);
      }

      // getting quantity
      attr = xmlGetProp(cur, (const xmlChar *)"quantity");
      if (attr != NULL)
      {
        quantity = (char *)malloc(sizeof(attr)*sizeof(char));
        sprintf(quantity, "%s", attr);
        //printf( "quantity: '%s'\n", quantity);
        m_nPackSizeTime = atol(quantity);
        count++;
        free(quantity);
        xmlFree(attr);
      }
    }
  }

  // if we found 1 or 3 attributes there is no syntax error in the XML file
  m_error |= !((count == 1) || (count == 3));
}


ParseConfig::ParseConfig(char *docname)
{
  xmlDocPtr doc;
  xmlNodePtr cur;
  int count = 0;  // count the XML items found

  m_error = false;
  doc = xmlParseFile(docname);
  if (doc == NULL )
  {
    fprintf(stderr, "%s File doesn't exist. \n", APPNAME);
    m_error = true;
    return;
  }
  cur = xmlDocGetRootElement(doc);
  if (cur == NULL)
  {
    fprintf(stderr, "%s empty document\n", APPNAME);
    xmlFreeDoc(doc);
    m_error = true;
    return;
  }
  if (xmlStrcmp(cur->name, (const xmlChar *) "options"))
  {
    fprintf(stderr, "%s document of the wrong type, root node != options", APPNAME);
    xmlFreeDoc(doc);
    m_error = true;
    return;
  }
  cur = cur->xmlChildrenNode;
  while (cur != NULL)
  {
    if (!xmlStrcmp(cur->name, (const xmlChar *)"standard"))
    {
      parseStandard(cur);
      count++;
    }
    else if (!xmlStrcmp(cur->name, (const xmlChar *)"extras"))
    {
      parseExtras(cur);
      count++;
    }
    cur = cur->next;
  }
  xmlFreeDoc(doc);
  m_error |= (count != 2);   // have to be 2 if the XML file has no syntax error
}


char *ParseConfig::interface()
{
  return m_strInterface;
}


char *ParseConfig::sniffDirectory()
{
  return m_strSniffDirectory;
}


char *ParseConfig::sniffFile()
{
  return m_strSniffFile;
}


char *ParseConfig::sniffResultFile()
{
  return m_strResultFile;
}


int ParseConfig::sniffType()
{
  return m_sniffType;
}


long ParseConfig::nPackSizeTime()
{
  return m_nPackSizeTime;
}


long ParseConfig::nUnits()
{
  return m_nUnits;
}


bool ParseConfig::error()
{
  return m_error;
}
