/*****************************************************************
 * PTlink IRCd is (C) CopyRight PTlink Coders Team 1999-2001     *
 * 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: sgline.c
 Desc: services glines (real name glines)
 Author: Lamego@PTlink.net
  
*/

#include "m_commands.h"
#include "client.h"
#include "s_user.h"
#include "s_misc.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 "sgline.h"
#include "conf_vars.h"
#include "m_svsinfo.h"

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

/* sglines storage */
aConfItem *sglines = (aConfItem *)NULL;

/*
 * m_sgline() - add info ban line
 *
 *	parv[0] = sender prefix
 *      parv[1] = mask length
 *	parv[2] = real name banned mask:reason
 */
int	m_sgline(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
  {
    aConfItem *aconf;
    char *reason = NULL;
    char *mask;
    int len;

        if (!IsSAdmin(sptr) && !IsService(sptr) && !IsServer(cptr))
	  {
                sendto_one(sptr, form_str(ERR_NOPRIVILEGES), MENAME(sptr), parv[0]);
		return 0;
	  }	  
		
	if(parc<3)
	  {
		sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
      	  me.name, parv[0], "SGLINE");
        return 0;
	  }
      
    len = atoi(parv[1]);
    mask = parv[2];
    
    if ((strlen(mask) > len) && (mask[len])==':')
      {
        mask[len] = '\0';
        reason = mask+len+1;
      } 
    else
      { /* Bogus */
          if (MyClient(sptr)) {
              sendto_one(sptr, ":%s NOTICE %s :Wrong format. use /sgline size :realname:reason",
                         me.name, parv[0]);
          }
        return 0;
      }
    
    if (!find_sgline(mask)) /* sgline does not exist */
	  {

		aconf = make_conf();
		DupString(aconf->name, mask);
		DupString(aconf->passwd, reason);
                aconf->next = sglines;
		sglines = aconf;		
//                if (MyClient(sptr)) {
//                    sendto_ops("%s!%s@%s added sgline for %s (%s)",
//                                sptr->name, sptr->username, sptr->host,
//                                mask, reason);
//                }

        sendto_serv_butone(cptr, ":%s SGLINE %d :%s:%s", sptr->name, len,
                       aconf->name,aconf->passwd);
	  }

	return 0;
  }

/*
 * m_unsgline() - remove sgline
 *
 *	parv[0] = sender prefix
 *	parv[1] = sglined name
 */
int	m_unsgline(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
  {
	aConfItem *sgl = sglines;
	aConfItem *last_sgl = NULL;
		
        if (!IsSAdmin(sptr) && !IsService(sptr) && !IsServer(cptr))
	  {
                sendto_one(sptr, form_str(ERR_NOPRIVILEGES), MENAME(sptr), parv[0]);
		return 0;
	  }	  
		
	if(parc<2)
	  {
		sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
      	  me.name, parv[0], "UNSGLINE");
        return 0;
	  }		  
	
	while(sgl && irccmp(sgl->name, parv[1]))
	  {
		last_sgl = sgl;
		sgl = sgl->next;
	  }
	  
    if (sgl) /* if sgline does exist */
	  {
		if(last_sgl) /* this is not the first sgline */
			last_sgl->next=sgl->next; /* adjust list link -> */
		  else
			sglines = sgl->next;
			
                 free_conf(sgl);
                 if (MyClient(sptr)) {
                     my_svsinfo_ts = CurrentTime;
                     sendto_ops("%s!%s@%s removed sgline for %s",
                                sptr->name, sptr->username, sptr->host,
                                parv[1]);
                 }
	    sendto_serv_butone(cptr, ":%s UNSGLINE :%s",
			parv[0], parv[1]);
	  }
          else 
              sendto_one(sptr, ":%s NOTICE %s :SGline not found.",
                         me.name, parv[0]);
          
	return 0;
  }
  

/*
 * find_sgline  - checks if the host matchs any entry on the sqline list
 * inputs       - lookup host
 * output       - return sgline entry if found or NULL if not found;
 * side effects - heading sgline will be checked and deleted if expired
 */
struct ConfItem* find_sgline(char *name)
  {
	aConfItem *sgl;

	/* First lets check if we have sglines */
	if(!sglines)
	  return NULL;
	  	  
	sgl = sglines;

    /* search for host */	
	while(sgl && irccmp(sgl->name, name))
	  sgl=sgl->next;
	  
    return sgl;	
		
  }

/*
 * is_sglined  - checks if the host matchs any entry on the sqline list
 * inputs       - lookup name
 * output       - return sgline entry if found or NULL if not found;
 * side effects - heading sgline will be checked and deleted if expired
 */
struct ConfItem* is_sglined(char *name)
  {
	aConfItem *sgl;

	/* First lets check if we have sglines */
	if(!sglines)
	  return NULL;
	  	  
	sgl = sglines;

    /* search for host */	
	while(sgl && !match(sgl->name, name))
	  sgl=sgl->next;
	  
    return sgl;	
		
  }
  
  
/* send_all_sglines
 *
 * inputs       - pointer to aClient
 * output       - none
 * Side effects - sends all sglines to the specified server
 *
 */
void send_all_sglines(struct Client *acptr)
  {
	struct ConfItem *sgl = sglines;
	
	while(sgl)
	  {	  	  	  
        sendto_one(acptr, ":%s SGLINE %d :%s:%s",
              me.name, strlen(sgl->name), sgl->name, sgl->passwd ? sgl->passwd : "");
		sgl = sgl->next;
	  }
  }
  
/*
 * report_sglines
 *
 * inputs       - pointer to client to report to
 * output       - none
 * side effects - all SG lines are listed to client 
 */
void report_sglines(struct Client *sptr)
{
  struct ConfItem *aconf;
  char *host;
  char *user;
  char *pass;
  char *name;
  int port;
  
  aconf = sglines;
  
  while(aconf)
	{
  	  get_printable_conf(aconf, &name, &host, &pass, &user, &port);
          
      sendto_one(sptr, form_str(RPL_STATSQLINE),
                   me.name, sptr->name, name, pass, "", "");
	  aconf=aconf->next;	  
    }
}

/*
 * clear_sglines
 *
 * inputs       - none
 * output       - none
 * side effects - clear the sgline list
 */
void clear_sglines(void)
  {
  
    aConfItem *aconf;
	aConfItem *sgl=sglines;
  
	while(sgl)
	  {
		aconf = sgl->next;
		free_conf(sgl);
		sgl = aconf;
		}
			  
	sglines = NULL;
	
  }
