IRCForumları - IRC ve mIRC Kullanıcılarının Buluşma Noktası

IRCForumları - IRC ve mIRC Kullanıcılarının Buluşma Noktası (https://www.ircforumlari.net/)
-   Unreal IRCd (https://www.ircforumlari.net/unreal-ircd/)
-   -   özel okuma modülü hatası (https://www.ircforumlari.net/unreal-ircd/578831-ozel-okuma-modulu-hatasi.html)

Delioper 14 Nisan 2014 21:15

özel okuma modülü hatası
 
Unreal3.2.10.2 sürümü kullanıyorum

unrealircd.conf:562: loadmodule src/modules/m_spy.so: failed to load: Lacking mod_header->modversion

hatası veriyor bunu nasıl çözeriz arkadaşlar

No_FeaR 14 Nisan 2014 21:57

Cevap: özel okuma modülü hatası
 
Farklı Bi Modul Dene Kardeşim Onda Bak Bir de Aynı Hatayı Veriyor mu Diye ;
ssh/telnet uzerinden..
Login olduktan sonra... sirasi ile..
cd Unreal3.2
cd src
cd modules
wget [Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]
cd ..
cd ..
tekrar Unreal3.2 icine donuyoruz.
make custommodule MODULEFILE=m_spy
pico unrealircd.conf

ctrl + x + y
unrealircd.conf a usteki satiri kaydettikten sonra
./unreal rehash yada IRC uzerinden /rehash
Komut :
/spy add nick
/spy add nick1 nick2 #kanal


Kod:

/*
 * ==================================================================
 * Filename:            m_spy.c
 * Description:          Real-time spying
 * Written by:                AngryWolf <angrywolf@[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]mail.com>
 * The idea was born by: Toxyc <toxyc@[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]mail.hu>
 * ==================================================================
 */

#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

// ==================================================================
// Definitions & macros
// ==================================================================

#define MSG_SPY                "spy"
#define TOK_SPY                "spy"
#define MSG_SPYCHANNEL                "SPYCHAN"
#define TOK_SPYCHANNEL                "SPC"
#define MSG_SPYSEND                "SPYSEND"
#define TOK_SPYSEND                "SPE"
#define MSG_SPYCHSEND                "SPYCHSEND"
#define TOK_SPYCHSEND                "SPT"
#define MSG_SPYFORWARD                "SPYFORWARD"
#define TOK_SPYFORWARD                "SPF"
#define MSG_SPYCHFORWARD        "SPYCHFORWARD"
#define TOK_SPYCHFORWARD        "SPG"
#define MSG_SPYSTATS                "SPYSTATS"
#define TOK_SPYSTATS                "SPS"

#define MyMod                        SpyModInfo->handle
#define FlagSpy                        'P'
#define LockFlag                '@'
#define LockFlagStr                "@"

#define SPY_NOTICE                ":%s NOTICE %s :*** "
#define SPY_LINE                "=================================================="

#define ircfree(x)                if (x) free(x)
#define ircstrdup(x,y)                if (x) MyFree(x); if (!y) x = NULL; else x = strdup(y)
#define DelSnomask(x)                if (x) SnomaskDel(x); x = NULL
#define DelHook(x)                if (x) HookDel(x); x = NULL
#define DelCommand(x)                if (x) CommandDel(x); x = NULL


#define IsParam(x)                (parc > (x) && !BadPtr(parv[(x)]))
#define IsValidParam(x)                (parc > (x) && !BadPtr(parv[(x)]) && *parv[(x)] != '*')

#define AddLock(lock)                (lock ? LockFlagStr : "")
#define GetLock(str)                (*str == LockFlag ? 1 : 0)
#define SplitLock(lock, str)        del_prefix(str, &(lock), &(str))
#define MergeLock(lock, str)        AddLock(lock), str
#define MergeLockOpt(lock, str)        str ? AddLock(lock) : "", str ? str : "*"
#define MergeLockEmp(lock, str)        str ? AddLock(lock) : "", str ? str : ""

#define SpyForward5(cptr, cmd, who, nick1, nick2, channel, lock1, lock2) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYFORWARD, TOK_SPYFORWARD, \
                "%s %s %s%s %s%s %s", \
                cmd, who, MergeLock(lock1, nick1), MergeLockOpt(lock2, nick2), \
                channel ? channel : "*")

#define SpyForward4(cptr, cmd, who, nick1, nick2, lock1, lock2) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYFORWARD, TOK_SPYFORWARD, \
                "%s %s %s%s %s%s", \
                cmd, who, MergeLock(lock1, nick1), MergeLockOpt(lock2, nick2))

#define SpyForward3(cptr, cmd, who, nick1, lock1) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYFORWARD, TOK_SPYFORWARD, \
                "%s %s %s%s", \
                cmd, who, MergeLock(lock1, nick1))

#define SpyForward2(cptr, cmd, who) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYFORWARD, TOK_SPYFORWARD, \
                "%s %s", \
                cmd, who)

#define SpyForward1(cptr, cmd) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYFORWARD, TOK_SPYFORWARD, \
                "%s", \
                cmd)

#define SpyChForward4(cptr, cmd, who, channel, sendto, lock) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYCHFORWARD, TOK_SPYCHFORWARD, \
                "%s %s %s%s %s", \
                cmd, who, MergeLock(lock, channel), sendto ? sendto : "*")

#define SpyChForward3(cptr, cmd, who, channel, lock) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYCHFORWARD, TOK_SPYCHFORWARD, \
                "%s %s %s%s", \
                cmd, who, MergeLock(lock, channel))

#define SpyChForward2(cptr, cmd, who) \
                sendto_serv_butone_token(cptr, me.name, MSG_SPYCHFORWARD, TOK_SPYCHFORWARD, \
                "%s %s", \
                cmd, who)

typedef struct _spystruct        SpyStruct;
typedef struct _spychstruct        SpyChStruct;

struct _spystruct
{
        SpyStruct        *prev, *next;

        aClient                *who;                /* Who is spying */
        char                *nick1;                /* First nick to spy */
        char                *nick2;                /* Second nick to spy (may be NULL) */
        char                *chname;        /* Where to put messages (may be NULL) */
        u_int                lock1:1;                /* 1 if nick1 is locked, otherwise 0 */
        u_int                lock2:1;                /* 1 if nick2 is locked, otherwise 0 */
};

struct _spychstruct
{
        SpyChStruct        *prev, *next;

        aClient                *who;                /* Who is spying */
        char                *channel;        /* Channel to be spyed */
        char                *sendto;        /* Where to put messages (may be NULL) */
        u_int                lock;                /* True if nick1 is locked, otherwise 0 */
};

