///
/// Load the values from xml data.
/// Copied and modified from mime_manager.cpp
/// Only returns 0.
//  TODO: Change to use libxml2 or XmlParser more "proper"
//
int MIMEtypeXML::load_core(XmlParser & parser)
{
   int extNumber = 0;

   clear();

   xmlDocPtr doc = parser.getDoc();
   xmlNodePtr node=doc->children->children;
   for(;node;node=node->next )
     {
	if(xmlStrcmp(node->name, (const xmlChar *)"MIMETYPE"))
	  continue;
	xmlNodePtr lcur=node->children;
	while(lcur)
	  {
	     if(!xmlStrcmp(lcur->name, (const xmlChar *)"EXT"))
	       {
		  if(lcur->children->content)
		    extNumber = addExt((char*)lcur->children->content);
#ifdef DEBUG
		  printf("EXT: %s, No: %d\n", (char*)lcur->children->content, extNumber);
#endif
	       }
	     else if(!xmlStrcmp(lcur->name, (const xmlChar *)"MIME"))
	       {
		  if(lcur->children->content)
		    setType(extNumber, addMime((char*)lcur->children->content));
#ifdef DEBUG
		  printf("MIME: %s, No: %d, Result: %s, %d\n", (char*)lcur->children->content, extNumber, Mime.at(getType(extNumber))->Text, getType(extNumber));
#endif
	       }
	     else if(!xmlStrcmp(lcur->name, (const xmlChar *)"CMD"))
	       {
		  if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"SEND"))
		    setCmd(extNumber, CMD_SEND);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"RUNCGI"))
		    setCmd(extNumber, CMD_RUNCGI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"RUNMSCGI"))
		    setCmd(extNumber, CMD_RUNMSCGI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"EXECUTE"))
		    setCmd(extNumber, CMD_EXECUTE);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"RUNISAPI"))
		    setCmd(extNumber, CMD_RUNISAPI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"EXECUTEISAPI"))
		    setCmd(extNumber, CMD_EXECUTEISAPI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"SENDLINK"))
		    setCmd(extNumber, CMD_SENDLINK);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"EXECUTEWINCGI"))
		    setCmd(extNumber, CMD_EXECUTEWINCGI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"RUNFASTCGI"))
		    setCmd(extNumber, CMD_RUNFASTCGI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"EXECUTEFASTCGI"))
		    setCmd(extNumber, CMD_EXECUTEFASTCGI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"RUNSCGI"))
		    setCmd(extNumber, CMD_RUNSCGI);
		  else if(!xmlStrcmp(lcur->children->content,(const xmlChar *)"EXECUTESCGI"))
		    setCmd(extNumber, CMD_EXECUTESCGI);

#ifdef DEBUG
		  printf("CMD: %s, No: %d, Result: %d\n", (char*)lcur->children->content, extNumber, getCmd(extNumber));
#endif
	       }
	     else if(!xmlStrcmp(lcur->name, (const xmlChar *)"MANAGER"))
	       {
		  if(lcur->children->content)
		    {
		       if(strcmpi((char*)lcur->children->content,"NONE") == 0)
			 setManager(extNumber, NONE);
		       else
			 setManager(extNumber, (char*)lcur->children->content);
#ifdef DEBUG
		       printf("MANAGER: %s, No: %d, Result: %s\n", (char*)lcur->children->content, extNumber, getManager(extNumber));
#endif
		    }
	       }
	     lcur=lcur->next;
	  }
	// while(lcur)
     }
   // for(;node;node=node->next )
   Mime.sort();

   return 0;
}
/*!
  Load the virtual hosts from a XML configuration file
  Returns non-null on errors.
  \param filename The XML file to open.
 */
