#include "os.h"
#include "s_defines.h"
#include "match_ext.h"
#include "s_externs.h"

#ifdef RUSNET_IRCD
#include "rusnet_cmds_ext.h"

int m_codepage(cptr, sptr, parc, parv)
aClient *cptr;
aClient *sptr;
int     parc;
char    *parv[];
{
    int  i;

    if (parc < 2) return -1;

    for (i = 0; parv[1][i] != '\0'; i++) parv[1][i] = toupper(parv[1][i]); 
 
    rusnet_changecodepage(sptr, parv[1], parv[0]);

    return 0;    
}

int m_force(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
    aClient *acptr, *zptr;

    if (parc < 3)
	return -1;

    /* Check if parv[2] is a registered nickname */
    acptr = NULL;
    if (find_client( parv[2], acptr ) != NULL)
	return -1; /* Could not force nickchange, new nick is registered */

    /* Check if parv[1] exists and local */
    acptr = NULL;
    if ((zptr = find_client( parv[1], acptr )) == NULL)
	return -1; /* No such user */

    if (MyConnect(zptr))
    {  
	char    *pparv[] = { parv[1], parv[2], NULL };

	/* Do nick change procedure */
	return m_nick(zptr, zptr, 2, pparv);
    }
    else
    {
	/* Propagate FORCE to single server where $nick is registered */
	acptr = zptr->from;
	if (acptr != cptr)			/* Split horizon */
	  if (acptr->serv->version & SV_FORCE)	/* don't send to old servers */
		sendto_one(acptr,"FORCE %s %s", parv[1], parv[2]);
	  else
	    {
		char    *pparv[] = { parv[0], parv[1],
					get_client_name(cptr, TRUE), NULL };
		/* Do KILL procedure */
		return m_kill(zptr, zptr, 3, pparv);
	    }
    }

    return 0;
}

/*
 * parv[0] - sender
 * parv[1] - username to change mode for
 * parv[2] - modes to change
 */
int m_rmode(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
    aClient *acptr, *zptr;
    char    *s;

    if (parc < 3)
	return -1;
#if 0
    /* cut more than 4 parrameters */
    
    parv[2][4]='\0';
#endif
    /* restricted O line */

    if ( *parv[2] == '+' ) 
	for (s = (char *) parv[2] + 1; *s != '\0'; s++) 
		if (*s == 'o' || *s == 'O') 
			return -1 ;

    /* Check if parv[1] exists and local */

    acptr = NULL;

    if ((zptr = find_client(parv[1], acptr)) == NULL)
	return -1; /* No such user */

    if (MyConnect(zptr))
    {
	char    *pparv[] = { parv[1], parv[1], parv[2], NULL };

	if ( *parv[2] == '+' ) 
	    for (s = (char *) parv[2] + 1; *s != '\0'; s++) 
    		if (*s == 'h' && !IsOper(zptr)) 
    			return -1;	/* deny non-opered shadows */

	/* Do change mode procedure */
	return m_umode(&me, zptr, 3, pparv); /* internal fake call */
    }
    else
    {
      acptr = zptr->from;
      if ((acptr != cptr) &&                     /* Split horizon */
	  (acptr->serv->version & SV_RMODE))   /* don't send to old servers */
	  sendto_one(acptr,"RMODE %s %s", parv[1], parv[2]);
    }

    return 0;
}

int m_rcpage(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
    aClient *acptr, *workptr, *zptr;

    if (parc < 3)
	return -1;

    /* Check if parv[1] exists and local */

    workptr = NULL;

    if ((zptr = find_client(parv[1], workptr)) == NULL)
       return -1; /* No such user */

    if (MyConnect(zptr))
    { 
	int i;

        /* Do change codepage procedure */
	for (i = 0; parv[2][i] != '\0'; i++) parv[2][i] = toupper(parv[2][i]); 

        rusnet_changecodepage(zptr, parv[2], parv[1]);
    }
    else
    {
      acptr = zptr->from;
      if ((acptr != cptr) &&                     /* Split horizon */
	  (acptr->serv->version & SV_RMODE))   /* don't send to old servers */
	  sendto_one(acptr,"RCPAGE %s %s", parv[1], parv[2]);
    }

    return 0;
}