static SpyStruct        *FindSpyItem1(aClient *acptr, char *nick);
static SpyStruct        *FindSpyItem2(aClient *acptr, char *nick1, char *nick2);
static SpyChStruct        *FindSpyChItem(aClient *acptr, char *channel);
static void                AddSpyItem(aClient *acptr, char *nick1, char *nick2, char *chname, u_int lock1, u_int lock2);
static void                AddSpyChItem(aClient *acptr, char *channel, char *sendto, u_int lock);
static void                DelSpyItem(SpyStruct *s);
static void                DelSpyChItem(SpyChStruct *s);
static unsigned int        spy_paramcheck(aClient *cptr, int parc, char *parv[], char **nick1, char **nick2, char **channel, u_int *lock1, u_int *lock2);
static unsigned int        spych_paramcheck(aClient *cptr, int parc, char *parv[], char **channel, char **sendto, u_int *lock);
static void                spy_send_client(aClient *acptr, int notice, char *nick1, char *nick2, char *text);
static void                spy_send_channel(aClient *cptr, char *channel, int notice, char *nick1, char *nick2, char *text);
static void                spych_send_client(aClient *acptr, int notice, char *nick, char *channel, char *text);
static void                spych_send_channel(aClient *cptr, char *sendto, int notice, char *nick, char *channel, char *text);
static void                del_prefix(char *str, u_int *lock, char **newstr);

