/*****************************************************************
 * 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.       *
 *****************************************************************
 $Id: s_services.c,v 1.6 2001/01/27 01:01:44 jpinto Exp $
 
 File: m_svsadmin
 Desc: remote administration - services based
 Author: Lamego@PTlink.net
  
*/
#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 "fdlist.h" 	/* FDL_* */
#include "struct.h"
#include "s_user.h"
#include "dconf.h"   /* conf_read() */
#include "restart.h" /* server_reboots() */
#include "conf_vars.h"
#include "s_conf.h"

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


/*
** m_svsadmin - remote services administration - based on ircplus m_svsnoop - lamego
**      parv[0] = sender prefix
**      parv[2] = operation (noopers|noconn|conn|rehash|restart|die to do noservices|dielock)
*/
int	m_svsadmin(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  aClient *acptr;  
  struct ConfItem *aconf;
  char *op;
  int setflags;
  
  
  if (!IsServer(cptr) || !IsService(sptr)) 
	{	
	  if (IsServer(cptr))
		{ 
		  ts_warn("Got SVSADMIN from non-service: %s", 
			sptr->name);
		  sendto_one(cptr, ":%s WALLOPS :ignoring SVSADMIN from non-service %s",
			me.name, sptr->name);
		}
	  return 0;
	}

  if ( parc < 3) /* missing arguments */
	{
	  if(parc>1)	  
	  ts_warn("Invalid SVSADMIN (%s) from %s",
		(parc==2 ) ? parv[1]: "-", parv[0]);
  	  return 0;
	}
	
  if (hunt_server (cptr, sptr, ":%s SVSADMIN %s :%s", 1, parc, parv) != HUNTED_ISME)	
	return 0;
  
  op=strtok(parv[2]," ");
  
  while(op)
    {
      if(!irccmp(op,"noopers") )
		{
                  sendto_sanotice("Disabling O:Lines on this server");
		
		  /* remove existing opers */
  	  	  while(oper_cptr_list)
  		  	{
			  acptr = oper_cptr_list;

			  
			  /* notify user */
  		      sendto_one(acptr, ":%s NOTICE %s :Please contact your IRC Administrator",
        		  me.name, acptr->name);
			
			  /* remove all oline related permissions */
    	  	  fdlist_delete(acptr->fd, FDL_OPER | FDL_BUSY);
        	  detach_conf(acptr, acptr->confs->value.aconf);
			  
			  /* remove oper modes */
			  setflags = acptr->umodes;
			  acptr->umodes &= USER_UMODES;			  
			  
			  /* remove from oper list */
			  oper_cptr_list = acptr->next_oper_client;
			  acptr->next_oper_client = NULL;		
			  	  
			  send_umode_out(acptr, acptr, setflags);
    		}
           
		  /* disable O:lines */
  	  	  for (aconf = ConfigItemList; aconf; aconf = aconf->next)
 			{
    	    	if (aconf->status & CONF_OPERATOR || aconf->status & CONF_LOCOP)
 	  		  aconf->status = 0;
    		}
			
      } else if(!irccmp(op,"rehash"))
      {
           sendto_ops("Server Rehashing by Services request");
           ReadMessageFile( &ConfigFileEntry.opermotd );
           ReadMessageFile( &ConfigFileEntry.motd );
           ReadMessageFile( &ConfigFileEntry.wmotd );
           flush_temp_klines();
           if ((conf_read("save.dconf", 0) == -1))      /* first check for saved settings */
           {         
               if ((conf_read("main.dconf", 0) == -1) )        /* read our local settings */
               {
                   sendto_serv_butone(NULL, ":%s ERROR :Error opening main.dconf", me.name);
                   return -1;
               }  
           }
           (void) rehash (&me, &me, 2);

      } else if(!irccmp(op,"restart"))
      {
           sendto_ops("Remote server restart requested from Services");
           for(acptr = local_cptr_list; acptr; acptr = acptr->next_local_client) 
               {      
                   sendto_one(acptr,":%s NOTICE %s :Servidor sendo reiniciado para manutencao. Desculpem o transtorno.",
                              MENAME(acptr), acptr->name);
               }
           sendto_serv_butone(NULL,":%s ERROR :Server Restarting by Services request.",
                              me.name);
           server_reboot();
      } else if(!irccmp(op,"die"))
      {
           sendto_ops("Remote server die requested from Services");
      
           for(acptr = local_cptr_list; acptr; acptr = acptr->next_local_client) 
               {      
                   sendto_one(acptr,":%s NOTICE %s :Servidor sendo desligado para manutencao. Voltamos em breve.",
                              MENAME(acptr), acptr->name);
               }
           sendto_serv_butone(NULL,":%s ERROR :Server Terminating by Services request",
                              me.name);
           dump_connections(me.fd);
           exit(0);
      } else if(!irccmp(op,"htm"))
      {
              LIFESUX = 1;
              sendto_sanotice("HTM is now ON.");
              sendto_ops("Entering high-traffic mode: Forced by %s",
                         parv[0]);
              LCF = 300; /* 300s */
      } else if(!irccmp(op,"noconn")) {
           MAXCLIENTS = 10;
      } else if(!irccmp(op,"conn")) {
           MAXCLIENTS = MAX_CLIENTS;
      } else if(!irccmp(op,"ishubyes")) {
           IsHub = 1;
      } else if(!irccmp(op,"ishubno")) {
           IsHub = 0;
      }
        else
           ts_warn("Invalid SVSADMIN command (%s) from %s", op, parv[0]);

      op=strtok(NULL," "); /* check for more operations */
    }
  return 0;
}