int m_kline(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
    aClient *acptr, *workptr, *zptr;

    /*
     * KLINE server nickmask usermask hostmask [hours|E] 
     * Wildcards in masks are allowed. No hours means forever
     * "E" instead of hours means E-line (Exempt)
     */

    if (parc < 5)
	return -1;		/* not enough parameters */

    workptr = NULL;

    if (parv[1][0] == '*') /* masks need to be broadcasted */
    {
	int i;

	for (i = fdas.highest; i >= 0; i--)
	    if ((acptr = local[fdas.fd[i]]) &&
		(acptr != cptr) && !IsMe(acptr) &&
		(acptr->serv->version & SV_KLINE))	/* skip old servers */
		sendto_one(acptr, "KLINE %s %s %s %s %s %s", parv[1], parv[2],
				parv[3], parv[4], parv[5] ? parv[5] : "",
							parv[6] ? parv[6] : "");

	if (parv[1][1])		/* mask is not just '*' but '*.ru' or so */
	{
	    char *s1, *s2;	/* only one asterisk in mask is possible */

	    for (s1 = ME + strlen(ME) - 1, s2 = parv[1] + strlen(parv[1]) - 1;
			*s2 != '*'; s1--, s2--)
		if (tolower(*s1) != tolower(*s2))
		    break;

	    if (*s2 == '*')	/* we succeed, nullify mask */
		parv[1][1] = '\0';
	}
	if (parv[1][1])	/* mask must be either '*' or match */
	    return 0;
    } else {
	    /* Check if parv[2] exists and local */
	    if ((zptr = find_server(parv[1], workptr)) == NULL)
	       return -1;		/* No such server known */

	    if (!IsMe(zptr))
	    {
		acptr = zptr->from;
		if ((acptr != cptr) &&                     /* Split horizon */
		   (acptr->serv->version & SV_KLINE))   /* skip old servers */
		   sendto_one(acptr, "KLINE %s %s %s %s %s %s", parv[1], parv[2],
				parv[3], parv[4], parv[5] ? parv[5] : "",
							parv[6] ? parv[6] : "");
		return 0;
	    }
    }

    if ((acptr = best_service("TkServ", workptr)) == NULL)
	return -1;

    if (!MyConnect(acptr))
	return -1;

    /*
     * Call for TkServ:
     * TKLINE <password> <lifetime> <user@host> <reason>
     * Nick masks should be mapped to user masks if present
     */

    sendto_one(acptr, ":%s SQUERY TkServ :TKLINE %s %s %s@%s %s",
		TK_USER, TK_PASS, parv[5] ? parv[5] : "0",
		/* we use <user> if it is NOT equal to "*", be attentional */
		(strcmp(parv[3], "*")) ? parv[3] : parv[2],
				parv[4], (parv[6]) ? parv[6] : TK_REASON);
    return 0;
}

#ifdef USE_SERVICES
/*
 * Internal method for usage with *serv commands e.g. /nickserv
 */

int m_services(cptr, sptr, nick, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *nick, *parv[];
{
    aClient *acptr;

    if (parc < 2 || *parv[1] == '\0')
    {
	sendto_one(sptr, err_str(ERR_NOTEXTTOSEND, parv[0]));
	return 1;
    }

    /* Check if nick is a registered nickname and user@host matches */
    if ((acptr = find_person(nick, NULL)) &&
	!strcasecmp(SERVICES_IDENT, acptr->user->username) &&
	!strcasecmp(SERVICES_HOST, acptr->user->host))
    {
	sendto_prefix_one(acptr, sptr, ":%s PRIVMSG %s@%s :%s",
				parv[0], nick, acptr->user->server, parv[1]);
	return 0;
    }

    sendto_one(sptr, err_str(ERR_NOSUCHSERVICE, nick),
			"Not found:", nick, "No Message Delivered");
    return 1;
}

int m_nickserv(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
	return m_services(cptr, sptr, NICKSERV_NICK, parc, parv);
}

int m_chanserv(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
	return m_services(cptr, sptr, CHANSERV_NICK, parc, parv);
}

int m_memoserv(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
	return m_services(cptr, sptr, MEMOSERV_NICK, parc, parv);
}

int m_infoserv(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
	return m_services(cptr, sptr, INFOSERV_NICK, parc, parv);
}

int m_statserv(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
	return m_services(cptr, sptr, STATSERV_NICK, parc, parv);
}

int m_operserv(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int     parc;
char    *parv[];
{
	return m_services(cptr, sptr, OPERSERV_NICK, parc, parv);
}
#endif
#endif


syntax highlighted by Code2HTML, v. 0.9.1