static Command                *AddCommand(char *msg, char *token, int (*func)());
DLLFUNC int                m_spy(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int                m_spychannel(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int                m_spysend(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int                m_spychsend(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int                m_spyforward(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int                m_spychforward(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int                m_spystats(aClient *cptr, aClient *sptr, int parc, char *parv[]);

DLLFUNC char                *spy_on_privmsg(aClient *, aClient *, aClient *, char *, int);
DLLFUNC char                *spy_on_chanmsg(aClient *, aClient *, aChannel *, char *, int);
DLLFUNC int                spy_on_quit(aClient *, char *);
DLLFUNC int                spy_on_remote_quit(aClient *, char *);
DLLFUNC int                spy_on_server_connect(aClient *);
DLLFUNC int                spy_on_local_nickchange(aClient *, char *);
DLLFUNC int                spy_on_remote_nickchange(aClient *, aClient *, char *);
DLLFUNC int                spy_on_channel_destroy(aChannel *);

// ==================================================================
// Module header
// ==================================================================

ModuleHeader MOD_HEADER(m_spy)
  = {
        "Saint",
        "$Id: m_spy.c,v 3.6 2003/12/01 18:31:45 angrywolf Exp $",
        "The End Of Life",
        "3.2-b8-1",
        NULL
    };

// ==================================================================
// Main declarations
// ==================================================================

static char *SpyHelp[] =
{
    SPY_NOTICE        "\2Usage:\2",
    SPY_NOTICE        "/spy add <nick1> [<nick2> [<#channel>]]",
    SPY_NOTICE        "/spy del <nick1> [<nick2>]",
    SPY_NOTICE        "/spy list [<nick1> [<nick2>]] [<#channel>]",
    SPY_NOTICE        "/spy clear",
    SPY_NOTICE        "\2Examples:\2",
    SPY_NOTICE        "/spy add AngryWolf Toxyc #secret",
    SPY_NOTICE        "/spy del AngryWolf",
    SPY_NOTICE        "/spy list #secret",
    NULL
};

static char *SpyChHelp[] =
{
    SPY_NOTICE        "\2Usage:\2",
    SPY_NOTICE        "/spychan add <#channel> [<#sendto>]]",
    SPY_NOTICE        "/spychan del <#channel>",
    SPY_NOTICE        "/spychan list [<#channel>]",
    SPY_NOTICE        "/spychan clear",
    SPY_NOTICE        "\2Examples:\2",
    SPY_NOTICE        "/spychan add #***** #spy",
    SPY_NOTICE        "/spychan del #*****",
    SPY_NOTICE        "/spychan list",
    NULL
};

ModuleInfo                *SpyModInfo;
Command                        *CmdSpy, *CmdSpychannel, *CmdSpysend, *CmdSpychsend;
Command                        *CmdSpyforward, *CmdSpychforward, *CmdSpystats;
Snomask                        *SpySnomask;
long                        SNO_SPY;

static Hook                *HookPrivMsg;
static Hook                *HookChanMsg;
static Hook                *HookQuit;
static Hook                *HookRemoteQuit;
static Hook                *HookServConn;
static Hook                *HookLocalNick;
static Hook                *HookRemoteNick;
static Hook                *HookChanDest;

static SpyStruct        *SpyList = NULL;
static SpyChStruct        *SpyChList = NULL;

// ==================================================================
// Module initalization, loading and unloading
// ==================================================================

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;
}

static Snomask *AddSnomask(char flag, int (*allowed)(aClient *sptr, int what), long *mode)
{
        Snomask *s;

        *mode = 0;
        s = SnomaskAdd(MyMod, flag, allowed, mode);

#ifndef _WIN32
        if ((ModuleGetError(MyMod) != MODERR_NOERROR) || !s)
#else
        if (!s)
#endif
        {
#ifndef _WIN32
                sendto_realops("[\2m_spy\2] Error adding snomask %c: %s",
                        flag, ModuleGetErrorStr(MyMod));
#else
                sendto_realops("[\2m_spy\2] Error adding snomask %c",
                        flag);
#endif
                return NULL;
        }

        return s;
}

DLLFUNC int MOD_INIT(m_spy)(ModuleInfo *modinfo)
{
        int ret = MOD_SUCCESS;

        SpyModInfo        = modinfo;

        HookPrivMsg        = HookAddPCharEx(MyMod, HOOKTYPE_USERMSG, spy_on_privmsg);
        HookChanMsg        = HookAddPCharEx(MyMod, HOOKTYPE_CHANMSG, spy_on_chanmsg);
        HookQuit        = HookAddEx(MyMod, HOOKTYPE_LOCAL_QUIT, spy_on_quit);
        HookRemoteQuit        = HookAddEx(MyMod, HOOKTYPE_REMOTE_QUIT, spy_on_remote_quit);
        HookServConn        = HookAddEx(MyMod, HOOKTYPE_SERVER_CONNECT, spy_on_server_connect);
        HookLocalNick        = HookAddEx(MyMod, HOOKTYPE_LOCAL_NICKCHANGE, spy_on_local_nickchange);
        HookRemoteNick        = HookAddEx(MyMod, HOOKTYPE_REMOTE_NICKCHANGE, spy_on_remote_nickchange);
        HookChanDest        = HookAddEx(MyMod, HOOKTYPE_CHANNEL_DESTROY, spy_on_channel_destroy);

        CmdSpy                = AddCommand(MSG_SPY, TOK_SPY, m_spy);
        CmdSpychannel        = AddCommand(MSG_SPYCHANNEL, TOK_SPYCHANNEL, m_spychannel);
        CmdSpysend        = AddCommand(MSG_SPYSEND, TOK_SPYSEND, m_spysend);
        CmdSpychsend        = AddCommand(MSG_SPYCHSEND, TOK_SPYCHSEND, m_spychsend);
        CmdSpyforward        = AddCommand(MSG_SPYFORWARD, TOK_SPYFORWARD, m_spyforward);
        CmdSpychforward        = AddCommand(MSG_SPYCHFORWARD, TOK_SPYCHFORWARD, m_spychforward);
        CmdSpystats        = AddCommand(MSG_SPYSTATS, TOK_SPYSTATS, m_spystats);

        SpySnomask        = AddSnomask(FlagSpy, umode_allow_opers, &SNO_SPY);

        if (!SpySnomask || !CmdSpy || !CmdSpychannel || !CmdSpysend || !CmdSpychsend)
                ret = MOD_FAILED;
        if (!CmdSpyforward || !CmdSpychforward || !CmdSpystats)
                ret = MOD_FAILED;

        return ret;
}

DLLFUNC int MOD_LOAD(m_spy)(int module_load)
{
        return MOD_SUCCESS;
}

DLLFUNC int MOD_UNLOAD(m_spy)(int module_unload)
{
        SpyStruct        *s;
        SpyChStruct        *sc;
        ListStruct        *next;

        DelSnomask(SpySnomask);

        DelCommand(CmdSpystats);
        DelCommand(CmdSpychforward);
        DelCommand(CmdSpyforward);
        DelCommand(CmdSpychsend);
        DelCommand(CmdSpysend);
        DelCommand(CmdSpychannel);
        DelCommand(CmdSpy);

        DelHook(HookChanDest);
        DelHook(HookRemoteNick);
        DelHook(HookLocalNick);
        DelHook(HookServConn);
        DelHook(HookRemoteQuit);
        DelHook(HookQuit);
        DelHook(HookChanMsg);
        DelHook(HookPrivMsg);

        for (s = SpyList; s; s = (SpyStruct *) next)
        {
                next = (ListStruct *) s->next;
                DelSpyItem(s);
        }
        for (sc = SpyChList; sc; sc = (SpyChStruct *) next)
        {
                next = (ListStruct *) sc->next;
                DelSpyChItem(sc);
        }

        return MOD_SUCCESS;
}

// ==================================================================
// Functions for nicknames, channel names and prefixes
// ==================================================================

static void del_prefix(char *str, u_int *lock, char **newstr)
{
        *lock = 0;

        if (*str == LockFlag)
        {
                *lock = 1;
                str++;
        }

        *newstr = str;
}

// ==================================================================
// Misc functions
// ==================================================================

static SpyStruct *FindSpyItem1(aClient *acptr, char *nick)
{
        SpyStruct *s;
       
        for (s = SpyList; s; s = s->next)
                if (s->who == acptr && !s->nick2 && !strcasecmp(s->nick1, nick))
                        break;

        return s;
}

static SpyStruct *FindSpyItem2(aClient *acptr, char *nick1, char *nick2)
{
        SpyStruct *s;
       
        for (s = SpyList; s; s = s->next)
                if (s->who == acptr && !strcasecmp(s->nick1, nick1)
                  && (s->nick2 && !strcasecmp(s->nick2, nick2)))
                        break;

        return s;
}

static SpyChStruct *FindSpyChItem(aClient *acptr, char *channel)
{
        SpyChStruct *sc;
       
        for (sc = SpyChList; sc; sc = sc->next)
                if (sc->who == acptr && !strcasecmp(sc->channel, channel))
                        break;

        return sc;
}

static void AddSpyItem(aClient *acptr, char *nick1, char *nick2, char *chname, u_int lock1, u_int lock2)
{
        SpyStruct        *s;

        s                = (SpyStruct *) MyMalloc(sizeof(SpyStruct));
        s->who                = acptr;
        s->nick1        = strdup(nick1);
        s->nick2        = BadPtr(nick2) ? NULL : strdup(nick2);
        s->chname        = BadPtr(chname) ? NULL : strdup(chname);
        s->lock1        = lock1;
        s->lock2        = lock2;

        AddListItem(s, SpyList);
}

static void AddSpyChItem(aClient *acptr, char *channel, char *sendto, u_int lock)
{
        SpyChStruct        *sc;

        sc                = (SpyChStruct *) MyMalloc(sizeof(SpyChStruct));
        sc->who                = acptr;
        sc->channel        = strdup(channel);
        sc->sendto        = BadPtr(sendto) ? NULL : strdup(sendto);
        sc->lock        = lock;

        AddListItem(sc, SpyChList);
}

static void DelSpyItem(SpyStruct *s)
{
        DelListItem(s, SpyList);
        MyFree(s->nick1);
        ircfree(s->nick2);
        ircfree(s->chname);
        MyFree(s);
}

static void DelSpyChItem(SpyChStruct *sc)
{
        DelListItem(sc, SpyChList);
        MyFree(sc->channel);
        ircfree(sc->sendto);
        MyFree(sc);
}

// ==================================================================
// display_text: a general function to display two or more lines
//    of text to a user
// ==================================================================

static void display_text(aClient *cptr, char *text[])
{
        char **pp;

        for (pp = text; *pp; pp++)
                    sendto_one(cptr, *pp, me.name, cptr->name);
        /* let user take 7 seconds to read it! */
        if (MyClient(cptr))
                cptr->since += 7;
}

// ==================================================================
// spy_paramcheck: checks for validity of /spy parameters
// ==================================================================

static unsigned int spy_paramcheck(aClient *cptr, int parc, char *parv[],
        char **nick1, char **nick2, char **channel, u_int *lock1, u_int *lock2)
{
        *nick1                = NULL;
        *nick2                = NULL;
        *channel        = NULL;
        *lock1                = 0;
        *lock2                = 0;

        if (IsParam(2))
        {
                if (*parv[2] == '#')
                        *channel = parv[2];
                else
                        *nick1        = parv[2];
        }
        if (IsParam(3))
        {
                if (*channel)
                        return 0;
                else if (*parv[3] == '#')
                {
                        *nick2                = NULL;
                        *channel        = parv[3];
                }
                else
                        *nick2                = parv[3];
        }
        if (IsParam(4))
        {
                if (*channel)
                        return 0;
                *channel = parv[4];
        }

        if (*nick1)
                SplitLock(*lock1, *nick1);
        if (*nick2)
                SplitLock(*lock2, *nick2);

        return 1;
}

// ==================================================================
// spych_paramcheck: checks for validity of /spychannel parameters
// ==================================================================

static unsigned int spych_paramcheck(aClient *cptr, int parc, char *parv[],
        char **channel, char **sendto, u_int *lock)
{
        *channel        = NULL;
        *sendto                = NULL;
        *lock                = 0;

        if (!IsParam(2))
                return 0;

        *channel = parv[2];

        if (IsParam(3))
                *sendto = parv[3];

        if (*channel)
                SplitLock(*lock, *channel);

        return 1;
}

// ==================================================================
// spy_send_client & spy_send_channel: handle sending users's private
//        messages to clients & channels
// ==================================================================

static void spy_send_client(aClient *acptr, int notice, char *nick1, char *nick2, char *text)
{
        if (MyClient(acptr))
                    sendto_one(acptr, ":IRC!IRC@%s PRIVMSG %s :[%s %c> %s] %s",
                            me.name, acptr->name,
                        nick1, (notice ? '-' : '>'), nick2, text);
        else
                sendto_one(acptr->from, "%s %s %c %s %s :%s",
                        IsToken(acptr->from) ? TOK_SPYSEND : MSG_SPYSEND,
                        acptr->name, (notice ? 'N' : 'P'),
                        nick1, nick2, text);
}

static void spy_send_channel(aClient *cptr, char *channel, int notice, char *nick1, char *nick2, char *text)
{
        aChannel        *chptr;

        if ((chptr = find_channel(channel, NullChn)) == NullChn)
                return;

        sendto_channel_butserv(chptr, &me, ":IRC!IRC@%s PRIVMSG %s :[%s %c> %s] %s",
                me.name, chptr->chname,
                nick1, (notice ? '-' : '>'), nick2, text);

        sendto_serv_butone_token(cptr, me.name, MSG_SPYSEND, TOK_SPYSEND,
                "%s %c %s %s :%s",
                chptr->chname, (notice ? 'N' : 'P'),
                nick1, nick2, text);
}

static void spych_send_client(aClient *acptr, int notice, char *nick, char *channel, char *text)
{
        if (MyClient(acptr))
                    sendto_one(acptr, ":IRC!IRC@%s PRIVMSG %s :[%s] %c%s%c %s",
                            me.name, acptr->name, channel,
                        (notice ? '-' : '<'), nick, (notice ? '-' : '>'), text);
        else
                sendto_one(acptr->from, "%s %s %c %s %s :%s",
                        IsToken(acptr->from) ? TOK_SPYCHSEND : MSG_SPYCHSEND,
                        acptr->name, (notice ? 'N' : 'P'),
                        nick, channel, text);
}

static void spych_send_channel(aClient *cptr, char *sendto, int notice, char *nick, char *channel, char *text)
{
        aChannel        *chptr;

        if ((chptr = find_channel(sendto, NullChn)) == NullChn)
                return;

        sendto_channel_butserv(chptr, &me, ":IRC!IRC@%s PRIVMSG %s :[%s] %c%s%c %s",
                me.name, chptr->chname, channel,
                (notice ? '-' : '<'), nick, (notice ? '-' : '>'), text);

        sendto_serv_butone_token(cptr, me.name, MSG_SPYCHSEND, TOK_SPYCHSEND,
                "%s %c %s %s :%s",
                chptr->chname, (notice ? 'N' : 'P'),
                nick, channel, text);
}

// ==================================================================
// Events
// ==================================================================

DLLFUNC int spy_on_quit(aClient *sptr, char *comment)
{
        SpyStruct        *s;
        SpyChStruct        *sc;
        ListStruct        *next;

        // sendto_realops("(spy_on_quit) sptr->name=[%s]", sptr->name);

        for (s = SpyList; s; s = (SpyStruct *) next)
        {
                next = (ListStruct *) s->next;
                if (s->who == sptr)
                        DelSpyItem(s);
                else if (!s->lock1 && !strcasecmp(s->nick1, sptr->name))
                        DelSpyItem(s);
                else if (s->nick2 && !s->lock2 && !strcasecmp(s->nick2, sptr->name))
                        DelSpyItem(s);
        }
        for (sc = SpyChList; sc; sc = (SpyChStruct *) next)
        {
                next = (ListStruct *) sc->next;
                if (sc->who == sptr)
                        DelSpyChItem(sc);
        }

        return 0;
}

// ==================================================================

DLLFUNC int spy_on_remote_quit(aClient *sptr, char *comment)
{
        SpyStruct        *s;
        SpyChStruct        *sc;
        ListStruct        *next;

        // sendto_realops("(spy_on_remote_quit) sptr->name=[%s]", sptr->name);

        for (s = SpyList; s; s = (SpyStruct *) next)
        {
                next = (ListStruct *) s->next;
                if (s->who == sptr)
                        DelSpyItem(s);
                else if (!s->lock1 && !strcasecmp(s->nick1, sptr->name))
                        DelSpyItem(s);
                else if (s->nick2 && !s->lock2 && !strcasecmp(s->nick2, sptr->name))
                        DelSpyItem(s);
        }
        for (sc = SpyChList; sc; sc = (SpyChStruct *) next)
        {
                next = (ListStruct *) sc->next;
                if (sc->who == sptr)
                        DelSpyChItem(sc);
        }

        return 0;
}

// ==================================================================

DLLFUNC int spy_on_local_nickchange(aClient *sptr, char *nick)
{
        SpyStruct        *s;

        for (s = SpyList; s; s = s->next)
        {
                if (!s->lock1 && !strcasecmp(s->nick1, sptr->name))
                {
                        ircstrdup(s->nick1, nick);
                }
                if (s->nick2 && !s->lock2 && !strcasecmp(s->nick2, sptr->name))
                {
                        ircstrdup(s->nick2, nick);
                }
        }

        return 0;
}

DLLFUNC int spy_on_remote_nickchange(aClient *cptr, aClient *sptr, char *nick)
{
        SpyStruct        *s;

        for (s = SpyList; s; s = s->next)
        {
                if (!s->lock1 && !strcasecmp(s->nick1, sptr->name))
                {
                        ircstrdup(s->nick1, nick);
                }
                if (s->nick2 && !s->lock2 && !strcasecmp(s->nick2, sptr->name))
                {
                        ircstrdup(s->nick2, nick);
                }
        }

        return 0;
}

// ==================================================================

DLLFUNC int spy_on_channel_destroy(aChannel *chptr)
{
        SpyChStruct        *sc;
        ListStruct        *next;

        for (sc = SpyChList; sc; sc = (SpyChStruct *) next)
        {
                next = (ListStruct *) sc->next;

                if (!sc->lock && !strcasecmp(sc->channel, chptr->chname))
                        DelSpyChItem(sc);
        }

        return 0;
}

// ==================================================================

DLLFUNC int spy_on_server_connect(aClient *sptr)
{
        SpyStruct        *s;
        SpyChStruct        *sc;

        // sendto_realops("(spy_on_server_connect) sptr->name=[%s]", sptr->name);

        /* TODO: optimize this! */
        sendto_one(sptr, ":%s %s CONNECT",
                me.name, (IsToken(sptr) ? TOK_SPYFORWARD : MSG_SPYFORWARD));
        sendto_one(sptr, ":%s %s CONNECT",
                me.name, (IsToken(sptr) ? TOK_SPYCHFORWARD : MSG_SPYCHFORWARD));

        for (s = SpyList; s; s = s->next)
        {
                sendto_one(sptr, ":%s %s ADD2 %s %s%s %s%s %s",
                        me.name,
                        (IsToken(sptr) ? TOK_SPYFORWARD : MSG_SPYFORWARD),
                        s->who->name,
                        MergeLock(s->lock1, s->nick1),
                        MergeLockOpt(s->lock2, s->nick2),
                        s->chname ? s->chname : "*");
        }
        for (sc = SpyChList; sc; sc = sc->next)
        {
                sendto_one(sptr, ":%s %s ADD2 %s %s%s %s",
                        me.name,
                        (IsToken(sptr) ? TOK_SPYCHFORWARD : MSG_SPYCHFORWARD),
                        sc->who->name,
                        MergeLock(sc->lock, sc->channel),
                        sc->sendto ? sc->sendto : "*");
        }

        return 0;
}

// ==================================================================

DLLFUNC char *spy_on_privmsg(aClient *cptr, aClient *sptr, aClient *acptr, char *text, int notice)
{
        SpyStruct        *s;
        aChannel        *chptr;
        char                *nick1, *nick2;

        if (!MyClient(sptr))
                return text;

        /* First do some sorting */

        if (smycmp(sptr->name, acptr->name) > 0)
        {
                    nick1 = acptr->name;
                    nick2 = sptr->name;
        }
        else
        {
                nick1 = sptr->name;
                nick2 = acptr->name;
        }

        for (s = SpyList; s; s = s->next)
        {
                if (
                        /* spy every messages sent and received by one client */
                        (
                                !s->nick2 &&
                                (!strcasecmp(s->nick1, sptr->name) || !strcasecmp(s->nick1, acptr->name))
                        ) ||
                        /* spy messages between two specific users */
                        (
                                !strcasecmp(s->nick1, nick1) && !strcasecmp(s->nick2, nick2)
                        )
                  )
                {
                        if (s->chname)
                                        spy_send_channel(&me, s->chname, notice,
                                                sptr->name, acptr->name, text);
                                else
                                        spy_send_client(s->who, notice,
                                                sptr->name, acptr->name, text);
                }
        }

        return text;
}

DLLFUNC char *spy_on_chanmsg(aClient *cptr, aClient *sptr, aChannel *chptr, char *text, int notice)
{
        SpyChStruct        *sc;

        if (!MyClient(sptr))
                return text;

        for (sc = SpyChList; sc; sc = sc->next)
        {
                if (!strcasecmp(chptr->chname, sc->channel))
                {
                        if (sc->sendto)
                                spych_send_channel(&me, sc->sendto, notice,
                                        sptr->name, chptr->chname, text);
                        else
                                spy_send_client(sc->who, notice,
                                        sptr->name, chptr->chname, text);
                }
        }

        return text;
}

// ==================================================================
// m_spy: Adds, removes or lists nicknames in spy list
// ==================================================================

DLLFUNC int m_spy(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        SpyStruct        *s;
        char                *tmp = NULL, *cmd;
        char                *nick1, *nick2, *channel;
        u_int                lock1, lock2;

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

        cmd = IsParam(1) ? parv[1] : NULL;

        if (!cmd)
        {
                display_text(cptr, SpyHelp);
                return -1;
        }

        /* ADD */
        if (!strcasecmp(cmd, "add"))
        {
                if (!spy_paramcheck(cptr, parc, parv, &nick1, &nick2, &channel, &lock1, &lock2))
                {
                        display_text(cptr, SpyHelp);
                        return -1;
                }
                if (!nick1 || IsParam(5))
                {
                        display_text(cptr, SpyHelp);
                        return -1;
                }
                if (nick2 && !strcasecmp(nick1, nick2))
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s %s: Nicks cannot be the same",
                                    me.name, sptr->name,
                                nick1, nick2);
                        return -1;
                }
                if (channel && *channel != '#')
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s: Invalid channel name",
                                    me.name, sptr->name, channel);
                        return -1;
                }
                if (nick2 && (smycmp(nick1, nick2) > 0))
                {
                        tmp        = nick1;
                        nick1        = nick2;
                        nick2        = tmp;
                }
                if ((nick2 && FindSpyItem2(sptr, nick1, nick2)) || (!nick2 && FindSpyItem1(sptr, nick1)))
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s %s: Already on your private spy list",
                                    me.name, sptr->name,
                                nick1, nick2 ? nick2 : "<irc>");
                        return -1;
                }
                AddSpyItem(sptr, nick1, nick2, channel, lock1, lock2);
                    sendto_one(sptr, ":%s NOTICE %s :*** %s %s: Added to your private spy list",
                            me.name, sptr->name,
                        nick1, nick2 ? nick2 : "<irc>");
                SpyForward5(&me, "ADD", sptr->name, nick1, nick2, channel, lock1, lock2);
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPY ADD %s%s" "%s" "%s%s" "%s" "%s",
                        sptr->name, MergeLock(lock1, nick1),
                        nick2 ? " " : "", MergeLockEmp(lock2, nick2),
                        channel ? " " : "", channel ? channel : "");
        }

        /* DEL */
        else if (!strcasecmp(cmd, "del"))
        {
                if (!spy_paramcheck(cptr, parc, parv, &nick1, &nick2, &channel, &lock1, &lock2))
                {
                        display_text(cptr, SpyHelp);
                        return -1;
                }
                if (!nick1 || channel || IsParam(4))
                {
                        display_text(cptr, SpyHelp);
                        return -1;
                }
                if (nick2 && (smycmp(nick1, nick2) > 0))
                {
                        tmp        = nick1;
                        nick1        = nick2;
                        nick2        = tmp;
                }
                if ((nick2 && !(s = FindSpyItem2(sptr, nick1, nick2))) || (!nick2 && !(s = FindSpyItem1(sptr, nick1))))
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s %s: Not yet on your private spy list",
                                    me.name, sptr->name,
                                nick1, nick2 ? nick2 : "<irc>");
                        return -1;
                }
                SpyForward4(&me, "DEL", s->who->name, s->nick1, s->nick2, 0, 0);
                    sendto_one(sptr, ":%s NOTICE %s :*** %s %s: Deleted from your private spy list",
                            me.name, sptr->name,
                        nick1, nick2 ? nick2 : "<irc>");
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPY DEL %s%s%s",
                        sptr->name, s->nick1, s->nick2 ? " " : "", s->nick2 ? s->nick2 : "");
                DelSpyItem(s);
        }

        /* LIST */
        else if (!strcasecmp(cmd, "list"))
        {
                enum ListType { LT_n1n2c, LT_n1n2, LT_n1c, LT_n1, LT_c, LT_none };
                unsigned int found = 0, type = 0, show = 0, empty = 1;

                if (!spy_paramcheck(cptr, parc, parv, &nick1, &nick2, &channel, &lock1, &lock2))
                {
                        display_text(cptr, SpyHelp);
                        return -1;
                }
                if (channel)
                {
                        if (nick2)
                                type = LT_n1n2c;
                        else if (nick1)
                                type = LT_n1c;
                        else
                                type = LT_c;
                }
                else if (nick2)
                        type = LT_n1n2;
                else if (nick1)
                        type = LT_n1;
                else
                        type = LT_none;

                if (nick1 && nick2 && (smycmp(nick1, nick2) > 0))
                {
                        tmp        = nick1;
                        nick1        = nick2;
                        nick2        = tmp;
                }

                for (s = SpyList; s; s = s->next)
                        if (s->who == sptr)
                        {
                                empty        = 0;
                                show        = 0;

                                switch (type)
                                {
                                        case LT_n1n2c:
                                                if (
                                                        s->nick2 &&
                                                        s->chname &&
                                                        !strcasecmp(s->nick1, nick1) &&
                                                        !strcasecmp(s->nick2, nick2) &&
                                                        !strcasecmp(s->chname, channel)
                                                  )
                                                        show = 1;
                                                break;
                                        case LT_n1n2:
                                                if (
                                                        s->nick2 &&
                                                        !strcasecmp(s->nick1, nick1) &&
                                                        !strcasecmp(s->nick2, nick2)
                                                  )
                                                        show = 1;
                                                break;
                                        case LT_n1c:
                                                if (
                                                        s->chname &&
                                                        !strcasecmp(s->nick1, nick1) &&
                                                        !strcasecmp(s->chname, channel)
                                                  )
                                                        show = 1;
                                                break;
                                        case LT_n1:
                                                if (!strcasecmp(s->nick1, nick1))
                                                        show = 1;
                                                break;
                                        case LT_c:
                                                if (s->chname && !strcasecmp(s->chname, channel))
                                                        show = 1;
                                                break;
                                        default:
                                                show = 1;
                                }

                                if (show)
                                {
                                        found++;
                               
                                            sendto_one(sptr, ":%s NOTICE %s :*** %s%s %s%s %s",
                                                    me.name, sptr->name,
                                                MergeLock(s->lock1, s->nick1),
                                                MergeLockOpt(s->lock2, s->nick2),
                                                s->chname ? s->chname : "<irc>");
                                }
                        }

                if (!found)
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s",
                                    me.name, sptr->name,
                                empty ? "Your spy list is empty" : "No matching entries");
                }
                else
                {
                        sendto_one(sptr, ":%s NOTICE %s :*** " SPY_LINE,
                                me.name, sptr->name);
                        sendto_one(sptr, ":%s NOTICE %s :*** %d entr%s",
                                me.name, sptr->name,
                                found, found > 1 ? "ies" : "y");
                }
        }

        /* CLEAR */
        else if (!strcasecmp(cmd, "clear"))
        {
                ListStruct *next;

                for (s = SpyList; s; s = (SpyStruct *) next)
                {
                        next = (ListStruct *) s->next;
                        if (s->who == sptr)
                                DelSpyItem(s);
                }
                    sendto_one(sptr, ":%s NOTICE %s :*** Your private spy list is now empty",
                            me.name, sptr->name);
                SpyForward2(&me, "CLEAR", sptr->name);
        }

        /* <INVALID OPTION> */
        else
        {
                    sendto_one(sptr, ":%s NOTICE %s :*** Invalid option %s",
                            me.name, sptr->name, cmd);
                return -1;
        }

        return 0;
}

