/*****************************************************************
 * PTlink IRCd is (C) CopyRight PTlink Coders Team 1999-2000     *
 * http://www.ptlink.net/Coders - coders@PTlink.net              *
 * This program is distributed under GNU Public License          *
 * Please read the file COPYING for copyright information.       *
 *****************************************************************
 
 File: vhost.c
 Desc: advanced vhost system into ircd core
 Author: hadman@brasillink.org
  
*/

#include "m_commands.h"
#include "client.h"
#include "common.h"
#include "ircd.h"
#include "numeric.h"
#include "s_serv.h"
#include "irc_string.h"
#include "send.h"
#include "s_conf.h"
#include "struct.h"
#include "conf_vars.h"
#include "m_svsinfo.h"

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

typedef struct vhost_ vhost;
struct vhost_ {
    vhost *next;
    char *ip;
    char *virtual;
    char *by;
};

static struct vhost_ *vhostlist = (struct vhost_ *)NULL;


char *is_vhost(char *text) {
    vhost *sp = vhostlist;

    while (sp) {
        if (match_wild_nocase(sp->ip, text)) {
            return sp->virtual;
        }
        sp = sp->next;
    }
    return (char *)NULL;
}

struct vhost_ *find_vhostrule(char *server)
{
        vhost *sp = vhostlist;

        while(sp && !match(sp->ip, server))
          sp = sp->next;

        if (!sp) {
            sp = vhostlist;
            while(sp && !match(sp->ip, server))
              sp = sp->next;
        }

        return sp;
}

int m_vhostadd(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
  {
    vhost *sp = vhostlist, *last_sp;
        if (strchr(parv[2], 160) || strchr(parv[2], ' '))
         {
         sendto_sanotice("%s tried to add a vhost out of our security rules (%s)", parv[0], parv[2]);
         return 0;
         }
        if (!match_wild("*brasmirc.org", parv[2])) 
         {
         sendto_sanotice("%s tried to add a vhost out of our security rules (%s)", parv[0], parv[2]);
         return 0;
         }
        if (!IsServer(sptr) && !IsService(sptr) && !IsRoot(sptr)) 
	  {	
		if (IsServer(cptr))
		  { 
                        ts_warn("Got vhostadd from non-service/server: %s", 
			  sptr->name);
                        sendto_one(cptr, ":%s WALLOPS :ignoring VHOSTADD from non-service/server %s",
			  me.name, sptr->name);
		}		
            if(MyClient(sptr))
              sendto_one(sptr,form_str(ERR_NOPRIVILEGES),
                  MENAME(sptr), parv[0]);
		return 0;
	  }

    if(parc<3)
        return 0;

       while (sp && (match(sp->ip, parv[1]) != 0)) {
           last_sp = sp;
           sp = sp->next;
       }

    if (!find_vhostrule(parv[1])) // nao encontrou
	{
		sp = MyMalloc(sizeof(vhost));
                DupString(sp->by, parv[0]);
                DupString(sp->ip, parv[1]);
                DupString(sp->virtual, parv[2]);

            sp->next = vhostlist;
            vhostlist = sp;

            sendto_serv_butone(cptr, ":%s VHOSTADD %s :%s", parv[0], parv[1], parv[2]);

            if (MyClient(sptr))
                sendto_sanotice("%s added vhost for '%s' (%s)", parv[0], parv[1], parv[2]);
	  }
	return 0;
  }


int m_vhostdel(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
  {
        vhost *last_sp;
	vhost *sp = vhostlist;
		
        if (!IsServer(sptr) && !IsService(sptr) && !IsRoot(sptr)) 
	  {	
		if (IsServer(cptr))
		  { 
                        ts_warn("Got VHOSTDEL from non-service/server: %s", 
			  sptr->name);
                        sendto_one(cptr, ":%s WALLOPS :ignoring VHOSTDEL from non-service/server %s",
			  me.name, sptr->name);
		}		
		return 0;
	  }

        if(parc<2)
	  return 0;

	last_sp = NULL;

	while (sp && irccmp(sp->ip, parv[1])) {
           last_sp = sp;
           sp = sp->next;
       }

       if (sp) { //achou
           if (last_sp)
               last_sp->next = sp->next;
           else
               vhostlist = sp->next;

                if (MyClient(sptr)) {
                    my_svsinfo_ts = CurrentTime;
                    sendto_sanotice("%s deleted vhost from '%s'.", parv[0], parv[1]);
                }
                sendto_serv_butone(cptr, ":%s VHOSTDEL %s", parv[0], parv[1]);
           free(sp->by);
           free(sp->ip);
           free(sp->virtual);
           free(sp);

	  }
	  
	return 0;
  }

void send_all_vhostrules(struct Client *acptr)
  {
        vhost *sp = vhostlist;
	
        while(sp)
	  {
              sendto_one(acptr, ":%s VHOSTADD %s :%s", me.name, sp->ip, sp->virtual );
              sp = sp->next;         
	  }
  }


void clear_vhostrules()
  {

    vhost *sp;
    vhost *sp2=vhostlist;

       while(sp2)
         {
               sp = sp2->next;
               free(sp2->by);
               free(sp2->ip);
	       free(sp2->virtual);
	       free(sp2);
               sp2 = sp;
               }

       vhostlist = NULL;

  }



void report_vhostrules(struct Client *sptr)
{
    vhost *sp = vhostlist;
 
    sendto_one(sptr, ":%s NOTICE %s :************* Virtual Host List *************", me.name, sptr->name);
    while (sp) {
    sendto_one(sptr, ":%s NOTICE %s :IP Range: %-20s Host: %-20s (%s)", me.name, sptr->name, sp->ip, sp->virtual, sp->by); 
    sp = sp->next;
    }
}
