/*
 * =================================================================
 * Filename:		m_sendraw.c
 * =================================================================
 * Description:         Command /sendraw: it sends a completely raw
 *                      string to either a server, client or channel.
 *                      It also has support for multiple targets.
 * =================================================================
 * Author:		AngryWolf
 * Email:		angrywolf@flashmail.com
 * =================================================================
 *
 * I accept bugreports, ideas and opinions, and if you have
 * questions, just send an email for me!
 *
 * Thank you for using my module!
 *
 * =================================================================
 * Requirements:
 * =================================================================
 *
 * o Unreal >=3.2-beta17
 * o One of the supported operating systems (see unreal32docs.html)
 *
 * =================================================================
 * Installation:
 * =================================================================
 *
 * See http://angrywolf.linktipp.org/compiling.php?lang=en
 *
 * =================================================================
 * Mirror files:
 * =================================================================
 *
 * http://angrywolf.linktipp.org/m_sendraw.c [Germany]
 * http://angrywolf.uw.hu/m_sendraw.c [Hungary]
 * http://angrywolf.fw.hu/m_sendraw.c [Hungary]
 *
 * =================================================================
 * Changes:
 * =================================================================
 *
 * $Log: m_sendraw.c,v $
 * Revision 2.2  2003/12/01 18:10:03  angrywolf
 * - Replaced add_Command and del_Command with CommandAdd and CommandDel.
 *
 * Revision 2.1  2003/08/31 20:36:56  angrywolf
 * From now on I'm using RCS
 *
 * 2003-05-14: Documentation updates
 * 2003-06-04: Little fix in the parameters of sendto_channel_butone
 *             (reported by ChRiS)
 * 2003-05-20: Fixed so channel messages sent from anywhere within
 *             the IRC Network are delivered to all members of the
 *             channel.
 * 2003-05-09: Added option -servers to send a message to all servers
 *             of the network
 * 2003-04-27: Fixed compile warnings for win32
 * 2003-02-07: Added multi-recipient support
 * 2003-02-02: Coded m_sendraw
 *
 * =================================================================
 */

#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif

#define MyMod		ModSendraw->handle
#define MSG_SENDRAW 	"SENDRAW"
#define TOK_SENDRAW 	"SR"
#define DelCommand(x)	if (x) CommandDel(x); x = NULL

static Command		*AddCommand(char *msg, char *token, int (*func)());
DLLFUNC int		m_sendraw(aClient *cptr, aClient *sptr, int parc, char *parv[]);

ModuleInfo		*ModSendraw;
Command			*CmdSendraw;

#ifndef DYNAMIC_LINKING
ModuleHeader m_sendraw_Header
#else
#define m_sendraw_Header Mod_Header
ModuleHeader Mod_Header
#endif
  = {
	"sendraw",
	"$Id: m_sendraw.c,v 2.2 2003/12/01 18:10:03 angrywolf Exp $",
	"command /sendraw",
	"3.2-b8-1",
	NULL 
    };

#ifdef DYNAMIC_LINKING
DLLFUNC int	Mod_Init(ModuleInfo *modinfo)
#else
int    m_sendraw_Init(ModuleInfo *modinfo)
#endif
{
	ModSendraw	= modinfo;
	CmdSendraw	= AddCommand(MSG_SENDRAW, TOK_SENDRAW, m_sendraw);

	if (!CmdSendraw)
		return MOD_FAILED;

	return MOD_SUCCESS;
}

#ifdef DYNAMIC_LINKING
DLLFUNC int	Mod_Load(int module_load)
#else
int    m_sendraw_Load(int module_load)
#endif
{
	return MOD_SUCCESS;
}

#ifdef DYNAMIC_LINKING
DLLFUNC int	Mod_Unload(int module_unload)
#else
int	m_sendraw_Unload(int module_unload)
#endif
{
	DelCommand(CmdSendraw);

	return MOD_SUCCESS;
}

static Command *AddCommand(char *msg, char *token, int (*func)())
{
	Command *cmd;

	if (CommandExists(msg))
    	{
		config_error("Command %s already exists", msg);
		return NULL;
    	}
    	if (CommandExists(token))
	{
		config_error("Token %s already exists", token);
		return NULL;
    	}

	cmd = CommandAdd(MyMod, msg, token, func, MAXPARA, 0);

#ifndef _WIN32
	if (ModuleGetError(MyMod) != MODERR_NOERROR || !cmd)
#else
	if (!cmd)
#endif
	{
#ifndef _WIN32
		config_error("Error adding command %s: %s", msg,
			ModuleGetErrorStr(MyMod));
#else
		config_error("Error adding command %s", msg);
#endif
		return NULL; /* just to be sure */
	}

	return cmd;
}

/*
** m_sendraw
**      parv[0] = sender prefix
**      parv[1] = targets separated by commas (nick/server/channel)
**      parv[2] = message
*/

DLLFUNC int m_sendraw(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient		*acptr;
	aChannel	*chptr;
	char		*recipients, *to, *message, *p;

        if (!MyClient(sptr) || !IsNetAdmin(sptr))
	{
        	sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return -1;
	}

        if (parc < 3 || BadPtr(parv[2]))
	{
    		sendto_one(sptr, ":%s NOTICE %s :*** Usage: /sendraw <to1>[,<to2>,[,<to3>...]]> [:]<message>",
	                me.name, sptr->name);
    		sendto_one(sptr, ":%s NOTICE %s :*** <to>: <#channel>|<nick>|-servers",
	                me.name, sptr->name);
    		sendto_one(sptr, ":%s NOTICE %s :*** Example: /sendraw #opers ::Lamer PRIVMSG #opers :Hello!",
	                me.name, sptr->name);
		return -1;
	}

	recipients	= strdup(parv[1]);
	message		= parv[2];

	sendto_realops("%s (%s@%s) did a /sendraw [ \2to=\2%s \2message=\2%s ]",
		sptr->name, sptr->user->username,
		IsHidden(sptr) ? sptr->user->virthost : sptr->user->realhost,
		recipients, message);

	for (to = strtoken(&p, recipients, ","); to; to = strtoken(&p, NULL, ","))
	{

    		if (!strcasecmp(to, "-servers"))
			sendto_serv_butone(&me, message);
    		else if (*to == '#' && (chptr = find_channel(to, NullChn)) != NullChn)
			sendto_channel_butone(&me, &me, chptr, message);
    		else if ((acptr = find_person(to, NULL)) || (acptr = find_server_quick(to)))
			sendto_one(acptr, message);
		else
		{
			if (!IsServer(sptr))
	    			sendto_one(sptr, err_str(ERR_NOSUCHNICK),
					me.name, sptr->name, to);
			return -1;
		}

	}

	MyFree(recipients);
	
	return 0;

}