// ==================================================================
// m_spychannel: Adds, removes or lists channel names in channel
//    spy list
// ==================================================================

DLLFUNC int m_spychannel(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        SpyChStruct        *sc;
        char                *cmd, *channel, *sendto;
        u_int                lock;

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

        cmd = IsParam(1) ? parv[1] : NULL;

        if (!cmd)
        {
                display_text(cptr, SpyChHelp);
                return -1;
        }

        /* ADD */
        if (!strcasecmp(cmd, "add"))
        {
                if (!spych_paramcheck(cptr, parc, parv, &channel, &sendto, &lock))
                {
                        display_text(cptr, SpyChHelp);
                        return -1;
                }
                if (*channel != '#')
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s: Invalid channel name",
                                    me.name, sptr->name, channel);
                        return -1;
                }
                if (sendto && *sendto != '#')
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s: Invalid channel name",
                                    me.name, sptr->name, sendto);
                        return -1;
                }
                if (FindSpyChItem(sptr, channel))
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s: Already on your channel spy list",
                                    me.name, sptr->name, channel);
                        return -1;
                }
                if (sendto && !strcasecmp(channel, sendto))
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s %s: Source and target channels cannot be the same",
                                    me.name, sptr->name, channel, sendto);
                        return -1;
                }
                AddSpyChItem(sptr, channel, sendto, lock);
                    sendto_one(sptr, ":%s NOTICE %s :*** %s: Added to your channel spy list",
                            me.name, sptr->name, channel);
                SpyChForward4(&me, "ADD", sptr->name, channel, sendto, lock);
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPYCHANNEL ADD %s%s" "%s" "%s",
                        sptr->name, MergeLock(lock, channel), sendto ? " " : "",
                        sendto ? sendto : "");
        }

        /* DEL */
        else if (!strcasecmp(cmd, "del"))
        {
                if (!spych_paramcheck(cptr, parc, parv, &channel, &sendto, &lock))
                {
                        display_text(cptr, SpyChHelp);
                        return -1;
                }
                if (!(sc = FindSpyChItem(sptr, channel)))
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s: Not yet on your channel spy list",
                                    me.name, sptr->name, channel);
                        return -1;
                }
                SpyChForward3(&me, "DEL", sc->who->name, sc->channel, 0);
                    sendto_one(sptr, ":%s NOTICE %s :*** %s: Deleted from your channel spy list",
                            me.name, sptr->name, channel);
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPYCHANNEL DEL %s",
                        sptr->name, sc->channel);
                DelSpyChItem(sc);
        }

        /* LIST */
        else if (!strcasecmp(cmd, "list"))
        {
                unsigned int found = 0, empty = 1;

                sendto        = NULL;
                channel        = IsParam(2) ? parv[2] : NULL;

                if (channel)
                        SplitLock(lock, channel);

                for (sc = SpyChList; sc; sc = sc->next)
                        if (sc->who == sptr)
                        {
                                empty = 0;

                                if (!channel || !strcasecmp(sc->channel, channel))
                                {
                                        found++;
                               
                                            sendto_one(sptr, ":%s NOTICE %s :*** %s%s %s",
                                                    me.name, sptr->name,
                                                MergeLock(sc->lock, sc->channel),
                                                sc->sendto ? sc->sendto : "<irc>");
                                }
                        }

                if (!found)
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** %s",
                                    me.name, sptr->name,
                                empty ? "Your channel spy list is empty" : "No matching entries");
                }
                else
                {
                        sendto_one(sptr, ":%s NOTICE %s :*** " SPY_LINE,
                                me.name, sptr->name);
                        sendto_one(sptr, ":%s NOTICE %s :*** %d entr%s",
                                me.name, sptr->name,
                                found, found > 1 ? "ies" : "y");
                }
        }

        /* CLEAR */
        else if (!strcasecmp(cmd, "clear"))
        {
                ListStruct *next;

                for (sc = SpyChList; sc; sc = (SpyChStruct *) next)
                {
                        next = (ListStruct *) sc->next;
                        if (sc->who == sptr)
                                DelSpyChItem(sc);
                }
                    sendto_one(sptr, ":%s NOTICE %s :*** Your channel spy list is now empty",
                            me.name, sptr->name);
                SpyChForward2(&me, "CLEAR", sptr->name);
        }

        /* <INVALID OPTION> */
        else
        {
                    sendto_one(sptr, ":%s NOTICE %s :*** Invalid option %s",
                            me.name, sptr->name, cmd);
                return -1;
        }

        return 0;
}