int XmlVhostHandler::load (const char *filename)
{
  XmlParser parser;
  xmlDocPtr doc;
  xmlNodePtr node;
  if (parser.open (filename))
    {
      Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                                         _("Error opening %s"), filename);
      return -1;
    }
  doc = parser.getDoc ();
  node = doc->children->children;

  for (; node; node = node->next )
    {
      xmlNodePtr lcur;
      Vhost *vh;
      if (xmlStrcmp (node->name, (const xmlChar *) "VHOST"))
        continue;
      lcur = node->children;
      vh = new Vhost (logManager);
      SslContext* sslContext = vh->getVhostSSLContext ();

      while (lcur)
        {
          XmlConf::build (lcur, vh->getHashedDataTrees (),
                          vh->getHashedData ());

          if (!xmlStrcmp (lcur->name, (const xmlChar *) "HOST"))
            {
              int useRegex = 0;
              for (xmlAttr *attrs = lcur->properties; attrs; attrs = attrs->next)
                {
                  if (!xmlStrcmp (attrs->name, (const xmlChar *) "isRegex")
                      && attrs->children && attrs->children->content
                      && (!xmlStrcmp (attrs->children->content,
                                     (const xmlChar *) "YES")))
                        useRegex = 1;
                }

              vh->addHost ((const char *)lcur->children->content, useRegex);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "NAME"))
            {
              vh->setName ((char *) lcur->children->content);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "LOCATION"))
            {
              string loc;

              for (xmlAttr *attrs = lcur->properties; attrs; attrs = attrs->next)
                if (!xmlStrcmp (attrs->name, (const xmlChar *) "path"))
                  loc = ((const char *) attrs->children->content);

              MimeRecord *record = XmlMimeHandler::readRecord (lcur);
              MimeRecord *prev = vh->addLocationMime (loc, record);
              if (prev)
                {
                  Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                     _("The location `%s' is registered multiple times"),
                                               loc.c_str ());

                  delete prev;
                }

              vh->getLocationsMime ()->put (loc, record);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "SSL_PRIVATEKEY"))
            {
              string pk ((char *) lcur->children->content);
              sslContext->setPrivateKeyFile (pk);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "SSL_CERTIFICATE"))
            {
              string certificate ((char *) lcur->children->content);
              sslContext->setCertificateFile (certificate);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "CONNECTIONS_PRIORITY"))
            {
              vh->setDefaultPriority (atoi ((const char *)lcur->children->content));
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "SSL_PASSWORD"))
            {
              string pw ((char *) lcur->children->content);
              sslContext->setPassword (pw);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "IP"))
            {
              int useRegex = 0;
              xmlAttr *attrs = lcur->properties;

              while (attrs)
                {
                  if (!xmlStrcmp (attrs->name, (const xmlChar *) "isRegex")
                      && !xmlStrcmp (attrs->children->content,
                                     (const xmlChar *) "YES"))
                    useRegex = 1;

                  attrs = attrs->next;
                }

              vh->addIP ((char *) lcur->children->content, useRegex);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "PORT"))
            {
              int val = atoi ((char *) lcur->children->content);
              if (val > (1 << 16) || val <= 0)
                Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                      _("An invalid port was specified: %s"),
                                             lcur->children->content);
              vh->setPort ((u_short)val);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "PROTOCOL"))
            {
              char* lastChar = (char *) lcur->children->content;
              while (*lastChar != '\0')
                {
                  *lastChar = tolower (*lastChar);
                  lastChar++;
                }
              vh->setProtocolName ((char *) lcur->children->content);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "DOCROOT"))
            {
              char* lastChar = (char *) lcur->children->content;
              while (*(lastChar+1) != '\0')
                lastChar++;

              if (*lastChar == '\\' || *lastChar == '/')
                *lastChar = '\0';

              vh->setDocumentRoot ((const char *)lcur->children->content);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "SYSROOT"))
            {
              char* lastChar = (char *) lcur->children->content;

              while (*(lastChar+1) != '\0')
                lastChar++;

              if (*lastChar == '\\' || *lastChar == '/')
                *lastChar = '\0';

              vh->setSystemRoot ((const char *)lcur->children->content);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "CACHEROOT"))
            {
              char* lastChar = (char *) lcur->children->content;

              while (*(lastChar+1) != '\0')
                lastChar++;

              if (*lastChar == '\\' || *lastChar == '/')
                *lastChar = '\0';

              vh->setCacheRoot ((const char *)lcur->children->content);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "ACCESSLOG"))
            {
              loadXMLlogData ("ACCESSLOG", vh, lcur);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "WARNINGLOG"))
            {
              loadXMLlogData ("WARNINGLOG", vh, lcur);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "MIME_FILE"))
            {
              string hnd ("xml");
              for (xmlAttr *attrs = lcur->properties; attrs; attrs = attrs->next)
                {
                  if (!xmlStrcmp (attrs->name, (const xmlChar *) "name")
                      && attrs->children && attrs->children->content)
                    hnd.assign((const char *) attrs->children->content);
                }

              const char *filename = (const char *) lcur->children->content;
              MimeManagerHandler *handler =
                Server::getInstance ()->getMimeManager ()->buildHandler (hnd);

              try
                {
                  handler->load (filename);
                }
              catch (...)
                {
                  delete handler;
                  handler = NULL;
                  Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                                         _("Error loading mime types file: %s"),
                                               filename);

                }
              vh->setMimeHandler (handler);
            }
          else if (!xmlStrcmp (lcur->name, (const xmlChar *) "THROTTLING_RATE"))
            {
              u_long rate = (u_long)atoi ((char *) lcur->children->content);
              vh->setThrottlingRate (rate);
            }

          lcur = lcur->next;
        }/* while (lcur)  */

      if (vh->openLogFiles ())
        {
          Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                                             _("Error opening log files"));
          delete vh;
          vh = 0;
          continue;
        }

      if (vh->initializeSSL () < 0)
        {
          Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                                             _("Error initializing SSL for %s"),
                                             vh->getName ());
          delete vh;
          vh = 0;
          continue;
        }

      if (addVHost (vh))
        {
          Server::getInstance ()->log (MYSERVER_LOG_MSG_ERROR,
                                             _("Internal error"));
          delete vh;
          vh = 0;
          continue;
        }
    }
  parser.close ();

  changeLocationsOwner ();

  return 0;
}