// ==================================================================
// m_spyforward: Keeps SpyList updated on all servers
// ==================================================================

DLLFUNC int m_spyforward(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        SpyStruct        *s;
        ListStruct        *next;
        aClient                *acptr;
        char                *tmp, *cmd, *who, *nick1, *nick2, *channel;
        u_int                lock1, lock2;

        if (IsClient(cptr))
        {
                sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
                return -1;
        }

        cmd        = IsParam(1)                ? parv[1] : NULL;
        who        = IsParam(2)                ? parv[2] : NULL;
        nick1        = IsParam(3)                ? parv[3] : NULL;
        nick2        = IsValidParam(4)        ? parv[4] : NULL;
        channel        = IsValidParam(5)        ? parv[5] : NULL;

        /* sendto_realops("(\2m_spyforward\2) cptr=%s, sptr=%s, cmd=%s who=%s nick1=%s nick2=%s channel=%s",
                cptr->name, sptr->name,
                cmd        ? cmd                : "(null)",
                who        ? who                : "(null)",
                nick1        ? nick1                : "(null)",
                nick2        ? nick2                : "(null)",
                channel        ? channel        : "(null)"); */

        if (!cmd)
                return -1;
        if (nick1)
                SplitLock(lock1, nick1);
        if (nick2)
                SplitLock(lock2, nick2);

        /* ADD */
        if (!strcasecmp(cmd, "add"))
        {
                if (!nick1)
                        return -1;
                if (nick2 && !strcasecmp(nick1, nick2))
                        return -1;
                if (nick2 && (smycmp(nick1, nick2) > 0))
                {
                        tmp        = nick1;
                        nick1        = nick2;
                        nick2        = tmp;
                }
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                if ((nick2 && FindSpyItem2(acptr, nick1, nick2)) || (!nick2 && FindSpyItem1(acptr, nick1)))
                        return -1;
                AddSpyItem(acptr, nick1, nick2, channel, lock1, lock2);
                SpyForward5(cptr, "ADD", acptr->name, nick1, nick2, channel, lock1, lock2);
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPY ADD %s%s" "%s" "%s%s" "%s" "%s",
                        acptr->name, MergeLock(lock1, nick1),
                        nick2 ? " " : "", MergeLockEmp(lock2, nick2),
                        channel ? " " : "", channel ? channel : "");
        }

        /* ADD2 -- Like ADD, but without forwarding */
        if (!strcasecmp(cmd, "add2"))
        {
                if (!nick1)
                        return -1;
                if (nick2 && !strcasecmp(nick1, nick2))
                        return -1;
                if (nick2 && (smycmp(nick1, nick2) > 0))
                {
                        tmp        = nick1;
                        nick1        = nick2;
                        nick2        = tmp;
                }
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                if ((nick2 && FindSpyItem2(acptr, nick1, nick2)) || (!nick2 && FindSpyItem1(acptr, nick1)))
                        return -1;
                AddSpyItem(acptr, nick1, nick2, channel, lock1, lock2);
        }

        /* DEL */
        else if (!strcasecmp(cmd, "del"))
        {
                if (!nick1)
                        return -1;
                if (nick2 && (smycmp(nick1, nick2) > 0))
                {
                        tmp        = nick1;
                        nick1        = nick2;
                        nick2        = tmp;
                }
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                if ((nick2 && !(s = FindSpyItem2(acptr, nick1, nick2))) || (!nick2 && !(s = FindSpyItem1(acptr, nick1))))
                        return -1;
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPY DEL %s%s%s",
                        acptr->name, s->nick1, s->nick2 ? " " : "", s->nick2 ? s->nick2 : "");
                SpyForward4(cptr, "DEL", acptr->name, s->nick1, s->nick2, 0, 0);
                DelSpyItem(s);
        }

        /* CLEAR */
        else if (!strcasecmp(cmd, "clear"))
        {
                if (!who)
                        return -1;
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                for (s = SpyList; s; s = (SpyStruct *) next)
                {
                        next = (ListStruct *) s->next;
                        if (s->who == acptr)
                                DelSpyItem(s);
                }
                SpyForward2(cptr, "CLEAR", acptr->name);
        }

        /* CONNECT */
        else if (!strcasecmp(cmd, "connect"))
        {
                for (s = SpyList; s; s = s->next)
                        /* act as a client who is just adding a spy entry */
                        SpyForward5(&me, "ADD", s->who->name, s->nick1, s->nick2,
                                s->chname, s->lock1, s->lock2);
        }

        /* <INVALID OPTION> */
        else
        {
                return -1;
        }

        return 0;
}

// ==================================================================
// m_spychforward: Keeps SpyChList updated on all servers
// ==================================================================

DLLFUNC int m_spychforward(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        SpyChStruct        *sc;
        ListStruct        *next;
        aClient                *acptr;
        char                *cmd, *who, *channel, *sendto;
        u_int                lock;

        if (IsClient(cptr))
        {
                sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
                return -1;
        }

        cmd        = IsParam(1)                ? parv[1] : NULL;
        who        = IsParam(2)                ? parv[2] : NULL;
        channel        = IsValidParam(3)        ? parv[3] : NULL;
        sendto        = IsValidParam(4)        ? parv[4] : NULL;

        /* sendto_realops("(\2m_spychforward\2) cptr=%s, sptr=%s, cmd=%s who=%s channel=%s sendto=%s",
                cptr->name, sptr->name,
                cmd        ? cmd                : "(null)",
                who        ? who                : "(null)",
                channel        ? channel        : "(null)",
                sendto        ? sendto        : "(null)"); */

        if (!cmd)
                return -1;
        if (channel)
                SplitLock(lock, channel);

        /* ADD */
        if (!strcasecmp(cmd, "add"))
        {
                if (!channel)
                        return -1;
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                if (FindSpyChItem(acptr, channel))
                        return -1;
                AddSpyChItem(acptr, channel, sendto, lock);
                SpyChForward4(cptr, "ADD", acptr->name, channel, sendto, lock);
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPYCHANNEL ADD %s%s" "%s" "%s",
                        acptr->name, MergeLock(lock, channel),
                        sendto ? " " : "", sendto ? sendto : "");
        }

        /* ADD2 -- Like ADD, but without forwarding */
        if (!strcasecmp(cmd, "add2"))
        {
                if (!channel)
                        return -1;
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                if (FindSpyChItem(acptr, channel))
                        return -1;
                AddSpyChItem(acptr, channel, sendto, lock);
        }

        /* DEL */
        else if (!strcasecmp(cmd, "del"))
        {
                if (!channel)
                        return -1;
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                if (!(sc = FindSpyChItem(acptr, channel)))
                        return -1;
                sendto_snomask(SNO_SPY, "*** [\2m_spy\2] %s used /SPYCHANNEL DEL %s",
                        acptr->name, sc->channel);
                SpyChForward3(cptr, "DEL", acptr->name, sc->channel, 0);
                DelSpyChItem(sc);
        }

        /* CLEAR */
        else if (!strcasecmp(cmd, "clear"))
        {
                if (!who)
                        return -1;
                if (!(acptr = find_person(who, NULL)))
                        return -1;
                for (sc = SpyChList; sc; sc = (SpyChStruct *) next)
                {
                        next = (ListStruct *) sc->next;
                        if (sc->who == acptr)
                                DelSpyChItem(sc);
                }
                SpyChForward2(cptr, "CLEAR", acptr->name);
        }

        /* CONNECT */
        else if (!strcasecmp(cmd, "connect"))
        {
                for (sc = SpyChList; sc; sc = sc->next)
                        /* act as a client who is just adding a channel spy entry */
                        SpyChForward4(&me, "ADD", sc->who->name, sc->channel,
                                sc->sendto, sc->lock);
        }

        /* <INVALID OPTION> */
        else
        {
                return -1;
        }

        return 0;
}

// ==================================================================
// m_spysend: Sends users' private messages to a client on the network
//        Easier way?
// ==================================================================

DLLFUNC int m_spysend(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        aClient                *acptr;
        char                *from, *to, *cmd, *nick1, *nick2, *text;
        unsigned        notice;

        if (!IsServer(sptr) || !IsParam(5))
                return -1;

        to        = IsParam(1)                ? parv[1] : NULL;
        cmd        = IsParam(2)                ? parv[2] : NULL;
        nick1        = IsParam(3)                ? parv[3] : NULL;
        nick2        = IsParam(4)                ? parv[4] : NULL;
        text        = IsParam(5)                ? parv[5] : NULL;

        if (!text)
                return -1;

        notice        = *cmd == 'N' ? 1 : 0;

        if (*to == '#')
                spy_send_channel(cptr, to, notice,
                        nick1, nick2, text);
        else
        {
                if (!(acptr = find_person(to, NULL)))
                        return -1;
                spy_send_client(acptr, notice,
                        nick1, nick2, text);
        }

        return 0;
}

// ==================================================================
// m_spychsend: Sends users' channel messages to a client on the network
//        Easier way?
// ==================================================================

DLLFUNC int m_spychsend(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        aClient                *acptr;
        char                *to, *cmd, *nick, *channel, *text;
        unsigned        notice;

        if (!IsServer(sptr) || !IsParam(5))
                return -1;

        to        = IsParam(1)                ? parv[1] : NULL;
        cmd        = IsParam(2)                ? parv[2] : NULL;
        nick        = IsParam(3)                ? parv[3] : NULL;
        channel        = IsParam(4)                ? parv[4] : NULL;
        text        = IsParam(5)                ? parv[5] : NULL;

        if (!text)
                return -1;

        notice        = *cmd == 'N' ? 1 : 0;

        if (*to == '#')
                spy_send_channel(cptr, to, notice,
                        nick, channel, text);
        else
        {
                if (!(acptr = find_person(to, NULL)))
                        return -1;
                spy_send_client(acptr, notice,
                        nick, channel, text);
        }

        return 0;
}

/*
 * m_spystats
 *
 * Displays SpyList statistics based on a given nickname. If you leave out
 * <nickname>, all SpyList entries will be displayed.
 *
 * :prefix SPYSTATS [<nickname>]
 * parv[0] - (sender)
 * parv[1] - channel|message
 * parv[2] - <nickname> (optional)
 *
 */

DLLFUNC int m_spystats(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        SpyStruct        *s;
        SpyChStruct        *sc;
        aClient                *acptr = NULL;
        unsigned long        item = 0, count = 0, total = 0;
        unsigned long        subcount = 0, subtotal = 0;
        char                *cmd;

        if (!MyClient(cptr) || !IsOper(cptr) || !IsSAdmin(cptr))
        {
                sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
                return -1;
        }
        if (!IsParam(1))
        {
                    sendto_one(sptr, ":%s NOTICE %s :*** Usage: /spystats private|channel [<nickname>]",
                            me.name, sptr->name);
                return 0;
        }

        cmd = parv[1];

        /* PRIVATE */
        if (!strcasecmp(cmd, "private"))
        {
                if (!SpyList)
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** Private spy list is empty",
                                    me.name, sptr->name);
                        return 0;
                }
                if (IsParam(2) && !(acptr = find_person(parv[2], NULL)))
                {
                            sendto_one(sptr, err_str(ERR_NOSUCHNICK),
                                me.name, sptr->name, parv[2]);
                            return -1;
                }

                for (s = SpyList; s; s = s->next)
                {
                        item = sizeof(*s) + 1; /* 1 byte is the size of (lock1 + lock2) */
                        item += sizeof(char) * (strlen(s->nick1) + 1);
                        if (s->nick2)
                                item += sizeof(char) * (strlen(s->nick2) + 1);
                        if (s->chname)
                                item += sizeof(char) * (strlen(s->chname) + 1);
                        if (acptr && s->who == acptr)
                        {
                                subtotal += item;
                                subcount++;
                        }
                        total += item;
                        count++;

                        if (!acptr || s->who == acptr)
                                    sendto_one(sptr, ":%s NOTICE %s :*** %s (%s%s): %s%s %s (mem: %ld)",
                                            me.name, sptr->name,
                                        s->who->name,
                                        MergeLock(s->lock1, s->nick1),
                                        MergeLockOpt(s->lock2, s->nick2),
                                        s->chname ? s->chname : "<irc>",
                                        item);
                }

                if (acptr)
                {
                        sendto_one(sptr, ":%s NOTICE %s :*** " SPY_LINE,
                                me.name, sptr->name);
                            sendto_one(sptr, ":%s NOTICE %s :*** Sub total (%s): %ld entr%s (mem: %ld)",
                                    me.name, sptr->name,
                                acptr->name,
                                subcount, count > 1 ? "ies" : "y",
                                subtotal);
                }

                sendto_one(sptr, ":%s NOTICE %s :*** " SPY_LINE,
                        me.name, sptr->name);

                sendto_one(sptr, ":%s NOTICE %s :*** Total: %d entr%s (mem: %ld)",
                        me.name, sptr->name,
                        count, count > 1 ? "ies" : "y",
                        total);
        }

        /* CHANNEL */
        else if (!strcasecmp(cmd, "channel"))
        {
                if (!SpyChList)
                {
                            sendto_one(sptr, ":%s NOTICE %s :*** Channel spy list is empty",
                                    me.name, sptr->name);
                        return 0;
                }
                if (IsParam(2) && !(acptr = find_person(parv[2], NULL)))
                {
                            sendto_one(sptr, err_str(ERR_NOSUCHNICK),
                                me.name, sptr->name, parv[2]);
                            return -1;
                }

                for (sc = SpyChList; sc; sc = sc->next)
                {
                        item = sizeof(*sc) + sizeof(sc->lock);
                        item += sizeof(char) * (strlen(sc->channel) + 1);
                        if (sc->sendto)
                                item += sizeof(char) * (strlen(sc->sendto) + 1);
                        if (acptr && sc->who == acptr)
                        {
                                subtotal += item;
                                subcount++;
                        }
                        total += item;
                        count++;

                        if (!acptr || sc->who == acptr)
                                    sendto_one(sptr, ":%s NOTICE %s :*** %s (%s%s): %s (mem: %ld)",
                                            me.name, sptr->name,
                                        sc->who->name,
                                        MergeLock(sc->lock, sc->channel),
                                        sc->sendto ? sc->sendto : "<irc>",
                                        item);
                }

                if (acptr)
                {
                        sendto_one(sptr, ":%s NOTICE %s :*** " SPY_LINE,
                                me.name, sptr->name);
                            sendto_one(sptr, ":%s NOTICE %s :*** Sub total (%s): %ld entr%s (mem: %ld)",
                                    me.name, sptr->name,
                                acptr->name,
                                subcount, count > 1 ? "ies" : "y",
                                subtotal);
                }

                sendto_one(sptr, ":%s NOTICE %s :*** " SPY_LINE,
                        me.name, sptr->name);

                sendto_one(sptr, ":%s NOTICE %s :*** Total: %d entr%s (mem: %ld)",
                        me.name, sptr->name,
                        count, count > 1 ? "ies" : "y",
                        total);
        }

        /* <INVALID OPTION> */
        else
        {
                    sendto_one(sptr, ":%s NOTICE %s :*** Invalid option %s",
                            me.name, sptr->name, cmd);
                return -1;
        }
       
        return 0;
}


Delioper 15 Nisan 2014 02:34

Cevap: özel okuma modülü hatası
 
Bu işe yaradı tşk

No_FeaR 15 Nisan 2014 20:34

Cevap: özel okuma modülü hatası
 
Yardımcı Olabildiysek Ne Mutlu...


Tüm Zamanlar GMT +3 Olarak Ayarlanmış. Şuanki Zaman: 05:00.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions, Inc.
Search Engine Friendly URLs by vBSEO
Copyright ©2004 - 2025 IRCForumlari.Net Sparhawk