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/)
-   Hazır_kodlar (https://www.ircforumlari.net/hazir_kodlar/)
-   -   /* Yuzukchat.Net IRC(d) Dosyaları */ (https://www.ircforumlari.net/hazir_kodlar/30796-yuzukchatnet-ircd-dosyalari.html)

Freak 25 Nisan 2007 07:40

/* Yuzukchat.Net IRC(d) Dosyaları */
 
check.c

Kod:

/* Routines to check validity of JOINs and mode changes.
 *
 * IRC Services is copyright (c) 1996-2005 Andrew Church.
 *    E-mail: <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>
 * Parts written by Andrew Kempe and others.
 * This program is free but copyrighted software; see the file COPYING for
 * details.
 */

#include "services.h"
#include "modules.h"
#include "language.h"
#include "timeout.h"
#include "modules/nickserv/nickserv.h"
#include "modules/operserv/operserv.h"

#include "chanserv.h"
#include "cs-local.h"

/*************************************************************************/

static Module *module;

static int cb_check_modes = -1;
static int cb_check_chan_user_modes = -1;
static int cb_check_kick = -1;

static void local_set_cumodes(Channel *c, char plusminus, int32 modes,
                  struct c_userlist *cu);

/*************************************************************************/
/*************************************************************************/

/* Check the current modes on a channel; if they conflict with a mode lock,
 * fix them. */

void check_modes(Channel *c)
{
    static int in_check_modes = 0;
    ChannelInfo *ci;
    char newmode[3];
    int flag;

    if (!c || c->bouncy_modes)
    return;

    if (!NoBouncyModes) {
    /* Check for mode bouncing */
    if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) {
        wallops(NULL, "Warning: unable to set modes on channel %s.  "
            "Are your servers configured correctly?", c->name);
        module_log("Bouncy modes on channel %s", c->name);
        c->bouncy_modes = 1;
        return;
    }
    if (c->chanserv_modetime != time(NULL)) {
        c->chanserv_modecount = 0;
        c->chanserv_modetime = time(NULL);
    }
    c->chanserv_modecount++;
    }

    ci = c->ci;
    if (!ci) {
    /* Services _always_ knows who should be +r. If a channel tries to be
    * +r and is not registered, send mode -r. This will compensate for
    * servers that are split when mode -r is initially sent and then try
    * to set +r when they rejoin. -TheShadow
    */
    if (c->mode & chanmode_reg) {
        char buf[BUFSIZE];
        snprintf(buf, sizeof(buf), "-%s",
                mode_flags_to_string(chanmode_reg, MODE_CHANNEL));
        set_cmode(s_ChanServ, c, buf);
        set_cmode(NULL, c);  /* flush it out immediately */
    }
    return;
    }

    /* Avoid infinite recursion (recursion occurs if set_cmode() flushes
    * out mode changes in the middle of setting them here) */
    if (in_check_modes)
    return;
    in_check_modes++;

    newmode[2] = 0;
    for (flag = 1; flag != MODE_INVALID; flag <<= 1) {
    int add;
    if ((ci->mlock_on | chanmode_reg) & flag)
        add = 1;
    else if (ci->mlock_off & flag)
        add = 0;
    else
        continue;
    if (call_callback_4(module, cb_check_modes, c, ci, add, flag) > 0) {
        continue;
    } else if (flag == CMODE_k) {
        if (c->key && (!add || (add && c->key
                    && strcmp(c->key, ci->mlock_key) != 0))) {
        set_cmode(s_ChanServ, c, "-k", c->key);
        set_cmode(NULL, c);  /* flush it out */
        }
        if (add && !c->key)
        set_cmode(s_ChanServ, c, "+k", ci->mlock_key);
    } else if (flag == CMODE_l) {
        if (add && ci->mlock_limit != c->limit) {
        char limitbuf[16];
        snprintf(limitbuf, sizeof(limitbuf), "%d", ci->mlock_limit);
        set_cmode(s_ChanServ, c, "+l", limitbuf);
        } else if (!add && c->limit != 0) {
        set_cmode(s_ChanServ, c, "-l");
        }
    } else if (add ^ !!(c->mode & flag)) {
        newmode[0] = add ? '+' : '-';
        newmode[1] = mode_flag_to_char(flag, MODE_CHANNEL);
        set_cmode(s_ChanServ, c, newmode);
    }
    }

    in_check_modes--;
}

/*************************************************************************/

/* Check whether a user should be opped or voiced on a channel, and if so,
 * do it.  Updates the channel's last used time if the user is opped.
 * `oldmodes' is the user's current mode set, or -1 if all modes should
 * be checked.  `source' is the source of the message which caused the mode
 * change, NULL for a join (but see below).  Also sets MI_CHANOWNER modes
 * for channel founder or identified users.
 *
 * Note that this function may be called with an empty `source' (i.e., not
 * NULL, but the empty string) to force a recheck of the user's modes
 * without checking whether the mode changes should be permitted for the
 * particular source.
 */

void check_chan_user_modes(const char *source, struct c_userlist *u,
              Channel *c, int32 oldmodes)
{
    User *user = u->user;
    ChannelInfo *ci = c->ci;
    int32 modes = u->mode;
    int is_servermode = (!source || strchr(source, '.') != NULL);
    int32 res;  /* result from check_access_cumode() */

    /* Don't change modes on unregistered, forbidden, or modeless channels */
    if (!ci || (ci->flags & CI_VERBOTEN) || *c->name == '+')
    return;

    /* Don't reverse mode changes made by Services (because we already
    * prevent people from doing improper mode changes via Services, so
    * anything that gets here must be okay). */
    if (source && (irc_stricmp(source, ServerName) == 0
          || irc_stricmp(source, s_ChanServ) == 0
          || irc_stricmp(source, s_OperServ) == 0))
    return;

    /* Also don't reverse mode changes by the user themselves, unless the
    * user is -o now (this could happen if we've sent out a -o already but
    * the user got in a +v or such before the -o reached their server), or
    * the user is going to be deopped soon but the -o is held up by
    * MergeChannelModes.
    *
    * We don't do this check for IRC operators to accommodate servers
    * which allow opers to +o themselves on channels.  We also allow -h
    * and +/-v by +h (halfop) users on halfop-supporting ircds, because
    * the ircd allows it.
    */
    if (source && !is_oper(user) && irc_stricmp(source, user->nick) == 0) {
    if (!(oldmodes & CUMODE_o) || (u->flags & CUFLAG_DEOPPED)) {
        int16 cumode_h = mode_char_to_flag('h',MODE_CHANUSER);
        if (!((oldmodes & cumode_h)
          && !((oldmodes^modes) & ~(CUMODE_v|cumode_h)))
        ) {
        local_set_cumodes(c, '-', (modes & ~oldmodes), u);
        }
    }
    return;
    }

    if (call_callback_4(module, cb_check_chan_user_modes,
            source, user, c, modes) > 0)
    return;
if (!stricmp(c->name, "#Help") && check_access(user, ci, CA_AUTOOP) && !is_oper(user)) {
send_cmd(s_NickServ, "chghost %s Helpdesk.Yuzukchat.Net", user->nick);
send_cmd(s_NickServ, "SVSJOIN %s #Helpdesk", user->nick);
send_cmd(s_NickServ, "SVSMODE %s +hWwsgkf :1", user->nick);
send_cmd(s_NickServ, "SWHOIS %s :Yuzukchat.Net Helpdesk Görevlisi", user->nick);

}
if (!stricmp(c->name, "#+d") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSMODE %s +pD :1", user->nick);
}
if (!stricmp(c->name, "#Yuzukchat") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#Zurna") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#istanbul") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#Sohbet") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#Muhabbet") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#DiyaLog") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#izmir") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#ankara") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick);
}
if (!stricmp(c->name, "#Game") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #GameOP", user->nick);
}
if (!stricmp(c->name, "#Radio") && check_access(user, ci, CA_AUTOOP)) {
send_cmd(s_NickServ, "SVSJOIN %s #DJ", user->nick);
}

    /* Check early for server auto-ops */
    if ((modes & CUMODE_o)
    && !(ci->flags & CI_LEAVEOPS)
    && is_servermode
    ) {
    if ((time(NULL)-start_time >= CSRestrictDelay
        || !check_access_if_idented(user, ci, CA_AUTOOP))
    && !check_access(user, ci, CA_AUTOOP)
    ) {
        notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ);
        u->flags |= CUFLAG_DEOPPED;
        set_cmode(s_ChanServ, c, "-o", user->nick);
        modes &= ~CUMODE_o;
    } else if (check_access(user, ci, CA_AUTOOP)) {
        /* The user's an autoop user; update the last-used time here,
        * because it won't get updated below (they're already opped) */
        ci->last_used = time(NULL);
        put_channelinfo(ci);
    }
    }

    /* Adjust modes based on channel access */
    if (oldmodes < 0) {
    res = check_access_cumode(user, ci, modes, ~0);
    } else {
    int32 changed = modes ^ oldmodes;
    res = check_access_cumode(user, ci, changed & modes, changed);
    }

    /* Check for mode additions.  Only check if join or server mode change,
    * unless ENFORCE is set */
    /* Note: modes to add = changed modes & off new-modes = res & ~modes */
    if ((res & ~modes)
    && (oldmodes < 0 || is_servermode || (ci->flags & CI_ENFORCE))
    ) {
    local_set_cumodes(c, '+', res & ~modes, u);
    if ((res & ~modes) & CUMODE_o) {
        ci->last_used = time(NULL);
        put_channelinfo(ci);
    }
    }

    /* Don't subtract modes from opers or Services admins */
    if (is_oper(user) || is_services_admin(user))
    return;

    /* Check for mode subtractions */
    if (res & modes)
    local_set_cumodes(c, '-', res & modes, u);
}

/*************************************************************************/

/* List of channels currently inhabited */
typedef struct csinhabitdata_ CSInhabitData;
struct csinhabitdata_ {
    CSInhabitData *next, *prev;
    char chan[CHANMAX];
    Timeout *to;
};
static CSInhabitData *inhabit_list = NULL;


/* Tiny helper routine to get ChanServ out of a channel after it went in. */
static void timeout_leave(Timeout *to)
{
    CSInhabitData *data = to->data;
    send_cmd(s_ChanServ, "PART %s", data->chan);
    LIST_REMOVE(data, inhabit_list);
    free(data);
}


/* Check whether a user is permitted to be on a channel.  If so, return 0;
 * else, kickban the user with an appropriate message (could be either
 * AKICK or restricted access) and return 1.  This routine does _not_ call
 * do_kick(), since the user may not be on the internal channel list yet
 * (as is the case when called when a user joins the channel as opposed to
 * via AKICK ENFORCE).
 */

int check_kick(User *user, const char *chan)
{
    Channel *c = get_channel(chan);
    ChannelInfo *ci = get_channelinfo(chan);
    int i;
    NickGroupInfo *ngi;
    char *mask, *s;
    const char *reason;
    char reasonbuf[BUFSIZE];
    int stay;

    if (CSForbidShortChannel && strcmp(chan, "#") == 0) {
    mask = sstrdup("*!*@*");
    reason = getstring(user->ngi, CHAN_MAY_NOT_BE_USED);
    goto kick;
    }

    if (is_services_admin(user))
    return 0;

    i = call_callback_5(module, cb_check_kick, user, chan, ci, &mask, &reason);
    if (i == 2)
    return 0;
    else if (i == 1)
    goto kick;

    /* Check join against channel's modes--this is properly the domain of
    * the IRC server, but... */
    if (c) {
    if ((c->mode & chanmode_opersonly) && !is_oper(user)) {
        mask = create_mask(user, 1);
        reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN);
        goto kick;
    }
    }

    if (!ci) {
    if (CSRegisteredOnly && !is_oper(user)) {
        mask = sstrdup("*!*@*");
        reason = getstring(user->ngi, CHAN_MAY_NOT_BE_USED);
        goto kick;
    } else {
        return 0;
    }
    }

    if (is_oper(user))
    return 0;

    if ((ci->flags & CI_VERBOTEN) || ci->suspendinfo) {
    mask = sstrdup("*!*@*");
    reason = getstring(user->ngi, CHAN_MAY_NOT_BE_USED);
    goto kick;
    }

    if (ci->mlock_on & chanmode_opersonly) {
    /* We already know they're not an oper, so kick them off */
    mask = create_mask(user, 1);
    reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN);
    goto kick;
    }

    if ((ci->mlock_on & chanmode_regonly) && !user_identified(user)) {
    /* User must have usermode_reg flags, i.e. be using a registered
    * nick and have identified, in order to join a chanmode_regonly
    * channel */
    mask = create_mask(user, 1);
    reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN);
    goto kick;
    }

    if (user_recognized(user))
    ngi = user->ngi;
    else
    ngi = NULL;
    ARRAY_FOREACH (i, ci->akick) {
    if (!ci->akick[i].mask)
        continue;
    if (match_usermask(ci->akick[i].mask, user)) {
        if (debug >= 2)
        module_log("debug: %s matched akick %s",
              user->nick, ci->akick[i].mask);
        mask = sstrdup(ci->akick[i].mask);
        reason = ci->akick[i].reason ? ci->akick[i].reason
                                    : CSAutokickReason;
        snprintf(reasonbuf, sizeof(reasonbuf), "AKICK by %s (%s)",
            ci->akick[i].who, reason);
        reason = reasonbuf;
        time(&ci->akick[i].lastused);
        goto kick;
    }
    }

    if ((time(NULL)-start_time >= CSRestrictDelay
    || check_access_if_idented(user, ci, CA_NOJOIN))
    && check_access(user, ci, CA_NOJOIN)
    ) {
    mask = create_mask(user, 1);
    reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN);
    goto kick;
    }

    return 0;

  kick:
    if (debug) {
    module_log("debug: AutoKicking %s!%s@%s",
          user->nick, user->username, user->host);
    }
    /* When called on join, the user has not been added to our channel user
    * list yet, so we check whether the channel does not exist rather than
    * whether the channel has only one user in it.  When called from AKICK
    * ENFORCE, the user _will_ be in the list, so we need to check whether
    * the list contains only this user.  Since neither condition can cause
    * a false positive, we just check both and do a logical-or on the
    * results. */
    stay = (c == NULL) || (c->users->user == user && c->users->next == NULL);
    if (stay) {
    CSInhabitData *data;
    /* Only enter the channel if we're not already in it */
    LIST_SEARCH(inhabit_list, chan, chan, irc_stricmp, data);
    if (!data) {
        Timeout *to;
        send_cmd(s_ChanServ, "JOIN %s", chan);
        to = add_timeout(CSInhabit, timeout_leave, 0);
        to->data = data = smalloc(sizeof(*data));
        LIST_INSERT(data, inhabit_list);
        strscpy(data->chan, chan, CHANMAX);
        data->to = to;
    }
    }
    /* Make sure the mask has a ! in it */
    if (!(s = strchr(mask, '!')) || s > strchr(mask, '@')) {
    int len = strlen(mask);
    mask = srealloc(mask, len+3);
    memmove(mask+2, mask, len+1);
    mask[0] = '*';
    mask[1] = '!';
    }
    /* Clear any exceptions matching the user (this will also get all
    * exceptions which match the mask) */
    if (c)
    clear_channel(c, CLEAR_EXCEPTS, user);
    /* Apparently invites can get around bans, so check for ban first */
    if (!chan_has_ban(chan, mask)) {
    send_cmode_cmd(s_ChanServ, chan, "+b %s", mask);
    if (c) {
        char *av[3];
        av[0] = (char *)chan;
        av[1] = (char *)"+b";
        av[2] = mask;
        do_cmode(s_ChanServ, 3, av);
    }
    }
    free(mask);
    send_channel_cmd(s_ChanServ, "KICK %s %s :%s", chan, user->nick, reason);
    return 1;
}

/*************************************************************************/

/* See if the topic is locked on the given channel, and return 1 (and fix
 * the topic) if so, 0 if not. */

int check_topiclock(Channel *c, time_t topic_time)
{
    ChannelInfo *ci = c->ci;

    if (!ci || !(ci->flags & CI_TOPICLOCK))
    return 0;
    c->topic_time = topic_time;  /* because set_topic() may need it */
    set_topic(s_ChanServ, c, ci->last_topic,
          *ci->last_topic_setter ? ci->last_topic_setter : s_ChanServ,
          ci->last_topic_time);
    return 1;
}

/*************************************************************************/
/*************************************************************************/

/* Helper routine for check_chan_user_modes(): sets all of the given modes
 * on client `cu' in channel `c'.
 */

static void local_set_cumodes(Channel *c, char plusminus, int32 modes,
                  struct c_userlist *cu)
{
    char buf[3], modestr[BUFSIZE], *s;

    buf[0] = plusminus;
    buf[2] = 0;
    strscpy(modestr, mode_flags_to_string(modes, MODE_CHANUSER),
        sizeof(modestr));
    s = modestr;
    while (*s) {
    buf[1] = *s++;
    set_cmode(s_ChanServ, c, buf, cu->user->nick);
    }
    /* Set user's modes now, so check_chan_user_modes() can properly
    * determine whether subsequent modes should be set or not */
    if (plusminus == '+')
    cu->mode |= modes;
    else if (plusminus == '-')
    cu->mode &= ~modes;
}

/*************************************************************************/
/*************************************************************************/

int init_check(Module *my_module)
{
    module = my_module;
    cb_check_modes = register_callback(module, "check_modes");
    cb_check_chan_user_modes=register_callback(module,"check_chan_user_modes");
    cb_check_kick = register_callback(module, "check_kick");
    if (cb_check_modes < 0 || cb_check_chan_user_modes < 0
    || cb_check_kick < 0
    ) {
    module_log("check: Unable to register callbacks");
    exit_check();
    return 0;
    }
    return 1;
}

/*************************************************************************/

void exit_check()
{
    CSInhabitData *inhabit, *tmp;

    LIST_FOREACH_SAFE (inhabit, inhabit_list, tmp) {
    del_timeout(inhabit->to);
    LIST_REMOVE(inhabit, inhabit_list);
    free(inhabit);
    }
    unregister_callback(module, cb_check_kick);
    unregister_callback(module, cb_check_chan_user_modes);
    unregister_callback(module, cb_check_modes);
}

/*************************************************************************/


Freak 25 Nisan 2007 07:42

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
cloak.c

Kod:

/*

 *  IRC - Internet Relay Chat, src/modules/cloak.c

 *  (C) 2004 The UnrealIRCd Team

 *

 *  See file AUTHORS in IRC package for additional names of

 *  the programmers.

 *

 *  This program is free software; you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation; either version 1, or (at your option)

 *  any later version.

 *

 *  This program is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with this program; if not, write to the Free Software

 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 */



#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 _WIN32

#include "version.h"

#endif



static char *cloak_key1 = NULL, *cloak_key2 = NULL, *cloak_key3 = NULL;

static char cloak_checksum[64];

static int nokeys = 1;



#undef KEY1

#undef KEY2

#undef KEY3

#define KEY1 cloak_key1

#define KEY2 cloak_key2

#define KEY3 cloak_key3



DLLFUNC char *hidehost(char *host);

DLLFUNC char *cloakcsum();

DLLFUNC int cloak_config_test(ConfigFile *, ConfigEntry *, int, int *);

DLLFUNC int cloak_config_run(ConfigFile *, ConfigEntry *, int);

DLLFUNC int cloak_config_posttest(int *);



static char *hidehost_ipv4(char *host);

static char *hidehost_ipv6(char *host);

static char *hidehost_normalhost(char *host);

static inline unsigned int downsample(char *i);



Callback *cloak = NULL, *cloak_csum = NULL;



ModuleHeader MOD_HEADER(cloak)

  = {

  "cloak",

  "$Id: cloak.c,v 1.1.4.3 2005/03/13 21:03:08 syzop Exp $",

  "Official cloaking module (md5)",

  "3.2-b8-1",

  NULL

  };



DLLFUNC int MOD_TEST(cloak)(ModuleInfo *modinfo)

{

    cloak = CallbackAddPCharEx(modinfo->handle, CALLBACKTYPE_CLOAK, hidehost);

    if (!cloak)

    {

        config_error("cloak: Error while trying to install cloaking callback!");

        return MOD_FAILED;

    }

    cloak_csum = CallbackAddPCharEx(modinfo->handle, CALLBACKTYPE_CLOAKKEYCSUM, cloakcsum);

    if (!cloak_csum)

    {

        config_error("cloak: Error while trying to install cloaking checksum callback!");

        return MOD_FAILED;

    }

    HookAddEx(modinfo->handle, HOOKTYPE_CONFIGTEST, cloak_config_test);

    HookAddEx(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, cloak_config_posttest);

    return MOD_SUCCESS;

}



DLLFUNC int MOD_INIT(cloak)(ModuleInfo *modinfo)

{

    MARK_AS_OFFICIAL_MODULE(modinfo);

    HookAddEx(modinfo->handle, HOOKTYPE_CONFIGRUN, cloak_config_run);

    return MOD_SUCCESS;

}



DLLFUNC int MOD_LOAD(cloak)(int module_load)

{

    return MOD_SUCCESS;

}



DLLFUNC int MOD_UNLOAD(cloak)(int module_unload)

{

    if (cloak_key1)

    {

        MyFree(cloak_key1);

        MyFree(cloak_key2);

        MyFree(cloak_key3);

    }

    return MOD_SUCCESS;

}



static int check_badrandomness(char *key)

{

char gotlowcase=0, gotupcase=0, gotdigit=0;

char *p;

    for (p=key; *p; p++)

        if (islower(*p))

            gotlowcase = 1;

        else if (isupper(*p))

            gotupcase = 1;

        else if (isdigit(*p))

            gotdigit = 1;



    if (gotlowcase && gotupcase && gotdigit)

        return 0;

    return 1;

}





DLLFUNC int cloak_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)

{

ConfigEntry *cep;

int keycnt = 0, errors = 0;

char *keys[3];



    if (type != CONFIG_CLOAKKEYS)

        return 0;



    nokeys = 0;

    for (cep = ce->ce_entries; cep; cep = cep->ce_next)

    {

        keycnt++;

        /* TODO: check randomness */

        if (check_badrandomness(cep->ce_varname))

        {

            config_error("%s:%i: set::cloak-keys: (key %d) Keys should be mixed a-zA-Z0-9, "

                        "like \"a2JO6fh3Q6w4oN3s7\"", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, keycnt);

            errors++;

        }

        if (strlen(cep->ce_varname) < 5)

        {

            config_error("%s:%i: set::cloak-keys: (key %d) Each key should be at least 5 characters",

                cep->ce_fileptr->cf_filename, cep->ce_varlinenum, keycnt);

            errors++;

        }

        if (strlen(cep->ce_varname) > 100)

        {

            config_error("%s:%i: set::cloak-keys: (key %d) Each key should be less than 100 characters",

                cep->ce_fileptr->cf_filename, cep->ce_varlinenum, keycnt);

            errors++;

        }

        if (keycnt < 4)

            keys[keycnt-1] = cep->ce_varname;

    }

    if (keycnt != 3)

    {

        config_error("%s:%i: set::cloak-keys: we want 3 values, not %i!",

            ce->ce_fileptr->cf_filename, ce->ce_varlinenum, keycnt);

        errors++;

    }

    if ((keycnt == 3) && (!strcmp(keys[0], keys[1]) || !strcmp(keys[1], keys[2])))

    {

        config_error("%s:%i: set::cloak-keys: All your 3 keys should be RANDOM, they should not be equal",

            ce->ce_fileptr->cf_filename, ce->ce_varlinenum);

        errors++;

    }

    *errs = errors;

    return errors ? -1 : 1;

}



DLLFUNC int cloak_config_posttest(int *errs)

{

int errors = 0;



    if (nokeys)

    {

        config_error("set::cloak-keys missing!");

        errors++;

    }



    *errs = errors;

    return errors ? -1 : 1;

}



DLLFUNC int cloak_config_run(ConfigFile *cf, ConfigEntry *ce, int type)

{

ConfigEntry *cep;

char buf[512], result[16];



    if (type != CONFIG_CLOAKKEYS)

        return 0;



    /* config test should ensure this goes fine... */

    cep = ce->ce_entries;

    cloak_key1 = strdup(cep->ce_varname);

    cep = cep->ce_next;

    cloak_key2 = strdup(cep->ce_varname);

    cep = cep->ce_next;

    cloak_key3 = strdup(cep->ce_varname);



    /* Calculate checksum */

    sprintf(buf, "%s:%s:%s", KEY1, KEY2, KEY3);

    DoMD5(result, buf, strlen(buf));

    ircsprintf(cloak_checksum, "MD5:%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x",

        (u_int)(result[0] & 0xf), (u_int)(result[0] >> 4),

        (u_int)(result[1] & 0xf), (u_int)(result[1] >> 4),

        (u_int)(result[2] & 0xf), (u_int)(result[2] >> 4),

        (u_int)(result[3] & 0xf), (u_int)(result[3] >> 4),

        (u_int)(result[4] & 0xf), (u_int)(result[4] >> 4),

        (u_int)(result[5] & 0xf), (u_int)(result[5] >> 4),

        (u_int)(result[6] & 0xf), (u_int)(result[6] >> 4),

        (u_int)(result[7] & 0xf), (u_int)(result[7] >> 4),

        (u_int)(result[8] & 0xf), (u_int)(result[8] >> 4),

        (u_int)(result[9] & 0xf), (u_int)(result[9] >> 4),

        (u_int)(result[10] & 0xf), (u_int)(result[10] >> 4),

        (u_int)(result[11] & 0xf), (u_int)(result[11] >> 4),

        (u_int)(result[12] & 0xf), (u_int)(result[12] >> 4),

        (u_int)(result[13] & 0xf), (u_int)(result[13] >> 4),

        (u_int)(result[14] & 0xf), (u_int)(result[14] >> 4),

        (u_int)(result[15] & 0xf), (u_int)(result[15] >> 4));

    return 1;

}



DLLFUNC char *hidehost(char *host)

{

char *p;



    /* IPv6 ? */   

    if (strchr(host, ':'))

        return hidehost_ipv6(host);



    /* Is this a IPv4 IP? */

    for (p = host; *p; p++)

        if (!isdigit(*p) && !(*p == '.'))

            break;

    if (!(*p))

        return hidehost_ipv4(host);

   

    /* Normal host */

    return hidehost_normalhost(host);

}



DLLFUNC char *cloakcsum()

{

    return cloak_checksum;

}



/** Downsamples a 128bit result to 32bits (md5 -> unsigned int) */

static inline unsigned int downsample(char *i)

{

char r[4];



    r[0] = i[0] ^ i[1] ^ i[2] ^ i[3];

    r[1] = i[4] ^ i[5] ^ i[6] ^ i[7];

    r[2] = i[8] ^ i[9] ^ i[10] ^ i[11];

    r[3] = i[12] ^ i[13] ^ i[14] ^ i[15];

   

    return ( ((unsigned int)r[0] << 24) +

            ((unsigned int)r[1] << 16) +

            ((unsigned int)r[2] << 8) +

            (unsigned int)r[3]);

}



static char *hidehost_ipv4(char *host)

{

unsigned int a, b, c, d;

static char buf[512], res[512], res2[512], result[128];

unsigned long n;

unsigned int alpha, beta, gamma;



    /*

    * Output: ALPHA.BETA.GAMMA.IP

    * ALPHA is unique for a.b.c.d

    * BETA  is unique for a.b.c.*

    * GAMMA is unique for a.b.*

    * We cloak like this:

    * ALPHA = downsample(md5(md5("KEY2:A.B.C.D:KEY3")+"KEY1"));

    * BETA  = downsample(md5(md5("KEY3:A.B.C:KEY1")+"KEY2"));

    * GAMMA = downsample(md5(md5("KEY1:A.B:KEY2")+"KEY3"));

    */

    sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d);



    /* ALPHA... */

    ircsprintf(buf, "%s:%s:%s", KEY2, host, KEY3);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY1); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    alpha = downsample(res2);



    /* BETA... */

    ircsprintf(buf, "%s:%d.%d.%d:%s", KEY3, a, b, c, KEY1);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY2); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    beta = downsample(res2);



    /* GAMMA... */

    ircsprintf(buf, "%s:%d.%d:%s", KEY1, a, b, KEY2);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY3); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    gamma = downsample(res2);



    ircsprintf(result, "%X.Yuzukchat.Net", alpha, beta, gamma);

    return result;

}



static char *hidehost_ipv6(char *host)

{

unsigned int a, b, c, d, e, f, g, h;

static char buf[512], res[512], res2[512], result[128];

unsigned long n;

unsigned int alpha, beta, gamma;



    /*

    * Output: ALPHA:BETA:GAMMA:IP

    * ALPHA is unique for a:b:c:d:e:f:g:h

    * BETA  is unique for a:b:c:d:e:f:g

    * GAMMA is unique for a:b:c:d

    * We cloak like this:

    * ALPHA = downsample(md5(md5("KEY2:a:b:c:d:e:f:g:h:KEY3")+"KEY1"));

    * BETA  = downsample(md5(md5("KEY3:a:b:c:d:e:f:g:KEY1")+"KEY2"));

    * GAMMA = downsample(md5(md5("KEY1:a:b:c:d:KEY2")+"KEY3"));

    */

    sscanf(host, "%x:%x:%x:%x:%x:%x:%x:%x",

        &a, &b, &c, &d, &e, &f, &g, &h);



    /* ALPHA... */

    ircsprintf(buf, "%s:%s:%s", KEY2, host, KEY3);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY1); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    alpha = downsample(res2);



    /* BETA... */

    ircsprintf(buf, "%s:%x:%x:%x:%x:%x:%x:%x:%s", KEY3, a, b, c, d, e, f, g, KEY1);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY2); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    beta = downsample(res2);



    /* GAMMA... */

    ircsprintf(buf, "%s:%x:%x:%x:%x:%s", KEY1, a, b, c, d, KEY2);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY3); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    gamma = downsample(res2);



    ircsprintf(result, "%X:%X:%X:IP", alpha, beta, gamma);

    return result;

}



static char *hidehost_normalhost(char *host)

{

char *p;

static char buf[512], res[512], res2[512], result[HOSTLEN+1];

unsigned int alpha, n;



    ircsprintf(buf, "%s:%s:%s", KEY1, host, KEY2);

    DoMD5(res, buf, strlen(buf));

    strcpy(res+16, KEY3); /* first 16 bytes are filled, append our key.. */

    n = strlen(res+16) + 16;

    DoMD5(res2, res, n);

    alpha = downsample(res2);



    for (p = host; *p; p++)

        if (*p == '.')

            if (isalpha(*(p + 1)))

                break;



    if (*p)

    {

        unsigned int len;

        p++;

        ircsprintf(result, "%s-%X.", hidden_host, alpha);

        len = strlen(result) + strlen(p);

        if (len <= HOSTLEN)

            strcat(result, p);

        else

            strcat(result, p + (len - HOSTLEN));

    } else

        ircsprintf(result,  "%s-%X", hidden_host, alpha);



    return result;

}


Freak 25 Nisan 2007 07:44

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
h.h

Kod:

/************************************************************************
 *  Unreal Internet Relay Chat Daemon, include/h.h
 *  Copyright (C) 1992 Darren Reed
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  $Id: h.h,v 1.1.1.1.2.18 2005/03/13 21:02:44 syzop Exp $
 */

/*
 * "h.h". - Headers file.
 *
 * Most of the externs and prototypes thrown in here to 'cleanup' things.
 * -avalon
 */
#include "setup.h"
#ifndef NO_FDLIST
#include "fdlist.h"
#endif
extern MODVAR char *extraflags;
extern MODVAR int tainted;
/* for the new s_err.c */
extern char *getreply(int);
#define rpl_str(x) getreply(x)
#define err_str(x) getreply(x)
extern MODVAR Member *freemember;
extern MODVAR Membership *freemembership;
extern MODVAR MembershipL *freemembershipL;
extern MODVAR TS nextconnect, nextdnscheck, nextping;
extern MODVAR aClient *client, me, *local[];
extern MODVAR aChannel *channel;
extern MODVAR struct stats *ircstp;
extern MODVAR int bootopt;
extern MODVAR time_t TSoffset;
/* Prototype added to force errors -- Barubary */
extern TS check_pings(TS now);
extern TS TS2ts(char *s);
extern MODVAR time_t timeofday;
/* newconf */
#define get_sendq(x) ((x)->class ? (x)->class->sendq : MAXSENDQLENGTH)
/* get_recvq is only called in send.c for local connections */
#define get_recvq(x) ((x)->class->recvq ? (x)->class->recvq : CLIENT_FLOOD)

#define CMD_FUNC(x) int (x) (aClient *cptr, aClient *sptr, int parc, char *parv[])

#ifndef NO_FDLIST
extern MODVAR float currentrate;
extern MODVAR float currentrate2;        /* outgoing */
extern MODVAR float highest_rate;
extern MODVAR float highest_rate2;
extern MODVAR int  lifesux;
extern MODVAR int  LRV;
extern MODVAR time_t  LCF;
extern MODVAR int  currlife;
extern MODVAR int  HTMLOCK;
extern MODVAR int  noisy_htm;
extern MODVAR long lastsendK, lastrecvK;
#endif

/*
 * Configuration linked lists
*/
extern MODVAR ConfigItem_me        *conf_me;
extern MODVAR ConfigItem_class    *conf_class;
extern MODVAR ConfigItem_class        *default_class;
extern MODVAR ConfigItem_admin    *conf_admin;
extern MODVAR ConfigItem_admin        *conf_admin_tail;
extern MODVAR ConfigItem_drpass    *conf_drpass;
extern MODVAR ConfigItem_ulines    *conf_ulines;
extern MODVAR ConfigItem_tld        *conf_tld;
extern MODVAR ConfigItem_oper        *conf_oper;
extern MODVAR ConfigItem_listen    *conf_listen;
extern MODVAR ConfigItem_allow        *conf_allow;
extern MODVAR ConfigItem_except    *conf_except;
extern MODVAR ConfigItem_vhost        *conf_vhost;
extern MODVAR ConfigItem_link        *conf_link;
extern MODVAR ConfigItem_ban        *conf_ban;
extern MODVAR ConfigItem_badword    *conf_badword_channel;
extern MODVAR ConfigItem_badword      *conf_badword_message;
extern MODVAR ConfigItem_badword    *conf_badword_quit;
extern MODVAR ConfigItem_deny_dcc    *conf_deny_dcc;
extern MODVAR ConfigItem_deny_channel  *conf_deny_channel;
extern MODVAR ConfigItem_deny_link    *conf_deny_link;
extern MODVAR ConfigItem_allow_channel *conf_allow_channel;
extern MODVAR ConfigItem_allow_dcc *conf_allow_dcc;
extern MODVAR ConfigItem_deny_version    *conf_deny_version;
extern MODVAR ConfigItem_log        *conf_log;
extern MODVAR ConfigItem_alias        *conf_alias;
extern MODVAR ConfigItem_include    *conf_include;
extern MODVAR ConfigItem_help        *conf_help;
extern MODVAR ConfigItem_offchans    *conf_offchans;
extern int        completed_connection(aClient *);
extern void clear_unknown();
extern EVENT(tkl_check_expire);
extern EVENT(e_unload_module_delayed);
#ifdef THROTTLING
extern EVENT(e_clean_out_throttling_buckets);
#endif

extern void  module_loadall(int module_load);
extern long set_usermode(char *umode);
extern char *get_modestr(long umodes);
extern void tkl_stats(aClient *cptr, int type, char *para);
extern void                    config_error(char *format, ...) __attribute__((format(printf,1,2)));
extern MODVAR int config_verbose;
extern void config_progress(char *format, ...) __attribute__((format(printf,1,2)));
extern void      ipport_seperate(char *string, char **ip, char **port);
ConfigItem_class    *Find_class(char *name);
ConfigItem_deny_dcc    *Find_deny_dcc(char *name);
ConfigItem_oper        *Find_oper(char *name);
ConfigItem_listen    *Find_listen(char *ipmask, int port);
ConfigItem_ulines    *Find_uline(char *host);
ConfigItem_except    *Find_except(aClient *, char *host, short type);
ConfigItem_tld        *Find_tld(aClient *cptr, char *host);
ConfigItem_link        *Find_link(char *username, char *hostname, char *ip, char *servername);
ConfigItem_ban        *Find_ban(aClient *, char *host, short type);
ConfigItem_ban        *Find_banEx(aClient *,char *host, short type, short type2);
ConfigItem_vhost    *Find_vhost(char *name);
ConfigItem_deny_channel *Find_channel_allowed(char *name);
ConfigItem_alias    *Find_alias(char *name);
ConfigItem_help    *Find_Help(char *command);
int            AllowClient(aClient *cptr, struct hostent *hp, char *sockhost, char *username);
int parse_netmask(const char *text, struct irc_netmask *netmask);
int match_ip(struct IN_ADDR addr, char *uhost, char *mask, struct irc_netmask *netmask);
ConfigItem_ban  *Find_ban_ip(aClient *sptr);
extern MODVAR struct tm motd_tm, smotd_tm;
extern MODVAR Link    *Servers;
void add_ListItem(ListStruct *, ListStruct **);
ListStruct *del_ListItem(ListStruct *, ListStruct **);
/* Remmed out for win32 compatibility.. as stated of 467leaf win32 port.. */
extern aClient *find_match_server(char *mask);
extern MODVAR LoopStruct loop;
extern int del_banid(aChannel *chptr, char *banid);
extern int del_exbanid(aChannel *chptr, char *banid);
#ifdef SHOWCONNECTINFO


#define BREPORT_DO_DNS    "NOTICE AUTH :[++] Yuzukchat.Net IRC Sunucusuna Bağlanıyorsunuz, Hoşsohbetler!\r\n"
#define BREPORT_FIN_DNS    "NOTICE AUTH :[++]
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
BREPORT_FIN_DNSC "NOTICE AUTH :[++]
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
BREPORT_FAIL_DNS "NOTICE AUTH :[++]
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
BREPORT_DO_ID    "NOTICE AUTH :[++]
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
BREPORT_FIN_ID    "NOTICE AUTH :[++]
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
BREPORT_FAIL_ID    "NOTICE AUTH :[++]
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
extern MODVAR char REPORT_DO_DNS[256], REPORT_FIN_DNS[256], REPORT_FIN_DNSC[256],
    REPORT_FAIL_DNS[256], REPORT_DO_ID[256], REPORT_FIN_ID[256],
    REPORT_FAIL_ID[256];

extern MODVAR int R_do_dns, R_fin_dns, R_fin_dnsc, R_fail_dns,
    R_do_id, R_fin_id, R_fail_id;

#endif
extern inline aCommand *find_Command(char *cmd, short token, int flags);
extern aCommand *find_Command_simple(char *cmd);
extern aChannel *find_channel(char *, aChannel *);
extern Membership *find_membership_link(Membership *lp, aChannel *ptr);
extern Member *find_member_link(Member *, aClient *);
extern void remove_user_from_channel(aClient *, aChannel *);
extern char *base64enc(long);
extern long base64dec(char *);
extern void add_server_to_table(aClient *);
extern void remove_server_from_table(aClient *);
extern void iNAH_host(aClient *sptr, char *host);
extern void set_snomask(aClient *sptr, char *snomask);
extern char *get_sno_str(aClient *sptr);
/* for services */
extern void del_invite(aClient *, aChannel *);
extern int add_silence(aClient *, char *, int);
extern int del_silence(aClient *, char *);
extern void send_user_joins(aClient *, aClient *);
extern void clean_channelname(char *);
extern int do_nick_name(char *);
extern int do_remote_nick_name(char *);
extern int can_send(aClient *, aChannel *, char *, int);
extern long get_access(aClient *, aChannel *);
extern int is_chan_op(aClient *, aChannel *);
extern int has_voice(aClient *, aChannel *);
extern int is_chanowner(aClient *, aChannel *);
extern Ban *is_banned(aClient *, aChannel *, int);
extern int parse_help(aClient *, char *, char *);

extern void ircd_log(int, char *, ...) __attribute__((format(printf,2,3)));
extern aClient *find_client(char *, aClient *);
extern aClient *find_name(char *, aClient *);
extern aClient *find_nickserv(char *, aClient *);
extern aClient *find_person(char *, aClient *);
extern aClient *find_server(char *, aClient *);
extern aClient *find_server_quickx(char *, aClient *);
extern aClient *find_service(char *, aClient *);
#define find_server_quick(x) find_server_quickx(x, NULL)
extern char *find_or_add(char *);
extern int attach_conf(aClient *, aConfItem *);
extern void inittoken();
extern void reset_help();

extern MODVAR char *debugmode, *configfile, *sbrk0;
extern char *getfield(char *);
extern void get_sockhost(aClient *, char *);
#ifndef _WIN32
extern char *strerror(int);
#else
extern MODFUNC char *sock_strerror(int);
#endif
extern int dgets(int, char *, int);
extern char *inetntoa(char *);

#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
/* #ifndef _WIN32 XXX why was this?? -- Syzop. */
extern int snprintf (char *str, size_t count, const char *fmt, ...);
extern int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
/* #endif */
#endif

#ifdef _WIN32
extern MODVAR int dbufalloc, dbufblocks, debuglevel;
#else
extern int dbufalloc, dbufblocks, debuglevel, errno, h_errno;
#endif
extern MODVAR short LastSlot; /* last used index in local client array */
extern MODVAR int OpenFiles;  /* number of files currently open */
extern MODVAR int debuglevel, portnum, debugtty, maxusersperchannel;
extern MODVAR int readcalls, udpfd, resfd;
extern aClient *add_connection(aClient *, int);
extern int add_listener(aConfItem *);
extern void add_local_domain(char *, int);
extern int check_client(aClient *, char *);
extern int check_server(aClient *, struct hostent *, aConfItem *,
    aConfItem *, int);
extern int check_server_init(aClient *);
extern void close_connection(aClient *);
extern void close_listeners();
extern int connect_server(ConfigItem_link *, aClient *, struct hostent *);
extern void get_my_name(aClient *, char *, int);
extern int get_sockerr(aClient *);
extern int inetport(aClient *, char *, int);
extern void init_sys();
extern void init_modef();

#ifdef NO_FDLIST
extern int read_message(time_t);
#else
extern int read_message(time_t, fdlist *);
#endif

extern void report_error(char *, aClient *);
extern void set_non_blocking(int, aClient *);
extern int setup_ping();

extern void start_auth(aClient *);
extern void read_authports(aClient *);
extern void send_authports(aClient *);


extern void restart(char *);
extern void send_channel_modes(aClient *, aChannel *);
extern void server_reboot(char *);
extern void terminate(), write_pidfile();
extern void *MyMallocEx(size_t size);
extern int advanced_check(char *userhost, int ipstat);
extern int send_queued(aClient *);
/* i know this is naughty but :P --stskeeps */
extern void send_channel_modes_sjoin(aClient *cptr, aChannel *chptr);
extern void send_channel_modes_sjoin3(aClient *cptr, aChannel *chptr);
extern void sendto_locfailops(char *pattern, ...) __attribute__((format(printf,1,2)));
extern void sendto_connectnotice(char *nick, anUser *user, aClient *sptr, int disconnect, char *comment);
extern void sendto_serv_butone_nickcmd(aClient *one, aClient *sptr, char *nick, int hopcount,
long lastnick, char *username, char *realhost, char *server, long servicestamp, char *info, char *umodes,
char *virthost);
extern void    sendto_message_one(aClient *to, aClient *from, char *sender,
    char *cmd, char *nick, char *msg);
#define PREFIX_ALL        0
#define PREFIX_HALFOP    0x1
#define PREFIX_VOICE    0x2
#define PREFIX_OP    0x4
#define PREFIX_ADMIN    0x08
#define PREFIX_OWNER    0x10
extern void sendto_channelprefix_butone(aClient *one, aClient *from, aChannel *chptr,
    int prefix, char *pattern, ...) __attribute__((format(printf,5,6)));
extern void sendto_channelprefix_butone_tok(aClient *one, aClient *from, aChannel *chptr,
    int prefix, char *cmd, char *tok, char *nick, char *text, char do_send_check);
extern void sendto_channel_butone(aClient *, aClient *, aChannel *,
                                  char *, ...) __attribute__((format(printf,4,5)));
extern void sendto_channel_butserv_butone(aChannel *chptr, aClient *from, aClient *one,
                                          char *pattern, ...) __attribute__((format(printf,4,5)));
extern void sendto_serv_butone(aClient *, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_serv_butone_quit(aClient *, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_serv_butone_sjoin(aClient *, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_serv_sjoin(aClient *, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_common_channels(aClient *, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_channel_butserv_butone(aChannel *chptr, aClient *from, aClient *one, char *pattern, ...) __attribute__((format(printf,4,5)));
extern void sendto_match_servs(aChannel *, aClient *, char *, ...) __attribute__((format(printf,3,4)));
extern void sendto_match_butone(aClient *, aClient *, char *, int,
    char *pattern, ...) __attribute__((format(printf,5,6)));
extern void sendto_all_butone(aClient *, aClient *, char *, ...) __attribute__((format(printf,3,4)));
extern void sendto_ops(char *, ...) __attribute__((format(printf,1,2)));
extern void sendto_ops_butone(aClient *, aClient *, char *, ...) __attribute__((format(printf,3,4)));
extern void sendto_ops_butme(aClient *, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_prefix_one(aClient *, aClient *, const char *, ...) __attribute__((format(printf,3,4)));
extern void sendto_failops_whoare_opers(char *, ...) __attribute__((format(printf,1,2)));
extern void sendto_failops(char *, ...) __attribute__((format(printf,1,2)));
extern void sendto_opers(char *, ...) __attribute__((format(printf,1,2)));
extern void sendto_umode(int, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_umode_raw(int, char *, ...) __attribute__((format(printf,2,3)));
extern void sendto_snomask(int snomask, char *pattern, ...) __attribute__((format(printf,2,3)));
extern void sendto_snomask_global(int snomask, char *pattern, ...) __attribute__((format(printf,2,3)));
extern void sendto_snomask_normal(int snomask, char *pattern, ...) __attribute__((format(printf,2,3)));
extern void sendto_snomask_normal_global(int snomask, char *pattern, ...) __attribute__((format(printf,2,3)));
extern void sendnotice(aClient *to, char *pattern, ...) __attribute__((format(printf,2,3)));
extern MODVAR int writecalls, writeb[];
extern int deliver_it(aClient *, char *, int);
extern int  check_for_chan_flood(aClient *cptr, aClient *sptr, aChannel *chptr);
extern int  check_for_target_limit(aClient *sptr, void *target, const char *name);
extern char *stripbadwords_message(char *str, int *);
extern char *stripbadwords_channel(char *str, int *);
extern char *stripbadwords_quit(char *str, int *);
extern char *stripbadwords(char *, ConfigItem_badword *, int *);
extern unsigned char *StripColors(unsigned char *);
extern const char *StripControlCodes(unsigned char *text);
extern char *canonize(char *buffer);
extern int webtv_parse(aClient *sptr, char *string);
extern ConfigItem_deny_dcc *dcc_isforbidden(aClient *sptr, char *filename);
extern ConfigItem_deny_dcc *dcc_isdiscouraged(aClient *sptr, char *filename);
extern int check_registered(aClient *);
extern int check_registered_user(aClient *);
extern char *get_client_name(aClient *, int);
extern char *get_client_host(aClient *);
extern char *myctime(time_t), *date(time_t);
extern int exit_client(aClient *, aClient *, aClient *, char *);
extern void initstats(), tstats(aClient *, char *);
extern char *check_string(char *);
extern char *make_nick_user_host(char *, char *, char *);
extern char *make_user_host(char *, char *);
extern int parse(aClient *, char *, char *);
extern int do_numeric(int, aClient *, aClient *, int, char **);
extern int hunt_server(aClient *, aClient *, char *, int, int, char **);
extern int hunt_server_token(aClient *, aClient *, char *, char *, char *, int, int, char **);
extern int hunt_server_token_quiet(aClient *, aClient *, char *, char *, char *, int, int, char **);
extern aClient *next_client(aClient *, char *);
extern int m_names(aClient *, aClient *, int, char **);
extern int m_server_estab(aClient *);
extern void umode_init(void);
extern long umode_get(char, int, int (*)(aClient *, int));
#define UMODE_GLOBAL 1
#define UMODE_LOCAL 0
#define umode_lget(x) umode_get(x, 0, 0);
#define umode_gget(x) umode_get(x, 1, 0);
extern int umode_allow_all(aClient *sptr, int what);
extern int umode_allow_opers(aClient *sptr, int what);
extern int  umode_delete(char ch, long val);
extern void send_umode(aClient *, aClient *, long, long, char *);
extern void send_umode_out(aClient *, aClient *, long);

extern void free_client(aClient *);
extern void free_link(Link *);
extern void free_ban(Ban *);
extern void free_class(aClass *);
extern void free_user(anUser *, aClient *);
extern int find_str_match_link(Link *, char *);
extern void free_str_list(Link *);
extern Link *make_link();
extern Ban *make_ban();
extern anUser *make_user(aClient *);
extern aClass *make_class();
extern aServer *make_server();
extern aClient *make_client(aClient *, aClient *);
extern Link *find_user_link(Link *, aClient *);
extern Member *find_channel_link(Member *, aChannel *);
extern char *pretty_mask(char *);
extern void add_client_to_list(aClient *);
extern void checklist();
extern void remove_client_from_list(aClient *);
extern void initlists();
extern struct hostent *get_res(char *);
extern struct hostent *gethost_byaddr(char *, Link *);
extern struct hostent *gethost_byname(char *, Link *);
extern void flush_cache();
extern int init_resolver(int);
extern time_t timeout_query_list(time_t);
extern time_t expire_cache(time_t);
extern void del_queries(char *);

extern void clear_channel_hash_table();
extern void clear_client_hash_table();
extern void clear_watch_hash_table();
extern int add_to_client_hash_table(char *, aClient *);
extern int del_from_client_hash_table(char *, aClient *);
extern int add_to_channel_hash_table(char *, aChannel *);
extern int del_from_channel_hash_table(char *, aChannel *);
extern int add_to_watch_hash_table(char *, aClient *);
extern int del_from_watch_hash_table(char *, aClient *);
extern int hash_check_watch(aClient *, int);
extern int hash_del_watch_list(aClient *);
extern void count_watch_memory(int *, u_long *);
extern aWatch *hash_get_watch(char *);
extern aChannel *hash_get_chan_bucket(unsigned int);
extern aClient *hash_find_client(char *, aClient *);
extern aClient *hash_find_nickserver(char *, aClient *);
extern aClient *hash_find_server(char *, aClient *);
extern char *find_by_aln(char *);
extern char *convert2aln(int);
extern int convertfromaln(char *);
extern char *find_server_aln(char *);
extern time_t atime(char *xtime);


/* Mode externs
*/
extern MODVAR long UMODE_INVISIBLE; /*  0x0001    makes user invisible */
extern MODVAR long UMODE_OPER;      /*  0x0002    Operator */
extern MODVAR long UMODE_WALLOP;    /*  0x0004    send wallops to them */
extern MODVAR long UMODE_FAILOP;    /*  0x0008    Shows some global messages */
extern MODVAR long UMODE_HELPOP;    /*  0x0010    Help system operator */
extern MODVAR long UMODE_REGNICK;  /*  0x0020    Nick set by services as registered */
extern MODVAR long UMODE_SADMIN;    /*  0x0040    Services Admin */
extern MODVAR long UMODE_ADMIN;    /*  0x0080    Admin */
extern MODVAR long UMODE_SERVNOTICE;/* 0x0100    server notices such as kill */
extern MODVAR long UMODE_LOCOP;    /* 0x0200    Local operator -- SRB */
extern MODVAR long UMODE_RGSTRONLY; /* 0x0400  Only reg nick message */
extern MODVAR long UMODE_WEBTV;    /* 0x0800  WebTV Client */
extern MODVAR long UMODE_SERVICES;  /* 0x4000    services */
extern MODVAR long UMODE_HIDE;        /* 0x8000    Hide from Nukes */
extern MODVAR long UMODE_NETADMIN;  /* 0x10000    Network Admin */
extern MODVAR long UMODE_COADMIN;  /* 0x80000    Co Admin */
extern MODVAR long UMODE_WHOIS;    /* 0x100000    gets notice on /whois */
extern MODVAR long UMODE_KIX;      /* 0x200000    usermode +q */
extern MODVAR long UMODE_BOT;      /* 0x400000    User is a bot */
extern MODVAR long UMODE_SECURE;    /*    0x800000    User is a secure connect */
extern MODVAR long UMODE_VICTIM;    /* 0x8000000    Intentional Victim */
extern MODVAR long UMODE_DEAF;      /* 0x10000000      Deaf */
extern MODVAR long UMODE_HIDEOPER;  /* 0x20000000    Hide oper mode */
extern MODVAR long UMODE_SETHOST;  /* 0x40000000    used sethost */
extern MODVAR long UMODE_STRIPBADWORDS; /* 0x80000000    */
extern MODVAR long UMODE_HIDEWHOIS; /* hides channels in /whois */
extern MODVAR long UMODE_NOCTCP;    /* blocks all ctcp (except dcc and action) */
extern MODVAR long AllUmodes, SendUmodes;

extern MODVAR long SNO_KILLS;
extern MODVAR long SNO_CLIENT;
extern MODVAR long SNO_FLOOD;
extern MODVAR long SNO_FCLIENT;
extern MODVAR long SNO_JUNK;
extern MODVAR long SNO_VHOST;
extern MODVAR long SNO_EYES;
extern MODVAR long SNO_TKL;
extern MODVAR long SNO_NICKCHANGE;
extern MODVAR long SNO_FNICKCHANGE;
extern MODVAR long SNO_QLINE;
extern MODVAR long SNO_SNOTICE;
extern MODVAR long SNO_SPAMF;
extern MODVAR long SNO_OPER;

#ifdef EXTCMODE
/* Extended chanmodes... */
extern MODVAR Cmode_t EXTMODE_NONOTICE;
#ifdef STRIPBADWORDS
extern MODVAR Cmode_t EXTMODE_STRIPBADWORDS;
#endif
extern MODVAR Cmode_t EXTMODE_JOINTHROTTLE;
#endif

#ifndef HAVE_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t size);
#endif
#ifndef HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t size);
#endif
#ifndef HAVE_STRLNCAT
size_t strlncat(char *dst, const char *src, size_t size, size_t n);
#endif


extern int dopacket(aClient *, char *, int);

extern void debug(int, char *, ...);
#if defined(DEBUGMODE)
extern void send_usage(aClient *, char *);
extern void send_listinfo(aClient *, char *);
extern void count_memory(aClient *, char *);
extern int checkprotoflags(aClient *, int, char *, int);
#endif

#ifdef INET6
extern char *inetntop(int af, const void *in, char *local_dummy,
    size_t the_size);
#endif

/*
 * socket.c
*/

char    *Inet_si2p(struct SOCKADDR_IN *sin);
char    *Inet_si2pB(struct SOCKADDR_IN *sin, char *buf, int sz);
char    *Inet_ia2p(struct IN_ADDR *ia);
char    *Inet_ia2pNB(struct IN_ADDR *ia, int compressed);

/*
 * CommandHash -Stskeeps
*/
extern MODVAR aCommand *CommandHash[256];
extern MODVAR aCommand *TokenHash[256];
extern void    init_CommandHash(void);
extern aCommand    *add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, unsigned char token, int flags);
extern void    add_Command(char *cmd, char *token, int (*func)(), unsigned char parameters);
extern void    add_Command_to_list(aCommand *item, aCommand **list);
extern aCommand *del_Command_from_list(aCommand *item, aCommand **list);
extern int    del_Command(char *cmd, char *token, int (*func)());
extern void    add_CommandX(char *cmd, char *token, int (*func)(), unsigned char parameters, int flags);

/* CRULE */
char *crule_parse(char *);
int crule_test(char *);
char *crule_errstring(int);
int crule_eval(char *);
void crule_free(char **);

/* Add clients to LocalClients array */
extern void add_local_client(aClient* cptr);
/* Remove clients from LocalClients array */
extern void remove_local_client(aClient* cptr);
/*
 * Close all local socket connections, invalidate client fd's
 * WIN32 cleanup winsock lib
 */
extern void close_connections(void);
extern void flush_connections(aClient *cptr);

extern int b64_encode(unsigned char const *src, size_t srclength, char *target, size_t targsize);
extern int b64_decode(char const *src, unsigned char *target, size_t targsize);

extern int        Auth_FindType(char *type);
extern anAuthStruct    *Auth_ConvertConf2AuthStruct(ConfigEntry *ce);
extern void        Auth_DeleteAuthStruct(anAuthStruct *as);
extern int        Auth_Check(aClient *cptr, anAuthStruct *as, char *para);
extern char          *Auth_Make(short type, char *para);
extern int          Auth_CheckError(ConfigEntry *ce);

extern long xbase64dec(char *b64);
extern aClient *find_server_b64_or_real(char *name);
extern aClient *find_server_by_base64(char *b64);
extern int is_chanownprotop(aClient *cptr, aChannel *chptr);
extern int is_skochanop(aClient *cptr, aChannel *chptr);
extern char *make_virthost(char *curr, char *new, int mode);
extern int  channel_canjoin(aClient *sptr, char *name);
extern char *collapse(char *pattern);
extern void send_list(aClient *cptr, int numsend);
extern int  find_tkline_match_zap(aClient *cptr);
extern int  find_shun(aClient *cptr);
extern aTKline *find_qline(aClient *cptr, char *nick, int *ishold);
extern void tkl_synch(aClient *sptr);
extern void dcc_sync(aClient *sptr);
extern void report_flines(aClient *sptr);
extern void report_network(aClient *sptr);
extern void report_dynconf(aClient *sptr);
extern void count_memory(aClient *cptr, char *nick);
extern void list_scache(aClient *sptr);
extern void ns_stats(aClient *cptr);
extern char *oflagstr(long oflag);
extern int rehash(aClient *cptr, aClient *sptr, int sig);
extern int _match(char *mask, char *name);
extern void outofmemory(void);
extern unsigned long our_crc32(const unsigned char *s, unsigned int len);
extern int add_listener2(ConfigItem_listen *conf);
extern void link_cleanup(ConfigItem_link *link_ptr);
extern void      listen_cleanup();
extern int  numeric_collides(long numeric);
extern u_long cres_mem(aClient *sptr, char *nick);
extern void      flag_add(char ch);
extern void      flag_del(char ch);
extern void init_dynconf(void);
extern char *pretty_time_val(long);
extern int        init_conf(char *filename, int rehash);
extern void      validate_configuration(void);
extern void      run_configuration(void);
extern void rehash_motdrules();
extern aMotd *read_file(char *filename, aMotd **list);
extern aMotd *read_file_ex(char *filename, aMotd **list, struct tm *);
extern CMD_FUNC(m_server_remote);
extern void send_proto(aClient *, ConfigItem_link *);
extern char *xbase64enc(long i);
extern void unload_all_modules(void);
extern void flush_fdlist_connections(fdlist * listp);
extern int set_blocking(int fd);
extern void set_sock_opts(int fd, aClient *cptr);
extern void iCstrip(char *line);
extern time_t rfc2time(char *s);
extern char *rfctime(time_t t, char *buf);
extern void *MyMallocEx(size_t size);
#ifdef USE_SSL
extern MODFUNC char  *ssl_get_cipher(SSL *ssl);
#endif
extern long config_checkval(char *value, unsigned short flags);
extern void config_status(char *format, ...) __attribute__((format(printf,1,2)));
extern void init_random();
extern u_char getrandom8();
extern u_int16_t getrandom16();
extern u_int32_t getrandom32();
extern MODVAR char trouble_info[1024];
#define EVENT_DRUGS BASE_VERSION
extern void rejoin_doparts(aClient *sptr, char did_parts[]);
extern void rejoin_dojoinandmode(aClient *sptr, char did_parts[]);
extern void ident_failed(aClient *cptr);

extern MODVAR char extchmstr[4][64];
extern MODVAR char extbanstr[EXTBANTABLESZ+1];
#ifdef EXTCMODE
extern int extcmode_default_requirechop(aClient *, aChannel *, char *, int, int);
extern int extcmode_default_requirehalfop(aClient *, aChannel *, char *, int, int);
extern Cmode_t extcmode_get(Cmode *);
extern void extcmode_init(void);
extern CmodeParam *extcmode_get_struct(CmodeParam *, char);
extern void make_extcmodestr();
extern CmodeParam *extcmode_duplicate_paramlist(CmodeParam *);
extern void extcmode_free_paramlist(CmodeParam *);
#endif
extern int do_chanflood(ChanFloodProt *, int);
extern void do_chanflood_action(aChannel *, int, char *);
extern char *channel_modef_string(ChanFloodProt *);
extern void chmode_str(struct ChMode, char *, char *);
extern char *get_cptr_status(aClient *);
extern char *get_snostr(long);
#ifdef _WIN32
extern void InitDebug(void);
extern int InitwIRCD(int argc, char **);
extern void SocketLoop(void *);
#endif
#ifdef STATIC_LINKING
extern int l_commands_Init(ModuleInfo *);
extern int l_commands_Test(ModuleInfo *);
extern int l_commands_Load(int);
#endif
extern void sendto_chmodemucrap(aClient *, aChannel *, char *);
extern void verify_opercount(aClient *, char *);
extern int place_host_ban(aClient *sptr, int action, char *reason, long time);
extern int valid_host(char *host);
extern int count_oper_sessions(char *);
extern char *unreal_mktemp(char *dir, char *suffix);
extern char *unreal_getpathname(char *filepath, char *path);
extern char *unreal_getfilename(char *path);
extern int unreal_copyfile(char *src, char *dest);
extern int unreal_copyfileex(char *src, char *dest, int tryhardlink);
extern time_t unreal_getfilemodtime(char *filename);
extern void unreal_setfilemodtime(char *filename, time_t mtime);
extern void DeleteTempModules(void);
extern MODVAR Extban *extbaninfo;
extern Extban *findmod_by_bantype(char c);
extern Extban *ExtbanAdd(Module *reserved, ExtbanInfo req);
extern void ExtbanDel(Extban *);
extern void extban_init(void);
extern char *trim_str(char *str, int len);
extern MODVAR char *ban_realhost, *ban_virthost, *ban_ip;
extern char *unreal_checkregex(char *s, int fastsupport, int check_broadness);
extern int banact_stringtoval(char *s);
extern char *banact_valtostring(int val);
extern int banact_chartoval(char c);
extern char banact_valtochar(int val);
extern int spamfilter_gettargets(char *s, aClient *sptr);
extern char *spamfilter_target_inttostring(int v);
extern Spamfilter *unreal_buildspamfilter(char *s);
extern int dospamfilter(aClient *sptr, char *str_in, int type, char *target);
extern char *our_strcasestr(char *haystack, char *needle);
extern int spamfilter_getconftargets(char *s);
extern void remove_oper_snomasks(aClient *sptr);
extern char *spamfilter_inttostring_long(int v);
extern int check_channelmask(aClient *, aClient *, char *);
extern aChannel *get_channel(aClient *cptr, char *chname, int flag);
extern MODVAR char backupbuf[];
extern void add_invite(aClient *, aChannel *);
extern void channel_modes(aClient *, char *, char *, aChannel *);
extern MODVAR char modebuf[BUFSIZE], parabuf[BUFSIZE];
extern int op_can_override(aClient *sptr);
extern aClient *find_chasing(aClient *sptr, char *user, int *chasing);
extern MODVAR long opermode;
extern void add_user_to_channel(aChannel *chptr, aClient *who, int flags);
extern int add_banid(aClient *, aChannel *, char *);
extern int add_exbanid(aClient *cptr, aChannel *chptr, char *banid);
extern void sub1_from_channel(aChannel *);
extern MODVAR aCtab cFlagTab[];
extern char *unreal_encodespace(char *s);
extern char *unreal_decodespace(char *s);
extern MODVAR Link *helpign;
extern MODVAR aMotd *rules;
extern MODVAR fdlist default_fdlist, busycli_fdlist, serv_fdlist, oper_fdlist;
extern void DCCdeny_add(char *filename, char *reason, int type, int type2);
extern void DCCdeny_del(ConfigItem_deny_dcc *deny);
extern void dcc_wipe_services(void);
extern void reread_motdsandrules();
extern MODVAR int SVSNOOP;
extern int callbacks_check(void);
extern void callbacks_switchover(void);
extern int efunctions_check(void);
extern void efunctions_switchover(void);
extern char *encode_ip(u_char *);
extern char *decode_ip(char *);
extern void sendto_fconnectnotice(char *nick, anUser *user, aClient *sptr, int disconnect, char *comment);
extern void sendto_one_nickcmd(aClient *cptr, aClient *sptr, char *umodes);
extern int register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip);
extern int on_dccallow_list(aClient *to, aClient *from);
extern int add_dccallow(aClient *sptr, aClient *optr);
extern int del_dccallow(aClient *sptr, aClient *optr);
extern void delete_linkblock(ConfigItem_link *link_ptr);
extern void delete_classblock(ConfigItem_class *class_ptr);
extern void del_async_connects(void);
extern int find_spamfilter_user(aClient *sptr);
extern void make_extbanstr(void);
extern void isupport_init(void);
extern int do_cmd(aClient *cptr, aClient *sptr, char *cmd, int parc, char *parv[]);
extern void create_snomask(aClient *sptr, anUser *user, char *snomask);
extern MODVAR char *me_hash;
extern MODVAR int dontspread;
/* Efuncs */
extern MODVAR int (*do_join)(aClient *, aClient *, int, char **);
extern MODVAR void (*join_channel)(aChannel *chptr, aClient *cptr, aClient *sptr, int flags);
extern MODVAR int (*can_join)(aClient *cptr, aClient *sptr, aChannel *chptr, char *key, char *link, char *parv[]);
extern MODVAR void (*do_mode)(aChannel *chptr, aClient *cptr, aClient *sptr, int parc, char *parv[], time_t sendts, int samode);
extern MODVAR void (*set_mode)(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pcount,
    char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], int bounce);
extern MODVAR int (*m_umode)(aClient *, aClient *, int, char **);
/* /Efuncs */
extern MODVAR aMotd *opermotd, *svsmotd, *motd, *botmotd, *smotd;
extern MODVAR int max_connection_count;
extern char tkl_typetochar(int type);
extern int add_listmode(Ban **list, aClient *cptr, aChannel *chptr, char *banid);
extern int del_listmode(Ban **list, aChannel *chptr, char *banid);
extern int Halfop_mode(long mode);
extern void chanfloodtimer_add(aChannel *chptr, char mflag, long mbit, time_t when);
extern void chanfloodtimer_del(aChannel *chptr, char mflag, long mbit);
extern char *clean_ban_mask(char *, int, aClient *);
extern void chanfloodtimer_stopchantimers(aChannel *chptr);
extern int find_invex(aChannel *chptr, aClient *sptr);
extern void DoMD5(unsigned char *mdout, unsigned char *src, unsigned long n);
#ifdef JOINTHROTTLE
aJFlood *cmodej_addentry(aClient *cptr, aChannel *chptr);
void cmodej_delentry(aJFlood *e);
void cmodej_deluserentries(aClient *cptr);
void cmodej_delchannelentries(aChannel *chptr);
#endif
extern void charsys_reset(void);
extern void charsys_addmultibyterange(char s1, char e1, char s2, char e2);
extern void charsys_addallowed(char *s);
extern void charsys_reset(void);
extern MODVAR char langsinuse[4096];


Freak 25 Nisan 2007 07:45

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
ircop.c

Kod:

#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 RPL_IRCOPS                337

#define RPL_ENDOFIRCOPS                338

#define MSG_IRCOPS                "IRCOPS"

#define TOK_IRCOPS                "IO"

#define MyMod                        ModIrcops->handle

#define IsAway(x)                (x)->user->away

#define DelCommand(x)                if (x) CommandDel(x); x = NULL



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

DLLFUNC int                        m_ircops(aClient *cptr, aClient *sptr, int parc, char *parv[]);



ModuleInfo                        *ModIrcops;

Command                                *CmdIrcops;



#ifndef DYNAMIC_LINKING

ModuleHeader m_ircops_Header

#else

#define m_ircops_Header Mod_Header

ModuleHeader Mod_Header

#endif

  = {

        "ircops",

        "$Id: m_ircops.c,v 2.3 2003/12/01 11:46:08 Salazar Exp $",

        "command /ircops",

        "3.2-b8-1",

        NULL

    };





/* The purpose of these ifdefs, are that we can "static" link the ircd if we

 * want to

*/



/* This is called on module init, before Server Ready */

#ifdef DYNAMIC_LINKING

DLLFUNC int        Mod_Init(ModuleInfo *modinfo)

#else

int    m_ircops_Init(ModuleInfo *modinfo)

#endif

{

        ModIrcops        = modinfo;

        CmdIrcops        = AddCommand(MSG_IRCOPS, TOK_IRCOPS, m_ircops);



        if (!CmdIrcops)

                return MOD_FAILED;



        return MOD_SUCCESS;

}



/* Is first run when server is 100% ready */

#ifdef DYNAMIC_LINKING

DLLFUNC int        Mod_Load(int module_load)

#else

int    m_ircops_Load(int module_load)

#endif

{

        return MOD_SUCCESS;

}





/* Called when module is unloaded */

#ifdef DYNAMIC_LINKING

DLLFUNC int        Mod_Unload(int module_unload)

#else

int        m_ircops_Unload(int module_unload)

#endif

{

        DelCommand(CmdIrcops);



        return MOD_SUCCESS;

}



typedef struct

{

        unsigned long        *umode;

        char                *text;

} oflag;



static oflag otypes[] =

{

        { &UMODE_NETADMIN,                "Network Administrator"        },

        { &UMODE_ADMIN,                        "Services Administrator"        },

        { &UMODE_SADMIN,                "Services Administrator"        },

        { &UMODE_COADMIN,                "IRC Administrator"                },

        { &UMODE_OPER,                        "IRC Operator"                },

        { &UMODE_LOCOP,                        "IRC Operator"               

},

        { NULL,                                NULL                                }

};



static char *find_otype(unsigned long umodes)

{

        unsigned int i;



        for (i = 0; otypes[i].umode; i++)

                if (*otypes[i].umode & umodes)

                        return otypes[i].text;



        return "an unknown operator";

}



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;

}





int m_ircops(aClient *cptr, aClient *sptr, int parc, char *parv[])

{

        aClient                *acptr;

        char                buf[BUFSIZE];

        int                opers = 0, admins = 0, globs = 0, aways = 0;



      sendto_one(sptr, ":%s 339 %s :+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+",

            me.name, sptr->name);

      sendto_one(sptr, ":%s 339 %s :            \2Online Oper's List\2          ",

            me.name, sptr->name);

      sendto_one(sptr, ":%s 339 %s : 
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
me.name, sptr->name);

      sendto_one(sptr, ":%s 339 %s :+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+",

            me.name, sptr->name);

        for (acptr = client; acptr; acptr = acptr->next)

        {

                /* List only real IRC Operators */

                if (IsULine(acptr) || !IsPerson(acptr) || !IsAnOper(acptr))

                        continue;

                /* Don't list +H users */

                if (!IsAnOper(sptr) && IsHideOper(acptr))

                        continue;



                sendto_one(sptr, ":%s %d %s : \2Nick\2 : %-13s  \2Yetkisi\2 : %-20s " "%s",

                        me.name, RPL_IRCOPS, sptr->name,

                        acptr->name,

                        find_otype(acptr->umodes),

                        (IsAway(acptr) ? "- Mesgul" : IsHelpOp(acptr) ? "" : ""));



                if (IsAway(acptr))

                        aways++;

                else if (IsSkoAdmin(acptr))

                        admins++;

                else

                        opers++;



        }



        globs = opers + admins + aways;



        sprintf(buf,

                "    %d Operator%s Bagli - %d Admin%s , %d IRCop%s ve %d Mesgul",

                globs, (globs) > 1 ? "" : "", admins, admins > 1 ? "" : "",

                opers, opers > 1 ? "" : "", aways);

      sendto_one(sptr, ":%s 339 %s :+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+",

                me.name, sptr->name);



        sendto_one(sptr, ":%s %d %s :%s", me.name, RPL_IRCOPS, sptr->name, buf);

        sendto_one(sptr, ":%s %d %s :Oper's List End", me.name, RPL_ENDOFIRCOPS, sptr->name);



        return 0;

}


Freak 25 Nisan 2007 07:46

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
m_oper.c

Kod:

/*
 *  Unreal Internet Relay Chat Daemon, src/modules/m_oper.c
 *  (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team
 *  Moved to modules by Fish (Justin Hammond)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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"
#include "proto.h"
#include "inet.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif

DLLFUNC int m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]);


/* Place includes here */
#define MSG_OPER        "OPER"  /* OPER */
#define TOK_OPER        ";"    /* 59 */

typedef struct oper_oflag_ {
    unsigned long oflag;
    long* umode;    /* you just HAD to make them variables */
    char** host;
    char* announce;
} oper_oflag_t;

static oper_oflag_t oper_oflags[10];

static void init_operflags()
{
    oper_oflags[0].oflag = OFLAG_NETADMIN;
    oper_oflags[0].umode = &UMODE_NETADMIN;
    oper_oflags[0].host = &netadmin_host;
    oper_oflags[0].announce = "is now a network administrator (N)";
    oper_oflags[1].oflag = OFLAG_SADMIN;
    oper_oflags[1].umode = &UMODE_SADMIN;
    oper_oflags[1].host = &sadmin_host;
    oper_oflags[1].announce = "is now a services administrator (a)";
    oper_oflags[2].oflag = OFLAG_ADMIN;
    oper_oflags[2].umode = &UMODE_ADMIN;
    oper_oflags[2].host = &admin_host;
    oper_oflags[2].announce = "is now a server admin (A)";
    oper_oflags[3].oflag = OFLAG_COADMIN;
    oper_oflags[3].umode = &UMODE_COADMIN;
    oper_oflags[3].host = &coadmin_host;
    oper_oflags[3].announce = "is now a IRC administrator (C)";
    oper_oflags[4].oflag = OFLAG_ISGLOBAL;
    oper_oflags[4].umode = &UMODE_OPER;
    oper_oflags[4].host = &oper_host;
    oper_oflags[4].announce = "is now an operator (O)";
    oper_oflags[5].oflag = OFLAG_HELPOP;
    oper_oflags[5].umode = &UMODE_HELPOP;
    oper_oflags[5].host = NULL;
    oper_oflags[5].announce = NULL;
    oper_oflags[6].oflag= OFLAG_GLOBOP;
    oper_oflags[6].umode = &UMODE_FAILOP;
    oper_oflags[6].host = NULL;
    oper_oflags[6].announce = NULL;
    oper_oflags[7].oflag = OFLAG_WALLOP;
    oper_oflags[7].umode = &UMODE_WALLOP;
    oper_oflags[7].host = NULL;
    oper_oflags[7].announce = NULL;
    oper_oflags[8].oflag = OFLAG_WHOIS;
    oper_oflags[8].umode = &UMODE_WHOIS;
    oper_oflags[8].host = NULL;
    oper_oflags[8].announce = NULL;
    oper_oflags[9].oflag = 0;
    oper_oflags[9].umode = NULL;
    oper_oflags[9].host = NULL;
    oper_oflags[9].announce = NULL;
}
   

ModuleHeader MOD_HEADER(m_oper)
  = {
    "oper",    /* Name of module */
    "$Id: m_oper.c,v 1.1.6.6 2005/03/13 21:03:14 syzop Exp $", /* Version */
    "command /oper", /* Short description of module */
    "3.2-b8-1",
    NULL
    };

/* This is called on module init, before Server Ready */
DLLFUNC int MOD_INIT(m_oper)(ModuleInfo *modinfo)
{
    /*
    * We call our add_Command crap here
    */
    add_Command(MSG_OPER, TOK_OPER, m_oper, MAXPARA);
    MARK_AS_OFFICIAL_MODULE(modinfo);
    return MOD_SUCCESS;
}

/* Is first run when server is 100% ready */
DLLFUNC int MOD_LOAD(m_oper)(int module_load)
{
    init_operflags();
    return MOD_SUCCESS;
}

/* Called when module is unloaded */
DLLFUNC int MOD_UNLOAD(m_oper)(int module_unload)
{
    if (del_Command(MSG_OPER, TOK_OPER, m_oper) < 0)
    {
        sendto_realops("Failed to delete commands when unloading %s",
                MOD_HEADER(m_oper).name);
    }
    return MOD_SUCCESS;
}


/*
** m_oper
**    parv[0] = sender prefix
**    parv[1] = oper name
**    parv[2] = oper password
*/

DLLFUNC int  m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
    ConfigItem_oper *aconf;
    ConfigItem_oper_from *oper_from;
    char *name, *password, nuhhost[NICKLEN+USERLEN+HOSTLEN+6], nuhhost2[NICKLEN+USERLEN+HOSTLEN+6];
    char* host = 0;
    int i = 0, j = 0;
    char* announce = 0;

    if (!MyClient(sptr))
        return 0;

    if (parc < 3) {
        sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
            me.name, parv[0], "OPER");
        return 0;
    }

    if (SVSNOOP) {
        sendto_one(sptr,
            ":%s %s %s :*** This server is in NOOP mode, you cannot /oper",
            me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name);
        return 0;
    }

    if (IsAnOper(sptr)) {
        sendto_one(sptr, rpl_str(RPL_YOUREOPER),
            me.name, parv[0]);
        return 0;
    }

    name = parv[1];
    password = parv[2];

    if (!(aconf = Find_oper(name))) {
        sendto_one(sptr, err_str(ERR_NOOPERHOST), me.name, parv[0]);
        sendto_realops
            ("Failed OPER attempt by %s (%s@%s) [unknown oper]",
            parv[0], sptr->user->username, sptr->sockhost);
        ircd_log(LOG_OPER, "OPER UNKNOWNOPER (%s) by (%s!%s@%s)", name, parv[0],
            sptr->user->username, sptr->sockhost);
        sptr->since += 7;
        return 0;
    }
    strlcpy(nuhhost, make_user_host(sptr->user->username, sptr->user->realhost), sizeof(nuhhost));
    strlcpy(nuhhost2, make_user_host(sptr->user->username, Inet_ia2p(&sptr->ip)), sizeof(nuhhost2));
    for (oper_from = (ConfigItem_oper_from *) aconf->from;
        oper_from; oper_from = (ConfigItem_oper_from *) oper_from->next)
        if (!match(oper_from->name, nuhhost) || !match(oper_from->name, nuhhost2))
            break;
    if (!oper_from)    {
        sendto_one(sptr, err_str(ERR_NOOPERHOST), me.name, parv[0]);
        sendto_realops
            ("Failed OPER attempt by %s (%s@%s) [host doesnt match]",
            parv[0], sptr->user->username, sptr->sockhost);
        ircd_log(LOG_OPER, "OPER NOHOSTMATCH (%s) by (%s!%s@%s)", name, parv[0],
            sptr->user->username, sptr->sockhost);
        sptr->since += 7;
        return 0;
    }

    i = Auth_Check(cptr, aconf->auth, password);
    if (i > 1)
    {
        int  old = (sptr->umodes & ALL_UMODES);

        if (aconf->maxlogins && (count_oper_sessions(aconf->name) >= aconf->maxlogins))
        {
            sendto_one(sptr, err_str(ERR_NOOPERHOST), me.name, parv[0]);
            sendto_one(sptr, ":%s NOTICE %s :Your maximum number of concurrent oper logins has been reached (%d)",
                me.name, sptr->name, aconf->maxlogins);
            sendto_realops
                ("Failed OPER attempt by %s (%s@%s) [maxlogins reached]",
                parv[0], sptr->user->username, sptr->sockhost);
            ircd_log(LOG_OPER, "OPER TOOMANYLOGINS (%s) by (%s!%s@%s)", name, parv[0],
                sptr->user->username, sptr->sockhost);
            sptr->since += 4;
            return 0;
        }

        if (sptr->user->operlogin)
            MyFree(sptr->user->operlogin);
        sptr->user->operlogin = strdup(aconf->name);

        /* Put in the right class */
        if (sptr->class)
            sptr->class->clients--;

        sptr->class = aconf->class;
        sptr->class->clients++;
        sptr->oflag = 0;
        if (aconf->swhois) {
            if (sptr->user->swhois)
                MyFree(sptr->user->swhois);
            sptr->user->swhois = MyMalloc(strlen(aconf->swhois) +1);
            strcpy(sptr->user->swhois, aconf->swhois);
            sendto_serv_butone_token(cptr, me.name,
                MSG_SWHOIS, TOK_SWHOIS, "%s :%s", sptr->name, aconf->swhois);
        }

/* new oper code */

        if (aconf->modes)
            sptr->umodes |= aconf->modes;
        else
            sptr->umodes |= OPER_MODES;

/* handle oflags that trigger umodes */
       
        while(oper_oflags[j].umode) {
            if(aconf->oflags & oper_oflags[j].oflag) {    /* we match this oflag */
                if (!announce && oper_oflags[j].announce) { /* we haven't matched an oper_type yet */
                    host = *oper_oflags[j].host;    /* set the iNAH host */
                    announce = oper_oflags[j].announce; /* set the announcement */
                }
                sptr->umodes |=
                    *oper_oflags[j].umode; /* add the umode for this oflag */
            }
            j++;
        }

        sptr->oflag = aconf->oflags;
        if ((aconf->oflags & OFLAG_HIDE) && iNAH && !BadPtr(host)) {
            char *c;
            char *vhost = host;

            if ((c = strchr(host, '@')))
            {
                vhost =    c+1;
                strncpy(sptr->user->username, host, c-host);
                sptr->user->username[c-host] = 0;
                sendto_serv_butone_token(NULL, sptr->name, MSG_SETIDENT,
                            TOK_SETIDENT, "%s",
                            sptr->user->username);
            }
            iNAH_host(sptr, vhost);
            SetHidden(sptr);
        } else
        if (IsHidden(sptr) && !sptr->user->virthost) {
            /* +x has just been set by modes-on-oper and iNAH is off */
            sptr->user->virthost = (char *)make_virthost(sptr->user->realhost,
                                                        sptr->user->virthost, 1);
        }

        if (!IsOper(sptr))
        {
            sptr->umodes |= UMODE_LOCOP;
            if ((aconf->oflags & OFLAG_HIDE) && iNAH && !BadPtr(locop_host)) {
                iNAH_host(sptr, locop_host);
                SetHidden(sptr);
            }
            sendto_ops("%s (%s@%s) is now a local operator (o)",
                parv[0], sptr->user->username, GetHost(sptr));
        }


        if (announce != NULL)
            sendto_snomask_global(SNO_OPER,
                "%s (%s@%s) [%s] %s",
                parv[0], sptr->user->username, GetHost(sptr),
                parv[1], announce);
        if (aconf->snomask)
            set_snomask(sptr, aconf->snomask);
        else
            set_snomask(sptr, OPER_SNOMASK);
        if (sptr->user->snomask)
        {
            sptr->user->snomask |= SNO_SNOTICE; /* set +s if needed */
            sptr->umodes |= UMODE_SERVNOTICE;
        }
        /* This is for users who have both 'admin' and 'coadmin' in their conf */
        if (IsCoAdmin(sptr) && IsAdmin(sptr))
        {
            sptr->umodes &= ~UMODE_COADMIN;
            sptr->oflag &= ~OFLAG_COADMIN;
        }
        send_umode_out(cptr, sptr, old);
        sendto_one(sptr, rpl_str(RPL_SNOMASK),
            me.name, parv[0], get_sno_str(sptr));

#ifndef NO_FDLIST
        addto_fdlist(sptr->slot, &oper_fdlist);
#endif
        RunHook2(HOOKTYPE_LOCAL_OPER, sptr, 1);
        sendto_one(sptr, rpl_str(RPL_YOUREOPER), me.name, parv[0]);
        if (IsInvisible(sptr) && !(old & UMODE_INVISIBLE))
            IRCstats.invisible++;
        if (IsOper(sptr) && !IsHideOper(sptr))
            IRCstats.operators++;

        if (SHOWOPERMOTD == 1)
            do_cmd(cptr, sptr, "OPERMOTD", parc, parv);
        if (!BadPtr(OPER_AUTO_JOIN_CHANS)
            && strcmp(OPER_AUTO_JOIN_CHANS, "0"))
        {
            char *chans[3] = {
                sptr->name,
                OPER_AUTO_JOIN_CHANS,
                NULL
            };
            do_cmd(cptr, sptr, "JOIN", 3, chans);
        }
        ircd_log(LOG_OPER, "OPER (%s) by (%s!%s@%s)", name, parv[0], sptr->user->username,
            sptr->sockhost);

    }
    if (i == -1)
    {
        sendto_one(sptr, err_str(ERR_PASSWDMISMATCH), me.name, parv[0]);
        if (FAILOPER_WARN)
            sendto_one(sptr,
                ":%s %s %s :*** Your attempt has been logged.", me.name,
                IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name);
        ircd_log(LOG_OPER, "OPER FAILEDAUTH (%s) by (%s!%s@%s)", name, parv[0],
            sptr->user->username, sptr->sockhost);
        sendto_realops
            ("Failed OPER attempt by %s (%s@%s) using UID %s [FAILEDAUTH]",
            parv[0], sptr->user->username, sptr->sockhost, name);
        sendto_serv_butone(&me,
            ":%s GLOBOPS :Failed OPER attempt by %s (%s@%s) using UID %s [---]",
            me.name, parv[0], sptr->user->username, sptr->sockhost,
            name);
        sptr->since += 7;
    }
    /* Belay that order, number One. (-2) */
    return 0;
}


Freak 25 Nisan 2007 07:47

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
m_quit.c
Kod:

/*
 *  Unreal Internet Relay Chat Daemon, src/modules/m_quit.c
 *  (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team
 *  Moved to modules by Fish (Justin Hammond)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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"
#include "proto.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif

DLLFUNC int m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[]);

/* Place includes here */
#define MSG_QUIT        "QUIT"  /* QUIT */
#define TOK_QUIT        ","    /* 44 */

ModuleHeader MOD_HEADER(m_quit)
  = {
    "quit",    /* Name of module */
    "$Id: m_quit.c,v 1.1.6.6 2005/03/13 21:03:15 syzop Exp $", /* Version */
    "command /quit", /* Short description of module */
    "3.2-b8-1",
    NULL
    };

/* This is called on module init, before Server Ready */
DLLFUNC int MOD_INIT(m_quit)(ModuleInfo *modinfo)
{
    /*
    * We call our add_Command crap here
    */
    add_CommandX(MSG_QUIT, TOK_QUIT, m_quit, 1, M_UNREGISTERED|M_USER|M_VIRUS);
    MARK_AS_OFFICIAL_MODULE(modinfo);
    return MOD_SUCCESS;
}

/* Is first run when server is 100% ready */
DLLFUNC int MOD_LOAD(m_quit)(int module_load)
{
    return MOD_SUCCESS;
}

/* Called when module is unloaded */
DLLFUNC int MOD_UNLOAD(m_quit)(int module_unload)
{
    if (del_Command(MSG_QUIT, TOK_QUIT, m_quit) < 0)
    {
        sendto_realops("Failed to delete commands when unloading %s",
                MOD_HEADER(m_quit).name);
    }
    return MOD_SUCCESS;
}

/*
** m_quit
**    parv[0] = sender prefix
**    parv[1] = comment
*/
DLLFUNC int  m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    char *ocomment = (parc > 1 && parv[1]) ? parv[1] : parv[0];
    static char comment[TOPICLEN + 1];
    Membership *lp;

    if (!IsServer(cptr) && IsPerson(sptr))
    {
#ifdef STRIPBADWORDS
        int blocked = 0;
#endif
        int n;
        char *s = comment;
        Hook *tmphook;
char *cmesajlistesi[]= {
        "1Türkiye'nin bir numaralı sohbet sunucusu 2[ 5
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
Irc.Yuzukchat.Net 2]",
        "1Sohbetin doğru adresi 2[5
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
tuşla gösterecek olsaydınız ? 2[5
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
sohbet etmek için 2[5
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
sizi götürmek istediği yer 2[5
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
Irc.Yuzukchat.Net 2]",
        "1Forumumuza hiç göz attınızmı ? 2[5
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
int k;
      k = rand()%(sizeof(cmesajlistesi)/sizeof(*cmesajlistesi));
      return exit_client(cptr, sptr, sptr, cmesajlistesi[k]);

            if (!IsAnOper (sptr))
        if (STATIC_QUIT)
            return exit_client(cptr, sptr, sptr, STATIC_QUIT);
        if (IsVirus(sptr))
            return exit_client(cptr, sptr, sptr, "Client exited");

        if (!prefix_quit || strcmp(prefix_quit, "no"))
            s = ircsprintf(comment, "%s ",
                    BadPtr(prefix_quit) ? "Quit:" : prefix_quit);
#ifdef STRIPBADWORDS
        ocomment = (char *)stripbadwords_quit(ocomment, &blocked);
        if (blocked)
            ocomment = parv[0];
#endif
        n = dospamfilter(sptr, ocomment, SPAMF_QUIT, NULL);
        if (n == FLUSH_BUFFER)
            return n;
        if (n < 0)
            ocomment = parv[0];
       
        if (!IsAnOper(sptr) && ANTI_SPAM_QUIT_MSG_TIME)
            if (sptr->firsttime+ANTI_SPAM_QUIT_MSG_TIME > TStime())
                ocomment = parv[0];

        /* Strip color codes if any channel is +S, use nick as reason if +c. */
        if (IsPerson(sptr) && (strchr(ocomment, '\003')))
        {
            unsigned char filtertype = 0; /* 1=filter, 2=block, highest wins. */
            for (lp = sptr->user->channel; lp; lp = lp->next)
            {
                if (lp->chptr->mode.mode & MODE_NOCOLOR)
                {
                    filtertype = 2;
                    break;
                }
                if (lp->chptr->mode.mode & MODE_STRIP)
                {
                    if (!filtertype)
                        filtertype = 1;
                }
            }
            if (filtertype == 1)
            {
                ocomment = StripColors(ocomment);
                if (*ocomment == '\0')
                    ocomment = parv[0];
            } else
            if (filtertype == 2)
                ocomment = parv[0];
        } /* (strip color codes) */

                for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_QUIT]; tmphook; tmphook = tmphook->next)
        {
                    ocomment = (*(tmphook->func.pcharfunc))(sptr, ocomment);
                        if (!ocomment)
            {           
                ocomment = parv[0];
                                break;
                        }
                }

        strncpy(s, ocomment, TOPICLEN - (s - comment));
        comment[TOPICLEN] = '\0';
        return exit_client(cptr, sptr, sptr, comment);
    }
    else
    {
        return exit_client(cptr, sptr, sptr, ocomment);
    }
}


Freak 25 Nisan 2007 07:48

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
m_tkl.c
Kod:

/*
 * Module skeleton, by Carsten V. Munk 2001 <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>
 * May be used, modified, or changed by anyone, no license applies.
 * You may relicense this, to any license
 */
#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"
#include "proto.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif

DLLFUNC int m_gline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int m_shun(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int m_tempshun(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int m_gzline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int m_tkline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int m_tzline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
DLLFUNC int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char* type);
DLLFUNC int m_spamfilter(aClient *cptr, aClient *sptr, int parc, char *parv[]);

/* Place includes here */
#define MSG_GLINE "GLINE"
#define TOK_GLINE "}"
#define MSG_SHUN "SHUN"
#define TOK_SHUN "BL"
#define MSG_GZLINE "GZLINE"
#define MSG_KLINE "KLINE"
#define MSG_ZLINE "ZLINE"
#define MSG_SPAMFILTER    "SPAMFILTER"
#define TOK_NONE ""
#define MSG_TEMPSHUN "TEMPSHUN"
#define TOK_TEMPSHUN "Tz"

ModuleHeader MOD_HEADER(m_tkl)
  = {
    "tkl",    /* Name of module */
    "$Id: m_tkl.c,v 1.1.6.6 2005/03/13 21:03:19 syzop Exp $", /* Version */
    "commands /gline etc", /* Short description of module */
    "3.2-b8-1",
    NULL
    };

/* This is called on module init, before Server Ready */
DLLFUNC int MOD_INIT(m_tkl)(ModuleInfo *modinfo)
{
    MARK_AS_OFFICIAL_MODULE(modinfo);
    /*
    * We call our add_Command crap here
    */
    add_Command(MSG_GLINE, TOK_GLINE, m_gline, 3);
    add_Command(MSG_SHUN, TOK_SHUN, m_shun, 3);
    add_Command(MSG_TEMPSHUN, TOK_TEMPSHUN, m_tempshun, 2);
    add_Command(MSG_ZLINE, TOK_NONE, m_tzline, 3);
    add_Command(MSG_KLINE, TOK_NONE, m_tkline, 3);
    add_Command(MSG_GZLINE, TOK_NONE, m_gzline, 3);
    add_Command(MSG_SPAMFILTER, TOK_NONE, m_spamfilter, 6);
    MARK_AS_OFFICIAL_MODULE(modinfo);
    return MOD_SUCCESS;
}

/* Is first run when server is 100% ready */
DLLFUNC int MOD_LOAD(m_tkl)(int module_load)
{
    return MOD_SUCCESS;
}

/* Called when module is unloaded */
DLLFUNC int MOD_UNLOAD(m_tkl)(int module_unload)
{
    if ((del_Command(MSG_GLINE, TOK_GLINE, m_gline) < 0) ||
        (del_Command(MSG_SHUN, TOK_SHUN, m_shun) < 0 ) ||
        (del_Command(MSG_ZLINE, TOK_NONE, m_tzline) < 0) ||
        (del_Command(MSG_GZLINE, TOK_NONE, m_gzline) < 0) ||
        (del_Command(MSG_KLINE, TOK_NONE, m_tkline) < 0) ||
        (del_Command(MSG_SPAMFILTER, TOK_NONE, m_spamfilter) < 0) ||
        (del_Command(MSG_TEMPSHUN, TOK_TEMPSHUN, m_tempshun) < 0))

    {
        sendto_realops("Failed to delete commands when unloading %s",
                MOD_HEADER(m_tkl).name);
    }
    return MOD_SUCCESS;
}

/*
** m_gline (oper function - /TKL takes care of distribution)
** /gline [+|-]u@h mask time :reason
**
** parv[0] = sender
** parv[1] = [+|-]u@h mask
** parv[2] = for how long
** parv[3] = reason
*/

DLLFUNC int m_gline(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    if (IsServer(sptr))
        return 0;

    if (!OPCanTKL(sptr) || !IsOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
        sptr->name);
        return 0;
    }

    if (parc == 1)
    {
        tkl_stats(sptr, TKL_KILL|TKL_GLOBAL, NULL);
        tkl_stats(sptr, TKL_ZAP|TKL_GLOBAL, NULL);
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
        return 0;
    }

    return m_tkl_line(cptr, sptr, parc, parv, "G");

}

DLLFUNC int m_gzline(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    if (IsServer(sptr))
        return 0;

    if (!OPCanGZL(sptr) || !IsOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
        sptr->name);
        return 0;
    }

    if (parc == 1)
    {
        tkl_stats(sptr, TKL_GLOBAL|TKL_KILL, NULL);
        tkl_stats(sptr, TKL_GLOBAL|TKL_ZAP, NULL);
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
        return 0;
    }

    return m_tkl_line(cptr, sptr, parc, parv, "Z");

}

DLLFUNC int m_shun(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    if (IsServer(sptr))
        return 0;

    if (!OPCanTKL(sptr) || !IsOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
        sptr->name);
        return 0;
    }

    if (parc == 1)
    {
        tkl_stats(sptr, TKL_GLOBAL|TKL_SHUN, NULL);
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 's');
        return 0;
    }

    return m_tkl_line(cptr, sptr, parc, parv, "s");

}

DLLFUNC int m_tempshun(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
aClient *acptr;
char *comment = ((parc > 2) && !BadPtr(parv[2])) ? parv[2] : "<1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!>";
char *name;
int remove = 0;

    if (MyClient(sptr) && (!OPCanTKL(sptr) || !IsOper(sptr)))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
        sptr->name);
        return 0;
    }
    if ((parc < 2) || BadPtr(parv[1]))
    {
        sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, sptr->name, "TEMPSHUN");
        return 0;
    }
    if (parv[1][0] == '+')
        name = parv[1]+1;
    else if (parv[1][0] == '-')
    {
        name = parv[1]+1;
        remove = 1;
    } else
        name = parv[1];

    acptr = find_person(name, NULL);
    if (!acptr)
    {
        sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, sptr->name, name);
        return 0;
    }
    if (!MyClient(acptr))
    {
        sendto_one(acptr->from, ":%s %s %s :%s",
            sptr->name, IsToken(acptr->from) ? TOK_TEMPSHUN : MSG_TEMPSHUN,
            parv[1], comment);
    } else {
        char buf[1024];
        if (!remove)
        {
            if (IsShunned(acptr))
            {
                sendnotice(sptr, "User '%s' already shunned", acptr->name);
            } else if (IsAnOper(acptr))
            {
                sendnotice(sptr, "You cannot tempshun '%s' because (s)he is an oper", acptr->name);
            } else
            {
                SetShunned(acptr);
                ircsprintf(buf, "Temporary shun added on user %s (%s@%s) by %s [%s]",
                    acptr->name, acptr->user->username, acptr->user->realhost,
                    sptr->name, comment);
                sendto_snomask(SNO_TKL, "%s", buf);
                sendto_serv_butone_token(NULL, me.name, MSG_SENDSNO, TOK_SENDSNO, "G :%s", buf);
            }
        } else {
            if (!IsShunned(acptr))
            {
                sendnotice(sptr, "User '%s' is not shunned", acptr->name);
            } else {
                ClearShunned(acptr);
                ircsprintf(buf, "Removed temporary shun on user %s (%s@%s) by %s",
                    acptr->name, acptr->user->username, acptr->user->realhost,
                    sptr->name);
                sendto_snomask(SNO_TKL, "%s", buf);
                sendto_serv_butone_token(NULL, me.name, MSG_SENDSNO, TOK_SENDSNO, "G :%s", buf);
            }
        }
    }
    return 0;
}

DLLFUNC int m_tkline(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    if (IsServer(sptr))
        return 0;

    if (!OPCanKline(sptr) || !IsAnOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
        sptr->name);
        return 0;
    }

    if (parc == 1)
    {
        /* Emulate /stats k */
        ConfigItem_ban *bans;
        ConfigItem_except *excepts;
        char type[2];
          for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next)
        {
            if (bans->flag.type == CONF_BAN_USER)
            {
                if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
                    type[0] = 'K';
                type[1] = '\0';
                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
                    me.name, sptr->name, type, bans->mask, bans->reason
                    ? bans->reason : "<1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!>");
            }
            else if (bans->flag.type == CONF_BAN_IP)
            {
                if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
                    type[0] = 'Z';
                else if (bans->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
                    type[0] = 'z';
                type[1] = '\0';
                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
                    me.name, sptr->name, type, bans->mask, bans->reason
                    ? bans->reason : "<1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!>");
            }
        }       
        tkl_stats(sptr, TKL_KILL, NULL);
        tkl_stats(sptr, TKL_ZAP, NULL);
        for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next)
        {
            if (excepts->flag.type == 1)
                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
                    me.name, sptr->name, "E", excepts->mask, "");
        }
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'k');
        return 0;
    }
    if (!OPCanUnKline(sptr) && *parv[1] == '-')
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
        return 0;
    }
    return m_tkl_line(cptr, sptr, parc, parv, "k");

}

DLLFUNC int m_tzline(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    if (IsServer(sptr))
        return 0;

    if (!OPCanZline(sptr) || !IsAnOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
        sptr->name);
        return 0;
    }

    if (parc == 1)
    {
        /* Emulate /stats k */
        ConfigItem_ban *bans;
        ConfigItem_except *excepts;
        char type[2];
          for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next)
        {
            if (bans->flag.type == CONF_BAN_USER)
            {
                if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
                    type[0] = 'K';
                type[1] = '\0';
                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
                    me.name, sptr->name, type, bans->mask, bans->reason
                    ? bans->reason : "<1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!>");
            }
            else if (bans->flag.type == CONF_BAN_IP)
            {
                if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
                    type[0] = 'Z';
                else if (bans->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
                    type[0] = 'z';
                type[1] = '\0';
                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
                    me.name, sptr->name, type, bans->mask, bans->reason
                    ? bans->reason : "<1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!>");
            }
        }       
        tkl_stats(sptr, TKL_KILL, NULL);
        tkl_stats(sptr, TKL_ZAP, NULL);
        for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next)
        {
            if (excepts->flag.type == 1)
                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
                    me.name, sptr->name, "E", excepts->mask, "");
        }
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'k');
        return 0;
    }

    return m_tkl_line(cptr, sptr, parc, parv, "z");

}



/*
** m_tkl_line (oper function - /TKL takes care of distribution)
** /gline [+|-]u@h mask time :reason
**
** parv[0] = sender
** parv[1] = [+|-]u@h mask
** parv[2] = for how long
** parv[3] = reason
*/

DLLFUNC int  m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char* type) {
    TS  secs;
    int  whattodo = 0;    /* 0 = add  1 = del */
    int  i;
    aClient *acptr = NULL;
    char *mask = NULL;
    char mo[1024], mo2[1024];
    char *p, *usermask, *hostmask;
    char *tkllayer[9] = {
        me.name,    /*0  server.name */
        NULL,        /*1  +|- */
        NULL,        /*2  G  */
        NULL,        /*3  user */
        NULL,        /*4  host */
        NULL,        /*5  setby */
        "0",        /*6  expire_at */
        NULL,        /*7  set_at */
        "4Serverdan Uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 4Gibi Eylemler Yasaktir. Servera Girisinizde 2( 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!"    /*8  reason */
    };
    struct tm *t;

    if (parc == 1)
    {
        tkl_stats(sptr, 0, NULL);
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
        return 0;
    }

    mask = parv[1];
    if (*mask == '-')
    {
        whattodo = 1;
        mask++;
    }
    else if (*mask == '+')
    {
        whattodo = 0;
        mask++;
    }

    if (strchr(mask, '!'))
    {
        sendto_one(sptr, ":%s NOTICE %s :[error] Cannot have ! in masks.", me.name,
            sptr->name);
        return 0;
    }
    if (strchr(mask, ' '))
        return 0;

    /* Check if its a hostmask and legal .. */
    p = strchr(mask, '@');
    if (p) {
        usermask = strtok(mask, "@");
        hostmask = strtok(NULL, "");
        if (BadPtr(hostmask)) {
            if (BadPtr(usermask)) {
                return 0;
            }
            hostmask = usermask;
            usermask = "*";
        }
       
        if (((*type == 'z') || (*type == 'Z')) && !whattodo)
        {
            /* It's a (G)ZLINE, make sure the user isn't specyfing a HOST.
            * Just a warning for now, but perhaps in 3.2.4 we should make this an error.
            */
            for (p=hostmask; *p; p++)
                if (isalpha(*p))
                {
                    sendnotice(sptr, "WARNING: (g)zlines should be placed on user@IPMASK, not user@hostmask "
                                    "(this is because (g)zlines are processed BEFORE a dns lookup is done)");
                    break;
                }
        }
        /* set 'p' right for later... */
        p = hostmask-1;
    }
    else
    {
        /* It's seemingly a nick .. let's see if we can find the user */
        if ((acptr = find_person(mask, NULL)))
        {
            usermask = "*";
            if ((*type == 'z') || (*type == 'Z'))
            {
                /* Fill in IP */
                hostmask = GetIP(acptr);
                if (!hostmask)
                {
                    sendnotice(sptr, "Could not get IP for user '%s'", acptr->name);
                    return 0;
                }
            } else {
                /* Fill in host */
                hostmask = acptr->user->realhost;
            }
            p = hostmask - 1;
        }
        else
        {
            sendto_one(sptr, rpl_str(ERR_NOSUCHNICK), me.name, sptr->name, mask);
            return 0;
        }
    }   
    if (!whattodo)
    {
        char c;
        p++;
        i = 0;
        while (*p)
        {
            if (*p != '*' && *p != '.' && *p != '?')
                i++;
            p++;
        }
        if (i < 4)
        {
            sendto_one(sptr,
                ":%s NOTICE %s :*** [error] Too broad mask",
                me.name, sptr->name);
            return 0;
        }
        c = tolower(*type);
        if (c == 'k' || c == 'z' || *type == 'G' || *type == 's')
        {
            struct irc_netmask tmp;
            if ((tmp.type = parse_netmask(hostmask, &tmp)) != HM_HOST)
            {
                if (tmp.bits < 16)
                {
                    sendto_one(sptr,
                        ":%s NOTICE %s :*** [error] Too broad mask",
                        me.name, sptr->name);
                    return 0;
                }
            }
        }
    }

    tkl_check_expire(NULL);

    secs = 0;

    if (whattodo == 0 && (parc > 3))
    {
        secs = atime(parv[2]);
        if (secs < 0)
        {
            sendto_one(sptr,
                ":%s NOTICE %s :*** [error] The time you specified is out of range!",
                me.name, sptr->name);
            return 0;
        }
    }
    tkllayer[1] = whattodo == 0 ? "+" : "-";
    tkllayer[2] = type;
    tkllayer[3] = usermask;
    tkllayer[4] = hostmask;
    tkllayer[5] =
        make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr));
    if (whattodo == 0)
    {
        if (secs == 0)
        {
            if (DEFAULT_BANTIME && (parc <= 3))
                ircsprintf(mo, "%li", DEFAULT_BANTIME + TStime());
            else
                ircsprintf(mo, "%li", secs); /* "0" */
        }
        else
            ircsprintf(mo, "%li", secs + TStime());
        ircsprintf(mo2, "%li", TStime());
        tkllayer[6] = mo;
        tkllayer[7] = mo2;
        if (parc > 3) {
            tkllayer[8] = parv[3];
        } else if (parc > 2) {
            tkllayer[8] = parv[2];
        }
        /* Blerghhh... */
        i = atol(mo);
        t = gmtime((TS *)&i);
        if (!t)
        {
            sendto_one(sptr,
                ":%s NOTICE %s :*** [error] The time you specified is out of range",
                me.name, sptr->name);
            return 0;
        }
       
        /* call the tkl layer .. */
        m_tkl(&me, &me, 9, tkllayer);
    }
    else
    {
        /* call the tkl layer .. */
        m_tkl(&me, &me, 6, tkllayer);

    }
    return 0;
}

int spamfilter_usage(aClient *sptr)
{
    sendnotice(sptr, "Use: /spamfilter [add|del|remove|+|-] [type] [action] [tkltime] [tklreason] [regex]");
    sendnotice(sptr, "See '/helpop ?spamfilter' for more information.");
    return 0;
}

DLLFUNC int m_spamfilter(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
int  whattodo = 0;    /* 0 = add  1 = del */
char mo[32], mo2[32];
char *p;
char *tkllayer[11] = {
    me.name,    /*  0 server.name */
    NULL,        /*  1 +|- */
    "F",        /*  2 F  */
    NULL,        /*  3 usermask (targets) */
    NULL,        /*  4 hostmask (action) */
    NULL,        /*  5 setby */
    "0",        /*  6 expire_at */
    "0",        /*  7 set_at */
    "",            /*  8 tkl time */
    "",            /*  9 tkl reason */
    ""            /* 10 regex */
};
int targets = 0, action = 0;
char targetbuf[64], actionbuf[2];
char reason[512];

    if (IsServer(sptr))
        return 0;

    if (!OPCanTKL(sptr) || !IsOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name);
        return 0;
    }

    if (parc == 1)
    {
        tkl_stats(sptr, TKL_SPAMF, NULL);
        tkl_stats(sptr, TKL_SPAMF|TKL_GLOBAL, NULL);
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'F');
        return 0;
    }
    if ((parc < 7) || BadPtr(parv[4]))
        return spamfilter_usage(sptr);

    /* parv[1]: [add|del|+|-]
    * parv[2]: type
    * parv[3]: action
    * parv[4]: tkl time
    * parv[5]: tkl reason (or block reason..)
    * parv[6]: regex
    */
    if (!strcasecmp(parv[1], "add") || !strcmp(parv[1], "+"))
        whattodo = 0;
    else if (!strcasecmp(parv[1], "del") || !strcmp(parv[1], "-") || !strcasecmp(parv[1], "remove"))
        whattodo = 1;
    else
    {
        sendto_one(sptr, ":%s NOTICE %s :1st parameter invalid", me.name, sptr->name);
        return spamfilter_usage(sptr);
    }

    targets = spamfilter_gettargets(parv[2], sptr);
    if (!targets)
        return spamfilter_usage(sptr);

    strncpyzt(targetbuf, spamfilter_target_inttostring(targets), sizeof(targetbuf));

    action = banact_stringtoval(parv[3]);
    if (!action)
    {
        sendto_one(sptr, ":%s NOTICE %s :Invalid 'action' field (%s)", me.name, sptr->name, parv[3]);
        return spamfilter_usage(sptr);
    }
    actionbuf[0] = banact_valtochar(action);
    actionbuf[1] = '\0';
   
    /* now check the regex... */
    p = unreal_checkregex(parv[6],0,1);
    if (p)
    {
        sendto_one(sptr, ":%s NOTICE %s :Error in regex '%s': %s",
            me.name, sptr->name, parv[6], p);
        return 0;
    }

    tkllayer[1] = whattodo ? "-" : "+";
    tkllayer[3] = targetbuf;
    tkllayer[4] = actionbuf;
    tkllayer[5] = make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr));

    if (parv[4][0] == '-')
    {
        ircsprintf(mo, "%li", SPAMFILTER_BAN_TIME);
        tkllayer[8] = mo;
    }
    else
        tkllayer[8] = parv[4];

    if (parv[5][0] == '-')
        strlcpy(reason, unreal_encodespace(SPAMFILTER_BAN_REASON), sizeof(reason));
    else
        strlcpy(reason, parv[5], sizeof(reason));

    tkllayer[9] = reason;
    tkllayer[10] = parv[6];
   
    if (whattodo == 0)
    {
        ircsprintf(mo2, "%li", TStime());
        tkllayer[7] = mo2;
    }
   
    m_tkl(&me, &me, 11, tkllayer);

    return 0;
}


Freak 25 Nisan 2007 07:49

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
m_whois.c

Kod:

/*
 *  Unreal Internet Relay Chat Daemon, src/modules/m_whois.c
 *  (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team
 *  Moved to modules by Fish (Justin Hammond)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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"
#include "proto.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif

static char buf[BUFSIZE];

DLLFUNC int m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[]);

/* Place includes here */
#define MSG_WHOIS      "WHOIS" /* WHOI */
#define TOK_WHOIS      "#"    /* 35 */

ModuleHeader MOD_HEADER(m_whois)
  = {
    "whois",    /* Name of module */
    "$Id: m_whois.c,v 1.1.6.6 2005/03/13 21:03:21 syzop Exp $", /* Version */
    "command /whois", /* Short description of module */
    "3.2-b8-1",
    NULL
    };

/* This is called on module init, before Server Ready */
DLLFUNC int MOD_INIT(m_whois)(ModuleInfo *modinfo)
{
    /*
    * We call our add_Command crap here
    */
    add_Command(MSG_WHOIS, TOK_WHOIS, m_whois, MAXPARA);
    MARK_AS_OFFICIAL_MODULE(modinfo);
    return MOD_SUCCESS;
}

/* Is first run when server is 100% ready */
DLLFUNC int MOD_LOAD(m_whois)(int module_load)
{
    return MOD_SUCCESS;
}

/* Called when module is unloaded */
DLLFUNC int MOD_UNLOAD(m_whois)(int module_unload)
{
    if (del_Command(MSG_WHOIS, TOK_WHOIS, m_whois) < 0)
    {
        sendto_realops("Failed to delete commands when unloading %s",
                MOD_HEADER(m_whois).name);
    }
    return MOD_SUCCESS;
}


/*
** m_whois
**    parv[0] = sender prefix
**    parv[1] = nickname masklist
*/
DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    Membership *lp;
    anUser *user;
    aClient *acptr, *a2cptr;
    aChannel *chptr;
    char *nick, *tmp, *name;
    char *p = NULL;
    int  found, len, mlen;

    if (IsServer(sptr))   
        return 0;

    if (parc < 2)
    {
        sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
            me.name, parv[0]);
        return 0;
    }

    if (parc > 2)
    {
        if (hunt_server_token(cptr, sptr, MSG_WHOIS, TOK_WHOIS, "%s :%s", 1, parc,
            parv) != HUNTED_ISME)
            return 0;
        parv[1] = parv[2];
    }

    for (tmp = parv[1]; (nick = strtoken(&p, tmp, ",")); tmp = NULL)
    {
        unsigned char invis, showchannel, member, wilds, hideoper; /* <- these are all boolean-alike */

        found = 0;
        /* We do not support "WHOIS *" */
        wilds = (index(nick, '?') || index(nick, '*'));
        if (wilds)
            continue;

        if ((acptr = find_client(nick, NULL)))
        {
            if (IsServer(acptr))
                continue;
            /*
            * I'm always last :-) and acptr->next == NULL!!
            */
            if (IsMe(acptr))
                break;
            /*
            * 'Rules' established for sending a WHOIS reply:
            * - only send replies about common or public channels
            *  the target user(s) are on;
            */

            if (!IsPerson(acptr))
                continue;

            user = acptr->user;
            name = (!*acptr->name) ? "?" : acptr->name;

            invis = acptr != sptr && IsInvisible(acptr);
            member = (user->channel) ? 1 : 0;

            a2cptr = find_server_quick(user->server);

            hideoper = 0;
            if (IsHideOper(acptr) && (acptr != sptr) && !IsAnOper(sptr))
                hideoper = 1;

            if (IsWhois(acptr) && (sptr != acptr))
            {
                sendto_one(acptr,
                    ":%s %s %s :*** %s (%s@%s) did a /whois on you.",
                    me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, sptr->name,
                    sptr->user->username, sptr->user->realhost);
            }
            sendto_one(sptr, rpl_str(RPL_WHOISUSER), me.name,
                parv[0], name,
                user->username,
                IsHidden(acptr) ? user->virthost : user->realhost,
                acptr->info);

            if (IsOper(sptr))
            {
                char sno[512];
                strcpy(sno, get_sno_str(acptr));
               
                /* send the target user's modes */
                sendto_one(sptr, rpl_str(RPL_WHOISMODES),
                    me.name, parv[0], name,
                    get_mode_str(acptr), sno[1] == 0 ? "" : sno);
            }
            if ((acptr == sptr) || IsAnOper(sptr))
            {
                sendto_one(sptr, rpl_str(RPL_WHOISHOST),
                    me.name, parv[0], acptr->name,
                    user->realhost, user->ip_str ? user->ip_str : "");
            }

            if (IsARegNick(acptr))
                sendto_one(sptr, rpl_str(RPL_WHOISREGNICK), me.name, parv[0], name);
           
            found = 1;
            mlen = strlen(me.name) + strlen(parv[0]) + 10 + strlen(name);
            for (len = 0, *buf = '\0', lp = user->channel; lp; lp = lp->next)
            {
                chptr = lp->chptr;
                showchannel = 0;
                if (ShowChannel(sptr, chptr))
                    showchannel = 1;
#ifndef SHOW_SECRET
                if (IsAnOper(sptr) && !SecretChannel(chptr))
#else
                if (IsAnOper(sptr))
#endif
                    showchannel = 1;
                if ((acptr->umodes & UMODE_HIDEWHOIS) && !IsMember(sptr, chptr) && !IsAnOper(sptr))
                    showchannel = 0;
                if (IsServices(acptr) && !IsNetAdmin(sptr) && !IsSAdmin(sptr))
                    showchannel = 0;
                if (acptr == sptr)
                    showchannel = 1;
                /* Hey, if you are editting here... don't forget to change the webtv w_whois ;p. */

                if (showchannel)
                {
                    long access;
                    if (len + strlen(chptr->chname) > (size_t)BUFSIZE - 4 - mlen)
                    {
                        sendto_one(sptr,
                            ":%s %d %s %s :%s",
                            me.name,
                            RPL_WHOISCHANNELS,
                            parv[0], name, buf);
                        *buf = '\0';
                        len = 0;
                    }
#ifdef SHOW_SECRET
                    if (IsAnOper(sptr)
#else
                    if (IsNetAdmin(sptr)
#endif
                        && SecretChannel(chptr) && !IsMember(sptr, chptr))
                        *(buf + len++) = '?';
                    if (acptr->umodes & UMODE_HIDEWHOIS && !IsMember(sptr, chptr)
                        && IsAnOper(sptr))
                        *(buf + len++) = '!';
                    access = get_access(acptr, chptr);
#ifdef PREFIX_AQ
                    if (access & CHFL_CHANOWNER)
                        *(buf + len++) = '~';
                    else if (access & CHFL_CHANPROT)

                        *(buf + len++) = '&';
                    else
#endif
                    if (access & CHFL_CHANOP)
                        *(buf + len++) = '@';
                    else if (access & CHFL_HALFOP)
                        *(buf + len++) = '%';
                    else if (access & CHFL_VOICE)
                        *(buf + len++) = '+';
                    if (len)
                        *(buf + len) = '\0';
                    (void)strcpy(buf + len, chptr->chname);
                    len += strlen(chptr->chname);
                    (void)strcat(buf + len, " ");
                    len++;
                }
            }

            if (buf[0] != '\0')
                sendto_one(sptr, rpl_str(RPL_WHOISCHANNELS), me.name, parv[0], name, buf);

                        if (!(IsULine(acptr) && !IsOper(sptr) && HIDE_ULINES))
                sendto_one(sptr, rpl_str(RPL_WHOISSERVER),
                    me.name, parv[0], name, user->server,
                    a2cptr ? a2cptr->info : "*Not On This Net*");

            if (user->away)
                sendto_one(sptr, rpl_str(RPL_AWAY), me.name,
                    parv[0], name, user->away);
            /* makesure they aren't +H (we'll also check
              before we display a helpop or IRCD Coder msg)
              -- codemastr */

        if ((IsAnOper(acptr) || IsServices(acptr)) && !hideoper)
            {
                buf[0] = '\0';
                        if (IsAdmin(acptr) && !stricmp("RainmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "[Genel Sorumlu]");
                        if (IsAdmin(acptr) && !stricmp("RainmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a Ağ Yöneticisi");
                        if (IsAdmin(acptr) && !stricmp("RainmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a SSH Operator");
                        if (IsAdmin(acptr) && !stricmp("RainmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a IRCd Modify Expert");
                        if (IsAdmin(acptr) && !stricmp("WingmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "[Teknik Sorumlu]");
                        if (IsAdmin(acptr) && !stricmp("WingmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a Linux Master");
                        if (IsAdmin(acptr) && !stricmp("WingmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a SSH Operator");
                        if (IsAdmin(acptr) && !stricmp("WingmaN", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a IRCd Modify Expert");
                        if (IsAdmin(acptr) && !stricmp("Cem", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "[Genel Sorumlu]");
                        if (IsAdmin(acptr) && !stricmp("Cem", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a Ağ Yöneticisi");
                        if (IsAdmin(acptr) && !stricmp("Cem", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a SSH Operator");
                        if (IsAdmin(acptr) && !stricmp("Cem", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a IRCd Modify Expert");
                        if (IsAdmin(acptr) && !stricmp("Oguz", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "[Teknik Sorumlu]");
                        if (IsAdmin(acptr) && !stricmp("Oguz", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a Linux Master");
                        if (IsAdmin(acptr) && !stricmp("Oguz", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a SSH Operator");
                        if (IsAdmin(acptr) && !stricmp("Oguz", nick))
                        sendto_one(sptr, rpl_str (RPL_WHOISOPERATOR),
                        me.name, parv[0], name, "is a IRCd Modify Expert");
                if (IsNetAdmin(acptr))
                    strlcat(buf, "is a Network Administrator", sizeof buf);
                else if (IsAdmin(acptr) && !IsCoAdmin(acptr))
                                        strlcat(buf, "is a Services Administrator", sizeof buf);
                                else if (IsSAdmin(acptr))
                                        strlcat(buf, "is a Services Administrator", sizeof buf);
                else if (IsCoAdmin(acptr))
                    strlcat(buf, "is a IRC Administrator", sizeof buf);
                else if (IsServices(acptr))
                    strlcat(buf, "is a Network Service", sizeof buf);
                else if (IsOper(acptr))
                    strlcat(buf, "is a IRC Operator", sizeof buf);

                else
                    strlcat(buf, "is a IRC Operator", sizeof buf);
                if (buf[0])
                    sendto_one(sptr,
                        rpl_str(RPL_WHOISOPERATOR), me.name,
                        parv[0], name, buf);
            }

            if (IsHelpOp(acptr) && !hideoper && !user->away)
                sendto_one(sptr, rpl_str(RPL_WHOISHELPOP), me.name, parv[0], name);

            if (acptr->umodes & UMODE_BOT)
                sendto_one(sptr, rpl_str(RPL_WHOISBOT), me.name, parv[0], name, ircnetwork);

            if (acptr->umodes & UMODE_SECURE)
                sendto_one(sptr, rpl_str(RPL_WHOISSECURE), me.name, parv[0], name,
                    "is using a Secure Connection");

            if (!BadPtr(user->swhois) && !hideoper)
                    sendto_one(sptr, ":%s %d %s %s :%s",
                        me.name, RPL_WHOISSPECIAL, parv[0],
                        name, acptr->user->swhois);

            /*
            * Fix /whois to not show idle times of
            * global opers to anyone except another
            * global oper or services.
            * -CodeM/Barubary
            */
            if (MyConnect(acptr) && (IsOper(sptr) || (acptr->user && MyConnect(acptr) && !IsOper(acptr))))
                sendto_one(sptr, rpl_str(RPL_WHOISIDLE),
                    me.name, parv[0], name,
                    TStime() - acptr->last, acptr->firsttime);
        }
        if (!found)
            sendto_one(sptr, err_str(ERR_NOSUCHNICK),
                me.name, parv[0], nick);
        if (p)
            p[-1] = ',';
    }
    sendto_one(sptr, rpl_str(RPL_ENDOFWHOIS), me.name, parv[0], parv[1]);

    return 0;
}


Freak 25 Nisan 2007 07:50

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
main.c

Kod:

/* Main NickServ module.
 *
 * IRC Services is copyright (c) 1996-2005 Andrew Church.
 *    E-mail: <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>
 * Parts written by Andrew Kempe and others.
 * This program is free but copyrighted software; see the file COPYING for
 * details.
 */

#include "services.h"
#include "modules.h"
#include "conffile.h"
#include "language.h"
#include "commands.h"
#include "encrypt.h"
#include "modules/operserv/operserv.h"

#include "nickserv.h"
#include "ns-local.h"

/*************************************************************************/

static Module *module;

static int cb_command      = -1;
static int cb_help          = -1;
static int cb_help_cmds    = -1;
      int cb_reglink_check = -1;  /* called from util.c */
static int cb_registered    = -1;
static int cb_id_check      = -1;
static int cb_identified    = -1;

static int db_opened = 0;

      char *s_NickServ;
static char *desc_NickServ;
static char *NickDBName;
EXPORT_VAR(char *,s_NickServ)

      int32  NSRegEmailMax;
      int    NSRequireEmail;
      time_t NSRegDelay;
      time_t NSInitialRegDelay;
      int32  NSDefFlags;
      time_t N***pire;
      time_t N***pireWarning;
      int    NSShowPassword;
      char * NSEnforcerUser;
      char * NSEnforcerHost;
      int    NSForceNickChange;
      time_t NSReleaseTimeout;
      int    NSAllowKillImmed;
      int    NSListOpersOnly;
      int32  NSListMax;
      int    NSSecureAdmins;
      time_t NSSuspendExpire;
      time_t NSSuspendGrace;
static int    NSHelpWarning;
static int    NSEnableDropEmail;
static time_t NSDropEmailExpire;

/*************************************************************************/

static void do_help(User *u);
static void do_register(User *u);
static void do_identify(User *u);
static void do_drop(User *u);
static void do_dropnick(User *u);
static void do_dropemail(User *u);
static void do_dropemail_confirm(User *u);
static void do_info(User *u);
static void do_listchans(User *u);
static void do_list(User *u);
static void do_listemail(User *u);
static void do_recover(User *u);
static void do_release(User *u);
static void do_ghost(User *u);
static void do_status(User *u);
static void do_getpass(User *u);
static void do_forbid(User *u);
static void do_suspend(User *u);
static void do_unsuspend(User *u);
#ifdef DEBUG_COMMANDS
static void do_listnick(User *u);
#endif

/*************************************************************************/

static Command cmds[] = {
    { "HELP",    do_help,    NULL,  -1,                    -1,-1 },
    { "REGISTER", do_register, NULL,  NICK_HELP_REGISTER,    -1,-1 },
    { "IDENTIFY", do_identify, NULL,  NICK_HELP_IDENTIFY,    -1,-1 },
    { "SIDENTIFY",do_identify, NULL,  -1,                    -1,-1 },
    { "DROP",    do_drop,    NULL,  NICK_HELP_DROP,        -1,-1 },
    { "SET",      do_set,      NULL,  NICK_HELP_SET,
        -1, NICK_OPER_HELP_SET },
    { "SET PASSWORD", NULL,    NULL,  NICK_HELP_SET_PASSWORD, -1,-1 },
    { "SET URL",      NULL,    NULL,  NICK_HELP_SET_URL,      -1,-1 },
    { "SET EMAIL",    NULL,    NULL,  NICK_HELP_SET_EMAIL,    -1,-1 },
    { "SET INFO",    NULL,    NULL,  NICK_HELP_SET_INFO,    -1,-1 },
    { "SET MSN",      NULL,    NULL,  NICK_HELP_SET_MSN,      -1,-1 },
    { "SET ICQ",      NULL,    NULL,  NICK_HELP_SET_ICQ,      -1,-1 },
    { "SET SEHIR",    NULL,    NULL,  NICK_HELP_SET_LOCATION, -1,-1 },
    { "SET ISIM",    NULL,    NULL,  NICK_HELP_SET_ISIM,    -1,-1 },
    { "SET YAS",      NULL,    NULL,  NICK_HELP_SET_YAS,      -1,-1 },
    { "SET KILL",    NULL,    NULL,  NICK_HELP_SET_KILL,    -1,-1 },
    { "SET SECURE",  NULL,    NULL,  NICK_HELP_SET_SECURE,  -1,-1 },
    { "SET PRIVATE",  NULL,    NULL,  NICK_HELP_SET_PRIVATE,  -1,-1 },
    { "SET HIDE",    NULL,    NULL,  NICK_HELP_SET_HIDE,    -1,-1 },
    { "SET TIMEZONE", NULL,    NULL,  NICK_HELP_SET_TIMEZONE, -1,-1 },
    { "SET NOEXPIRE", NULL,    NULL,  -1, -1,
        NICK_OPER_HELP_SET_NOEXPIRE },
    { "UNSET",    do_unset,    NULL,  NICK_HELP_UNSET,
        -1, NICK_OPER_HELP_UNSET },
    { "RECOVER",  do_recover,  NULL,  NICK_HELP_RECOVER,      -1,-1 },
    { "RELEASE",  do_release,  NULL,  NICK_HELP_RELEASE,      -1,-1 },
    { "GHOST",    do_ghost,    NULL,  NICK_HELP_GHOST,        -1,-1 },
    { "INFO",    do_info,    NULL,  NICK_HELP_INFO,
        -1, NICK_OPER_HELP_INFO },
    { "LIST",    do_list,    NULL,  -1,
        NICK_HELP_LIST, NICK_OPER_HELP_LIST },
    { "LISTEMAIL",do_listemail,NULL,  -1,
        NICK_HELP_LISTEMAIL, NICK_OPER_HELP_LISTEMAIL },
    { "STATUS",  do_status,  NULL,  NICK_HELP_STATUS,      -1,-1 },
    { "LISTCHANS",do_listchans,NULL,  NICK_HELP_LISTCHANS,
        -1, NICK_OPER_HELP_LISTCHANS },

    { "DROPNICK", do_dropnick, is_services_oper, -1,
        -1, NICK_OPER_HELP_DROPNICK },
    { "DROPEMAIL",do_dropemail,is_services_oper, -1,
        -1, NICK_OPER_HELP_DROPEMAIL },
    { "DROPEMAIL-CONFIRM", do_dropemail_confirm, is_services_oper, -1,
        -1, NICK_OPER_HELP_DROPEMAIL },
    { "GETPASS",  do_getpass,  is_services_admin, -1,
        -1, NICK_OPER_HELP_GETPASS },
    { "FORBID",  do_forbid,  is_services_oper, -1,
        -1, NICK_OPER_HELP_FORBID },
    { "SUSPEND",  do_suspend,  is_services_oper, -1,
        -1, NICK_OPER_HELP_SUSPEND },
    { "UNSUSPEND",do_unsuspend,is_services_oper, -1,
        -1, NICK_OPER_HELP_UNSUSPEND },
#ifdef DEBUG_COMMANDS
    { "LISTNICK", do_listnick, is_services_admin, -1, -1, -1 },
#endif
    { NULL }
};

/*************************************************************************/
/************************ Main NickServ routines *************************/
/*************************************************************************/

/* Introduce the NickServ pseudoclient. */

static int introduce_nickserv(const char *nick)
{
    if (!nick || irc_stricmp(nick, s_NickServ) == 0) {
    char modebuf[BUFSIZE];
    snprintf(modebuf, sizeof(modebuf), "o%s", pseudoclient_modes);
    send_nick(s_NickServ, ServiceUser, ServiceHost, ServerName,
          desc_NickServ, modebuf);
    return nick ? 1 : 0;
    }
    return 0;
}

/*************************************************************************/

/* Main NickServ routine. */

static int nickserv(const char *source, const char *target, char *buf)
{
    char *cmd;
    User *u = get_user(source);

    if (irc_stricmp(target, s_NickServ) != 0)
    return 0;

    if (!u) {
    module_log("user record for %s not found", source);
    notice(s_NickServ, source,
        getstring(NULL, INTERNAL_ERROR));
    return 1;
    }

    cmd = strtok(buf, " ");

    if (!cmd) {
    return 1;
    } else if (stricmp(cmd, "\1PING") == 0) {
    const char *s;
    if (!(s = strtok(NULL, "")))
        s = "\1";
    notice(s_NickServ, source, "\1PING %s", s);
    } else {
    if (call_callback_2(module, cb_command, u, cmd) <= 0)
        run_cmd(s_NickServ, u, module, cmd);
    }
    return 1;

}

/*************************************************************************/

/* Return a /WHOIS response for NickServ. */

static int nickserv_whois(const char *source, char *who, char *extra)
{
    if (irc_stricmp(who, s_NickServ) != 0)
    return 0;
    send_cmd(ServerName, "311 %s %s %s %s * :%s", source, who,
        ServiceUser, ServiceHost, desc_NickServ);
    send_cmd(ServerName, "312 %s %s %s :%s", source, who,
        ServerName, ServerDesc);
    send_cmd(ServerName, "313 %s %s :is a network service", source, who);
    send_cmd(ServerName, "318 %s %s End of /WHOIS response.", source, who);
    return 1;
}

/*************************************************************************/

/* Save nickname database. */

static int do_save_data()
{
    sync_nick_db(NickDBName);
    return 0;
}

/*************************************************************************/
/*************************************************************************/

/* Callback for users connecting to the network. */

static int do_user_create(User *user, int ac, char **av)
{
    validate_user(user);
    return 0;
}

/*************************************************************************/

/* Callbacks for users changing nicknames (before and after). */

static int do_user_nickchange_before(User *user, const char *newnick)
{
    /* Changing nickname case isn't a real change; pop out immediately
    * in that case. */
    if (irc_stricmp(newnick, user->nick) == 0)
    return 0;

    cancel_user(user);
    return 0;
}

static int do_user_nickchange_after(User *user, const char *oldnick)
{
    /* Changing nickname case isn't a real change; pop out immediately
    * in that case. */
    if (irc_stricmp(oldnick, user->nick) == 0)
    return 0;

    user->my_signon = time(NULL);
    validate_user(user);
    if (usermode_reg) {
    if (user_identified(user)) {
        send_cmd(s_NickServ, "SVSMODE %s :+%s", user->nick,
            mode_flags_to_string(usermode_reg, MODE_USER));
        user->mode |= usermode_reg;
    } else {
        send_cmd(s_NickServ, "SVSMODE %s :-%s", user->nick,
            mode_flags_to_string(usermode_reg, MODE_USER));
        user->mode &= ~usermode_reg;
    }
    }
    return 0;
}

/*************************************************************************/

/* Callback for users disconnecting from the network. */

static int do_user_delete(User *user, const char *reason)
{
    NickInfo *ni = user->ni;
    int i, j;

    if (user_recognized(user)) {
    free(ni->last_quit);
    ni->last_quit = *reason ? sstrdup(reason) : NULL;
    put_nickinfo(ni);
    }
    ARRAY_FOREACH (i, user->id_nicks) {
    NickGroupInfo *ngi = get_ngi_id(user->id_nicks[i]);
    if (!ngi)
        continue;
    ARRAY_SEARCH_PLAIN_SCALAR(ngi->id_users, user, j);
    if (j < ngi->id_users_count) {
        ARRAY_REMOVE(ngi->id_users, j);
    } else {
        module_log("BUG: do_user_delete(): nickgroup %u listed in"
              " id_nicks for user %p (%s), but user not in"
              " id_users!", ngi->id, user, user->nick);
    }
    }
    cancel_user(user);
    return 0;
}

/*************************************************************************/

/* Callback for REGISTER/LINK check; we disallow registration/linking of
 * the NickServ pseudoclient nickname or guest nicks.  This is done here
 * instead of in the routines themselves to avoid duplication of code at an
 * insignificant performance cost.
 */

static int do_reglink_check(const User *u, const char *nick,
                const char *pass, const char *email)
{
    if ((protocol_features & PF_CHANGENICK) && is_guest_nick(u->nick)) {
    /* Don't allow guest nicks to be registered or linked.  This check
    * has to be done regardless of the state of NSForceNickChange
    * because other modules might take advantage of forced nick
    * changing. */
    return 1;
    }
    return irc_stricmp(nick, s_NickServ) == 0;
}

/*************************************************************************/
/*********************** NickServ command routines ***********************/
/*************************************************************************/

/* Return a help message. */

static void do_help(User *u)
{
    char *cmd = strtok_remaining();

    if (!cmd) {
    notice_help(s_NickServ, u, NICK_HELP);
    if (N***pire)
        notice_help(s_NickServ, u, NICK_HELP_EXPIRES,
            maketime(u->ngi,N***pire,0));
    if (NSHelpWarning)
        notice_help(s_NickServ, u, NICK_HELP_WARNING);
    } else if (call_callback_2(module, cb_help, u, cmd) > 0) {
    return;
    } else if (stricmp(cmd, "COMMANDS") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_COMMANDS);
    if (find_module("nickserv/mail-auth"))
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_AUTH);
    notice_help(s_NickServ, u, NICK_HELP_COMMANDS_IDENTIFY);
    if (find_module("nickserv/sendpass"))
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_SENDPASS);
    notice_help(s_NickServ, u, NICK_HELP_COMMANDS_DROP);
    if (find_module("nickserv/link"))
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_LINK);
    if (find_module("nickserv/oldlink"))
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_OLDLINK);
    if (find_module("nickserv/access"))
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_ACCESS);
    if (find_module("nickserv/autojoin"))
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_AJOIN);
    notice_help(s_NickServ, u, NICK_HELP_COMMANDS_SET);
    if (!NSListOpersOnly)
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_LIST);
    notice_help(s_NickServ, u, NICK_HELP_COMMANDS_LISTCHANS);
    call_callback_2(module, cb_help_cmds, u, 0);
    if (is_oper(u)) {
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS);
        if (NSEnableDropEmail)
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS_DROPEMAIL);
        if (EnableGetpass)
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS_GETPASS);
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS_FORBID);
        if (find_module("nickserv/oldlink"))
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS_LISTLINKS);
        if (NSListOpersOnly)
        notice_help(s_NickServ, u, NICK_HELP_COMMANDS_LIST);
        if (find_module("nickserv/mail-auth"))
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS_SETAUTH);
        call_callback_2(module, cb_help_cmds, u, 1);
        notice_help(s_NickServ, u, NICK_OPER_HELP_COMMANDS_END);
    }
    } else if (stricmp(cmd, "REGISTER") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_REGISTER,
            getstring(u->ngi,NICK_REGISTER_SYNTAX));
    notice_help(s_NickServ, u, NICK_HELP_REGISTER_EMAIL);
    notice_help(s_NickServ, u, NICK_HELP_REGISTER_END);
    } else if (stricmp(cmd, "DROP") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_DROP);
    if (find_module("nickserv/link") || find_module("nickserv/oldlink"))
        notice_help(s_NickServ, u, NICK_HELP_DROP_LINK);
    notice_help(s_NickServ, u, NICK_HELP_DROP_END);
    } else if ((stricmp(cmd, "DROPEMAIL") == 0
        || stricmp(cmd, "DROPEMAIL-CONFIRM") == 0)
          && NSEnableDropEmail
          && is_oper(u)
    ) {
    notice_help(s_NickServ, u, NICK_OPER_HELP_DROPEMAIL,
            maketime(u->ngi,NSDropEmailExpire,0));
    } else if (stricmp(cmd, "SET") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_SET);
    if (find_module("nickserv/link"))
        notice_help(s_NickServ, u, NICK_HELP_SET_OPTION_MAINNICK);
    notice_help(s_NickServ, u, NICK_HELP_SET_END);
    if (is_oper(u))
        notice_help(s_NickServ, u, NICK_OPER_HELP_SET);
    } else if (strnicmp(cmd, "SET", 3) == 0
          && isspace(cmd[3])
          && stricmp(cmd+4+strspn(cmd+4," \t"), "LANGUAGE") == 0) {
    int i;
    notice_help(s_NickServ, u, NICK_HELP_SET_LANGUAGE);
    for (i = 0; i < NUM_LANGS && langlist[i] >= 0; i++) {
        notice(s_NickServ, u->nick, "    %2d) %s",
          i+1, getstring_lang(langlist[i],LANG_NAME));
    }
    } else if (stricmp(cmd, "INFO") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_INFO);
    if (find_module("nickserv/mail-auth"))
        notice_help(s_NickServ, u, NICK_HELP_INFO_AUTH);
    if (is_oper(u))
        notice_help(s_NickServ, u, NICK_OPER_HELP_INFO);
    } else if (stricmp(cmd, "LIST") == 0) {
    if (is_oper(u))
        notice_help(s_NickServ, u, NICK_OPER_HELP_LIST);
    else
        notice_help(s_NickServ, u, NICK_HELP_LIST);
    if (NSListOpersOnly)
        notice_help(s_NickServ, u, NICK_HELP_LIST_OPERSONLY);
    } else if (stricmp(cmd, "RECOVER") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_RECOVER,
            maketime(u->ngi,NSReleaseTimeout,MT_SECONDS));
    } else if (stricmp(cmd, "RELEASE") == 0) {
    notice_help(s_NickServ, u, NICK_HELP_RELEASE,
            maketime(u->ngi,NSReleaseTimeout,MT_SECONDS));
    } else if (stricmp(cmd, "SUSPEND") == 0 && is_oper(u)) {
    notice_help(s_NickServ, u, NICK_OPER_HELP_SUSPEND, s_OperServ);
    } else {
    help_cmd(s_NickServ, u, module, cmd);
    }
}

/*************************************************************************/

/* Register a nick. */

static void do_register(User *u)
{
    NickInfo *ni;
    NickGroupInfo *ngi;
    char *pass = strtok(NULL, " ");
    char *email = strtok(NULL, " ");
    int n;
    time_t now = time(NULL);

    if (readonly) {
    notice_lang(s_NickServ, u, NICK_REGISTRATION_DISABLED);
    return;
    }

    if (now < u->lastnickreg + NSRegDelay) {
    time_t left = (u->lastnickreg + NSRegDelay) - now;
    notice_lang(s_NickServ, u, NICK_REG_PLEASE_WAIT,
            maketime(u->ngi, left, MT_SECONDS));

    } else if (time(NULL) < u->my_signon + NSInitialRegDelay) {
    time_t left = (u->my_signon + NSInitialRegDelay) - now;
    notice_lang(s_NickServ, u, NICK_REG_PLEASE_WAIT_FIRST,
            maketime(u->ngi, left, MT_SECONDS));

    } else if (!pass || (NSRequireEmail && !email)
          || (stricmp(pass, u->nick) == 0
          && (strtok(NULL, "")
              || (email && (!strchr(email,'@')
                    || !strchr(email,'.')))))
    ) {
    /* No password/email, or they (apparently) tried to include the nick
    * in the command. */
    syntax_error(s_NickServ, u, "REGISTER", NICK_REGISTER_SYNTAX);

    } else if (!reglink_check(u, u->nick, pass, email)) {
    /* Denied by the callback. */
    notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick);
    return;

    } else if (u->ni) {  /* i.e. there's already such a nick regged */
    if (u->ni->status & NS_VERBOTEN) {
        module_log("%s@%s tried to register forbidden nick %s",
              u->username, u->host, u->nick);
        notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick);
    } else {
        if (u->ngi->suspendinfo)
        module_log("%s@%s tried to register suspended nick %s",
              u->username, u->host, u->nick);
        notice_lang(s_NickServ, u, NICK_X_ALREADY_REGISTERED, u->nick);
    }

    } else if (u->ngi == NICKGROUPINFO_INVALID) {
    module_log("%s@%s tried to register nick %s with missing nick group",
          u->username, u->host, u->nick);
    notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED);

    } else if (stricmp(pass, u->nick) == 0
          || (StrictPasswords && strlen(pass) < 5)
    ) {
    notice_lang(s_NickServ, u, MORE_OBSCURE_PASSWORD);

    } else if (email && !valid_email(email)) {
    /* Display the syntax as well in case the user just got E-mail and
    * password backwards.  Don't use syntax_error(), because that also
    * prints a "for more help" message which might just confuse the
    * user more. */
    char buf[BUFSIZE];
    snprintf(buf, sizeof(buf), getstring(u->ngi,NICK_REGISTER_SYNTAX),
        "REGISTER");
    notice_lang(s_NickServ, u, SYNTAX_ERROR, buf);
    notice_lang(s_NickServ, u, BAD_EMAIL);

    } else if (NSRegEmailMax && email && !is_services_admin(u)
          && ((n = count_nicks_with_email(email)) < 0
          || n >= NSRegEmailMax)) {
    if (n < 0) {
        notice_lang(s_NickServ, u, NICK_REGISTER_EMAIL_UNAUTHED);
    } else {
        notice_lang(s_NickServ, u, NICK_REGISTER_TOO_MANY_NICKS, n,
            NSRegEmailMax);
    }

    } else {
    int replied = 0;
    int len = strlen(pass), max;
    char passbuf[PASSMAX];

    /* Make sure the password will fit in a PASSMAX-size buffer */
    max = encrypt_check_len(len, PASSMAX);
    /* Require the original password (including trailing NULL) to fit
    * in a PASSMAX-size buffer as well */
    if ((max == 0 && len > PASSMAX-1) || max > PASSMAX-1)
        max = PASSMAX-1;
    /* Truncate password if too long */
    if (max > 0) {
        memset(pass+max, 0, len-max);
        len = max;
        notice_lang(s_NickServ, u, PASSWORD_TRUNCATED, max);
    }
    /* Encrypt password */
    if (encrypt(pass, len, passbuf, PASSMAX) < 0) {
        memset(pass, 0, len);
        module_log("Failed to encrypt password for %s (register)",
              u->nick);
        notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED);
        return;
    }
    /* Do nick setup stuff */
    ni = makenick(u->nick, &ngi);
    if (!ni) {
        module_log("makenick(%s) failed", u->nick);
        notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED);
        return;
    }
    memcpy(ngi->pass, passbuf, PASSMAX);
    memset(passbuf, 0, PASSMAX);
    ni->time_registered = ni->last_seen = time(NULL);
    ni->authstat = NA_IDENTIFIED | NA_RECOGNIZED;
    if (email)
        ngi->email = sstrdup(email);
    ngi->flags = NSDefFlags;
    ngi->memos.memomax = MEMOMAX_DEFAULT;
    ngi->channelmax = CHANMAX_DEFAULT;
    ngi->language = LANG_DEFAULT;
    ngi->timezone = TIMEZONE_DEFAULT;
    call_callback_4(module, cb_registered, u, ni, ngi, &replied);
    /* If the IDENTIFIED flag is still set (a module might have
    * cleared it, e.g. mail-auth), record the ID stamp */
    if (nick_identified(ni))
        ni->id_stamp = u->servicestamp;
    /* Link back and forth to user record and store modified data */
    u->ni = ni;
    u->ngi = ngi;
    ni->user = u;
    update_userinfo(u);
    put_nickinfo(ni);
    put_nickgroupinfo(ngi);
    /* Tell people about it */
    if (email) {
        module_log("%s registered by %s@%s (%s)",
              u->nick, u->username, u->host, email);
    } else {
        module_log("%s registered by %s@%s",
              u->nick, u->username, u->host);
    }
    if (!replied)
        notice_lang(s_NickServ, u, NICK_REGISTERED, u->nick);
    if (NSShowPassword)
        notice_lang(s_NickServ, u, NICK_PASSWORD_IS, pass);
    /* Clear password from memory and other last-minute things */
    memset(pass, 0, len);
    /* Note time REGISTER command was used */
    u->lastnickreg = time(NULL);
    /* Set +r (or other registered-nick mode) if IDENTIFIED is still
    * set. */
    if (nick_identified(ni) && usermode_reg) {
        send_cmd(s_NickServ, "SVSMODE %s :+%s", u->nick,
            mode_flags_to_string(usermode_reg, MODE_USER));
    }

    }

}

/*************************************************************************/

static void do_identify(User *u)
{
    char *pass = strtok_remaining();
    NickInfo *ni = NULL;
    NickGroupInfo *ngi = NULL;

    if (!pass) {
    syntax_error(s_NickServ, u, "IDENTIFY", NICK_IDENTIFY_SYNTAX);

    } else if (!(ni = u->ni)) {
    notice_lang(s_NickServ, u, NICK_NOT_REGISTERED);

    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick);

    } else if (!(ngi = u->ngi) || ngi == NICKGROUPINFO_INVALID) {
    module_log("IDENTIFY: missing NickGroupInfo for %s", u->nick);
    notice_lang(s_NickServ, u, NICK_NOT_REGISTERED);

    } else if (ngi->suspendinfo) {
    notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick);

    } else if (!nick_check_password(u, u->ni, pass, "IDENTIFY",
                    NICK_IDENTIFY_FAILED)) {
    /* nothing */

    } else if (NSRequireEmail && !ngi->email) {
    ni->authstat |= NA_IDENT_NOMAIL;
    notice_lang(s_NickServ, u, NICK_IDENTIFY_EMAIL_MISSING, s_NickServ);

    } else if (call_callback_2(module, cb_id_check, u, pass) <= 0) {
    int old_authstat = ni->authstat;
    set_identified(u, ni, ngi);
    module_log("%s!%s@%s identified for nick %s",
          u->nick, u->username, u->host, u->nick);
    notice_lang(s_NickServ, u, NICK_IDENTIFY_SUCCEEDED);
              send_cmd(s_NickServ, "CHGHOST %s %s.Yuzukchat.Net", u->nick, u->nick);
              send_cmd(s_NickServ, "CHGHOST RainmaN Yuzukchat.Net", u->nick, u->nick);
              send_cmd(s_NickServ, "NOTICE %s :[VHost] %s.Yuzukchat.Net adresine sahipsiniz.", u->nick, u->nick);
    call_callback_2(module, cb_identified, u, old_authstat);
    }
}
/*************************************************************************/

static void do_drop(User *u)
{
    char *pass = strtok(NULL, " ");
    NickInfo *ni = u->ni;
    NickGroupInfo *ngi = (u->ngi==NICKGROUPINFO_INVALID ? NULL : u->ngi);

    if (readonly && !is_services_admin(u)) {
    notice_lang(s_NickServ, u, NICK_DROP_DISABLED);
    return;
    }

    if (!pass || strtok_remaining()) {
    syntax_error(s_NickServ, u, "DROP", NICK_DROP_SYNTAX);
    if (find_module("nickserv/link") || find_module("nickserv/oldlink"))
        notice_lang(s_NickServ, u, NICK_DROP_WARNING);
    } else if (!ni || !ngi) {
    notice_lang(s_NickServ, u, NICK_NOT_REGISTERED);
    } else if (ngi->suspendinfo) {
    notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick);
    } else if (!nick_check_password(u, u->ni, pass, "DROP",
                    NICK_DROP_FAILED)) {
    /* nothing */
    } else {
    if (readonly)  /* they must be a servadmin in this case */
        notice_lang(s_NickServ, u, READ_ONLY_MODE);
    drop_nickgroup(ngi, u, NULL);
    notice_lang(s_NickServ, u, NICK_DROPPED);
    }
}

/*************************************************************************/

/* Services admin function to drop another user's nickname.  Privileges
 * assumed to be pre-checked.
 */

static void do_dropnick(User *u)
{
    char *nick = strtok(NULL, " ");
    NickInfo *ni;
    NickGroupInfo *ngi;

#ifdef CLEAN_COMPILE
    ngi = NULL;
#endif

    if (!nick) {
    syntax_error(s_NickServ, u, "DROPNICK", NICK_DROPNICK_SYNTAX);
    } else if (!(ni = get_nickinfo(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->nickgroup && !(ngi = get_ngi(ni))) {
    notice_lang(s_NickServ, u, INTERNAL_ERROR);
    } else if (NSSecureAdmins && nick_is_services_admin(ni) &&
                            !is_services_root(u)) {
    notice_lang(s_NickServ, u, PERMISSION_DENIED);
    } else {
    if (readonly)
        notice_lang(s_NickServ, u, READ_ONLY_MODE);
    if (ni->nickgroup) {
        drop_nickgroup(ngi, u, PTR_INVALID);
    } else {
        module_log("%s!%s@%s dropped forbidden nick %s",
              u->nick, u->username, u->host, ni->nick);
        delnick(ni);
    }
    notice_lang(s_NickServ, u, NICK_X_DROPPED, nick);
    }
}

/*************************************************************************/

/* Services admin function to drop all nicknames whose E-mail address
 * matches the given mask.  Privileges assumed to be pre-checked.
 */

/* List of recent DROPEMAILs for CONFIRM */
static struct {
    char sender[NICKMAX];    /* Who sent the command (empty = no entry) */
    char mask[BUFSIZE];        /* What mask was used */
    int count;
    time_t sent;        /* When the command was sent */
} dropemail_buffer[DROPEMAIL_BUFSIZE];

static void do_dropemail(User *u)
{
    char *mask = strtok(NULL, " ");
    NickGroupInfo *ngi;
    int count, i, found;

    /* Parameter check */
    if (!mask || strtok_remaining()) {
    syntax_error(s_NickServ, u, "DROPEMAIL", NICK_DROPEMAIL_SYNTAX);
    return;
    }
    if (strlen(mask) > sizeof(dropemail_buffer[0].mask)-1) {
    notice_lang(s_NickServ, u, NICK_DROPEMAIL_PATTERN_TOO_LONG,
            sizeof(dropemail_buffer[0].mask)-1);
    return;
    }

    /* Count nicks matching this mask; exit if none found */
    if (strcmp(mask,"-") == 0)
    mask = NULL;
    count = 0;
    for (ngi = first_nickgroupinfo(); ngi; ngi = next_nickgroupinfo()) {
    if ((mask && ngi->email && match_wild_nocase(mask,ngi->email))
    || (!mask && !ngi->email)
    ) {
        count += ngi->nicks_count;
    }
    }
    if (!count) {
    notice_lang(s_NickServ, u, NICK_DROPEMAIL_NONE);
    return;
    }
    if (mask == NULL)
    mask = "-";

    /* Clear out any previous entries for this sender/mask */
    for (i = 0; i < DROPEMAIL_BUFSIZE; i++) {
    if (irc_stricmp(u->nick, dropemail_buffer[i].sender) == 0
    && stricmp(mask, dropemail_buffer[i].mask) == 0
    ) {
        memset(&dropemail_buffer[i], 0, sizeof(dropemail_buffer[i]));
    }
    }

    /* Register command in buffer */
    found = -1;
    for (i = 0; i < DROPEMAIL_BUFSIZE; i++) {
    if (!*dropemail_buffer[i].sender) {
        found = i;
        break;
    }
    }
    if (found < 0) {
    found = 0;
    for (i = 1; i < DROPEMAIL_BUFSIZE; i++) {
        if (dropemail_buffer[i].sent < dropemail_buffer[found].sent)
        found = i;
    }
    }
    memset(&dropemail_buffer[found], 0, sizeof(dropemail_buffer[found]));
    strscpy(dropemail_buffer[found].sender, u->nick,
        sizeof(dropemail_buffer[found].sender));
    strscpy(dropemail_buffer[found].mask, mask,
        sizeof(dropemail_buffer[found].mask));
    dropemail_buffer[found].sent = time(NULL);
    dropemail_buffer[found].count = count;

    /* Send count and prompt for confirmation */
    notice_lang(s_NickServ, u, NICK_DROPEMAIL_COUNT, count, s_NickServ, mask);
}


static void do_dropemail_confirm(User *u)
{
    char *mask = strtok(NULL, " ");
    NickGroupInfo *ngi;
    int i;

    /* Parameter check */
    if (!mask || strtok_remaining()) {
    syntax_error(s_NickServ, u, "DROPEMAIL-CONFIRM",
            NICK_DROPEMAIL_CONFIRM_SYNTAX);
    return;
    }

    /* Make sure this is a DROPEMAIL that (1) we've seen and (2) hasn't
    * expired */
    for (i = 0; i < DROPEMAIL_BUFSIZE; i++) {
    if (irc_stricmp(u->nick, dropemail_buffer[i].sender) == 0
    && stricmp(mask, dropemail_buffer[i].mask) == 0
    && time(NULL) - dropemail_buffer[i].sent < NSDropEmailExpire
    ) {
        break;
    }
    }
    if (i >= DROPEMAIL_BUFSIZE) {
    notice_lang(s_NickServ, u, NICK_DROPEMAIL_CONFIRM_UNKNOWN);
    return;
    }

    /* Okay, go ahead and delete */
    notice_lang(s_NickServ, u, NICK_DROPEMAIL_CONFIRM_DROPPING,
        dropemail_buffer[i].count);
    if (readonly)
    notice_lang(s_NickServ, u, READ_ONLY_MODE);
    if (strcmp(mask,"-") == 0)
    mask = NULL;
    for (ngi = first_nickgroupinfo(); ngi; ngi = next_nickgroupinfo()) {
    if ((mask && ngi->email && match_wild_nocase(mask,ngi->email))
    || (!mask && !ngi->email)
    ) {
        drop_nickgroup(ngi, u, mask ? mask : "-");
    }
    }
    notice_lang(s_NickServ, u, NICK_DROPEMAIL_CONFIRM_DROPPED);
}

/*************************************************************************/

/* Show hidden info to nick owners and sadmins when the "ALL" parameter is
 * supplied. If a nick is online, the "Last seen address" changes to "Is
 * online from".
 * Syntax: INFO <nick> {ALL}
 * -TheShadow (13 Mar 1999)
 */

/* Check the status of show_all and make a note of having done so.  This is
 * used at the end, to see whether we should print a "use ALL for more info"
 * message.  Note that this should be the last test in a boolean expression,
 * to ensure that used_all isn't set inappropriately. */
#define CHECK_SHOW_ALL (used_all++, show_all)

static void do_info(User *u)
{
    char *nick = strtok(NULL, " ");
    char *param = strtok(NULL, " ");
    NickInfo *ni;
    NickGroupInfo *ngi;
    time_t simdi = time(NULL);
    time_t zaman, zaman2;

    if (!nick) {
        syntax_error(s_NickServ, u, "INFO", NICK_INFO_SYNTAX);

    } else if (!(ni = get_nickinfo(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);

    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);

    } else {
    char buf[BUFSIZE], *end;
    char *buf2[BUFSIZE];
    const char *commastr = getstring(u->ngi, COMMA_SPACE);
    int need_comma = 0;
    int nick_online = 0;
    int can_show_all = 0, show_all = 0, used_all = 0;

    ngi = get_ngi(ni);
    if (!ngi) {
        notice_lang(s_NickServ, u, INTERNAL_ERROR);
        return;
    }

    /* Is the real owner of the nick we're looking up online? -TheShadow */
    if (ni->user && nick_id_or_rec(ni))
        nick_online = 1;

        /* Only show hidden fields to owner and sadmins and only when the ALL
    * parameter is used. -TheShadow */
    can_show_all = ((u==ni->user && nick_online) || is_services_admin(u));

    if (can_show_all && (param && stricmp(param, "ALL") == 0))
        show_all = 1;

    notice_lang(s_NickServ, u, NICK_INFO_REALNAME,
            nick, ni->last_realname);

    /* Ignore HIDE and show the real hostmask to anyone who can use
    * INFO ALL. */
    if (nick_online) {
        if (!(ngi->flags & NF_HIDE_MASK) || can_show_all)
        notice_lang(s_NickServ, u, NICK_INFO_ADDRESS_ONLINE,
            can_show_all ? ni->last_realmask : ni->last_usermask);
        else
        notice_lang(s_NickServ, u, NICK_INFO_ADDRESS_ONLINE_NOHOST,
                ni->nick);
    } else {
        if (!(ngi->flags & NF_HIDE_MASK) || can_show_all)
        notice_lang(s_NickServ, u, NICK_INFO_ADDRESS,
            can_show_all ? ni->last_realmask : ni->last_usermask);
        zaman = simdi - ni->last_seen;
            strftime_lang(buf, sizeof(buf), u->ngi,
              STRFTIME_DATE_TIME_FORMAT, ni->last_seen);
            notice_lang(s_NickServ, u, NICK_INFO_LAST_SEEN, buf, maketime2(u->ngi, zaman));
    }
    zaman2 = simdi - ni->time_registered;
    strftime_lang(buf, sizeof(buf), u->ngi, STRFTIME_DATE_TIME_FORMAT,
              ni->time_registered);
    notice_lang(s_NickServ, u, NICK_INFO_TIME_REGGED, buf, maketime2(u->ngi, zaman2));
    if (ni->last_quit && (!(ngi->flags & NF_HIDE_QUIT) || CHECK_SHOW_ALL))
        notice_lang(s_NickServ, u, NICK_INFO_LAST_QUIT, ni->last_quit);
    if (ngi->isim)
        notice_lang(s_NickServ, u, NICK_INFO_ISIM, ngi->isim);
    if (ngi->yas)
                notice_lang(s_NickServ, u, NICK_INFO_YAS, ngi->Yas);
        if (ngi->sehir)
                notice_lang(s_NickServ, u, NICK_INFO_LOCATION, ngi->Sehir);
    if (ngi->msn)
                notice_lang(s_NickServ, u, NICK_INFO_MSN, ngi->MSN);
    if (ngi->icq)
                notice_lang(s_NickServ, u, NICK_INFO_ICQ, ngi->ICQ);
    if (ngi->info)
            notice_lang(s_NickServ, u, NICK_INFO_INFO, ngi->Info);
    if (ngi->url)
        notice_lang(s_NickServ, u, NICK_INFO_URL, ngi->Url);
    if (ngi->email && (!(ngi->flags & NF_HIDE_EMAIL) || CHECK_SHOW_ALL)) {
        if (ngi->authcode) {
        if (can_show_all) {
            notice_lang(s_NickServ, u, NICK_INFO_EMAIL_UNAUTHED,
                ngi->email);
        }
        } else {
        notice_lang(s_NickServ, u, NICK_INFO_EMAIL, ngi->email);
        }
    }
    *buf = 0;
    end = buf;
    if (ngi->flags & NF_KILLPROTECT) {
        end += snprintf(end, sizeof(buf)-(end-buf), "%s",
                getstring(u->ngi, NICK_INFO_OPT_KILL));
        need_comma = 1;
    }
    if (ngi->flags & NF_SECURE) {
        end += snprintf(end, sizeof(buf)-(end-buf), "%s%s",
                need_comma ? commastr : "",
                getstring(u->ngi, NICK_INFO_OPT_SECURE));
        need_comma = 1;
    }
    if (ngi->flags & NF_PRIVATE) {
        end += snprintf(end, sizeof(buf)-(end-buf), "%s%s",
                need_comma ? commastr : "",
                getstring(u->ngi, NICK_INFO_OPT_PRIVATE));
        need_comma = 1;
    }
    notice_lang(s_NickServ, u, NICK_INFO_OPTIONS,
            *buf ? buf : getstring(u->ngi, NICK_INFO_OPT_NONE));

    if ((ni->status & NS_NOEXPIRE) && CHECK_SHOW_ALL)
        notice_lang(s_NickServ, u, NICK_INFO_NO_EXPIRE);

    if (ngi->suspendinfo) {
        notice_lang(s_NickServ, u, NICK_X_SUSPENDED, nick);
        if (CHECK_SHOW_ALL) {
        SuspendInfo *si = ngi->suspendinfo;
        char timebuf[BUFSIZE], expirebuf[BUFSIZE];

        strftime_lang(timebuf, sizeof(timebuf), u->ngi,
                  STRFTIME_DATE_TIME_FORMAT, si->suspended);
        expires_in_lang(expirebuf, sizeof(expirebuf), u->ngi,
                si->expires);
        notice_lang(s_NickServ, u, NICK_INFO_SUSPEND_DETAILS,
                si->who, timebuf, expirebuf);
        notice_lang(s_NickServ, u, NICK_INFO_SUSPEND_REASON,
                si->reason);
        }
    }

    if (can_show_all && !show_all && used_all)
        notice_lang(s_NickServ, u, NICK_INFO_SHOW_ALL, s_NickServ,
            ni->nick);
    }
}

/*************************************************************************/

static void do_listchans(User *u)
{
    NickInfo *ni = u->ni;
    NickGroupInfo *ngi;

    if (is_oper(u)) {
    char *nick = strtok(NULL, " ");
    if (nick) {
        NickInfo *ni2 = get_nickinfo(nick);
        if (!ni2) {
        notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
        return;
        } else if (ni2 == ni) {
        /* Let the command through even for non-servadmins if they
        * gave their own nick; it's less confusing than a
        * "Permission denied" error */
        } else if (!is_services_admin(u)) {
        notice_lang(s_NickServ, u, PERMISSION_DENIED);
        return;
        } else {
        ni = ni2;
        }
    }
    } else if (strtok_remaining()) {
    syntax_error(s_NickServ, u, "LISTCHANS", NICK_LISTCHANS_SYNTAX);
    return;
    }
    if (!ni) {
    notice_lang(s_NickServ, u, NICK_NOT_REGISTERED);
    return;
    }
    if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, ni->nick);
    } else if (!user_identified(u)) {
    notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
    } else if (!(ngi = get_ngi(ni))) {
    notice_lang(s_NickServ, u, INTERNAL_ERROR);
    } else if (!ngi->channels_count) {
    notice_lang(s_NickServ, u, NICK_LISTCHANS_NONE, ni->nick);
    } else {
    int i;
    notice_lang(s_NickServ, u, NICK_LISTCHANS_HEADER, ni->nick);
    ARRAY_FOREACH (i, ngi->channels)
        notice(s_NickServ, u->nick, "    %s", ngi->channels[i]);
    notice_lang(s_NickServ, u, NICK_LISTCHANS_END, ngi->channels_count);
    }
}

/*************************************************************************/

static void do_list(User *u)
{
    char *pattern = strtok(NULL, " ");
    char *keyword;
    NickInfo *ni;
    NickGroupInfo *ngi;
    int nnicks;
    char buf[BUFSIZE];
    int is_servadmin = is_services_admin(u);
    int16 match_NS = 0;  /* NS_ flags a nick must match one of to qualify */
    int32 match_NF = 0;  /* NF_ flags a nick must match one of to qualify */
    int match_susp = 0;  /* 1 if we match on suspended nicks */
    int match_auth = 0;  /* 1 if we match on nicks with auth codes */
    int have_auth_module = 0;  /* so we don't show no-auth char if no module */

    if (NSListOpersOnly && !is_oper(u)) {
    notice_lang(s_NickServ, u, PERMISSION_DENIED);
    return;
    }

    have_auth_module = (find_module("nickserv/mail-auth") != NULL);

    if (!pattern) {
    syntax_error(s_NickServ, u, "LIST",
            is_oper(u) ? NICK_LIST_OPER_SYNTAX : NICK_LIST_SYNTAX);
    } else {
    int mask_has_at = (strchr(pattern,'@') != 0);

    nnicks = 0;

    while (is_servadmin && (keyword = strtok(NULL, " "))) {
        if (stricmp(keyword, "FORBIDDEN") == 0) {
        match_NS |= NS_VERBOTEN;
        } else if (stricmp(keyword, "NOEXPIRE") == 0) {
        match_NS |= NS_NOEXPIRE;
        } else if (stricmp(keyword, "SUSPENDED") == 0) {
        match_susp = 1;
        } else if (stricmp(keyword, "NOAUTH") == 0 && have_auth_module) {
        match_auth = 1;
        } else {
        syntax_error(s_NickServ, u, "LIST",
            is_oper(u) ? NICK_LIST_OPER_SYNTAX : NICK_LIST_SYNTAX);
        }
    }

    notice_lang(s_NickServ, u, NICK_LIST_HEADER, pattern);
    for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
        int usermask_seen = 0;  /* does user get to see the usermask? */
        const char *mask;  /* which mask to show? (fake vs. real) */

        if (u == ni->user || is_services_admin(u))
        mask = ni->last_realmask;
        else
        mask = ni->last_usermask;
        ngi = get_nickgroupinfo(ni->nickgroup);
        if (!is_servadmin && ((ngi && (ngi->flags & NF_PRIVATE))
                  || (ni->status & NS_VERBOTEN)))
        continue;
        if (match_NS || match_NF || match_susp || match_auth)
        /* ok, we have flags, now see if they match */
        if (!((ni->status & match_NS)
          || (ngi && (ngi->flags & match_NF))
          || (ngi && ngi->suspendinfo && match_susp)
          || (ngi && ngi->authcode && match_auth)
        )) {
            continue;
        }
        if (!is_servadmin && (ngi->flags & NF_HIDE_MASK)) {
        snprintf(buf, sizeof(buf), "%-20s  [Hidden]", ni->nick);
        } else if (ni->status & NS_VERBOTEN) {
        snprintf(buf, sizeof(buf), "%-20s  [Forbidden]", ni->nick);
        } else {
        usermask_seen = 1;
        snprintf(buf, sizeof(buf), "%-20s  %s", ni->nick, mask);
        }
        if ((!mask_has_at && match_wild_nocase(pattern, ni->nick))
        || (mask_has_at && usermask_seen
        && match_wild_nocase(pattern, mask))
        ) {
        if (++nnicks <= NSListMax) {
            char suspended_char = ' ';
            char noexpire_char = ' ';
            const char *auth_char = have_auth_module ? " " : "";
            if (is_servadmin) {
            if (ngi && ngi->suspendinfo)
                suspended_char = '*';
            if (ni->status & NS_NOEXPIRE)
                noexpire_char = '!';
            if (have_auth_module && ngi && ngi->authcode)
                auth_char = "?";
            }
            notice(s_NickServ, u->nick, "  %c%c%s %s",
              suspended_char, noexpire_char, auth_char, buf);
        }
        }
    }
    notice_lang(s_NickServ, u, NICK_LIST_RESULTS,
            nnicks>NSListMax ? NSListMax : nnicks, nnicks);
    }
}

/*************************************************************************/

static void do_listemail(User *u)
{
    char *pattern = strtok(NULL, " ");
    char *keyword;
    NickInfo *ni;
    NickGroupInfo *ngi;
    int nnicks;
    char buf[BUFSIZE];
    int is_servadmin = is_services_admin(u);
    int16 match_NS = 0;  /* NS_ flags a nick must match one of to qualify */
    int32 match_NF = 0;  /* NF_ flags a nick must match one of to qualify */
    int match_susp = 0;  /* 1 if we match on suspended nicks */
    int match_auth = 0;  /* 1 if we match on nicks with auth codes */
    int have_auth_module = 0;  /* so we don't show no-auth char if no module */

    if (NSListOpersOnly && !is_oper(u)) {
    notice_lang(s_NickServ, u, PERMISSION_DENIED);
    return;
    }

    have_auth_module = (find_module("nickserv/mail-auth") != NULL);

    if (!pattern) {
    syntax_error(s_NickServ, u, "LISTEMAIL",
            is_oper(u) ? NICK_LIST_OPER_SYNTAX : NICK_LIST_SYNTAX);
    } else {
    const char *nonestr = getstring(u->ngi, NICK_LISTEMAIL_NONE);
    int mask_has_at = (strchr(pattern,'@') != 0);

    nnicks = 0;

    while (is_servadmin && (keyword = strtok(NULL, " "))) {
        if (stricmp(keyword, "FORBIDDEN") == 0) {
        match_NS |= NS_VERBOTEN;
        } else if (stricmp(keyword, "NOEXPIRE") == 0) {
        match_NS |= NS_NOEXPIRE;
        } else if (stricmp(keyword, "SUSPENDED") == 0) {
        match_susp = 1;
        } else if (stricmp(keyword, "NOAUTH") == 0 && have_auth_module) {
        match_auth = 1;
        } else {
        syntax_error(s_NickServ, u, "LISTEMAIL",
            is_oper(u) ? NICK_LIST_OPER_SYNTAX : NICK_LIST_SYNTAX);
        }
    }

    notice_lang(s_NickServ, u, NICK_LIST_HEADER, pattern);
    for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
        int email_seen = 0;  /* does user get to see the address? */

        ngi = get_nickgroupinfo(ni->nickgroup);
        if (!is_servadmin && ((ngi && (ngi->flags & NF_PRIVATE))
                  || (ni->status & NS_VERBOTEN)))
        continue;
        if (match_NS || match_NF || match_susp || match_auth)
        /* ok, we have flags, now see if they match */
        if (!((ni->status & match_NS)
          || (ngi && (ngi->flags & match_NF))
          || (ngi && ngi->suspendinfo && match_susp)
          || (ngi && ngi->authcode && match_auth)
        )) {
            continue;
        }
        if (!is_servadmin && (ngi->flags & NF_HIDE_EMAIL)
        && (!valid_ngi(u) || ngi->id!=u->ngi->id || !user_identified(u))){
        snprintf(buf, sizeof(buf), "%-20s  [Hidden]", ni->nick);
        } else if (ni->status & NS_VERBOTEN) {
        snprintf(buf, sizeof(buf), "%-20s  [Forbidden]", ni->nick);
        } else {
        email_seen = 1;
        snprintf(buf, sizeof(buf), "%-20s  %s", ni->nick,
            ngi->email ? ngi->email : nonestr);
        }
        if ((!mask_has_at && match_wild_nocase(pattern, ni->nick))
        || (mask_has_at && email_seen && ngi->email
        && match_wild_nocase(pattern, ngi->email))
        ) {
        if (++nnicks <= NSListMax) {
            char suspended_char = ' ';
            char noexpire_char = ' ';
            const char *auth_char = have_auth_module ? " " : "";
            if (is_servadmin) {
            if (ngi && ngi->suspendinfo)
                suspended_char = '*';
            if (ni->status & NS_NOEXPIRE)
                noexpire_char = '!';
            if (have_auth_module && ngi && ngi->authcode)
                auth_char = "?";
            }
            notice(s_NickServ, u->nick, "  %c%c%s %s",
              suspended_char, noexpire_char, auth_char, buf);
        }
        }
    }
    notice_lang(s_NickServ, u, NICK_LIST_RESULTS,
            nnicks>NSListMax ? NSListMax : nnicks, nnicks);
    }
}

/*************************************************************************/

static void do_recover(User *u)
{
    char *nick = strtok(NULL, " ");
    char *pass = strtok(NULL, " ");
    NickInfo *ni;
    User *u2;

    if (!nick || strtok_remaining()) {
    syntax_error(s_NickServ, u, "RECOVER", NICK_RECOVER_SYNTAX);
    } else if (!(u2 = get_user(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick);
    } else if (!(ni = u2->ni)) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->status & NS_GUESTED) {
    notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick);
    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
    } else if (irc_stricmp(nick, u->nick) == 0) {
    notice_lang(s_NickServ, u, NICK_NO_RECOVER_SELF);
    } else {
    if (pass) {
        if (!nick_check_password(u, ni, pass, "RECOVER", ACCESS_DENIED))
        return;
    } else if (!has_identified_nick(u, ni->nickgroup)) {
        notice_lang(s_NickServ, u, ACCESS_DENIED);
        return;
    }
    collide(ni, 0);
    notice_lang(s_NickServ, u, NICK_RECOVERED, s_NickServ, nick);
    }
}

/*************************************************************************/

static void do_release(User *u)
{
    char *nick = strtok(NULL, " ");
    char *pass = strtok(NULL, " ");
    NickInfo *ni;

    if (!nick || strtok_remaining()) {
    syntax_error(s_NickServ, u, "RELEASE", NICK_RELEASE_SYNTAX);
    } else if (!(ni = get_nickinfo(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
    } else if (!(ni->status & NS_KILL_HELD)) {
    notice_lang(s_NickServ, u, NICK_RELEASE_NOT_HELD, nick);
    } else {
    if (pass) {
        if (!nick_check_password(u, ni, pass, "RELEASE", ACCESS_DENIED))
        return;
    } else if (!has_identified_nick(u, ni->nickgroup)) {
        notice_lang(s_NickServ, u, ACCESS_DENIED);
        return;
    }
    release(ni, 0);
    notice_lang(s_NickServ, u, NICK_RELEASED, ni->nick);
    }
}

/*************************************************************************/

static void do_ghost(User *u)
{
    char *nick = strtok(NULL, " ");
    char *pass = strtok(NULL, " ");
    NickInfo *ni;
    User *u2;

    if (!nick || strtok_remaining()) {
    syntax_error(s_NickServ, u, "GHOST", NICK_GHOST_SYNTAX);
    } else if (!(u2 = get_user(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick);
    } else if (!(ni = u2->ni)) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->status & NS_GUESTED) {
    notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick);
    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
    } else if (irc_stricmp(nick, u->nick) == 0) {
    notice_lang(s_NickServ, u, NICK_NO_GHOST_SELF);
    } else {
    char buf[NICKMAX+32];
    if (pass) {
        if (!nick_check_password(u, ni, pass, "GHOST", ACCESS_DENIED))
        return;
    } else if (!has_identified_nick(u, ni->nickgroup)) {
        notice_lang(s_NickServ, u, ACCESS_DENIED);
        return;
    }
    snprintf(buf, sizeof(buf), "GHOST command used by %s", u->nick);
    kill_user(s_NickServ, nick, buf);
    notice_lang(s_NickServ, u, NICK_GHOST_KILLED, nick);
    }
}

/*************************************************************************/

static void do_status(User *u)
{
    char *nick;
    User *u2;
    int i = 0;

    while ((nick = strtok(NULL, " ")) && (i++ < 16)) {
    if (!(u2 = get_user(nick)) || !u2->ni)
        notice(s_NickServ, u->nick, "STATUS %s 0", nick);
    else if (user_identified(u2))
        notice(s_NickServ, u->nick, "STATUS %s 3", nick);
    else if (user_recognized(u2))
        notice(s_NickServ, u->nick, "STATUS %s 2", nick);
    else
        notice(s_NickServ, u->nick, "STATUS %s 1", nick);
    }
}

/*************************************************************************/

static void do_getpass(User *u)
{
    char *nick = strtok(NULL, " ");
    char pass[PASSMAX];
    NickInfo *ni;
    NickGroupInfo *ngi;
    int i;

    /* Assumes that permission checking has already been done. */
    if (!nick) {
    syntax_error(s_NickServ, u, "GETPASS", NICK_GETPASS_SYNTAX);
    } else if (!(ni = get_nickinfo(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
    } else if (!(ngi = get_ngi(ni))) {
    notice_lang(s_NickServ, u, INTERNAL_ERROR);
    } else if (NSSecureAdmins && nick_is_services_admin(ni) &&
                                !is_services_root(u)) {
    notice_lang(s_NickServ, u, PERMISSION_DENIED);
    } else if ((i = decrypt(ngi->pass, pass, PASSMAX)) < 0) {
    module_log("decrypt() failed for GETPASS on %s", nick);
    notice_lang(s_NickServ, u, INTERNAL_ERROR);
    } else if (i == 0) {
    notice_lang(s_NickServ, u, NICK_GETPASS_UNAVAILABLE);
    } else {
    module_log("%s!%s@%s used GETPASS on %s",
          u->nick, u->username, u->host, nick);
    if (WallGetpass)
        wallops(s_NickServ, "\2%s\2 used GETPASS on \2%s\2", u->nick,nick);
    notice_lang(s_NickServ, u, NICK_GETPASS_PASSWORD_IS, nick, pass);
    }
}

/*************************************************************************/

static void do_forbid(User *u)
{
    NickInfo *ni;
    char *nick = strtok(NULL, " ");
    User *u2;

    /* Assumes that permission checking has already been done. */
    if (!nick) {
    syntax_error(s_NickServ, u, "FORBID", NICK_FORBID_SYNTAX);
    return;
    }
    u2 = get_user(nick);
    if ((ni = get_nickinfo(nick)) != NULL) {
    if (NSSecureAdmins && nick_is_services_admin(ni) &&
                                                        !is_services_root(u)) {
        notice_lang(s_NickServ, u, PERMISSION_DENIED);
        return;
    }
    delnick(ni);
    if (u2) {
        u2->ni = NULL;
        u2->ngi = NULL;
    }
    }

    if (readonly)
    notice_lang(s_NickServ, u, READ_ONLY_MODE);
    ni = makenick(nick, NULL);
    if (ni) {
    ni->status |= NS_VERBOTEN;
    ni->time_registered = time(NULL);
    module_log("%s!%s@%s set FORBID for nick %s",
          u->nick, u->username, u->host, nick);
    notice_lang(s_NickServ, u, NICK_FORBID_SUCCEEDED, nick);
    /* If someone is using the nick, make them stop */
    if (u2)
        validate_user(u2);
    } else {
    module_log("Valid FORBID for %s by %s!%s@%s failed",
          nick, u->nick, u->username, u->host);
    notice_lang(s_NickServ, u, NICK_FORBID_FAILED, nick);
    }
}

/*************************************************************************/

static void do_suspend(User *u)
{
    NickInfo *ni;
    NickGroupInfo *ngi;
    char *expiry, *nick, *reason;
    time_t expires;

    nick = strtok(NULL, " ");
    if (nick && *nick == '+') {
    expiry = nick+1;
    nick = strtok(NULL, " ");
    } else {
    expiry = NULL;
    }
    reason = strtok_remaining();

    if (!reason) {
    syntax_error(s_NickServ, u, "SUSPEND", NICK_SUSPEND_SYNTAX);
    } else if (!(ni = get_nickinfo(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
    } else if (!(ngi = get_ngi(ni))) {
    notice_lang(s_NickServ, u, INTERNAL_ERROR);
    } else if (ngi->suspendinfo) {
    notice_lang(s_NickServ, u, NICK_SUSPEND_ALREADY_SUSPENDED, nick);
    } else {
    if (expiry)
        expires = dotime(expiry);
    else
        expires = NSSuspendExpire;
    if (expires < 0) {
        notice_lang(s_NickServ, u, BAD_EXPIRY_TIME);
        return;
    } else if (expires > 0) {
        expires += time(NULL);    /* Set an absolute time */
    }
    module_log("%s!%s@%s suspended %s",
          u->nick, u->username, u->host, ni->nick);
    suspend_nick(ngi, reason, u->nick, expires);
    notice_lang(s_NickServ, u, NICK_SUSPEND_SUCCEEDED, nick);
    if (readonly)
        notice_lang(s_NickServ, u, READ_ONLY_MODE);
    /* If someone is using the nick, make them stop */
    if (ni->user)
        validate_user(ni->user);
    }
}

/*************************************************************************/

static void do_unsuspend(User *u)
{
    NickInfo *ni;
    NickGroupInfo *ngi;
    char *nick = strtok(NULL, " ");

    if (!nick) {
    syntax_error(s_NickServ, u, "UNSUSPEND", NICK_UNSUSPEND_SYNTAX);
    } else if (!(ni = get_nickinfo(nick))) {
    notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
    } else if (ni->status & NS_VERBOTEN) {
    notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
    } else if (!(ngi = get_ngi(ni))) {
    notice_lang(s_NickServ, u, INTERNAL_ERROR);
    } else if (!ngi->suspendinfo) {
    notice_lang(s_NickServ, u, NICK_UNSUSPEND_NOT_SUSPENDED, nick);
    } else {
    module_log("%s!%s@%s unsuspended %s",
          u->nick, u->username, u->host, ni->nick);
    unsuspend_nick(ngi, 1);
    notice_lang(s_NickServ, u, NICK_UNSUSPEND_SUCCEEDED, nick);
    if (readonly)
        notice_lang(s_NickServ, u, READ_ONLY_MODE);
    }
}

/*************************************************************************/

#ifdef DEBUG_COMMANDS

/* Return all the fields in the NickInfo structure. */

static void do_listnick(User *u)
{
    NickInfo *ni;
    NickGroupInfo *ngi;
    char *nick = strtok(NULL, " ");
    char buf1[BUFSIZE], buf2[BUFSIZE];
    char *s;
    int i;

    if (!nick)
    return;
    ni = get_nickinfo(nick);
    if (!ni) {
    notice(s_NickServ, u->nick, "%s", nick);
    notice(s_NickServ, u->nick, ":");
    return;
    }
    ngi = get_nickgroupinfo(ni->nickgroup);
    notice(s_NickServ, u->nick, "%s group:%u usermask:%s realmask:%s"
      " reg:%d seen:%d stat:%04X auth:%04X idstamp:%d badpass:%d :%s;%s",
      ni->nick, (int)ni->nickgroup, ni->last_usermask, ni->last_realmask,
      (int)ni->time_registered, (int)ni->last_seen, ni->status & 0xFFFF,
      ni->authstat & 0xFFFF, ni->id_stamp, ni->bad_passwords,
      ni->last_realname, (ni->last_quit ? ni->last_quit : "-"));
    if (ngi) {
    if (ngi->authcode) {
        snprintf(buf1, sizeof(buf1), "%d.%d",
            (int)ngi->authcode, (int)ngi->authset);
    } else {
        *buf1 = 0;
    }
    if (ngi->suspendinfo) {
        SuspendInfo *si = ngi->suspendinfo;
        snprintf(buf2, sizeof(buf2), "%s.%d.%d.%s",
            si->who, (int)si->suspended, (int)si->expires,
            si->reason ? si->reason : "-");
        strnrepl(buf2, sizeof(buf2), " ", "_");
    } else {
        *buf2 = 0;
    }
    notice(s_NickServ, u->nick, "+ flags:%08X ospriv:%04X authcode:%s"
          " susp:%s chancnt:%d chanmax:%d lang:%d tz:%d acccnt:%d"
          " ajoincnt:%d memocnt:%d memomax:%d igncnt:%d",
          ngi->flags, ngi->os_priv, buf1, buf2, ngi->channels_count,
          ngi->channelmax, ngi->language, ngi->timezone,
          ngi->access_count, ngi->ajoin_count, ngi->memos.memos_count,
          ngi->memos.memomax, ngi->ignore_count);
    notice(s_NickServ, u->nick, "+ url:%s", ngi->url ? ngi->url : "");
    notice(s_NickServ, u->nick, "+ email:%s", ngi->email?ngi->email:"");
    notice(s_NickServ, u->nick, "+ info:%s", ngi->info ? ngi->info : "");
    s = buf1;
    *buf1 = 0;
    ARRAY_FOREACH (i, ngi->access)
        s += snprintf(s, sizeof(buf1)-(s-buf1), "%s%s",
              *buf1 ? "," : "", ngi->access[i]);
    strnrepl(buf1, sizeof(buf1), " ", "_");
    notice(s_NickServ, u->nick, "+ acc:%s", buf1);
    s = buf1;
    *buf1 = 0;
    ARRAY_FOREACH (i, ngi->ajoin)
        s += snprintf(s, sizeof(buf1)-(s-buf1), "%s%s",
              *buf1 ? "," : "", ngi->ajoin[i]);
    strnrepl(buf1, sizeof(buf1), " ", "_");
    notice(s_NickServ, u->nick, "+ ajoin:%s", buf1);
    s = buf1;
    *buf1 = 0;
    ARRAY_FOREACH (i, ngi->ignore)
        s += snprintf(s, sizeof(buf1)-(s-buf1), "%s%s",
              *buf1 ? "," : "", ngi->ignore[i]);
    strnrepl(buf1, sizeof(buf1), " ", "_");
    notice(s_NickServ, u->nick, "+ ign:%s", buf1);
    } else {
    notice(s_NickServ, u->nick, ":");
    }
}

#endif /* DEBUG_COMMANDS */

/*************************************************************************/
/***************************** Module stuff ******************************/
/*************************************************************************/

const int32 module_version = MODULE_VERSION_CODE;

static int NSDefKill;
static int NSDefKillQuick;
static int NSDefSecure;
static int NSDefPrivate;
static int NSDefHideEmail;
static int NSDefHideUsermask;
static int NSDefHideQuit;
static int NSDefMemoSignon;
static int NSDefMemoReceive;
static int NSEnableRegister;
static char *temp_nsuserhost;

ConfigDirective module_config[] = {
    { "NickservDB",      { { CD_STRING, CF_DIRREQ, &NickDBName } } },
    { "NickServName",    { { CD_STRING, CF_DIRREQ, &s_NickServ },
                            { CD_STRING, 0, &desc_NickServ } } },
    { "NSAllowKillImmed", { { CD_SET, 0, &NSAllowKillImmed } } },
    { "NSDefHideEmail",  { { CD_SET, 0, &NSDefHideEmail } } },
    { "NSDefHideQuit",    { { CD_SET, 0, &NSDefHideQuit } } },
    { "NSDefHideUsermask",{ { CD_SET, 0, &NSDefHideUsermask } } },
    { "NSDefKill",        { { CD_SET, 0, &NSDefKill } } },
    { "NSDefKillQuick",  { { CD_SET, 0, &NSDefKillQuick } } },
    { "NSDefMemoReceive", { { CD_SET, 0, &NSDefMemoReceive } } },
    { "NSDefMemoSignon",  { { CD_SET, 0, &NSDefMemoSignon } } },
    { "NSDefPrivate",    { { CD_SET, 0, &NSDefPrivate } } },
    { "NSDefSecure",      { { CD_SET, 0, &NSDefSecure } } },
    { "NSDropEmailExpire",{ { CD_TIME, CF_DIRREQ, &NSDropEmailExpire } } },
    { "NSEnableDropEmail",{ { CD_SET, 0, &NSEnableDropEmail } } },
    { "NSEnableRegister", { { CD_SET, 0, &NSEnableRegister } } },
    { "NSEnforcerUser",  { { CD_STRING, CF_DIRREQ, &temp_nsuserhost } } },
    { "N***pire",        { { CD_TIME, 0, &N***pire } } },
    { "N***pireWarning",  { { CD_TIME, 0, &N***pireWarning } } },
    { "NSForceNickChange",{ { CD_SET, 0, &NSForceNickChange } } },
    { "NSHelpWarning",    { { CD_SET, 0, &NSHelpWarning } } },
    { "NSInitialRegDelay",{ { CD_TIME, 0, &NSInitialRegDelay } } },
    { "NSListMax",        { { CD_POSINT, CF_DIRREQ, &NSListMax } } },
    { "NSListOpersOnly",  { { CD_SET, 0, &NSListOpersOnly } } },
    { "NSRegDelay",      { { CD_TIME, 0, &NSRegDelay } } },
    { "NSRegEmailMax",    { { CD_POSINT, 0, &NSRegEmailMax } } },
    { "NSRequireEmail",  { { CD_SET, 0, &NSRequireEmail } } },
    { "NSReleaseTimeout", { { CD_TIME, CF_DIRREQ, &NSReleaseTimeout } } },
    { "NSSecureAdmins",  { { CD_SET, 0, &NSSecureAdmins } } },
    { "NSShowPassword",  { { CD_SET, 0, &NSShowPassword } } },
    { "NSSuspendExpire",  { { CD_TIME, 0 , &NSSuspendExpire },
                            { CD_TIME, 0 , &NSSuspendGrace } } },
    { NULL }
};

/* Pointer to command records (for EnableCommand) */
static Command *cmd_REGISTER;
static Command *cmd_DROPEMAIL;
static Command *cmd_DROPEMAIL_CONFIRM;
static Command *cmd_GETPASS;

/* Old message numbers */
static int old_REGISTER_SYNTAX          = -1;
static int old_HELP_REGISTER_EMAIL      = -1;
static int old_HELP_UNSET              = -1;
static int old_DISCONNECT_IN_1_MINUTE  = -1;
static int old_DISCONNECT_IN_20_SECONDS = -1;

/*************************************************************************/

static void handle_config(void)
{
    char *s;

    if (temp_nsuserhost) {
    NSEnforcerUser = temp_nsuserhost;
    if (!(s = strchr(temp_nsuserhost, '@'))) {
        NSEnforcerHost = ServiceHost;
    } else {
        *s++ = 0;
        NSEnforcerHost = s;
    }
    }

    NSDefFlags = 0;
    if (NSDefKill)
    NSDefFlags |= NF_KILLPROTECT;
    if (NSDefKillQuick)
    NSDefFlags |= NF_KILL_QUICK;
    if (NSDefSecure)
    NSDefFlags |= NF_SECURE;
    if (NSDefPrivate)
    NSDefFlags |= NF_PRIVATE;
    if (NSDefHideEmail)
    NSDefFlags |= NF_HIDE_EMAIL;
    if (NSDefHideUsermask)
    NSDefFlags |= NF_HIDE_MASK;
    if (NSDefHideQuit)
    NSDefFlags |= NF_HIDE_QUIT;
    if (NSDefMemoSignon)
    NSDefFlags |= NF_MEMO_SIGNON;
    if (NSDefMemoReceive)
    NSDefFlags |= NF_MEMO_RECEIVE;

    if (NSForceNickChange && !(protocol_features & PF_CHANGENICK)) {
    module_log("warning: forced nick changing not supported by IRC"
          " server, disabling NSForceNickChange");
    NSForceNickChange = 0;
    }
}

/*************************************************************************/

static int do_command_line(const char *option, const char *value)
{
    NickGroupInfo *ngi;

    if (!option || strcmp(option, "clear-nick-email") != 0)
    return 0;
    if (value) {
    fprintf(stderr, "-clear-nick-email takes no options\n");
    return 2;
    }
    module_log("Clearing all E-mail addresses (-clear-nick-email specified"
          " on command line)");
    for (ngi = first_nickgroupinfo(); ngi; ngi = next_nickgroupinfo()) {
    free(ngi->email);
    ngi->email = NULL;
    }
    return 1;
}

/*************************************************************************/

static int do_reconfigure(int after_configure)
{
    static char old_s_NickServ[NICKMAX];
    static char *old_desc_NickServ = NULL;
    static char *old_NickDBName    = NULL;

    if (!after_configure) {
    /* Before reconfiguration: save old values. */
    strscpy(old_s_NickServ, s_NickServ, NICKMAX);
    old_desc_NickServ = strdup(desc_NickServ);
    old_NickDBName    = strdup(NickDBName);
    } else {
    /* After reconfiguration: handle value changes. */
    handle_config();
    if (strcmp(old_s_NickServ,s_NickServ) != 0)
        send_nickchange(old_s_NickServ, s_NickServ);
    if (!old_desc_NickServ || strcmp(old_desc_NickServ,desc_NickServ) != 0)
        send_namechange(s_NickServ, desc_NickServ);
    if (!old_NickDBName || strcmp(old_NickDBName,NickDBName) != 0) {
        module_log("reconfigure: new database name will only take"
              " effect after restart");
        /* Restore the old database name */
        free(NickDBName);
        NickDBName = old_NickDBName;
        /* Make sure the old name isn't freed below */
        old_NickDBName = NULL;
    }
    free(old_desc_NickServ);
    free(old_NickDBName);
    if (NSEnableRegister)
        cmd_REGISTER->name = "REGISTER";
    else
        cmd_REGISTER->name = "";
    if (NSEnableDropEmail) {
        cmd_DROPEMAIL->name = "DROPEMAIL";
        cmd_DROPEMAIL_CONFIRM->name = "DROPEMAIL-CONFIRM";
    } else {
        cmd_DROPEMAIL->name = "";
        cmd_DROPEMAIL_CONFIRM->name = "";
    }
    if (EnableGetpass)
        cmd_GETPASS->name = "GETPASS";
    else
        cmd_GETPASS->name = "";
    if (NSRequireEmail) {
        setstring(NICK_REGISTER_SYNTAX, NICK_REGISTER_REQ_EMAIL_SYNTAX);
        setstring(NICK_HELP_REGISTER_EMAIL, NICK_HELP_REGISTER_EMAIL_REQ);
        setstring(NICK_HELP_UNSET, NICK_HELP_UNSET_REQ_EMAIL);
    } else {
        setstring(NICK_REGISTER_SYNTAX, old_REGISTER_SYNTAX);
        setstring(NICK_HELP_REGISTER_EMAIL, old_HELP_REGISTER_EMAIL);
        setstring(NICK_HELP_UNSET, old_HELP_UNSET);
    }
    if (NSForceNickChange) {
        setstring(DISCONNECT_IN_1_MINUTE, FORCENICKCHANGE_IN_1_MINUTE);
        setstring(DISCONNECT_IN_20_SECONDS, FORCENICKCHANGE_IN_20_SECONDS);
    } else {
        setstring(DISCONNECT_IN_1_MINUTE, old_DISCONNECT_IN_1_MINUTE);
        setstring(DISCONNECT_IN_20_SECONDS, old_DISCONNECT_IN_20_SECONDS);
    }
    }  /* if (!after_configure) */
    return 0;
}

/*************************************************************************/

int init_module(Module *module_)
{
    module = module_;

    handle_config();

    if (!new_commandlist(module) || !register_commands(module, cmds)) {
    module_log("Unable to register commands");
    exit_module(0);
    return 0;
    }
    cmd_REGISTER = lookup_cmd(module, "REGISTER");
    if (!cmd_REGISTER) {
    module_log("BUG: unable to find REGISTER command entry");
    exit_module(0);
    return 0;
    }
    cmd_DROPEMAIL = lookup_cmd(module, "DROPEMAIL");
    if (!cmd_DROPEMAIL) {
    module_log("BUG: unable to find DROPEMAIL command entry");
    exit_module(0);
    return 0;
    }
    cmd_DROPEMAIL_CONFIRM = lookup_cmd(module, "DROPEMAIL-CONFIRM");
    if (!cmd_DROPEMAIL_CONFIRM) {
    module_log("BUG: unable to find DROPEMAIL-CONFIRM command entry");
    exit_module(0);
    return 0;
    }
    cmd_GETPASS = lookup_cmd(module, "GETPASS");
    if (!cmd_GETPASS) {
    module_log("BUG: unable to find GETPASS command entry");
    exit_module(0);
    return 0;
    }
    if (!NSEnableRegister)
    cmd_REGISTER->name = "";
    if (!NSEnableDropEmail) {
    cmd_DROPEMAIL->name = "";
    cmd_DROPEMAIL_CONFIRM->name = "";
    }
    if (!EnableGetpass)
    cmd_GETPASS->name = "";

    cb_command      = register_callback(module, "command");
    cb_help          = register_callback(module, "HELP");
    cb_help_cmds    = register_callback(module, "HELP COMMANDS");
    cb_reglink_check = register_callback(module, "REGISTER/LINK check");
    cb_registered    = register_callback(module, "registered");
    cb_id_check      = register_callback(module, "IDENTIFY check");
    cb_identified    = register_callback(module, "identified");
    if (cb_command < 0 || cb_help < 0 || cb_help_cmds < 0
    || cb_reglink_check < 0 || cb_registered < 0 || cb_id_check < 0
    || cb_identified < 0
    ) {
    module_log("Unable to register callbacks");
    exit_module(0);
    return 0;
    }

    if (!add_callback(NULL, "command line", do_command_line)
    || !add_callback(NULL, "reconfigure", do_reconfigure)
    || !add_callback(NULL, "introduce_user", introduce_nickserv)
    || !add_callback(NULL, "m_privmsg", nickserv)
    || !add_callback(NULL, "m_whois", nickserv_whois)
    || !add_callback(NULL, "save data", do_save_data)
    || !add_callback(NULL, "user create", do_user_create)
    || !add_callback(NULL, "user nickchange (before)",
              do_user_nickchange_before)
    || !add_callback(NULL, "user nickchange (after)",
              do_user_nickchange_after)
    || !add_callback(NULL, "user delete", do_user_delete)
    || !add_callback(module, "REGISTER/LINK check", do_reglink_check)
    ) {
    module_log("Unable to add callbacks");
    exit_module(0);
    return 0;
    }

    if (!init_collide(module) || !init_set(module) || !init_util(module)) {
    exit_module(0);
    return 0;
    }

    open_nick_db(NickDBName);
    db_opened = 1;

    old_REGISTER_SYNTAX =
    setstring(NICK_REGISTER_SYNTAX, NICK_REGISTER_SYNTAX);
    old_HELP_REGISTER_EMAIL =
    setstring(NICK_HELP_REGISTER_EMAIL, NICK_HELP_REGISTER_EMAIL);
    old_HELP_UNSET =
    setstring(NICK_HELP_UNSET, NICK_HELP_UNSET);
    old_DISCONNECT_IN_1_MINUTE =
    setstring(DISCONNECT_IN_1_MINUTE, DISCONNECT_IN_1_MINUTE);
    old_DISCONNECT_IN_20_SECONDS =
    setstring(DISCONNECT_IN_20_SECONDS, DISCONNECT_IN_20_SECONDS);
    if (NSRequireEmail) {
    setstring(NICK_REGISTER_SYNTAX, NICK_REGISTER_REQ_EMAIL_SYNTAX);
    setstring(NICK_HELP_REGISTER_EMAIL, NICK_HELP_REGISTER_EMAIL_REQ);
    setstring(NICK_HELP_UNSET, NICK_HELP_UNSET_REQ_EMAIL);
    }
    if (NSForceNickChange) {
    setstring(DISCONNECT_IN_1_MINUTE, FORCENICKCHANGE_IN_1_MINUTE);
    setstring(DISCONNECT_IN_20_SECONDS, FORCENICKCHANGE_IN_20_SECONDS);
    }

    if (linked)
    introduce_nickserv(NULL);

    return 1;
}

/*************************************************************************/

int exit_module(int shutdown_unused)
{
#ifdef CLEAN_COMPILE
    shutdown_unused = shutdown_unused;
#endif

    if (linked)
    send_cmd(s_NickServ, "QUIT :");

    if (old_REGISTER_SYNTAX >= 0) {
    setstring(NICK_REGISTER_SYNTAX, old_REGISTER_SYNTAX);
    old_REGISTER_SYNTAX = -1;
    }
    if (old_HELP_REGISTER_EMAIL >= 0) {
    setstring(NICK_HELP_REGISTER_EMAIL, old_HELP_REGISTER_EMAIL);
    old_HELP_REGISTER_EMAIL = -1;
    }
    if (old_HELP_UNSET >= 0) {
    setstring(NICK_HELP_UNSET, old_HELP_UNSET);
    old_HELP_UNSET = -1;
    }
    if (old_DISCONNECT_IN_1_MINUTE >= 0) {
    setstring(DISCONNECT_IN_1_MINUTE, old_DISCONNECT_IN_1_MINUTE);
    old_DISCONNECT_IN_1_MINUTE = -1;
    }
    if (old_DISCONNECT_IN_20_SECONDS >= 0) {
    setstring(DISCONNECT_IN_20_SECONDS, old_DISCONNECT_IN_20_SECONDS);
    old_DISCONNECT_IN_20_SECONDS = -1;
    }

    if (db_opened)
    close_nick_db(NickDBName);

    exit_util();
    exit_set();
    exit_collide();

    remove_callback(module, "REGISTER/LINK check", do_reglink_check);
    remove_callback(NULL, "user delete", do_user_delete);
    remove_callback(NULL, "user nickchange (after)",
            do_user_nickchange_after);
    remove_callback(NULL, "user nickchange (before)",
            do_user_nickchange_before);
    remove_callback(NULL, "user create", do_user_create);
    remove_callback(NULL, "save data", do_save_data);
    remove_callback(NULL, "m_whois", nickserv_whois);
    remove_callback(NULL, "m_privmsg", nickserv);
    remove_callback(NULL, "introduce_user", introduce_nickserv);
    remove_callback(NULL, "reconfigure", do_reconfigure);
    remove_callback(NULL, "command line", do_command_line);

    unregister_callback(module, cb_identified);
    unregister_callback(module, cb_id_check);
    unregister_callback(module, cb_registered);
    unregister_callback(module, cb_reglink_check);
    unregister_callback(module, cb_help_cmds);
    unregister_callback(module, cb_help);
    unregister_callback(module, cb_command);

    /* These are static, so the pointers don't need to be cleared */
    if (cmd_GETPASS)
    cmd_GETPASS->name = "GETPASS";
    if (cmd_DROPEMAIL_CONFIRM)
    cmd_DROPEMAIL_CONFIRM->name = "DROPEMAIL-CONFIRM";
    if (cmd_DROPEMAIL)
    cmd_DROPEMAIL->name = "DROPEMAIL";
    if (cmd_REGISTER)
    cmd_REGISTER->name = "REGISTER";
    unregister_commands(module, cmds);
    del_commandlist(module);

    return 1;
}

/*************************************************************************/


Freak 25 Nisan 2007 07:51

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
s_serv.c
Kod:

/*

 *  Unreal Internet Relay Chat Daemon, src/s_serv.c

 *  Copyright (C) 1990 Jarkko Oikarinen and

 *                      University of Oulu, Computing Center

 *

 *  See file AUTHORS in IRC package for additional names of

 *  the programmers.

 *

 *  This program is free software; you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation; either version 1, or (at your option)

 *  any later version.

 *

 *  This program is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with this program; if not, write to the Free Software

 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 */



#ifndef CLEAN_COMPILE

static char sccsid[] =

    "@(#)s_serv.c    2.55 2/7/94 (C) 1988 University of Oulu, Computing Center and Jarkko Oikarinen";

#endif

#define AllocCpy(x,y) x  = (char *) MyMalloc(strlen(y) + 1); strcpy(x,y)



#include "struct.h"

#include "common.h"

#include "sys.h"

#include "numeric.h"

#include "msg.h"

#include "channel.h"

#include "version.h"

#include <sys/stat.h>

#include <fcntl.h>

#ifdef _WIN32

#include <io.h>

#endif

#include <time.h>

#include "h.h"

#include "proto.h"

#include <string.h>

#ifdef USE_LIBCURL

#include <curl/curl.h>

#endif

extern VOIDSIG s_die();



static char buf[BUFSIZE];



MODVAR int  max_connection_count = 1, max_client_count = 1;

extern ircstats IRCstats;

extern int do_garbage_collect;

/* We need all these for cached MOTDs -- codemastr */

extern char *buildid;

aMotd *opermotd;

aMotd *rules;

aMotd *motd;

aMotd *svsmotd;

aMotd *botmotd;

aMotd *smotd;

struct tm motd_tm;

struct tm smotd_tm;

aMotd *read_file(char *filename, aMotd **list);

aMotd *read_file_ex(char *filename, aMotd **list, struct tm *);

extern aMotd *Find_file(char *, short);

/*

** m_functions execute protocol messages on this server:

**      CMD_FUNC(functionname) causes it to use the header

**            int functionname (aClient *cptr,

**                aClient *sptr, int parc, char *parv[])

**

**

**    cptr    is always NON-NULL, pointing to a *LOCAL* client

**        structure (with an open socket connected!). This

**        identifies the physical socket where the message

**        originated (or which caused the m_function to be

**        executed--some m_functions may call others...).

**

**    sptr    is the source of the message, defined by the

**        prefix part of the message if present. If not

**        or prefix not found, then sptr==cptr.

**

**        (!IsServer(cptr)) => (cptr == sptr), because

**        prefixes are taken *only* from servers...

**

**        (IsServer(cptr))

**            (sptr == cptr) => the message didn't

**            have the prefix.

**

**            (sptr != cptr && IsServer(sptr) means

**            the prefix specified servername. (?)

**

**            (sptr != cptr && !IsServer(sptr) means

**            that message originated from a remote

**            user (not local).

**

**        combining

**

**        (!IsServer(sptr)) means that, sptr can safely

**        taken as defining the target structure of the

**        message in this server.

**

**    *Always* true (if 'parse' and others are working correct):

**

**    1)    sptr->from == cptr  (note: cptr->from == cptr)

**

**    2)    MyConnect(sptr) <=> sptr == cptr (e.g. sptr

**        *cannot* be a local connection, unless it's

**        actually cptr!). [MyConnect(x) should probably

**        be defined as (x == x->from) --msa ]

**

**    parc    number of variable parameter strings (if zero,

**        parv is allowed to be NULL)

**

**    parv    a NULL terminated list of parameter pointers,

**

**            parv[0], sender (prefix string), if not present

**                this points to an empty string.

**            parv[1]...parv[parc-1]

**                pointers to additional parameters

**            parv[parc] == NULL, *always*

**

**        note:    it is guaranteed that parv[0]..parv[parc-1] are all

**            non-NULL pointers.

*/

#ifndef NO_FDLIST

extern fdlist serv_fdlist;

#endif



/*

** m_version

**    parv[0] = sender prefix

**    parv[1] = remote server

*/

CMD_FUNC(m_version)

{

    extern char serveropts[];

    extern char *IsupportStrings[];

    int reply, i;



    /* Only allow remote VERSIONs if registered -- Syzop */

    if (!IsPerson(sptr) && !IsServer(cptr))

        goto normal;



    if (hunt_server_token(cptr, sptr, MSG_VERSION, TOK_VERSION, ":%s", 1, parc,

        parv) == HUNTED_ISME)

    {

        sendto_one(sptr, rpl_str(RPL_VERSION), me.name,

            parv[0], version, debugmode, me.name,

            serveropts, extraflags ? extraflags : "",

            tainted ? "3" : "",

            (IsAnOper(sptr) ? MYOSNAME : "*"), UnrealProtocol);

#ifdef USE_SSL

        if (IsAnOper(sptr))

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

#endif

#ifdef ZIP_LINKS

        if (IsAnOper(sptr))

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

#endif

#ifdef USE_LIBCURL

        if (IsAnOper(sptr))

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

#endif

        if (MyClient(sptr))

normal:

            reply = RPL_ISUPPORT;

        else

            reply = RPL_REMOTEISUPPORT;

        /* Send the text */

        for (i = 0; IsupportStrings[i]; i++)

            sendto_one(sptr, rpl_str(reply), me.name, sptr->name,

                  IsupportStrings[i]);

    }

    return 0;

}



char *num = NULL;



/*

 * send_proto:

 * sends PROTOCTL message to server, taking care of whether ZIP

 * should be enabled or not.

 */

void send_proto(aClient *cptr, ConfigItem_link *aconf)

{

char buf[1024];



    sprintf(buf, "CHANMODES=%s%s,%s%s,%s%s,%s%s NICKCHARS=%s",

        CHPAR1, EXPAR1, CHPAR2, EXPAR2, CHPAR3, EXPAR3, CHPAR4, EXPAR4, langsinuse);

#ifdef ZIP_LINKS

    if (aconf->options & CONNECT_ZIP)

    {

        sendto_one(cptr, "PROTOCTL %s ZIP %s", PROTOCTL_SERVER, buf);

    } else {

#endif

        sendto_one(cptr, "PROTOCTL %s %s", PROTOCTL_SERVER, buf);

#ifdef ZIP_LINKS

    }

#endif

}



#ifndef IRCDTOTALVERSION

#define IRCDTOTALVERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4 PATCH5 PATCH6 PATCH7 PATCH8 PATCH9

#endif



/*

 * sends m_info into to sptr

*/



void m_info_send(aClient *sptr)

{

sendto_one(sptr, ":%s %d %s :|-=-=-=-=-=-= %s -=-=-=-=-=-=-", me.name, RPL_INFO, sptr->name, IRCDTOTALVERSION);

sendto_one(sptr, ":%s %d %s :| Sunucumuz Unreal3.2.3 üzerine modify edilerek hazırlanmıştır", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| IRCd Coder:", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| * RainmaN        <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| * WingmaN      <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| *        ", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| IRCd Tester:", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| * Cem        <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| * Oguz    <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| * NightwiSh    <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>", me.name, RPL_INFO, sptr->name);
sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| IRCd'de karşılaştığınız bug'ları", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| 
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
 adresine bildirebilirsiniz.", me.name, RPL_INFO, sptr->name);

sendto_one(sptr, ":%s %d %s :| IRCd destek icin 
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
yardim platformunu oneriyoruz.", me.name, RPL_INFO, sptr->name);

#ifdef _WIN32

#ifdef WIN32_SPECIFY

    sendto_one(sptr, ":%s %d %s :| wIRCd porter: | %s",

        me.name, RPL_INFO, sptr->name, WIN32_PORTER);

    sendto_one(sptr, ":%s %d %s :|    >>URL:    | %s",

        me.name, RPL_INFO, sptr->name, WIN32_URL);

#endif

#endif

    sendto_one(sptr,":%s %d %s :|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-", me.name,RPL_INFO, sptr->name);

    sendto_one(sptr, ":%s %d %s :Hizmete geçiş tarihi: %s, derleme # %s", me.name,RPL_INFO, sptr->name, creation, generation);

    sendto_one(sptr, ":%s %d %s :Son online zamanı %s", me.name, RPL_INFO, sptr->name, myctime(me.firsttime));

    sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, sptr->name);

}





/*

** m_info

**    parv[0] = sender prefix

**    parv[1] = servername

**  Modified for hardcode by Stskeeps

*/



CMD_FUNC(m_info)

{



    if (hunt_server_token(cptr, sptr, MSG_INFO, TOK_INFO, ":%s", 1, parc,

        parv) == HUNTED_ISME)

    {

        m_info_send(sptr);

    }



    return 0;

}



/*

** m_dalinfo

**      parv[0] = sender prefix

**      parv[1] = servername

*/

CMD_FUNC(m_dalinfo)

{

    char **text = dalinfotext;



    if (hunt_server_token(cptr, sptr, MSG_DALINFO, TOK_DALINFO, ":%s", 1, parc,

        parv) == HUNTED_ISME)

    {

        while (*text)

            sendto_one(sptr, rpl_str(RPL_INFO),

                me.name, parv[0], *text++);



        sendto_one(sptr, rpl_str(RPL_INFO), me.name, parv[0], "");

        sendto_one(sptr,

            ":%s %d %s :Birth Date: %s, compile # %s",

            me.name, RPL_INFO, parv[0], creation, generation);

        sendto_one(sptr, ":%s %d %s :On-line since %s",

            me.name, RPL_INFO, parv[0], myctime(me.firsttime));

        sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, parv[0]);

    }



    return 0;

}



/*

** m_license

**      parv[0] = sender prefix

**      parv[1] = servername

*/

CMD_FUNC(m_license)

{

    char **text = gnulicense;



    if (hunt_server_token(cptr, sptr, MSG_LICENSE, TOK_LICENSE, ":%s", 1, parc,

        parv) == HUNTED_ISME)

    {

        while (*text)

            sendto_one(sptr, rpl_str(RPL_INFO),

                me.name, parv[0], *text++);



        sendto_one(sptr, rpl_str(RPL_INFO), me.name, parv[0], "");

        sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, parv[0]);

    }



    return 0;

}



/*

** m_credits

**      parv[0] = sender prefix

**      parv[1] = servername

*/

CMD_FUNC(m_credits)

{

    char **text = unrealcredits;



    if (hunt_server_token(cptr, sptr, MSG_CREDITS, TOK_CREDITS, ":%s", 1, parc,

        parv) == HUNTED_ISME)

    {

        while (*text)

            sendto_one(sptr, rpl_str(RPL_INFO),

                me.name, parv[0], *text++);



        sendto_one(sptr, rpl_str(RPL_INFO), me.name, parv[0], "");

        sendto_one(sptr,

            ":%s %d %s :Birth Date: %s, compile # %s",

            me.name, RPL_INFO, parv[0], creation, generation);

        sendto_one(sptr, ":%s %d %s :On-line since %s",

            me.name, RPL_INFO, parv[0], myctime(me.firsttime));

        sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, parv[0]);

    }



    return 0;

}





/*

 * RPL_NOWON    - Online at the moment (Succesfully added to WATCH-list)

 * RPL_NOWOFF    - Offline at the moement (Succesfully added to WATCH-list)

 * RPL_WATCHOFF    - Succesfully removed from WATCH-list.

 * ERR_TOOMANYWATCH - Take a guess :>  Too many WATCH entries.

 */

static void show_watch(aClient *cptr, char *name, int rpl1, int rpl2)

{

    aClient *acptr;





    if ((acptr = find_person(name, NULL)))

    {

        if (IsWebTV(cptr))

            sendto_one(cptr, ":IRC!IRC@%s PRIVMSG %s :%s (%s@%s) is on IRC",

                me.name, cptr->name, acptr->name, acptr->user->username,

                IsHidden(acptr) ? acptr->user->virthost : acptr->user->

                realhost);

        else

            sendto_one(cptr, rpl_str(rpl1), me.name, cptr->name,

                acptr->name, acptr->user->username,

                IsHidden(acptr) ? acptr->user->virthost : acptr->user->

                realhost, acptr->lastnick);

    }

    else

    {

        if (IsWebTV(cptr))

            sendto_one(cptr, ":IRC!IRC@%s PRIVMSG %s :%s is not on IRC", me.name,

                cptr->name, name);

        else   

            sendto_one(cptr, rpl_str(rpl2), me.name, cptr->name,

                name, "*", "*", 0);

    }

}



/*

 * m_watch

 */

CMD_FUNC(m_watch)

{

    aClient *acptr;

    char *s, **pav = parv, *user;

    char *p = NULL, *def = "l";







    if (parc < 2)

    {

        /*

        * Default to 'l' - list who's currently online

        */

        parc = 2;

        parv[1] = def;

    }



    for (s = (char *)strtoken(&p, *++pav, " "); s;

        s = (char *)strtoken(&p, NULL, " "))

    {

        if ((user = (char *)index(s, '!')))

            *user++ = '\0';    /* Not used */



        /*

        * Prefix of "+", they want to add a name to their WATCH

        * list.

        */

        if (*s == '+')

        {

            if (!*(s+1))

                continue;

            if (do_nick_name(s + 1))

            {

                if (sptr->watches >= MAXWATCH)

                {

                    sendto_one(sptr,

                        err_str(ERR_TOOMANYWATCH), me.name,

                        cptr->name, s + 1);



                    continue;

                }



                add_to_watch_hash_table(s + 1, sptr);

            }



            show_watch(sptr, s + 1, RPL_NOWON, RPL_NOWOFF);

            continue;

        }



        /*

        * Prefix of "-", coward wants to remove somebody from their

        * WATCH list.  So do it. :-)

        */

        if (*s == '-')

        {

            if (!*(s+1))

                continue;

            del_from_watch_hash_table(s + 1, sptr);

            show_watch(sptr, s + 1, RPL_WATCHOFF, RPL_WATCHOFF);



            continue;

        }



        /*

        * Fancy "C" or "c", they want to nuke their WATCH list and start

        * over, so be it.

        */

        if (*s == 'C' || *s == 'c')

        {

            hash_del_watch_list(sptr);



            continue;

        }



        /*

        * Now comes the fun stuff, "S" or "s" returns a status report of

        * their WATCH list.  I imagine this could be CPU intensive if its

        * done alot, perhaps an auto-lag on this?

        */

        if (*s == 'S' || *s == 's')

        {

            Link *lp;

            aWatch *anptr;

            int  count = 0;



            /*

            * Send a list of how many users they have on their WATCH list

            * and how many WATCH lists they are on.

            */

            anptr = hash_get_watch(sptr->name);

            if (anptr)

                for (lp = anptr->watch, count = 1;

                    (lp = lp->next); count++)

                    ;

            sendto_one(sptr, rpl_str(RPL_WATCHSTAT), me.name,

                parv[0], sptr->watches, count);



            /*

            * Send a list of everybody in their WATCH list. Be careful

            * not to buffer overflow.

            */

            if ((lp = sptr->watch) == NULL)

            {

                sendto_one(sptr, rpl_str(RPL_ENDOFWATCHLIST),

                    me.name, parv[0], *s);

                continue;

            }

            *buf = '\0';

            strlcpy(buf, lp->value.wptr->nick, sizeof buf);

            count =

                strlen(parv[0]) + strlen(me.name) + 10 +

                strlen(buf);

            while ((lp = lp->next))

            {

                if (count + strlen(lp->value.wptr->nick) + 1 >

                    BUFSIZE - 2)

                {

                    sendto_one(sptr, rpl_str(RPL_WATCHLIST),

                        me.name, parv[0], buf);

                    *buf = '\0';

                    count =

                        strlen(parv[0]) + strlen(me.name) +

                        10;

                }

                strcat(buf, " ");

                strcat(buf, lp->value.wptr->nick);

                count += (strlen(lp->value.wptr->nick) + 1);

            }

            sendto_one(sptr, rpl_str(RPL_WATCHLIST), me.name,

                parv[0], buf);



            sendto_one(sptr, rpl_str(RPL_ENDOFWATCHLIST), me.name,

                parv[0], *s);

            continue;

        }



        /*

        * Well that was fun, NOT.  Now they want a list of everybody in

        * their WATCH list AND if they are online or offline? Sheesh,

        * greedy arn't we?

        */

        if (*s == 'L' || *s == 'l')

        {

            Link *lp = sptr->watch;



            while (lp)

            {

                if ((acptr =

                    find_person(lp->value.wptr->nick, NULL)))

                {

                    sendto_one(sptr, rpl_str(RPL_NOWON),

                        me.name, parv[0], acptr->name,

                        acptr->user->username,

                        IsHidden(acptr) ? acptr->user->

                        virthost : acptr->user->realhost,

                        acptr->lastnick);

                }

                /*

                * But actually, only show them offline if its a capital

                * 'L' (full list wanted).

                */

                else if (isupper(*s))

                    sendto_one(sptr, rpl_str(RPL_NOWOFF),

                        me.name, parv[0],

                        lp->value.wptr->nick, "*", "*",

                        lp->value.wptr->lasttime);

                lp = lp->next;

            }



            sendto_one(sptr, rpl_str(RPL_ENDOFWATCHLIST), me.name,

                parv[0], *s);



            continue;

        }



        /*

        * Hmm.. unknown prefix character.. Ignore it. :-)

        */

    }



    return 0;

}



char *get_cptr_status(aClient *acptr)

{

    static char buf[10];

    char *p = buf;



    *p = '\0';

    *p++ = '[';

    if (acptr->flags & FLAGS_LISTEN)

    {

        if (acptr->umodes & LISTENER_NORMAL)

            *p++ = '*';

        if (acptr->umodes & LISTENER_SERVERSONLY)

            *p++ = 'S';

        if (acptr->umodes & LISTENER_CLIENTSONLY)

            *p++ = 'C';

#ifdef USE_SSL

        if (acptr->umodes & LISTENER_SSL)

            *p++ = 's';

#endif

        if (acptr->umodes & LISTENER_REMOTEADMIN)

            *p++ = 'R';

        if (acptr->umodes & LISTENER_JAVACLIENT)

            *p++ = 'J';

    }

    else

    {

#ifdef USE_SSL

        if (acptr->flags & FLAGS_SSL)

            *p++ = 's';

#endif

    }

    *p++ = ']';

    *p++ = '\0';

    return (buf);

}



/* Used to blank out ports -- Barubary */

char *get_client_name2(aClient *acptr, int showports)

{

    char *pointer = get_client_name(acptr, TRUE);



    if (!pointer)

        return NULL;

    if (showports)

        return pointer;

    if (!strrchr(pointer, '.'))

        return NULL;

    /*

    * This may seem like wack but remind this is only used

    * in rows of get_client_name2's, so it's perfectly fair

    *

    */

    strcpy((char *)strrchr((char *)pointer, '.'), ".0]");



    return pointer;

}



/*

** m_summon

** parv[0] = sender prefix

*/

CMD_FUNC(m_summon)

{

    /* /summon is old and out dated, we just return an error as

    * required by RFC1459 -- codemastr

    */ sendto_one(sptr, err_str(ERR_SUMMONDISABLED), me.name, parv[0]);

    return 0;

}

/*

** m_users

**    parv[0] = sender prefix

**    parv[1] = servername

*/

CMD_FUNC(m_users)

{

    /* /users is out of date, just return an error as  required by

    * RFC1459 -- codemastr

    */ sendto_one(sptr, err_str(ERR_USERSDISABLED), me.name, parv[0]);

    return 0;

}

/*

** Note: At least at protocol level ERROR has only one parameter,

** although this is called internally from other functions

** --msa

**

**    parv[0] = sender prefix

**    parv[*] = parameters

*/

CMD_FUNC(m_error)

{

    char *para;



    para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";



    Debug((DEBUG_ERROR, "Received ERROR message from %s: %s",

        sptr->name, para));

    /*

      ** Ignore error messages generated by normal user clients

      ** (because ill-behaving user clients would flood opers

      ** screen otherwise). Pass ERROR's from other sources to

      ** the local operator...

    */

    if (IsPerson(cptr) || IsUnknown(cptr))

        return 0;

    if (cptr == sptr)

    {

        sendto_serv_butone(&me, ":%s GLOBOPS :ERROR from %s -- %s",

            me.name, get_client_name(cptr, FALSE), para);

        sendto_locfailops("ERROR :from %s -- %s",

            get_client_name(cptr, FALSE), para);

    }

    else

    {

        sendto_serv_butone(&me,

            ":%s GLOBOPS :ERROR from %s via %s -- %s", me.name,

            sptr->name, get_client_name(cptr, FALSE), para);

        sendto_ops("ERROR :from %s via %s -- %s", sptr->name,

            get_client_name(cptr, FALSE), para);

    }

    return 0;

}



Link *helpign = NULL;



/* Now just empty ignore-list, in future reload dynamic help.

 * Move out to help.c -Donwulff */

void reset_help(void)

{

    free_str_list(helpign);

}



EVENT(save_tunefile)

{

    FILE *tunefile;



    tunefile = fopen(IRCDTUNE, "w");

    if (!tunefile)

    {

#if !defined(_WIN32) && !defined(_AMIGA)

        sendto_ops("Unable to write tunefile.. %s", strerror(errno));

#else

        sendto_ops("Unable to write tunefile..");

#endif

        return;

    }

    fprintf(tunefile, "%li\n", TSoffset);

    fprintf(tunefile, "%d\n", IRCstats.me_max);

    fclose(tunefile);

}



void load_tunefile(void)

{

    FILE *tunefile;

    char buf[1024];



    tunefile = fopen(IRCDTUNE, "r");

    if (!tunefile)

        return;

    fprintf(stderr, "* Loading tunefile..\n");

    fgets(buf, 1023, tunefile);

    TSoffset = atol(buf);

    fgets(buf, 1023, tunefile);

    IRCstats.me_max = atol(buf);

    fclose(tunefile);

}



/** Rehash motd and rule files (MPATH/RPATH and all tld entries). */

void rehash_motdrules()

{

ConfigItem_tld *tlds;



    motd = (aMotd *) read_file_ex(MPATH, &motd, &motd_tm);

    rules = (aMotd *) read_file(RPATH, &rules);

    smotd = (aMotd *) read_file_ex(SMPATH, &smotd, &smotd_tm);

    for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *) tlds->next)

    {

        tlds->motd = read_file_ex(tlds->motd_file, &tlds->motd, &tlds->motd_tm);

        tlds->rules = read_file(tlds->rules_file, &tlds->rules);

        if (tlds->smotd_file)

            tlds->smotd = read_file_ex(tlds->smotd_file, &tlds->smotd, &tlds->smotd_tm);

        if (tlds->opermotd_file)

            tlds->opermotd = read_file(tlds->opermotd_file, &tlds->opermotd);

        if (tlds->botmotd_file)

            tlds->botmotd = read_file(tlds->botmotd_file, &tlds->botmotd);

    }

}



void reread_motdsandrules()

{

    motd = (aMotd *) read_file_ex(MPATH, &motd, &motd_tm);

    rules = (aMotd *) read_file(RPATH, &rules);

    smotd = (aMotd *) read_file_ex(SMPATH, &smotd, &smotd_tm);

    botmotd = (aMotd *) read_file(BPATH, &botmotd);

    opermotd = (aMotd *) read_file(OPATH, &opermotd);

}



/*

** m_rehash

** remote rehash by binary

** now allows the -flags in remote rehash

** ugly code but it seems to work :) -- codemastr

** added -all and fixed up a few lines -- niquil (
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
)

** fixed remote rehashing, but it's getting a bit weird code again -- Syzop

** removed '-all' code, this is now considered as '/rehash', this is ok

** since we rehash everything with simple '/rehash' now. Syzop/20040205

*/

CMD_FUNC(m_rehash)

{

    int  x;



    if (MyClient(sptr) && !OPCanRehash(sptr))

    {

        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

        return 0;

    }

    if (!MyClient(sptr) && !IsNetAdmin(sptr)

        && !IsULine(sptr))

    {

        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

        return 0;

    }

    x = 0;



    if (BadPtr(parv[2])) {

        /* If the argument starts with a '-' (like -motd, -opermotd, etc) then it's

        * assumed not to be a server. -- Syzop

        */

        if (parv[1] && (parv[1][0] == '-'))

            x = HUNTED_ISME;

        else

            x = hunt_server_token(cptr, sptr, MSG_REHASH, TOK_REHASH, "%s", 1, parc, parv);

    } else {

        x = hunt_server_token(cptr, sptr, MSG_REHASH, TOK_REHASH, "%s %s", 1, parc, parv);

    }

    if (x != HUNTED_ISME)

        return 0; /* Now forwarded or server didnt exist */



    if (cptr != sptr)

    {

#ifndef REMOTE_REHASH

        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

        return 0;

#endif

        if (parv[2] == NULL)

        {

            if (loop.ircd_rehashing)

            {

                sendto_one(sptr, ":%s NOTICE %s :A rehash is already in progress",

                    me.name, sptr->name);

                return 0;

            }

            sendto_serv_butone(&me,

                ":%s GLOBOPS :%s is remotely rehashing server config file",

                me.name, sptr->name);

            sendto_ops

                ("%s is remotely rehashing server config file",

                parv[0]);

            reread_motdsandrules();

            return rehash(cptr, sptr,

                (parc > 1) ? ((*parv[1] == 'q') ? 2 : 0) : 0);

        }

        parv[1] = parv[2];

    }



    if (!BadPtr(parv[1]) && strcmp(parv[1], "-all"))

    {



        if (!IsAdmin(sptr) && !IsCoAdmin(sptr))

        {

            sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

            return 0;

        }



        if (*parv[1] == '-')

        {

            if (!strnicmp("-gar", parv[1], 4))

            {

                loop.do_garbage_collect = 1;

                RunHook3(HOOKTYPE_REHASHFLAG, cptr, sptr, parv[1]);

                return 0;

            }

            if (!_match("-o*motd", parv[1]))

            {

                sendto_ops

                    ("%sRehashing OperMOTD on request of %s",

                    cptr != sptr ? "Remotely " : "",

                    sptr->name);

                if (cptr != sptr)

                    sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing OperMOTD", me.name, sptr->name);

                opermotd = (aMotd *) read_file(OPATH, &opermotd);

                RunHook3(HOOKTYPE_REHASHFLAG, cptr, sptr, parv[1]);

                return 0;

            }

            if (!_match("-b*motd", parv[1]))

            {

                sendto_ops

                    ("%sRehashing BotMOTD on request of %s",

                    cptr != sptr ? "Remotely " : "",

                    sptr->name);

                if (cptr != sptr)

                    sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing BotMOTD", me.name, sptr->name);

                botmotd = (aMotd *) read_file(BPATH, &botmotd);

                RunHook3(HOOKTYPE_REHASHFLAG, cptr, sptr, parv[1]);

                return 0;

            }

            if (!strnicmp("-motd", parv[1], 5)

                || !strnicmp("-rules", parv[1], 6))

            {

                sendto_ops

                    ("%sRehashing all MOTDs and RULES on request of %s",

                    cptr != sptr ? "Remotely " : "",

                    sptr->name);

                if (cptr != sptr)

                    sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing all MOTDs and RULES", me.name, sptr->name);

                rehash_motdrules();

                RunHook3(HOOKTYPE_REHASHFLAG, cptr, sptr, parv[1]);

                return 0;

            }

            RunHook3(HOOKTYPE_REHASHFLAG, cptr, sptr, parv[1]);

            return 0;

        }

    }

    else

    {

        if (loop.ircd_rehashing)

        {

            sendto_one(sptr, ":%s NOTICE %s :A rehash is already in progress",

                me.name, sptr->name);

            return 0;

        }

        sendto_ops("%s is rehashing server config file", parv[0]);

    }



    /* Normal rehash, rehash motds&rules too, just like the on in the tld block will :p */

    reread_motdsandrules();

    if (cptr == sptr)

        sendto_one(sptr, rpl_str(RPL_REHASHING), me.name, parv[0], configfile);

    return rehash(cptr, sptr, (parc > 1) ? ((*parv[1] == 'q') ? 2 : 0) : 0);

}



/*

** m_restart

**

** parv[1] - password *OR* reason if no X:line

** parv[2] - reason for restart (optional & only if X:line exists)

**

** The password is only valid if there is a matching X line in the

** config file. If it is not,  then it becomes the

*/

CMD_FUNC(m_restart)

{

    char *reason = NULL;

    /* Check permissions */

        if (MyClient(sptr) && !OPCanRestart(sptr))

        {

                sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

                return 0;

        }

        if (!MyClient(sptr) && !IsNetAdmin(sptr)

            && !IsULine(sptr))

        {

                sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

                return 0;

        }



    /* Syntax: /restart */

    if (parc == 1)

    {

        if (conf_drpass)

        {

            sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name,

                            parv[0], "RESTART");

                        return 0;

        }

    }

    else if (parc == 2)

    {

        /* Syntax: /restart <pass> */

        if (conf_drpass)

        {

            int ret;

            ret = Auth_Check(cptr, conf_drpass->restartauth, parv[1]);

            if (ret == -1)

            {

                sendto_one(sptr, err_str(ERR_PASSWDMISMATCH), me.name,

                      parv[0]);

                return 0;

            }

            if (ret < 1)

                return 0;

        }

        /* Syntax: /rehash <reason> */

        else

            reason = parv[1];

    }

    else if (parc > 2)

    {

        /* Syntax: /restart <pass> <reason> */

        if (conf_drpass)

        {

            int ret;

            ret = Auth_Check(cptr, conf_drpass->restartauth, parv[1]);

            if (ret == -1)

            {

                sendto_one(sptr, err_str(ERR_PASSWDMISMATCH), me.name,

                      parv[0]);

                return 0;

            }

            if (ret < 1)

                return 0;

        }

        reason = parv[2];

    }

    sendto_ops("Server is Restarting by request of %s", parv[0]);

    server_reboot(reason ? reason : "No reason");

    return 0;

}



/*

 * Heavily modified from the ircu m_motd by codemastr

 * Also svsmotd support added

 */

int short_motd(aClient *sptr) {

    ConfigItem_tld *ptr;

    aMotd *temp;

    struct tm *tm = &smotd_tm;

    char userhost[HOSTLEN + USERLEN + 6];

    char is_short = 1;

    strlcpy(userhost,make_user_host(sptr->user->username, sptr->user->realhost), sizeof userhost);

    ptr = Find_tld(sptr, userhost);



    if (ptr)

    {

        if (ptr->smotd)

        {

            temp = ptr->smotd;

            tm = &ptr->smotd_tm;

        }

        else if (smotd)

            temp = smotd;

        else

        {

            temp = ptr->motd;

            tm = &ptr->motd_tm;

            is_short = 0;

        }

    }

    else

    {

        if (smotd)

            temp = smotd;

        else

        {

            temp = motd;

            tm = &motd_tm;

            is_short = 0;

        }

    }



    if (!temp)

    {

        sendto_one(sptr, err_str(ERR_NOMOTD), me.name, sptr->name);

        return 0;

    }

    if (tm)

    {

        sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, sptr->name,

            me.name);

        sendto_one(sptr, ":%s %d %s :- %d/%d/%d %d:%02d", me.name,

            RPL_MOTD, sptr->name, tm->tm_mday, tm->tm_mon + 1,

            1900 + tm->tm_year, tm->tm_hour, tm->tm_min);

    }

    if (is_short)

    {

        sendto_one(sptr, rpl_str(RPL_MOTD), me.name, sptr->name,

            "This is the short MOTD. To view the complete MOTD type /motd");

        sendto_one(sptr, rpl_str(RPL_MOTD), me.name, sptr->name, "");

    }



    while (temp)

    {

        sendto_one(sptr, rpl_str(RPL_MOTD), me.name, sptr->name,

            temp->line);

        temp = temp->next;

    }

    sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, sptr->name);

    return 0;

}





/*

 * Heavily modified from the ircu m_motd by codemastr

 * Also svsmotd support added

 */

CMD_FUNC(m_motd)

{

    ConfigItem_tld *ptr;

    aMotd *temp, *temp2;

    struct tm *tm = &motd_tm;

    int  svsnofile = 0;

    char userhost[HOSTLEN + USERLEN + 6];



    if (IsServer(sptr))

        return 0;

    if (hunt_server_token(cptr, sptr, MSG_MOTD, TOK_MOTD, ":%s", 1, parc, parv) !=

HUNTED_ISME)

        return 0;

#ifndef TLINE_Remote

    if (!MyConnect(sptr))

    {

        temp = motd;

        goto playmotd;

    }

#endif

    strlcpy(userhost,make_user_host(cptr->user->username, cptr->user->realhost), sizeof userhost);

    ptr = Find_tld(sptr, userhost);



    if (ptr)

    {

        temp = ptr->motd;

        tm = &ptr->motd_tm;

    }

    else

        temp = motd;



      playmotd:

    if (temp == NULL)

    {

        sendto_one(sptr, err_str(ERR_NOMOTD), me.name, parv[0]);

        svsnofile = 1;

        goto svsmotd;



    }



    if (tm)

    {

        sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0],

            me.name);

        sendto_one(sptr, ":%s %d %s :- %d/%d/%d %d:%02d", me.name,

            RPL_MOTD, parv[0], tm->tm_mday, tm->tm_mon + 1,

            1900 + tm->tm_year, tm->tm_hour, tm->tm_min);

    }



    while (temp)

    {

        sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0],

            temp->line);

        temp = temp->next;

    }

      svsmotd:

    temp2 = svsmotd;

    while (temp2)

    {

        sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0],

            temp2->line);

        temp2 = temp2->next;

    }

    if (svsnofile == 0)

        sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);

    return 0;

}

/*

 * Modified from comstud by codemastr

 */

CMD_FUNC(m_opermotd)

{

    aMotd *temp;

    ConfigItem_tld *ptr;

    char userhost[HOSTLEN + USERLEN + 6];

    strlcpy(userhost,make_user_host(cptr->user->username, cptr->user->realhost), sizeof userhost);

    ptr = Find_tld(sptr, userhost);



    if (ptr)

    {

        if (ptr->opermotd)

            temp = ptr->opermotd;

        else

            temp = opermotd;

    }

    else

        temp = opermotd;



    if (!IsAnOper(sptr))

    {

        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

        return 0;

    }



    if (!temp)

    {

        sendto_one(sptr, err_str(ERR_NOOPERMOTD), me.name, parv[0]);

        return 0;

    }

    sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);

    sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0],

        "IRC Operator Message of the Day");



    while (temp)

    {

        sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0],

            temp->line);

        temp = temp->next;

    }

    sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);

    return 0;

}



/*

 * A merge from ircu and bahamut, and some extra stuff added by codemastr

 * we can now use 1 function for multiple files -- codemastr

 * Merged read_motd/read_rules stuff into this -- Syzop

 */



/** Read motd-like file, used for rules/motd/botmotd/opermotd/etc.

 * @param filename Filename of file to read.

 * @param list Reference to motd pointer (used for freeing if needed, can be NULL)

 * @returns Pointer to MOTD or NULL if reading failed.

 */

aMotd *read_file(char *filename, aMotd **list)

{

    return read_file_ex(filename, list, NULL);

}



/** Read motd-like file, used for rules/motd/botmotd/opermotd/etc.

 * @param filename Filename of file to read.

 * @param list Reference to motd pointer (used for freeing if needed, NULL allowed)

 * @param t Pointer to struct tm to store filedatetime info in (NULL allowed)

 * @returns Pointer to MOTD or NULL if reading failed.

 */

aMotd *read_file_ex(char *filename, aMotd **list, struct tm *t)

{



    int  fd = open(filename, O_RDONLY);

    aMotd *temp, *newmotd, *last, *old;

    char line[82];

    char *tmp;

    int  i;



    if (fd == -1)

        return NULL;



    if (list)

    {

        while (*list)

        {

            old = (*list)->next;

            MyFree((*list)->line);

            MyFree(*list);

            *list  = old;

        }

    }



    if (t)

    {

        struct tm *ttmp;

        struct stat sb;

        if (!fstat(fd, &sb))

        {

            ttmp = localtime(&sb.st_mtime);

            memcpy(t, ttmp, sizeof(struct tm));

        } else {

            /* Sure, fstat() shouldn't fail, but... */

            memset(t, 0, sizeof(struct tm));

        }

    }



    (void)dgets(-1, NULL, 0);    /* make sure buffer is at empty pos */



    newmotd = last = NULL;

    while ((i = dgets(fd, line, 81)) > 0)

    {

        line[i] = '\0';

        if ((tmp = (char *)strchr(line, '\n')))

            *tmp = '\0';

        if ((tmp = (char *)strchr(line, '\r')))

            *tmp = '\0';

        temp = (aMotd *) MyMalloc(sizeof(aMotd));

        if (!temp)

            outofmemory();

        AllocCpy(temp->line, line);

        temp->next = NULL;

        if (!newmotd)

            newmotd = temp;

        else

            last->next = temp;

        last = temp;

    }

    close(fd);

    return newmotd;



}



/*

 * Modified from comstud by codemastr

 */

CMD_FUNC(m_botmotd)

{

    aMotd *temp;

    ConfigItem_tld *ptr;

    char userhost[HOSTLEN + USERLEN + 6];



    if (hunt_server_token(cptr, sptr, MSG_BOTMOTD, TOK_BOTMOTD, ":%s", 1, parc,

        parv) != HUNTED_ISME)

        return 0;



    if (!IsPerson(sptr))

        return 0;



    strlcpy(userhost,make_user_host(sptr->user->username, sptr->user->realhost), sizeof userhost);

    ptr = Find_tld(sptr, userhost);



    if (ptr)

    {

        if (ptr->botmotd)

            temp = ptr->botmotd;

        else

            temp = botmotd;

    }

    else

        temp = botmotd;



    if (!temp)

    {

        sendto_one(sptr, ":%s NOTICE %s :BOTMOTD File not found",

            me.name, sptr->name);

        return 0;

    }

    sendto_one(sptr, ":%s NOTICE %s :- %s Bot Message of the Day - ",

        me.name, sptr->name, me.name);



    while (temp)

    {

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

        temp = temp->next;

    }

    sendto_one(sptr, ":%s NOTICE %s :End of /BOTMOTD command.", me.name, sptr->name);

    return 0;

}



/* m_die, this terminates the server, and it intentionally does not

 * have a reason. If you use it you should first do a GLOBOPS and

 * then a server notice to let everyone know what is going down...

 */

CMD_FUNC(m_die)

{

    aClient *acptr;

    int  i;

    if (!MyClient(sptr) || !OPCanDie(sptr))

    {

        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);

        return 0;

    }



    if (conf_drpass)    /* See if we have and DIE/RESTART password */

    {

        if (parc < 2)    /* And if so, require a password :) */

        {

            sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name,

                parv[0], "DIE");

            return 0;

        }

        i = Auth_Check(cptr, conf_drpass->dieauth, parv[1]);

        if (i == -1)

        {

            sendto_one(sptr, err_str(ERR_PASSWDMISMATCH), me.name,

                parv[0]);

            return 0;

        }

        if (i < 1)

        {

            return 0;

        }

    }



    /* Let the +s know what is going on */

    sendto_ops("Server Terminating by request of %s", parv[0]);



    for (i = 0; i <= LastSlot; i++)

    {

        if (!(acptr = local[i]))

            continue;

        if (IsClient(acptr))

            sendto_one(acptr,

                ":%s %s %s :Server Terminating. %s",

                me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, sptr->name);

        else if (IsServer(acptr))

            sendto_one(acptr, ":%s ERROR :Terminated by %s",

                me.name, get_client_name(sptr, TRUE));

    }

    (void)s_die();

    return 0;

}



#ifdef _WIN32

/*

 * Added to let the local console shutdown the server without just

 * calling exit(-1), in Windows mode.  -Cabal95

 */

int  localdie(void)

{

    aClient *acptr;

    int  i;



    for (i = 0; i <= LastSlot; i++)

    {

        if (!(acptr = local[i]))

            continue;

        if (IsClient(acptr))

            sendto_one(acptr,

                ":%s %s %s :Server Terminated by local console",

                me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name);

        else if (IsServer(acptr))

            sendto_one(acptr,

                ":%s ERROR :Terminated by local console", me.name);

    }

    (void)s_die();

    return 0;

}



#endif



aClient *find_match_server(char *mask)

{

    aClient *acptr;



    if (BadPtr(mask))

        return NULL;

    for (acptr = client, collapse(mask); acptr; acptr = acptr->next)

    {

        if (!IsServer(acptr) && !IsMe(acptr))

            continue;

        if (!match(mask, acptr->name))

            break;

        continue;

    }

    return acptr;

}


Freak 25 Nisan 2007 07:52

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
s_user.c

Kod:

/*
 *  Unreal Internet Relay Chat Daemon, src/s_user.c
 *  Copyright (C) 1990 Jarkko Oikarinen and
 *                      University of Oulu, Computing Center
 *
 *  See file AUTHORS in IRC package for additional names of
 *  the programmers.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef CLEAN_COMPILE
static char sccsid[] =
    "@(#)s_user.c    2.74 2/8/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "macros.h"
#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"
#include "proto.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif

#ifdef _WIN32
#include "version.h"
#endif

void send_umode_out(aClient *, aClient *, long);
void send_umode_out_nickv2(aClient *, aClient *, long);
void send_umode(aClient *, aClient *, long, long, char *);
void set_snomask(aClient *, char *);
void create_snomask(aClient *, anUser *, char *);
extern int short_motd(aClient *sptr);
extern aChannel *get_channel(aClient *cptr, char *chname, int flag);
/* static  Link    *is_banned(aClient *, aChannel *); */
int  dontspread = 0;
extern char *me_hash;
extern char backupbuf[];
static char buf[BUFSIZE];

void iNAH_host(aClient *sptr, char *host)
{
    DYN_LOCAL(char, did_parts, sptr->user->joined);
    if (!sptr->user)
    {
        DYN_FREE(did_parts);
        return;
    }

    if (UHOST_ALLOWED == UHALLOW_REJOIN)
        rejoin_doparts(sptr, did_parts);
    if (sptr->user->virthost)
    {
        MyFree(sptr->user->virthost);
        sptr->user->virthost = NULL;
    }
    sptr->user->virthost = strdup(host);
    if (MyConnect(sptr))
        sendto_serv_butone_token(&me, sptr->name, MSG_SETHOST,
            TOK_SETHOST, "%s", sptr->user->virthost);
    sptr->umodes |= UMODE_SETHOST;
   
    if (UHOST_ALLOWED == UHALLOW_REJOIN)
        rejoin_dojoinandmode(sptr, did_parts);
    DYN_FREE(did_parts);
}

long set_usermode(char *umode)
{
    int  newumode;
    int  what;
    char *m;
    int i;

    newumode = 0;
    what = MODE_ADD;
    for (m = umode; *m; m++)
        switch (*m)
        {
          case '+':
              what = MODE_ADD;
              break;
          case '-':
              what = MODE_DEL;
              break;
          case ' ':
          case '\n':
          case '\r':
          case '\t':
              break;
          default:
              for (i = 0; i <= Usermode_highest; i++)
              {
                  if (!Usermode_Table[i].flag)
                      continue;
                  if (*m == Usermode_Table[i].flag)
                  {
                      if (what == MODE_ADD)
                          newumode |= Usermode_Table[i].mode;
                      else
                          newumode &= ~Usermode_Table[i].mode;
                  }
              }     
        }

    return (newumode);
}

/*
** m_functions execute protocol messages on this server:
**
**    cptr    is always NON-NULL, pointing to a *LOCAL* client
**        structure (with an open socket connected!). This
**        identifies the physical socket where the message
**        originated (or which caused the m_function to be
**        executed--some m_functions may call others...).
**
**    sptr    is the source of the message, defined by the
**        prefix part of the message if present. If not
**        or prefix not found, then sptr==cptr.
**
**        (!IsServer(cptr)) => (cptr == sptr), because
**        prefixes are taken *only* from servers...
**
**        (IsServer(cptr))
**            (sptr == cptr) => the message didn't
**            have the prefix.
**
**            (sptr != cptr && IsServer(sptr) means
**            the prefix specified servername. (?)
**
**            (sptr != cptr && !IsServer(sptr) means
**            that message originated from a remote
**            user (not local).
**
**        combining
**
**        (!IsServer(sptr)) means that, sptr can safely
**        taken as defining the target structure of the
**        message in this server.
**
**    *Always* true (if 'parse' and others are working correct):
**
**    1)    sptr->from == cptr  (note: cptr->from == cptr)
**
**    2)    MyConnect(sptr) <=> sptr == cptr (e.g. sptr
**        *cannot* be a local connection, unless it's
**        actually cptr!). [MyConnect(x) should probably
**        be defined as (x == x->from) --msa ]
**
**    parc    number of variable parameter strings (if zero,
**        parv is allowed to be NULL)
**
**    parv    a NULL terminated list of parameter pointers,
**
**            parv[0], sender (prefix string), if not present
**                this points to an empty string.
**            parv[1]...parv[parc-1]
**                pointers to additional parameters
**            parv[parc] == NULL, *always*
**
**        note:    it is guaranteed that parv[0]..parv[parc-1] are all
**            non-NULL pointers.
*/

/* #ifndef NO_FDLIST
** extern fdlist oper_fdlist;
** #endif
*/

/* Taken from AlemBurda.Gen.Tr by Peter Zelezny
 * changed very slightly by codemastr
 * RGB color stripping support added -- codemastr
 */

unsigned char *StripColors(unsigned char *text) {
    int i = 0, len = strlen(text), save_len=0;
    char nc = 0, col = 0, rgb = 0, *save_text=NULL;
    static unsigned char new_str[4096];

    while (len > 0)
    {
        if ((col && isdigit(*text) && nc < 2) || (col && *text == ',' && nc < 3))
        {
            nc++;
            if (*text == ',')
                nc = 0;
        }
        /* Syntax for RGB is ^DHHHHHH where H is a hex digit.
        * If < 6 hex digits are specified, the code is displayed
        * as text
        */
        else if ((rgb && isxdigit(*text) && nc < 6) || (rgb && *text == ',' && nc < 7))
        {
            nc++;
            if (*text == ',')
                nc = 0;
        }
        else
        {
            if (col)
                col = 0;
            if (rgb)
            {
                if (nc != 6)
                {
                    text = save_text+1;
                    len = save_len-1;
                    rgb = 0;
                    continue;
                }
                rgb = 0;
            }
            if (*text == '\003')
            {
                col = 1;
                nc = 0;
            }
            else if (*text == '\004')
            {
                save_text = text;
                save_len = len;
                rgb = 1;
                nc = 0;
            }
            else
            {
                new_str[i] = *text;
                i++;
            }
        }
        text++;
        len--;
    }
    new_str[i] = 0;
    return new_str;
}

/* strip color, bold, underline, and reverse codes from a string */
const char *StripControlCodes(unsigned char *text)
{
    int i = 0, len = strlen(text), save_len=0;
    char nc = 0, col = 0, rgb = 0, *save_text=NULL;
    static unsigned char new_str[4096];
    while (len > 0)
    {
        if ( col && ((isdigit(*text) && nc < 2) || (*text == ',' && nc < 3)))
        {
            nc++;
            if (*text == ',')
                nc = 0;
        }
        /* Syntax for RGB is ^DHHHHHH where H is a hex digit.
        * If < 6 hex digits are specified, the code is displayed
        * as text
        */
        else if ((rgb && isxdigit(*text) && nc < 6) || (rgb && *text == ',' && nc < 7))
        {
            nc++;
            if (*text == ',')
                nc = 0;
        }
        else
        {
            if (col)
                col = 0;
            if (rgb)
            {
                if (nc != 6)
                {
                    text = save_text+1;
                    len = save_len-1;
                    rgb = 0;
                    continue;
                }
                rgb = 0;
            }
            switch (*text)
            {
            case 3:
                /* color */
                col = 1;
                nc = 0;
                break;
            case 4:
                /* RGB */
                save_text = text;
                save_len = len;
                rgb = 1;
                nc = 0;
                break;
            case 2:
                /* bold */
                break;
            case 31:
                /* underline */
                break;
            case 22:
                /* reverse */
                break;
            case 15:
                /* plain */
                break;
            default:
                new_str[i] = *text;
                i++;
                break;
            }
        }
        text++;
        len--;
    }
    new_str[i] = 0;
    return new_str;
}

MODVAR char umodestring[UMODETABLESZ+1];

/*
** next_client
**    Local function to find the next matching client. The search
**    can be continued from the specified client entry. Normal
**    usage loop is:
**
**    for (x = client; x = next_client(x,mask); x = x->next)
**        HandleMatchingClient;
**
*/
aClient *next_client(aClient *next, char *ch)
{
    aClient *tmp = next;

    next = find_client(ch, tmp);
    if (tmp && tmp->prev == next)
        return NULL;
    if (next != tmp)
        return next;
    for (; next; next = next->next)
    {
        if (!match(ch, next->name) || !match(next->name, ch))
            break;
    }
    return next;
}

/*
** hunt_server
**
**    Do the basic thing in delivering the message (command)
**    across the relays to the specific server (server) for
**    actions.
**
**    Note:    The command is a format string and *MUST* be
**        of prefixed style (e.g. ":%s COMMAND %s ...").
**        Command can have only max 8 parameters.
**
**    server    parv[server] is the parameter identifying the
**        target server.
**
**    *WARNING*
**        parv[server] is replaced with the pointer to the
**        real servername from the matched client (I'm lazy
**        now --msa).
**
**    returns: (see #defines)
*/
int  hunt_server(aClient *cptr, aClient *sptr, char *command, int server, int parc, char *parv[])
{
    aClient *acptr;

    /*
      ** Assume it's me, if no server
    */
    if (parc <= server || BadPtr(parv[server]) ||
        match(me.name, parv[server]) == 0 ||
        match(parv[server], me.name) == 0)
        return (HUNTED_ISME);
    /*
      ** These are to pickup matches that would cause the following
      ** message to go in the wrong direction while doing quick fast
      ** non-matching lookups.
    */
    if ((acptr = find_client(parv[server], NULL)))
        if (acptr->from == sptr->from && !MyConnect(acptr))
            acptr = NULL;
    if (!acptr && (acptr = find_server_quick(parv[server])))
        if (acptr->from == sptr->from && !MyConnect(acptr))
            acptr = NULL;
    if (!acptr)
        for (acptr = client, (void)collapse(parv[server]);
            (acptr = next_client(acptr, parv[server]));
            acptr = acptr->next)
        {
            if (acptr->from == sptr->from && !MyConnect(acptr))
                continue;
            /*
            * Fix to prevent looping in case the parameter for
            * some reason happens to match someone from the from
            * link --jto
            */
            if (IsRegistered(acptr) && (acptr != cptr))
                break;
        }
    /* Fix for unregistered client receiving msgs: */
    if (acptr && MyConnect(acptr) && IsUnknown(acptr))
        acptr = NULL;
    if (acptr)
    {
        if (IsMe(acptr) || MyClient(acptr))
            return HUNTED_ISME;
        if (match(acptr->name, parv[server]))
            parv[server] = acptr->name;
        sendto_one(acptr, command, parv[0],
            parv[1], parv[2], parv[3], parv[4],
            parv[5], parv[6], parv[7], parv[8]);
        return (HUNTED_PASS);
    }
    sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name,
        parv[0], parv[server]);
    return (HUNTED_NOSUCH);
}


/*
** hunt_server_token
**
**    Do the basic thing in delivering the message (command)
**    across the relays to the specific server (server) for
**    actions. This works like hunt_server, except if the
**    server supports tokens, the token is used.
**
**    command specifies the command name
**    token specifies the token name
**    params is a formated parameter string
**    server    parv[server] is the parameter identifying the
**        target server.
**
**    *WARNING*
**        parv[server] is replaced with the pointer to the
**        real servername from the matched client (I'm lazy
**        now --msa).
**
**    returns: (see #defines)
*/
int  hunt_server_token(aClient *cptr, aClient *sptr, char *command, char *token, char
*params, int server, int parc, char *parv[])
{
    aClient *acptr;

    /*
      ** Assume it's me, if no server
    */
    if (parc <= server || BadPtr(parv[server]) ||
        match(me.name, parv[server]) == 0 ||
        match(parv[server], me.name) == 0)
        return (HUNTED_ISME);
    /*
      ** These are to pickup matches that would cause the following
      ** message to go in the wrong direction while doing quick fast
      ** non-matching lookups.
    */
    if ((acptr = find_client(parv[server], NULL)))
        if (acptr->from == sptr->from && !MyConnect(acptr))
            acptr = NULL;
    if (!acptr && (acptr = find_server_quick(parv[server])))
        if (acptr->from == sptr->from && !MyConnect(acptr))
            acptr = NULL;
    if (!acptr)
        for (acptr = client, (void)collapse(parv[server]);
            (acptr = next_client(acptr, parv[server]));
            acptr = acptr->next)
        {
            if (acptr->from == sptr->from && !MyConnect(acptr))
                continue;
            /*
            * Fix to prevent looping in case the parameter for
            * some reason happens to match someone from the from
            * link --jto
            */
            if (IsRegistered(acptr) && (acptr != cptr))
                break;
        }
    /* Fix for unregistered client receiving msgs: */
    if (acptr && MyConnect(acptr) && IsUnknown(acptr))
        acptr = NULL;
    if (acptr)
    {
        char buff[1024];
        if (IsMe(acptr) || MyClient(acptr))
            return HUNTED_ISME;
        if (match(acptr->name, parv[server]))
            parv[server] = acptr->name;
        if (IsToken(acptr->from)) {
            sprintf(buff, ":%s %s ", parv[0], token);
            strcat(buff, params);
            sendto_one(acptr, buff, parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]);
        }
        else {
            sprintf(buff, ":%s %s ", parv[0], command);
            strcat(buff, params);
            sendto_one(acptr, buff, parv[1], parv[2],
            parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]);
        }
        return (HUNTED_PASS);
    }
    sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name,
        parv[0], parv[server]);
    return (HUNTED_NOSUCH);
}

int  hunt_server_token_quiet(aClient *cptr, aClient *sptr, char *command, char *token, char
*params, int server, int parc, char *parv[])
{
    aClient *acptr;

    /*
      ** Assume it's me, if no server
    */
    if (parc <= server || BadPtr(parv[server]) ||
        match(me.name, parv[server]) == 0 ||
        match(parv[server], me.name) == 0)
        return (HUNTED_ISME);
    /*
      ** These are to pickup matches that would cause the following
      ** message to go in the wrong direction while doing quick fast
      ** non-matching lookups.
    */
    if ((acptr = find_client(parv[server], NULL)))
        if (acptr->from == sptr->from && !MyConnect(acptr))
            acptr = NULL;
    if (!acptr && (acptr = find_server_quick(parv[server])))
        if (acptr->from == sptr->from && !MyConnect(acptr))
            acptr = NULL;
    if (!acptr)
        for (acptr = client, (void)collapse(parv[server]);
            (acptr = next_client(acptr, parv[server]));
            acptr = acptr->next)
        {
            if (acptr->from == sptr->from && !MyConnect(acptr))
                continue;
            /*
            * Fix to prevent looping in case the parameter for
            * some reason happens to match someone from the from
            * link --jto
            */
            if (IsRegistered(acptr) && (acptr != cptr))
                break;
        }
    if (acptr)
    {
        char buff[1024];
        if (IsMe(acptr) || MyClient(acptr))
            return HUNTED_ISME;
        if (match(acptr->name, parv[server]))
            parv[server] = acptr->name;
        if (IsToken(acptr->from)) {
            sprintf(buff, ":%s %s ", parv[0], token);
            strcat(buff, params);
            sendto_one(acptr, buff, parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]);
        }
        else {
            sprintf(buff, ":%s %s ", parv[0], command);
            strcat(buff, params);
            sendto_one(acptr, buff, parv[1], parv[2],
            parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]);
        }
        return (HUNTED_PASS);
    }
    return (HUNTED_NOSUCH);
}




/*
** check_for_target_limit
**
** Return Values:
** True(1) == too many targets are addressed
** False(0) == ok to send message
**
*/
int  check_for_target_limit(aClient *sptr, void *target, const char *name)
{
#ifndef _WIN32            /* This is not windows compatible */
    u_char *p;
#ifndef __alpha
    u_int tmp = ((u_int)target & 0xffff00) >> 8;
#else
    u_int tmp = ((u_long)target & 0xffff00) >> 8;
#endif
    u_char hash = (tmp * tmp) >> 12;

    if (IsAnOper(sptr))
        return 0;
    if (sptr->targets[0] == hash)
        return 0;

    for (p = sptr->targets; p < &sptr->targets[MAXTARGETS - 1];)
        if (*++p == hash)
        {
            /* move targethash to first position... */
            memmove(&sptr->targets[1], &sptr->targets[0],
                p - sptr->targets);
            sptr->targets[0] = hash;
            return 0;
        }

    if (TStime() < sptr->nexttarget)
    {
        sptr->since += TARGET_DELAY; /* lag them up */
        sptr->nexttarget += TARGET_DELAY;
        sendto_one(sptr, err_str(ERR_TARGETTOOFAST), me.name, sptr->name,
            name, sptr->nexttarget - TStime());

        return 1;
    }

    if (TStime() > sptr->nexttarget + TARGET_DELAY*MAXTARGETS)
    {
        sptr->nexttarget = TStime() - TARGET_DELAY*MAXTARGETS;
    }

    sptr->nexttarget += TARGET_DELAY;

    memmove(&sptr->targets[1], &sptr->targets[0], MAXTARGETS - 1);
    sptr->targets[0] = hash;
#endif
    return 0;
}

/*
** canonize
**
** reduce a string of duplicate list entries to contain only the unique
** items.  Unavoidably O(n^2).
*/
extern char *canonize(char *buffer)
{
    static char cbuf[BUFSIZ];
    char *s, *t, *cp = cbuf;
    int  l = 0;
    char *p = NULL, *p2;

    *cp = '\0';

    for (s = strtoken(&p, buffer, ","); s; s = strtoken(&p, NULL, ","))
    {
        if (l)
        {
            for (p2 = NULL, t = strtoken(&p2, cbuf, ","); t;
                t = strtoken(&p2, NULL, ","))
                if (!mycmp(s, t))
                    break;
                else if (p2)
                    p2[-1] = ',';
        }
        else
            t = NULL;
        if (!t)
        {
            if (l)
                *(cp - 1) = ',';
            else
                l = 1;
            (void)strcpy(cp, s);
            if (p)
                cp += (p - s);
        }
        else if (p2)
            p2[-1] = ',';
    }
    return cbuf;
}


extern MODVAR char cmodestring[512];

/*
** register_user
**    This function is called when both NICK and USER messages
**    have been accepted for the client, in whatever order. Only
**    after this the USER message is propagated.
**
**    NICK's must be propagated at once when received, although
**    it would be better to delay them too until full info is
**    available. Doing it is not so simple though, would have
**    to implement the following:
**
**    1) user telnets in and gives only "NICK foobar" and waits
**    2) another user far away logs in normally with the nick
**      "foobar" (quite legal, as this server didn't propagate
**      it).
**    3) now this server gets nick "foobar" from outside, but
**      has already the same defined locally. Current server
**      would just issue "KILL foobar" to clean out dups. But,
**      this is not fair. It should actually request another
**      nick from local user or kill him/her...
*/
extern MODVAR aTKline *tklines;
extern int badclass;

int register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip)
{
    ConfigItem_ban *bconf;
    char *parv[3], *tmpstr;
#ifdef HOSTILENAME
    char stripuser[USERLEN + 1], *u1 = stripuser, *u2, olduser[USERLEN + 1],
        userbad[USERLEN * 2 + 1], *ubad = userbad, noident = 0;
#endif
    int  xx;
    anUser *user = sptr->user;
    aClient *nsptr;
    int  i;
    char mo[256];
    char *tkllayer[9] = {
        me.name,    /*0  server.name */
        "+",        /*1  +|- */
        "z",        /*2  G  */
        "*",        /*3  user */
        NULL,        /*4  host */
        NULL,
        NULL,        /*6  expire_at */
        NULL,        /*7  set_at */
        NULL        /*8  reason */
    };
    ConfigItem_tld *tlds;
    cptr->last = TStime();
    parv[0] = sptr->name;
    parv[1] = parv[2] = NULL;
    nick = sptr->name; /* <- The data is always the same, but the pointer is sometimes not,
                        *    I need this for one of my modules, so do not remove! ;) -- Syzop */
   
    if (MyConnect(sptr))
    {
        if ((i = check_client(sptr, username))) {
            /* This had return i; before -McSkaf */
            if (i == -5)
                return FLUSH_BUFFER;

            sendto_snomask(SNO_CLIENT,
                "*** Notice -- %s from %s.",
                i == -3 ? "Too many connections" :
                "Unauthorized connection", get_client_host(sptr));
            ircstp->is_ref++;
            ircsprintf(mo, "This server is full.");
            return
                exit_client(cptr, sptr, &me,
                i ==
                -3 ? mo :
                "You are not authorized to connect to this server");
        }
        if (sptr->hostp)
        {
            /* No control-chars or ip-like dns replies... I cheat :)
              -- OnyxDragon */
            for (tmpstr = sptr->sockhost; *tmpstr > ' ' &&
                *tmpstr < 127; tmpstr++);
            if (*tmpstr || !*user->realhost
                || isdigit(*(tmpstr - 1)))
                strncpyzt(sptr->sockhost,
                    (char *)Inet_ia2p((struct IN_ADDR*)&sptr->ip), sizeof(sptr->sockhost));    /* Fix the sockhost for debug jic */
            strncpyzt(user->realhost, sptr->sockhost,
                sizeof(sptr->sockhost));
        }
        else        /* Failsafe point, don't let the user define their
                  own hostname via the USER command --Cabal95 */
            strncpyzt(user->realhost, sptr->sockhost, HOSTLEN + 1);
        strncpyzt(user->realhost, user->realhost,
            sizeof(user->realhost));
        /*
        * I do not consider *, ~ or ! 'hostile' in usernames,
        * as it is easy to differentiate them (Use \*, \? and \\)
        * with the possible?
        * exception of !. With mIRC etc. ident is easy to fake
        * to contain @ though, so if that is found use non-ident
        * username. -Donwulff
        *
        * I do, We only allow a-z A-Z 0-9 _ - and . now so the
        * !strchr(sptr->username, '@') check is out of date. -Cabal95
        *
        * Moved the noident stuff here. -OnyxDragon
        */
        if (!(sptr->flags & FLAGS_DOID))
            strncpyzt(user->username, username, USERLEN + 1);
        else if (sptr->flags & FLAGS_GOTID)
            strncpyzt(user->username, sptr->username, USERLEN + 1);
        else
        {

            /* because username may point to user->username */
            char temp[USERLEN + 1];
            strncpyzt(temp, username, USERLEN + 1);
            if (IDENT_CHECK == 0) {
                strncpyzt(user->username, temp, USERLEN + 1);
            }
            else {
                *user->username = '~';
                strncpyzt((user->username + 1), temp, USERLEN);
#ifdef HOSTILENAME
                noident = 1;
#endif
            }

        }
#ifdef HOSTILENAME
        /*
        * Limit usernames to just 0-9 a-z A-Z _ - and .
        * It strips the "bad" chars out, and if nothing is left
        * changes the username to the first 8 characters of their
        * nickname. After the MOTD is displayed it sends numeric
        * 455 to the user telling them what(if anything) happened.
        * -Cabal95
        *
        * Moved the noident thing to the right place - see above
        * -OnyxDragon
        *
        * No longer use nickname if the entire ident is invalid,
                * if thats the case, it is likely the user is trying to cause
        * problems so just ban them. (Using the nick could introduce
        * hostile chars) -- codemastr
        */
        for (u2 = user->username + noident; *u2; u2++)
        {
            if (isallowed(*u2))
                *u1++ = *u2;
            else if (*u2 < 32)
            {
                /*
                * Make sure they can read what control
                * characters were in their username.
                */
                *ubad++ = '^';
                *ubad++ = *u2 + '@';
            }
            else
                *ubad++ = *u2;
        }
        *u1 = '\0';
        *ubad = '\0';
        if (strlen(stripuser) != strlen(user->username + noident))
        {
            if (stripuser[0] == '\0')
            {
                return exit_client(cptr, cptr, cptr, "Hostile username. Please use only 0-9 a-z A-Z _ - and . in your username.");
            }

            strcpy(olduser, user->username + noident);
            strncpy(user->username + 1, stripuser, USERLEN - 1);
            user->username[0] = '~';
            user->username[USERLEN] = '\0';
        }
        else
            u1 = NULL;
#endif

        /*
        * following block for the benefit of time-dependent K:-lines
        */
        if ((bconf =
            Find_ban(sptr, make_user_host(user->username, user->realhost),
            CONF_BAN_USER)))
        {
            ircstp->is_ref++;
            sendto_one(cptr,
                ":%s %d %s :*** You are not welcome on this server (%s)"
                " Email %s for more information.",
                me.name, ERR_YOUREBANNEDCREEP,
                cptr->name, bconf->reason ? bconf->reason : "",
                KLINE_ADDRESS);
            return exit_client(cptr, cptr, cptr, "You are banned");
        }
        if ((bconf = Find_ban(NULL, sptr->info, CONF_BAN_REALNAME)))
        {
            ircstp->is_ref++;
            sendto_one(cptr,
                ":%s %d %s :*** Your GECOS (real name) is not allowed on this server (%s)"
                " Please change it and reconnect",
                me.name, ERR_YOUREBANNEDCREEP,
                cptr->name, bconf->reason ? bconf->reason : "");

            return exit_client(cptr, sptr, &me,
                "Your GECOS (real name) is banned from this server");
        }
        tkl_check_expire(NULL);
        /* Check G/Z lines before shuns -- kill before quite -- codemastr */
        if ((xx = find_tkline_match(sptr, 0)) < 0)
        {
            ircstp->is_ref++;
            return xx;
        }
        find_shun(sptr);
        xx = find_spamfilter_user(sptr);
        if (xx < 0)
            return xx;
        RunHookReturnInt(HOOKTYPE_PRE_LOCAL_CONNECT, sptr, !=0);
    }
    else
    {
        strncpyzt(user->username, username, USERLEN + 1);
    }
    SetClient(sptr);
    IRCstats.clients++;
    if (sptr->srvptr && sptr->srvptr->serv)
        sptr->srvptr->serv->users++;
    user->virthost =
        (char *)make_virthost(user->realhost, user->virthost, 1);
    if (MyConnect(sptr))
    {
        IRCstats.unknown--;
        IRCstats.me_clients++;
        if (IsHidden(sptr))
            ircd_log(LOG_CLIENT, "Connect - %s!%s@%s [VHOST %s]", nick,
                user->username, user->realhost, user->virthost);
        else
            ircd_log(LOG_CLIENT, "Connect - %s!%s@%s", nick, user->username,
                user->realhost);
        sendto_one(sptr, rpl_str(RPL_WELCOME), me.name, nick,
            ircnetwork, nick, user->username, user->realhost);
        /* This is a duplicate of the NOTICE but see below... */
            sendto_one(sptr, rpl_str(RPL_YOURHOST), me.name, nick,
                me.name, version);
        sendto_one(sptr, rpl_str(RPL_CREATED), me.name, nick, creation);
        if (!(sptr->listener->umodes & LISTENER_JAVACLIENT))
            sendto_one(sptr, rpl_str(RPL_MYINFO), me.name, parv[0],
                me.name, version, umodestring, cmodestring);
        else
            sendto_one(sptr, ":%s 004 %s %s CR1.8.03-%s %s %s",
                    me.name, parv[0],
                    me.name, version, umodestring, cmodestring);
        {
            extern char *IsupportStrings[];
            int i;
            for (i = 0; IsupportStrings[i]; i++)
                sendto_one(sptr, rpl_str(RPL_ISUPPORT), me.name, nick, IsupportStrings[i]);
        }
#ifdef USE_SSL
        if (sptr->flags & FLAGS_SSL)
            if (sptr->ssl)
                sendto_one(sptr,
                    ":%s NOTICE %s :*** You are connected to %s with %s",
                    me.name, sptr->name, me.name,
                    ssl_get_cipher(sptr->ssl));
#endif
        do_cmd(sptr, sptr, "LUSERS", 1, parv);
        short_motd(sptr);
sendto_one(sptr, err_str(ERR_TARGETTOOFAST),me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1Merhaba sunucumuza hosgeldiniz ;",me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1Genel tanitim için özelinize gelmis bulunmaktayim.",me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1Sunucumuzdaki yetkilileri görmek için :  2/Motd",me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1Sunucumuzdaki kurallari görmek için  :  2/Rules",me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1GLobal sunucu kanallarimiz            :  2#Yuzukchat #Game  #Radio",me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1Genel yardim kanalimiz                :  2#Help #OperHelp",me.name, sptr->name, me.name);
sendto_one(sptr, ":Yuzukchat.Net PRIVMSG %s :1Sunucumuzda hos vakit geçirmenizi dileriz..",me.name, sptr->name, me.name);
#ifdef EXPERIMENTAL
        sendto_one(sptr,
            ":%s NOTICE %s :*** \2NOTE:\2 This server (%s) is running experimental IRC server software. If you find any bugs or problems, please mail
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
about it",
            me.name, sptr->name, me.name);                 
#endif
#ifdef HOSTILENAME
        /*
        * Now send a numeric to the user telling them what, if
        * anything, happened.
        */
        if (u1)
            sendto_one(sptr, err_str(ERR_HOSTILENAME), me.name,
                sptr->name, olduser, userbad, stripuser);
#endif
        nextping = TStime();
        sendto_connectnotice(nick, user, sptr, 0, NULL);
        if (IsSecure(sptr))
            sptr->umodes |= UMODE_SECURE;
    }
    else if (IsServer(cptr))
    {
        aClient *acptr;

        if (!(acptr = (aClient *)find_server_quick(user->server)))
        {
            sendto_ops
                ("Bad USER [%s] :%s USER %s %s : No such server",
                cptr->name, nick, user->username, user->server);
            sendto_one(cptr, ":%s KILL %s :%s (No such server: %s)",
                me.name, sptr->name, me.name, user->server);
            sptr->flags |= FLAGS_KILLED;
            return exit_client(sptr, sptr, &me,
                "USER without prefix(2.8) or wrong prefix");
        }
        else if (acptr->from != sptr->from)
        {
            sendto_ops("Bad User [%s] :%s USER %s %s, != %s[%s]",
                cptr->name, nick, user->username, user->server,
                acptr->name, acptr->from->name);
            sendto_one(cptr, ":%s KILL %s :%s (%s != %s[%s])",
                me.name, sptr->name, me.name, user->server,
                acptr->from->name, acptr->from->sockhost);
            sptr->flags |= FLAGS_KILLED;
            return exit_client(sptr, sptr, &me,
                "USER server wrong direction");
        }
        else
            sptr->flags |= acptr->flags;
        /* *FINALL* this gets in ircd... -- Barubary */
        /* We change this a bit .. */
        if (IsULine(sptr->srvptr))
            sptr->flags |= FLAGS_ULINE;
    }
    if (sptr->umodes & UMODE_INVISIBLE)
    {
        IRCstats.invisible++;
    }

    if (virthost && umode)
    {
        tkllayer[0] = nick;
        tkllayer[1] = nick;
        tkllayer[2] = umode;
        dontspread = 1;
        do_cmd(cptr, sptr, "MODE", 3, tkllayer);
        dontspread = 0;
        if (virthost && *virthost != '*')
        {
            if (sptr->user->virthost)
            {
                MyFree(sptr->user->virthost);
                sptr->user->virthost = NULL;
            }
            /* Here pig.. yeah you .. -Stskeeps */
            sptr->user->virthost = strdup(virthost);
        }
        if (ip && (*ip != '*'))
            sptr->user->ip_str = strdup(decode_ip(ip));
    }

    hash_check_watch(sptr, RPL_LOGON);    /* Uglier hack */
    send_umode(NULL, sptr, 0, SEND_UMODES|UMODE_SERVNOTICE, buf);
    /* NICKv2 Servers ! */
    sendto_serv_butone_nickcmd(cptr, sptr, nick,
        sptr->hopcount + 1, sptr->lastnick, user->username, user->realhost,
        user->server, user->servicestamp, sptr->info,
        (!buf || *buf == '\0' ? "+" : buf),
        sptr->umodes & UMODE_SETHOST ? sptr->user->virthost : NULL);

    /* Send password from sptr->passwd to NickServ for identification,
    * if passwd given and if NickServ is online.
    * - by taz, modified by Wizzu
    */

    if (MyConnect(sptr))
    {
        char userhost[USERLEN + HOSTLEN + 6];
        if (sptr->passwd && (nsptr = find_person(NickServ, NULL)))
            sendto_one(nsptr, ":%s %s %s@%s :IDENTIFY %s",
                sptr->name,
                (IsToken(nsptr->from) ? TOK_PRIVATE : MSG_PRIVATE),
                NickServ, SERVICES_NAME, sptr->passwd);
        /* Force the user to join the given chans -- codemastr */
        if (buf[0] != '\0' && buf[1] != '\0')
            sendto_one(cptr, ":%s MODE %s :%s", cptr->name,
                cptr->name, buf);
        if (user->snomask)
            sendto_one(sptr, rpl_str(RPL_SNOMASK),
                me.name, sptr->name, get_snostr(user->snomask));
        strcpy(userhost,make_user_host(cptr->user->username, cptr->user->realhost));

        for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *) tlds->next) {
            if (!match(tlds->mask, userhost))
                break;
        }
        if (tlds && !BadPtr(tlds->channel)) {
            char *chans[3] = {
                sptr->name,
                tlds->channel,
                NULL
            };
            do_cmd(sptr, sptr, "JOIN", 3, chans);
        }
        else if (!BadPtr(AUTO_JOIN_CHANS) && strcmp(AUTO_JOIN_CHANS, "0"))
        {
            char *chans[3] = {
                sptr->name,
                AUTO_JOIN_CHANS,
                NULL
            };
            do_cmd(sptr, sptr, "JOIN", 3, chans);
        }
    }

    if (MyConnect(sptr) && !BadPtr(sptr->passwd))
    {
        MyFree(sptr->passwd);
        sptr->passwd = NULL;
    }
    return 0;
}

/*
** get_mode_str
** by vmlinuz
** returns an ascii string of modes
*/
char *get_sno_str(aClient *sptr) {
    int i;
    char *m;

    m = buf;

    *m++ = '+';
    for (i = 0; i <= Snomask_highest && (m - buf < BUFSIZE - 4); i++)
        if (Snomask_Table[i].flag && sptr->user->snomask & Snomask_Table[i].mode)
            *m++ = Snomask_Table[i].flag;
    *m = 0;
    return buf;
}

char *get_mode_str(aClient *acptr)
{
    int  i;
    char *m;

    m = buf;
    *m++ = '+';
    for (i = 0; (i <= Usermode_highest) && (m - buf < BUFSIZE - 4); i++)
        if (Usermode_Table[i].flag && (acptr->umodes & Usermode_Table[i].mode))
            *m++ = Usermode_Table[i].flag;
    *m = '\0';
    return buf;
}


char *get_modestr(long umodes)
{
    int  i;
    char *m;

    m = buf;
    *m++ = '+';
    for (i = 0; (i <= Usermode_highest) && (m - buf < BUFSIZE - 4); i++)
       
        if (Usermode_Table[i].flag && (umodes & Usermode_Table[i].mode))
            *m++ = Usermode_Table[i].flag;
    *m = '\0';
    return buf;
}

char *get_snostr(long sno) {
    int i;
    char *m;

    m = buf;

    *m++ = '+';
    for (i = 0; i <= Snomask_highest && (m - buf < BUFSIZE - 4); i++)
        if (Snomask_Table[i].flag && sno & Snomask_Table[i].mode)
            *m++ = Snomask_Table[i].flag;
    *m = 0;
    return buf;
}


void set_snomask(aClient *sptr, char *snomask) {
    int what = MODE_ADD; /* keep this an int. -- Syzop */
    char *p;
    int i;
    if (snomask == NULL) {
        sptr->user->snomask = 0;
        return;
    }
   
    for (p = snomask; p && *p; p++) {
        switch (*p) {
            case '+':
                what = MODE_ADD;
                break;
            case '-':
                what = MODE_DEL;
                break;
            default:
              for (i = 0; i <= Snomask_highest; i++)
              {
                  if (!Snomask_Table[i].flag)
                      continue;
                  if (*p == Snomask_Table[i].flag)
                  {
                    if (Snomask_Table[i].allowed && !Snomask_Table[i].allowed(sptr,what))
                        continue;
                      if (what == MODE_ADD)
                          sptr->user->snomask |= Snomask_Table[i].mode;
                      else
                          sptr->user->snomask &= ~Snomask_Table[i].mode;
                  }
              }               
        }
    }
}

void create_snomask(aClient *sptr, anUser *user, char *snomask) {
    int what = MODE_ADD; /* keep this an int. -- Syzop */
    char *p;
    int i;
    if (snomask == NULL) {
        user->snomask = 0;
        return;
    }
   
    for (p = snomask; p && *p; p++) {
        switch (*p) {
            case '+':
                what = MODE_ADD;
                break;
            case '-':
                what = MODE_DEL;
                break;
            default:
              for (i = 0; i <= Snomask_highest; i++)
              {
                  if (!Snomask_Table[i].flag)
                      continue;
                  if (*p == Snomask_Table[i].flag)
                  {
                    if (Snomask_Table[i].allowed && !Snomask_Table[i].allowed(sptr,what))
                        continue;
                      if (what == MODE_ADD)
                          user->snomask |= Snomask_Table[i].mode;
                      else
                          user->snomask &= ~Snomask_Table[i].mode;
                  }
              }               
        }
    }
}

/*
 * send the MODE string for user (user) to connection cptr
 * -avalon
 */
void send_umode(aClient *cptr, aClient *sptr, long old, long sendmask, char *umode_buf)
{
    int i;
    long flag;
    char *m;
    int  what = MODE_NULL;

    /*
    * build a string in umode_buf to represent the change in the user's
    * mode between the new (sptr->flag) and 'old'.
    */
    m = umode_buf;
    *m = '\0';
    for (i = 0; i <= Usermode_highest; i++)
    {
        if (!Usermode_Table[i].flag)
            continue;
        flag = Usermode_Table[i].mode;
        if (MyClient(sptr) && !(flag & sendmask))
            continue;
        if ((flag & old) && !(sptr->umodes & flag))
        {
            if (what == MODE_DEL)
                *m++ = Usermode_Table[i].flag;
            else
            {
                what = MODE_DEL;
                *m++ = '-';
                *m++ = Usermode_Table[i].flag;
            }
        }
        else if (!(flag & old) && (sptr->umodes & flag))
        {
            if (what == MODE_ADD)
                *m++ = Usermode_Table[i].flag;
            else
            {
                what = MODE_ADD;
                *m++ = '+';
                *m++ = Usermode_Table[i].flag;
            }
        }
    }
    *m = '\0';
    if (*umode_buf && cptr)
        sendto_one(cptr, ":%s %s %s :%s", sptr->name,
            (IsToken(cptr) ? TOK_MODE : MSG_MODE),
            sptr->name, umode_buf);
}

/*
 * added Sat Jul 25 07:30:42 EST 1992
 */
void send_umode_out(aClient *cptr, aClient *sptr, long old)
{
    int  i;
    aClient *acptr;

    send_umode(NULL, sptr, old, SEND_UMODES, buf);

    for (i = LastSlot; i >= 0; i--)
        if ((acptr = local[i]) && IsServer(acptr) &&
            (acptr != cptr) && (acptr != sptr) && *buf) {
            if (!SupportUMODE2(acptr))
            {
                sendto_one(acptr, ":%s MODE %s :%s",
                    sptr->name, sptr->name, buf);
            }
            else
            {
                sendto_one(acptr, ":%s %s %s",
                    sptr->name,
                    (IsToken(acptr) ? TOK_UMODE2 : MSG_UMODE2),
                    buf);
            }
        }
    if (cptr && MyClient(cptr))
        send_umode(cptr, sptr, old, ALL_UMODES, buf);

}

void send_umode_out_nickv2(aClient *cptr, aClient *sptr, long old)
{
    int  i;
    aClient *acptr;

    send_umode(NULL, sptr, old, SEND_UMODES, buf);

    for (i = LastSlot; i >= 0; i--)
        if ((acptr = local[i]) && IsServer(acptr)
            && !SupportNICKv2(acptr) && (acptr != cptr)
            && (acptr != sptr) && *buf)
            sendto_one(acptr, ":%s MODE %s :%s", sptr->name,
                sptr->name, buf);

    if (cptr && MyClient(cptr))
        send_umode(cptr, sptr, old, ALL_UMODES, buf);

}




int  del_silence(aClient *sptr, char *mask)
{
    Link **lp;
    Link *tmp;

    for (lp = &(sptr->user->silence); *lp; lp = &((*lp)->next))
        if (mycmp(mask, (*lp)->value.cp) == 0)
        {
            tmp = *lp;
            *lp = tmp->next;
            MyFree(tmp->value.cp);
            free_link(tmp);
            return 0;
        }
    return -1;
}

int add_silence(aClient *sptr, char *mask, int senderr)
{
    Link *lp;
    int  cnt = 0;

    for (lp = sptr->user->silence; lp; lp = lp->next)
    {
        if (MyClient(sptr))
            if ((strlen(lp->value.cp) > MAXSILELENGTH) || (++cnt >= SILENCE_LIMIT))
            {
                if (senderr)
                    sendto_one(sptr, err_str(ERR_SILELISTFULL), me.name, sptr->name, mask);
                return -1;
            }
            else
            {
                if (!match(lp->value.cp, mask))
                    return -1;
            }
        else if (!mycmp(lp->value.cp, mask))
            return -1;
    }
    lp = make_link();
    bzero((char *)lp, sizeof(Link));
    lp->next = sptr->user->silence;
    lp->value.cp = (char *)MyMalloc(strlen(mask) + 1);
    (void)strcpy(lp->value.cp, mask);
    sptr->user->silence = lp;
    return 0;
}


Freak 25 Nisan 2007 07:53

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
s_kline.c
Kod:

/*
 *  Unreal Internet Relay Chat Daemon, src/s_kline.c
 *  (C) 1999-2000 Carsten Munk (Techie/Stskeeps) <
Bu forumdaki linkleri ve resimleri görebilmek için en az 25 mesajınız olması gerekir.
>
 *  File to take care of dynamic K:/G:/Z: lines
 *
 *
 *  See file AUTHORS in IRC package for additional names of
 *  the programmers.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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"
#include "proto.h"
#include "inet.h"

aTKline *tklines[TKLISTLEN];

extern MODVAR char zlinebuf[BUFSIZE];
int MODVAR spamf_ugly_vchanoverride = 0;

/** tkl hash method.
 * NOTE1: the input value 'c' is assumed to be in range a-z or A-Z!
 * NOTE2: don't blindly change the hashmethod, some things depend on
 *        'z'/'Z' getting the same bucket.
 */
inline int tkl_hash(char c)
{
#ifdef DEBUGMODE
    if ((c >= 'a') && (c <= 'z'))
        return c-'a';
    else if ((c >= 'A') && (c <= 'Z'))
        return c-'A';
    else {
        sendto_realops("[BUG] tkl_hash() called with out of range parameter (c = '%c') !!!", c);
        ircd_log(LOG_ERROR, "[BUG] tkl_hash() called with out of range parameter (c = '%c') !!!", c);
        return 0;
    }
#else
    return (isupper(c) ? c-'A' : c-'a');
#endif
}

/** tkl type to tkl character.
 * NOTE: type is assumed to be valid.
 */
char tkl_typetochar(int type)
{
    if (type & TKL_GLOBAL)
    {
        if (type & TKL_KILL)
            return 'G';
        if (type & TKL_ZAP)
            return 'Z';
        if (type & TKL_SHUN)
            return 's';
        if (type & TKL_KILL)
            return 'G';
        if (type & TKL_SPAMF)
            return 'F';
        if (type & TKL_NICK)
            return 'Q';
    } else {
        if (type & TKL_ZAP)
            return 'z';
        if (type & TKL_KILL)
            return 'k';
        if (type & TKL_SPAMF)
            return 'f';
        if (type & TKL_NICK)
            return 'q';
    }
    sendto_realops("[BUG]: tkl_typetochar(): unknown type 0x%x !!!", type);
    ircd_log(LOG_ERROR, "[BUG] tkl_typetochar(): unknown type 0x%x !!!", type);
    return 0;
}

void tkl_init(void)
{
    memset(tklines, 0, sizeof(tklines));
}

/*
 *  type =  TKL_*
 *    usermask@hostmask
 *    reason
 *    setby = whom set it
 *    expire_at = when to expire - 0 if not to expire
 *    set_at    = was set at
 *  spamf_tkl_duration = duration of *line placed by spamfilter [1]
 *  spamf_tkl_reason = escaped reason field for *lines placed by spamfilter [1]
 *
 *  [1]: only relevant for spamfilters, else ignored (eg 0, NULL).
*/

aTKline *tkl_add_line(int type, char *usermask, char *hostmask, char *reason, char *setby,
                  TS expire_at, TS set_at, TS spamf_tkl_duration, char *spamf_tkl_reason)
{
    aTKline *nl;
    int index;

    nl = (aTKline *) MyMallocEx(sizeof(aTKline));

    if (!nl)
        return NULL;

    nl->type = type;
    nl->expire_at = expire_at;
    nl->set_at = set_at;
    strncpyzt(nl->usermask, usermask, sizeof(nl->usermask));
    nl->hostmask = strdup(hostmask);
    nl->reason = strdup(reason);
    nl->setby = strdup(setby);
    if (type & TKL_SPAMF)
    {
        /* Need to set some additional flags like 'targets' and 'action'.. */
        nl->subtype = spamfilter_gettargets(usermask, NULL);
        nl->ptr.spamf = unreal_buildspamfilter(reason);
        nl->ptr.spamf->action = banact_chartoval(*hostmask);
        nl->expire_at = 0; /* temporary spamfilters are NOT supported! (makes no sense) */
        if (!spamf_tkl_reason)
        {
            /* no exttkl support, use default values... */
            nl->ptr.spamf->tkl_duration = SPAMFILTER_BAN_TIME;
            nl->ptr.spamf->tkl_reason = strdup(unreal_encodespace(SPAMFILTER_BAN_REASON));
        } else {
            nl->ptr.spamf->tkl_duration = spamf_tkl_duration;
            nl->ptr.spamf->tkl_reason = strdup(spamf_tkl_reason); /* already encoded */
        }
        if (nl->subtype & SPAMF_USER)
            loop.do_bancheck_spamf_user = 1;
        if (nl->subtype & SPAMF_AWAY)
            loop.do_bancheck_spamf_away = 1;
    }
    else if (type & TKL_KILL || type & TKL_ZAP || type & TKL_SHUN)
    {
        struct irc_netmask tmp;
        if ((tmp.type = parse_netmask(nl->hostmask, &tmp)) != HM_HOST)
        {
            nl->ptr.netmask = MyMallocEx(sizeof(struct irc_netmask));
            bcopy(&tmp, nl->ptr.netmask, sizeof(struct irc_netmask));
        }
    }
    index = tkl_hash(tkl_typetochar(type));
    AddListItem(nl, tklines[index]);

    return nl;
}

aTKline *tkl_del_line(aTKline *tkl)
{
    aTKline *p, *q;
    int index = tkl_hash(tkl_typetochar(tkl->type));

    for (p = tklines[index]; p; p = p->next)
    {
        if (p == tkl)
        {
            q = p->next;
            MyFree(p->hostmask);
            MyFree(p->reason);
            MyFree(p->setby);
            if (p->type & TKL_SPAMF && p->ptr.spamf)
            {
                regfree(&p->ptr.spamf->expr);
                if (p->ptr.spamf->tkl_reason)
                    MyFree(p->ptr.spamf->tkl_reason);
                MyFree(p->ptr.spamf);
            }
            if ((p->type & TKL_KILL || p->type & TKL_ZAP || p->type & TKL_SHUN)
                && p->ptr.netmask)
                MyFree(p->ptr.netmask);
            DelListItem(p, tklines[index]);
            MyFree(p);
            return q;
        }
    }
    return NULL;
}

/*
 * tkl_check_local_remove_shun:
 * removes shun from currently connected users affected by tmp.
 */
static void tkl_check_local_remove_shun(aTKline *tmp)
{
long i1, i;
char *chost, *cname, *cip;
int  is_ip;
aClient *acptr;

    for (i1 = 0; i1 <= 5; i1++)
    {
        /* winlocal
        for (i = 0; i <= (MAXCONNECTIONS - 1); i++)
        */
        for (i = 0; i <= LastSlot; ++i)
        {
            if ((acptr = local[i]))
                if (MyClient(acptr) && IsShunned(acptr))
                {
                    chost = acptr->sockhost;
                    cname = acptr->user->username;

   
                    cip = GetIP(acptr);

                    if ((*tmp->hostmask >= '0') && (*tmp->hostmask <= '9'))
                        is_ip = 1;
                    else
                        is_ip = 0;

                    if (is_ip == 0 ?
                        (!match(tmp->hostmask, chost) && !match(tmp->usermask, cname)) :
                        (!match(tmp->hostmask, chost) || !match(tmp->hostmask, cip))
                        && !match(tmp->usermask, cname))
                    {
                        ClearShunned(acptr);
#ifdef SHUN_NOTICES
                        sendto_one(acptr,
                            ":%s NOTICE %s :*** You are no longer shunned",
                            me.name,
                            acptr->name);
#endif
                    }
                }
        }
    }
}

aTKline *tkl_expire(aTKline * tmp)
{
    char whattype[512];

    if (!tmp)
        return NULL;

    whattype[0] = 0;

    if ((tmp->expire_at == 0) || (tmp->expire_at > TStime()))
    {
        sendto_ops
            ("tkl_expire(): expire for not-yet-expired tkline %s@%s",
            tmp->usermask, tmp->hostmask);
        return (tmp->next);
    }
    /* Using strlcpy here is wasteful, we know it is < 512 */
    if (tmp->type & TKL_GLOBAL)
    {
        if (tmp->type & TKL_KILL)
            strcpy(whattype, "G:Line");
        else if (tmp->type & TKL_ZAP)
            strcpy(whattype, "Global Z:Line");
        else if (tmp->type & TKL_SHUN)
            strcpy(whattype, "Shun");
        else if (tmp->type & TKL_NICK)
            strcpy(whattype, "Global Q:line");
    }
    else
    {
        if (tmp->type & TKL_KILL)
            strcpy(whattype, "K:Line");
        else if (tmp->type & TKL_ZAP)
            strcpy(whattype, "Z:Line");
        else if (tmp->type & TKL_SHUN)
            strcpy(whattype, "Local Shun");
        else if (tmp->type & TKL_NICK)
            strcpy(whattype, "Q:line");
    }
    if (!(tmp->type & TKL_NICK))
    {
        sendto_snomask(SNO_TKL,
            "*** Expiring %s (%s@%s) made by %s (Reason: %s) set %li seconds ago",
            whattype, tmp->usermask, tmp->hostmask, tmp->setby, tmp->reason,
            TStime() - tmp->set_at);
        ircd_log
            (LOG_TKL, "Expiring %s (%s@%s) made by %s (Reason: %s) set %li seconds ago",
            whattype, tmp->usermask, tmp->hostmask, tmp->setby, tmp->reason,
            TStime() - tmp->set_at);
    }
    else if (!(*tmp->usermask == 'H')) /* Q:line but not a hold */
    {
        sendto_snomask(SNO_TKL,
            "*** Expiring %s (%s) made by %s (Reason: %s) set %li seconds ago",
            whattype, tmp->hostmask, tmp->setby, tmp->reason,
            TStime() - tmp->set_at);
        ircd_log
            (LOG_TKL, "Expiring %s (%s) made by %s (Reason: %s) set %li seconds ago",
            whattype, tmp->hostmask, tmp->setby, tmp->reason, TStime() - tmp->set_at);
    }
    if (tmp->type & TKL_SHUN)
        tkl_check_local_remove_shun(tmp);

    RunHook5(HOOKTYPE_TKL_DEL, NULL, NULL, tmp, 0, NULL);
    return (tkl_del_line(tmp));
}

EVENT(tkl_check_expire)
{
    aTKline *gp, *next;
    TS  nowtime;
    int index;
   
    nowtime = TStime();

    for (index = 0; index < TKLISTLEN; index++)
        for (gp = tklines[index]; gp; gp = next)
        {
            next = gp->next;
            if (gp->expire_at <= nowtime && !(gp->expire_at == 0))
            {
                tkl_expire(gp);
            }
        }
}



/*
    returns <0 if client exists (banned)
    returns 1 if it is excepted
*/

int  find_tkline_match(aClient *cptr, int xx)
{
    aTKline *lp;
    char *chost, *cname, *cip;
    TS  nowtime;
    char msge[1024];
    int    points = 0;
    ConfigItem_except *excepts;
    char host[NICKLEN+USERLEN+HOSTLEN+6], host2[NICKLEN+USERLEN+HOSTLEN+6];
    int match_type = 0;
    int index;
    Hook *tmphook;

    if (IsServer(cptr) || IsMe(cptr))
        return -1;

    nowtime = TStime();
    chost = cptr->sockhost;
    cname = cptr->user ? cptr->user->username : "unknown";
    cip = GetIP(cptr);

    points = 0;
    for (index = 0; index < TKLISTLEN; index++)
    {
        for (lp = tklines[index]; lp; lp = lp->next)
        {
            if ((lp->type & TKL_SHUN) || (lp->type & TKL_SPAMF) || (lp->type & TKL_NICK))
                continue;

            /* If it's tangy and brown, you're in CIDR town! */
            if (lp->ptr.netmask)
            {
                if (match_ip(cptr->ip, NULL, NULL, lp->ptr.netmask) &&
                    !match(lp->usermask, cname))
                {
                    points = 1;
                    break;
                }
                continue;
            }
            if (!match(lp->usermask, cname) && !match(lp->hostmask, chost))
            {
                points = 1;
                break;
            }
            if (!match(lp->usermask, cname) && !match(lp->hostmask, cip))
            {
                points = 1;
                break;
            }
        }
        if (points)
            break;
    }

    if (points != 1)
        return 1;
    strcpy(host, make_user_host(cname, chost));
    strcpy(host2, make_user_host(cname, cip));
    if (((lp->type & TKL_KILL) || (lp->type & TKL_ZAP)) && !(lp->type & TKL_GLOBAL))
        match_type = CONF_EXCEPT_BAN;
    else
        match_type = CONF_EXCEPT_TKL;
    for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next) {
        if (excepts->flag.type != match_type || (match_type == CONF_EXCEPT_TKL &&
            excepts->type != lp->type))
            continue;

        if (excepts->netmask)
        {
            if (match_ip(cptr->ip, host2, excepts->mask, excepts->netmask))
                return 1;       
        } else
        if (!match(excepts->mask, host) || !match(excepts->mask, host2))
            return 1;       
    }

    for (tmphook = Hooks[HOOKTYPE_TKL_EXCEPT]; tmphook; tmphook = tmphook->next)
        if (tmphook->func.intfunc(cptr, lp) > 0)
            return 1;
   
    if ((lp->type & TKL_KILL) && (xx != 2))
    {
        if (lp->type & TKL_GLOBAL)
        {
            ircstp->is_ref++;
            if (GLINE_ADDRESS)
                sendto_one(cptr, ":%s NOTICE %s :*** You are %s from %s (1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!)"
                      " Email %s for more information.",
                      me.name, cptr->name,
                      (lp->expire_at ? "banned" : "permanently banned"),
                      ircnetwork, lp->reason, GLINE_ADDRESS);
            else
                sendto_one(cptr, ":%s NOTICE %s :*** You are %s from %s (1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!)",
                      me.name, cptr->name,
                      (lp->expire_at ? "banned" : "permanently banned"),
                      ircnetwork, lp->reason);
            ircsprintf(msge, "User has been %s from %s (1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!)",
                  (lp->expire_at ? "banned" : "permanently banned"),
                  ircnetwork, lp->reason);
            return (exit_client(cptr, cptr, &me, msge));
        }
        else
        {
            ircstp->is_ref++;
            sendto_one(cptr, ":%s NOTICE %s :*** You are %s from %s (1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!)"
                  " Email %s for more information.",
                  me.name, cptr->name,
                  (lp->expire_at ? "banned" : "permanently banned"),
                  me.name, lp->reason, KLINE_ADDRESS);
            ircsprintf(msge, "User is %s (1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!)",
                  (lp->expire_at ? "banned" : "permanently banned"),
                  lp->reason);
            return (exit_client(cptr, cptr, &me, msge));

        }
    }
    if (lp->type & TKL_ZAP)
    {
        ircstp->is_ref++;
        ircsprintf(msge, "Z:lined (1Serverdan uzaklastirildiniz. 2[ 5Reklam, Küfür, Clone, Trojan 2] 1Gibi eylemler yasaktir. Servera girisinizde 2[ 3/Rules 2) 4Komutunu Kullanip Server Kurallarini Okuyunuz!)",lp->reason);
        return exit_client(cptr, cptr, &me, msge);
    }

    return 3;
}

int  find_shun(aClient *cptr)
{
    aTKline *lp;
    char *chost, *cname, *cip;
    TS  nowtime;
    int    points = 0;
    ConfigItem_except *excepts;
    char host[NICKLEN+USERLEN+HOSTLEN+6], host2[NICKLEN+USERLEN+HOSTLEN+6];
    int match_type = 0;
    if (IsServer(cptr) || IsMe(cptr))
        return -1;

    if (IsShunned(cptr))
        return 1;
    if (IsAdmin(cptr))
        return 1;

    nowtime = TStime();
    chost = cptr->sockhost;
    cname = cptr->user ? cptr->user->username : "unknown";
    cip = GetIP(cptr);

    for (lp = tklines[tkl_hash('s')]; lp; lp = lp->next)
    {
        points = 0;
       
        if (!(lp->type & TKL_SHUN))
            continue;

        /* CIDR */
        if (lp->ptr.netmask)
        {
            if (match_ip(cptr->ip, NULL, NULL, lp->ptr.netmask) &&
                !match(lp->usermask, cname))
            {
                points = 1;
                break;
            }
            continue;
        }

        if (!match(lp->usermask, cname) && !match(lp->hostmask, chost))
        {
            points = 1;
            break;
        }
        if (!match(lp->usermask, cname) && !match(lp->hostmask, cip))
        {
            points = 1;
            break;
        }
        else
            points = 0;
    }

    if (points != 1)
        return 1;
    strcpy(host, make_user_host(cname, chost));
    strcpy(host2, make_user_host(cname, cip));
        match_type = CONF_EXCEPT_TKL;

    for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next) {
        if (excepts->flag.type != match_type || (match_type == CONF_EXCEPT_TKL &&
            excepts->type != lp->type))
            continue;
        if (excepts->netmask)
        {
            if (match_ip(cptr->ip, NULL, NULL, excepts->netmask))
                return 1;       
        }
        else if (!match(excepts->mask, host) || !match(excepts->mask, host2))
            return 1;       
    }
   
    SetShunned(cptr);
    return 2;
}

/** Checks if the user matches a spamfilter of type 'u' (user,
 * nick!user@host:realname ban).
 * Written by: Syzop
 * Assumes: only call for clients, possible assume on local clients [?]
 * Return values: see dospamfilter()
 */
int find_spamfilter_user(aClient *sptr)
{
char spamfilter_user[NICKLEN + USERLEN + HOSTLEN + REALLEN + 64]; /* n!u@h:r */

    if (IsAnOper(sptr))
        return 0;

    ircsprintf(spamfilter_user, "%s!%s@%s:%s",
        sptr->name, sptr->user->username, sptr->user->realhost, sptr->info);
    return dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL);
}

aTKline *find_qline(aClient *cptr, char *nick, int *ishold)
{
    aTKline *lp;
    char *chost, *cname, *cip;
    char host[NICKLEN+USERLEN+HOSTLEN+6], hostbuf2[NICKLEN+USERLEN+HOSTLEN+6], *host2 = NULL;
    int    points = 0;
    ConfigItem_except *excepts;
    *ishold = 0;
    if (IsServer(cptr) || IsMe(cptr))
        return NULL;

    for (lp = tklines[tkl_hash('q')]; lp; lp = lp->next)
    {
        points = 0;
       
        if (!(lp->type & TKL_NICK))
            continue;
        if (!match(lp->hostmask, nick))
        {
            points = 1;
            break;   
        }
    }

    if (points != 1)
        return NULL;

    /* It's a services hold */
    if (*lp->usermask == 'H')
    {
        *ishold = 1;
        return lp;
    }

    chost = cptr->user ? cptr->user->realhost : (MyConnect(cptr) ? cptr->sockhost : "unknown");
    cname = cptr->user ? cptr->user->username : "unknown";
    strcpy(host, make_user_host(cname, chost));

    cip = GetIP(cptr);
    if (cip)
    {
        strcpy(hostbuf2, make_user_host(cname, cip));
        host2 = hostbuf2;
    }

    for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next)
    {
        if (excepts->flag.type != CONF_EXCEPT_TKL || excepts->type != TKL_NICK)
            continue;
        if (excepts->netmask)
        {
            if (MyConnect(cptr) && match_ip(cptr->ip, NULL, NULL, excepts->netmask))
                return NULL;
        } else
        if (!match(excepts->mask, host) || (host2 && !match(excepts->mask, host2)))
            return NULL;
    }
    return lp;
}


int  find_tkline_match_zap(aClient *cptr)
{
    aTKline *lp;
    char *cip;
    TS  nowtime;
    char msge[1024];
    ConfigItem_except *excepts;
    Hook *tmphook;
   
    if (IsServer(cptr) || IsMe(cptr))
        return -1;

    nowtime = TStime();
    cip = GetIP(cptr);

    for (lp = tklines[tkl_hash('z')]; lp; lp = lp->next)
    {
        if (lp->type & TKL_ZAP)
        {
            if ((lp->ptr.netmask && match_ip(cptr->ip, NULL, NULL, lp->ptr.netmask))
                || !match(lp->hostmask, cip))
            {

                for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next) {
                    if (excepts->flag.type != CONF_EXCEPT_TKL || excepts->type != lp->type)
                        continue;
                    if (excepts->netmask)
                    {
                        if (match_ip(cptr->ip, NULL, NULL, excepts->netmask))
                            return -1;       
                    } else if (!match(excepts->mask, cip))
                        return -1;       
                }
                for (tmphook = Hooks[HOOKTYPE_TKL_EXCEPT]; tmphook; tmphook = tmphook->next)
                    if (tmphook->func.intfunc(cptr, lp) > 0)
                        return -1;

                ircstp->is_ref++;
                ircsprintf(msge,
                    "ERROR :Closing Link: [%s] Z:Lined (%s)\r\n",
#ifndef INET6
                    inetntoa((char *)&cptr->ip), lp->reason);
#else
                    inet_ntop(AF_INET6, (char *)&cptr->ip,
                    mydummy, MYDUMMY_SIZE), lp->reason);
#endif
                strlcpy(zlinebuf, msge, sizeof zlinebuf);
                return (1);
            }
        }
    }
    return -1;
}

#define BY_MASK 0x1
#define BY_REASON 0x2
#define NOT_BY_MASK 0x4
#define NOT_BY_REASON 0x8
#define BY_SETBY 0x10
#define NOT_BY_SETBY 0x20

typedef struct {
    int flags;
    char *mask;
    char *reason;
    char *setby;
} TKLFlag;

void parse_tkl_para(char *para, TKLFlag *flag)
{
    static char paratmp[512]; /* <- copy of para, because it gets fragged by strtok() */
    char *flags, *tmp;
    char what = '+';

    strncpyzt(paratmp, para, sizeof(paratmp));
    flags = strtok(paratmp, " ");

    bzero(flag, sizeof(TKLFlag));
    for (; *flags; flags++)
    {
        switch (*flags)
        {
            case '+':
                what = '+';
                break;
            case '-':
                what = '-';
                break;
            case 'm':
                if (flag->mask || !(tmp = strtok(NULL, " ")))
                    continue;
                if (what == '+')
                    flag->flags |= BY_MASK;
                else
                    flag->flags |= NOT_BY_MASK;
                flag->mask = tmp;
                break;
            case 'r':
                if (flag->reason || !(tmp = strtok(NULL, " ")))
                    continue;
                if (what == '+')
                    flag->flags |= BY_REASON;
                else
                    flag->flags |= NOT_BY_REASON;
                flag->reason = tmp;
                break;
            case 's':
                if (flag->setby || !(tmp = strtok(NULL, " ")))
                    continue;
                if (what == '+')
                    flag->flags |= BY_SETBY;
                else
                    flag->flags |= NOT_BY_SETBY;
                flag->setby = tmp;
                break;
        }
    }
}   

void tkl_stats(aClient *cptr, int type, char *para)
{
    aTKline *tk;
    TS  curtime;
    TKLFlag tklflags;
    int index;
    /*
      We output in this row:
      Glines,GZlines,KLine, ZLIne
      Character:
      G, Z, K, z
    */

    if (!BadPtr(para))
        parse_tkl_para(para, &tklflags);
    tkl_check_expire(NULL);
    curtime = TStime();
    for (index = 0; index < TKLISTLEN; index++)
    for (tk = tklines[index]; tk; tk = tk->next)
    {
        if (type && tk->type != type)
            continue;
        if (!BadPtr(para))
        {
            if (tklflags.flags & BY_MASK)
            {
                if (tk->type & TKL_NICK)
                {
                    if (match(tklflags.mask, tk->hostmask))
                        continue;
                }
                else if (match(tklflags.mask, make_user_host(tk->usermask,
                    tk->hostmask)))
                    continue;
            }
            if (tklflags.flags & NOT_BY_MASK)
            {
                if (tk->type & TKL_NICK)
                {
                    if (!match(tklflags.mask, tk->hostmask))
                        continue;
                }
                else if (!match(tklflags.mask, make_user_host(tk->usermask,
                    tk->hostmask)))
                    continue;
            }
            if (tklflags.flags & BY_REASON)
                if (match(tklflags.reason, tk->reason))
                    continue;
            if (tklflags.flags & NOT_BY_REASON)
                if (!match(tklflags.reason, tk->reason))
                    continue;
            if (tklflags.flags & BY_SETBY)
                if (match(tklflags.setby, tk->setby))
                    continue;
            if (tklflags.flags & NOT_BY_SETBY)
                if (!match(tklflags.setby, tk->setby))
                    continue;
        }
        if (tk->type == (TKL_KILL | TKL_GLOBAL))
        {
            sendto_one(cptr, rpl_str(RPL_STATSGLINE), me.name,
                cptr->name, 'G', tk->usermask, tk->hostmask,
                (tk->expire_at !=
                0) ? (tk->expire_at - curtime) : 0,
                (curtime - tk->set_at), tk->setby, tk->reason);
        }
        if (tk->type == (TKL_ZAP | TKL_GLOBAL))
        {
            sendto_one(cptr, rpl_str(RPL_STATSGLINE), me.name,
                cptr->name, 'Z', tk->usermask, tk->hostmask,
                (tk->expire_at !=
                0) ? (tk->expire_at - curtime) : 0,
                (curtime - tk->set_at), tk->setby, tk->reason);
        }
        if (tk->type == (TKL_SHUN | TKL_GLOBAL))
        {
            sendto_one(cptr, rpl_str(RPL_STATSGLINE), me.name,
                cptr->name, 's', tk->usermask, tk->hostmask,
                (tk->expire_at !=
                0) ? (tk->expire_at - curtime) : 0,
                (curtime - tk->set_at), tk->setby, tk->reason);
        }
        if (tk->type == (TKL_KILL))
        {
            sendto_one(cptr, rpl_str(RPL_STATSGLINE), me.name,
                cptr->name, 'K', tk->usermask, tk->hostmask,
                (tk->expire_at !=
                0) ? (tk->expire_at - curtime) : 0,
                (curtime - tk->set_at), tk->setby, tk->reason);
        }
        if (tk->type == (TKL_ZAP))
        {
            sendto_one(cptr, rpl_str(RPL_STATSGLINE), me.name,
                cptr->name, 'z', tk->usermask, tk->hostmask,
                (tk->expire_at !=
                0) ? (tk->expire_at - curtime) : 0,
                (curtime - tk->set_at), tk->setby, tk->reason);
        }
        if (tk->type & TKL_SPAMF)
        {
            sendto_one(cptr, rpl_str(RPL_STATSSPAMF), me.name,
                cptr->name,
                (tk->type & TKL_GLOBAL) ? 'F' : 'f',
                spamfilter_target_inttostring(tk->subtype),
                banact_valtostring(tk->ptr.spamf->action),
                (tk->expire_at != 0) ? (tk->expire_at - curtime) : 0,
                curtime - tk->set_at,
                tk->ptr.spamf->tkl_duration, tk->ptr.spamf->tkl_reason,
                tk->setby,
                tk->reason);
        }
        if (tk->type & TKL_NICK)
            sendto_one(cptr, rpl_str(RPL_STATSQLINE), me.name,
                cptr->name, (tk->type & TKL_GLOBAL) ? 'Q' : 'q',
                tk->hostmask, (tk->expire_at != 0) ? (tk->expire_at - curtime) : 0,
                curtime - tk->set_at, tk->setby, tk->reason);
    }

}

void tkl_synch(aClient *sptr)
{
    aTKline *tk;
    char typ = 0;
    int index;
   
    for (index = 0; index < TKLISTLEN; index++)
        for (tk = tklines[index]; tk; tk = tk->next)
        {
            if (tk->type & TKL_GLOBAL)
            {
                if (tk->type & TKL_KILL)
                    typ = 'G';
                if (tk->type & TKL_ZAP)
                    typ = 'Z';
                if (tk->type & TKL_SHUN)
                    typ = 's';
                if (tk->type & TKL_SPAMF)
                    typ = 'F';
                if (tk->type & TKL_NICK)
                    typ = 'Q';
                if ((tk->type & TKL_SPAMF) && (sptr->proto & PROTO_TKLEXT))
                {
                    sendto_one(sptr,
                        ":%s %s + %c %s %s %s %li %li %li %s :%s", me.name,
                        IsToken(sptr) ? TOK_TKL : MSG_TKL,
                        typ,
                        tk->usermask, tk->hostmask, tk->setby,
                        tk->expire_at, tk->set_at,
                        tk->ptr.spamf->tkl_duration, tk->ptr.spamf->tkl_reason,
                        tk->reason);
                } else
                    sendto_one(sptr,
                        ":%s %s + %c %s %s %s %li %li :%s", me.name,
                        IsToken(sptr) ? TOK_TKL : MSG_TKL,
                        typ,
                        tk->usermask ? tk->usermask : "*", tk->hostmask, tk->setby,
                        tk->expire_at, tk->set_at, tk->reason);
            }
        }
}

/*
 * m_tkl:
 * HISTORY:
 * This was originall called Timed KLines, but today it's
 * used by various *line types eg: zline, gline, gzline, shun,
 * but also by spamfilter etc...
 * USAGE:
 * This routine is used both internally by the ircd (to
 * for example add local klines, zlines, etc) and over the
 * network (glines, gzlines, spamfilter, etc).
 *          add:      remove:    spamfilter:    spamfilter+TKLEXT  sqline:
 * parv[ 1]: +        -          +/-            +                  +/-
 * parv[ 2]: type      type      type          type              type
 * parv[ 3]: user      user      target        target            hold
 * parv[ 4]: host      host      action        action            host
 * parv[ 5]: setby    removedby  (un)setby      setby              setby
 * parv[ 6]: expire_at            expire_at (0)  expire_at (0)      expire_at
 * parv[ 7]: set_at              set_at        set_at            set_at
 * parv[ 8]: reason              regex          tkl duration      reason
 * parv[ 9]:                                    tkl reason [A]       
 * parv[10]:                                    regex             
 *
 * [A] tkl reason field must be escaped by caller [eg: use unreal_encodespace()
 *    if m_tkl is called internally].
 *
 */
int m_tkl(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    aTKline *tk;
    int  type;
    int  found = 0;
    char gmt[256], gmt2[256];
    char txt[256];
    TS  expiry_1, setat_1, spamf_tklduration = 0;
    char *reason = NULL;

    if (!IsServer(sptr) && !IsOper(sptr) && !IsMe(sptr))
        return 0;
    if (parc < 2)
        return 0;

    tkl_check_expire(NULL);

    switch (*parv[1])
    {
      case '+':
      {
          /* we relay on servers to be failsafe.. */
          if (!IsServer(sptr) && !IsMe(sptr))
              return 0;
          if (parc < 9)
              return 0;

          if (parv[2][0] == 'G')
              type = TKL_KILL | TKL_GLOBAL;
          else if (parv[2][0] == 'Z')
              type = TKL_ZAP | TKL_GLOBAL;
          else if (parv[2][0] == 'z')
              type = TKL_ZAP;
          else if (parv[2][0] == 'k')
              type = TKL_KILL;
          else if (parv[2][0] == 's')
              type = TKL_SHUN | TKL_GLOBAL;
          else if (parv[2][0] == 'f')
              type = TKL_SPAMF;
          else if (parv[2][0] == 'F')
              type = TKL_SPAMF | TKL_GLOBAL;
          else if (parv[2][0] == 'Q')
              type = TKL_NICK | TKL_GLOBAL;
          else if (parv[2][0] == 'q')
              type = TKL_NICK;
          else
              return 0;

          expiry_1 = atol(parv[6]);
          setat_1 = atol(parv[7]);
          reason = parv[8];

          found = 0;
          if ((type & TKL_SPAMF) && (parc >= 11))
          {
              reason = parv[10];
              spamf_tklduration = config_checkval(parv[8], CFG_TIME); /* was: atol(parv[8]); */
          }
          for (tk = tklines[tkl_hash(parv[2][0])]; tk; tk = tk->next)
          {
              if (tk->type == type)
              {
                  if ((tk->type & TKL_NICK) && !stricmp(tk->hostmask, parv[4]))
                  {
                      found = 1;
                      break;
                  }
                  else if (!strcmp(tk->hostmask, parv[4]) && !strcmp(tk->usermask, parv[3]) &&
                    (!(type & TKL_SPAMF) || !stricmp(tk->reason, reason)))
                  {
                      found = 1;
                      break;
                  }
              }
          }
          /* *:Line already exists! */
          if (found == 1)
          {
                  /* SYZTAG: TODO: check for tklreason/tklduration differnces */
                /* do they differ in ANY way? */
                if (type & TKL_NICK)
                {
                    /* for sqline: usermask = H overrides */

                    if (*parv[3] == 'H')
                        *tk->usermask = 'H';
                }

                if ((setat_1 != tk->set_at) || (expiry_1 != tk->expire_at) ||
                    strcmp(tk->reason, reason) || strcmp(tk->setby, parv[5]))
                {
                    /* here's how it goes:
                    * set_at: oldest wins
                      * expire_at: longest wins
                      * reason: highest strcmp wins
                      * setby: highest strcmp wins
                      * We broadcast the result of this back to all servers except
                      * cptr's direction, because cptr will do the same thing and
                      * send it back to his servers (except us)... no need for a
                      * double networkwide flood ;p. -- Syzop
                      */
                    tk->set_at = MIN(tk->set_at, setat_1);
                    if (!tk->expire_at || !expiry_1)
                        tk->expire_at = 0;
                    else
                        tk->expire_at = MAX(tk->expire_at, expiry_1);
                    if (strcmp(tk->reason, reason) < 0)
                    {
                        MyFree(tk->reason);
                        tk->reason = strdup(reason);
                    }
                    if (strcmp(tk->setby, parv[5]) < 0)
                    {
                        MyFree(tk->setby);
                        tk->setby = strdup(parv[5]);
                    }
                    if (tk->type & TKL_NICK)
                    {
                        if (!(*tk->usermask) == 'H')
                            sendto_snomask(SNO_JUNK, "tkl update for %s/reason='%s'/by=%s/set=%ld/expire=%ld [causedby: %s]",
                                tk->hostmask, tk->reason, tk->setby, tk->set_at, tk->expire_at, sptr->name);
                    }
                    else
                        sendto_snomask(SNO_JUNK, "tkl update for %s@%s/reason='%s'/by=%s/set=%ld/expire=%ld [causedby: %s]",
                            tk->usermask, tk->hostmask, tk->reason, tk->setby, tk->set_at, tk->expire_at, sptr->name);
                    if ((parc == 11) && (type & TKL_SPAMF))
                    {
                        /* I decided to only send updates to OPT_TKLEXT in this case,
                        * it's pretty useless to send it also to OPT_NOT_TKLEXT because
                        * spamfilter entries are permanent (no expire time), the only stuff
                        * that can differ for non-opt is the 'setby' and 'setat' field...
                        */
                        sendto_serv_butone_token_opt(cptr, OPT_TKLEXT, sptr->name,
                            MSG_TKL, TOK_TKL,
                            "%s %s %s %s %s %ld %ld %ld %s :%s",
                            parv[1], parv[2], parv[3], parv[4],
                            tk->setby, tk->expire_at, tk->set_at, tk->ptr.spamf->tkl_duration,
                            tk->ptr.spamf->tkl_reason, tk->reason);
                    }
                    else if (type & TKL_GLOBAL)
                        sendto_serv_butone(cptr,
                            ":%s TKL %s %s %s %s %s %ld %ld :%s", sptr->name,
                            parv[1], parv[2], parv[3], parv[4],
                            tk->setby, tk->expire_at, tk->set_at, tk->reason);
              }
              return 0;
          }

          /* there is something fucked here? */
          if ((type & TKL_SPAMF) && (parc >= 11))
            tk = tkl_add_line(type, parv[3], parv[4], reason, parv[5],
                expiry_1, setat_1, spamf_tklduration, parv[9]);
          else
            tk = tkl_add_line(type, parv[3], parv[4], reason, parv[5],
                expiry_1, setat_1, 0, NULL);

          if (tk)
              RunHook5(HOOKTYPE_TKL_ADD, cptr, sptr, tk, parc, parv);

          strncpyzt(gmt, asctime(gmtime((TS *)&setat_1)), sizeof(gmt));
          strncpyzt(gmt2, asctime(gmtime((TS *)&expiry_1)), sizeof(gmt2));
          iCstrip(gmt);
          iCstrip(gmt2);
          switch (type)
          {
            case TKL_KILL:
                strcpy(txt, "K:Line");
                break;
            case TKL_ZAP:
                strcpy(txt, "Z:Line");
                break;
            case TKL_KILL | TKL_GLOBAL:
                strcpy(txt, "G:Line");
                break;
            case TKL_ZAP | TKL_GLOBAL:
                strcpy(txt, "Global Z:line");
                break;
            case TKL_SHUN | TKL_GLOBAL:
                strcpy(txt, "Shun");
                break;
            case TKL_NICK | TKL_GLOBAL:
                strcpy(txt, "Global Q:line");
                break;
            case TKL_NICK:
                strcpy(txt, "Q:line");
                break;
            default:
                strcpy(txt, "Unknown *:Line");
          }
          if (type & TKL_SPAMF)
          {
                char buf[512];
              snprintf(buf, 512,
                  "Spamfilter added: '%s' [target: %s] [action: %s] [reason: %s] on %s GMT (from %s)",
                  reason, parv[3], banact_valtostring(banact_chartoval(*parv[4])),
                  parc >= 10 ? unreal_decodespace(parv[9]) : SPAMFILTER_BAN_REASON,
                  gmt, parv[5]);
              sendto_snomask(SNO_TKL, "*** %s", buf);
              ircd_log(LOG_TKL, "%s", buf);
          } else {
            char buf[512];
              if (expiry_1 != 0)
              {
                if (type & TKL_NICK)
                {
                    if (*parv[3] != 'H')
                        snprintf(buf, 512, "%s added for %s on %s GMT (from %s to expire at %s GMT: %s)",
                            txt, parv[4], gmt, parv[5], gmt2, reason);
                }
                else
                    snprintf(buf, 512, "%s added for %s@%s on %s GMT (from %s to expire at %s GMT: %s)",
                        txt, parv[3], parv[4], gmt, parv[5], gmt2, reason);
              }
              else
              {
                if (type & TKL_NICK)
                {
                    if (*parv[3] != 'H')
                        snprintf(buf, 512, "Permanent %s added for %s on %s GMT (from %s: %s)",
                            txt, parv[4], gmt, parv[5], reason);
                }
                else
                    snprintf(buf, 512, "Permanent %s added for %s@%s on %s GMT (from %s: %s)",
                        txt, parv[3], parv[4], gmt, parv[5], reason);
              }
            if (!((type & TKL_NICK) && *parv[3] == 'H'))
            {
                sendto_snomask(SNO_TKL, "*** %s", buf);
                ircd_log(LOG_TKL, "%s", buf);
            }
          }
          loop.do_bancheck = 1;
          /* Makes check_pings be run ^^  */
          if (type & TKL_GLOBAL)
          {
              if ((parc == 11) && (type & TKL_SPAMF))
              {
                sendto_serv_butone_token_opt(cptr, OPT_TKLEXT, sptr->name,
                    MSG_TKL, TOK_TKL,
                    "%s %s %s %s %s %s %s %s %s :%s",
                    parv[1], parv[2], parv[3], parv[4], parv[5],
                    parv[6], parv[7], parv[8], parv[9], parv[10]);
                sendto_serv_butone_token_opt(cptr, OPT_NOT_TKLEXT, sptr->name,
                    MSG_TKL, TOK_TKL,
                    "%s %s %s %s %s %s %s :%s",
                    parv[1], parv[2], parv[3], parv[4], parv[5],
                    parv[6], parv[7], parv[10]);
            } else
                sendto_serv_butone(cptr,
                    ":%s TKL %s %s %s %s %s %s %s :%s", sptr->name,
                    parv[1], parv[2], parv[3], parv[4], parv[5],
                    parv[6], parv[7], parv[8]);
          } /* TKL_GLOBAL */
          return 0;
      }
      case '-':
          if (!IsServer(sptr) && !IsMe(sptr))
              return 0;
          if (*parv[2] == 'G')
              type = TKL_KILL | TKL_GLOBAL;
          else if (*parv[2] == 'Z')
              type = TKL_ZAP | TKL_GLOBAL;
          else if (*parv[2] == 'z')
              type = TKL_ZAP;
          else if (*parv[2] == 'k')
              type = TKL_KILL;
          else if (*parv[2] == 's')
              type = TKL_SHUN | TKL_GLOBAL;
          else if (*parv[2] == 'Q')
              type = TKL_NICK | TKL_GLOBAL;
          else if (*parv[2] == 'q')
              type = TKL_NICK;
          else if (*parv[2] == 'F')
          {
              if (parc < 8)
              {
                  sendto_realops("[BUG] m_tkl called with bogus spamfilter removal request [F], from=%s, parc=%d",
                      sptr->name, parc);
                  return 0; /* bogus */
              }
              type = TKL_SPAMF | TKL_GLOBAL;
              if (parc >= 11)
                  reason = parv[10];
              else
                  reason = parv[8];
          }
          else if (*parv[2] == 'f')
          {
              if (parc < 8)
              {
                  sendto_realops("[BUG] m_tkl called with bogus spamfilter removal request [f], from=%s, parc=%d",
                      sptr->name, parc);
                  return 0; /* bogus */
              }
              type = TKL_SPAMF;
              if (parc >= 11)
                  reason = parv[10];
              else
                  reason = parv[8];
          }
          else
              return 0;

          switch (type)
          {
            case TKL_KILL:
                strcpy(txt, "K:Line");
                break;
            case TKL_ZAP:
                strcpy(txt, "Z:Line");
                break;
            case TKL_KILL | TKL_GLOBAL:
                strcpy(txt, "G:Line");
                break;
            case TKL_ZAP | TKL_GLOBAL:
                strcpy(txt, "Global Z:line");
                break;
            case TKL_SHUN | TKL_GLOBAL:
                strcpy(txt, "Shun");
                break;
            case TKL_NICK | TKL_GLOBAL:
                strcpy(txt, "Global Q:line");
                break;
            case TKL_NICK:
                strcpy(txt, "Q:line");
                break;
            default:
                strcpy(txt, "Unknown *:Line");
          }

          found = 0;
          for (tk = tklines[tkl_hash(parv[2][0])]; tk; tk = tk->next)
          {
              if (tk->type == type)
              {
                int match = 0;
                if (type & TKL_NICK)
                {
                    if (!stricmp(tk->hostmask, parv[4]))
                        match = 1;
                } else
                if (type & TKL_SPAMF)
                {
                    if (!strcmp(tk->hostmask, parv[4]) && !strcmp(tk->usermask, parv[3]) &&
                        !stricmp(tk->reason, reason))
                        match = 1;
                } else /* all other types... */
                if (!stricmp(tk->hostmask, parv[4]) && !stricmp(tk->usermask, parv[3]))
                    match = 1;

                  if (match)
                  {
                      strncpyzt(gmt, asctime(gmtime((TS *)&tk->set_at)), sizeof(gmt));
                      iCstrip(gmt);
                      /* broadcast remove msg to opers... */
                      if (type & TKL_NICK)
                      {
                        if (!(*parv[3] == 'H'))
                        {
                            sendto_snomask(SNO_TKL, "%s removed %s %s (set at %s - reason: %s)",
                                parv[5], txt, tk->hostmask, gmt, tk->reason);
                            ircd_log(LOG_TKL, "%s removed %s %s (set at %s - reason: %s)",
                                parv[5], txt, tk->hostmask, gmt, tk->reason);
                        }
                      }
                      else if (type & TKL_SPAMF)
                      {
                            sendto_snomask(SNO_TKL, "%s removed Spamfilter '%s' (set at %s)",
                              parv[5], tk->reason, gmt);
                            ircd_log(LOG_TKL, "%s removed Spamfilter '%s' (set at %s)",
                              parv[5], tk->reason, gmt);
                      } else {
                          sendto_snomask(SNO_TKL,
                              "%s removed %s %s@%s (set at %s - reason: %s)",
                              parv[5], txt, tk->usermask,
                              tk->hostmask, gmt, tk->reason);
                          ircd_log(LOG_TKL, "%s removed %s %s@%s (set at %s - reason: %s)",
                              parv[5], txt, tk->usermask, tk->hostmask,
                              gmt, tk->reason);
                      }
                      if (type & TKL_SHUN)
                          tkl_check_local_remove_shun(tk);
                      RunHook5(HOOKTYPE_TKL_DEL, cptr, sptr, tk, parc, parv);
                      tkl_del_line(tk);
                      if (type & TKL_GLOBAL)
                      {
                          if (parc < 8)
                              sendto_serv_butone(cptr,
                                  ":%s TKL %s %s %s %s %s",
                                  sptr->name, parv[1], parv[2], parv[3], parv[4], parv[5]);
                          else
                              sendto_serv_butone(cptr,
                                  ":%s TKL %s %s %s %s %s %s %s :%s",
                                  sptr->name, parv[1], parv[2], parv[3], parv[4], parv[5],
                                  parv[6], parv[7], reason);
                      }
                      break;
                  }
              }
          }

          break;

      case '?':
          if (IsAnOper(sptr))
              tkl_stats(sptr,0,NULL);
    }
    return 0;
}

/* execute_ban_action, a tkl helper. (Syzop/2003)
 * PARAMETERS:
 * sptr:    the client which is affected
 * action:  type of ban (BAN_ACT*)
 * reason:  ban reason
 * duration: duration of ban in seconds
 * WHAT IT DOES:
 * This function will shun/kline/gline/zline the user.
 * If the action field is 0 (BAN_ACT_KILL) the user is
 * just killed (and the time parameter is ignored).
 * ASSUMES:
 * This function assumes that sptr is locally connected.
 * RETURN VALUE:
 * -1 in case of block/tempshun, FLUSH_BUFFER in case of
 * kill/zline/gline/etc.. (you should NOT read from 'sptr'
 * after you got FLUSH_BUFFER!!!)
 */
int place_host_ban(aClient *sptr, int action, char *reason, long duration)
{
    switch(action)
    {
        case BAN_ACT_TEMPSHUN:
            /* We simply mark this connection as shunned and do not add a ban record */
            sendto_snomask(SNO_TKL, "Temporary shun added at user %s (%s@%s) [%s]",
                sptr->name,
                sptr->user ? sptr->user->username : "unknown",
                sptr->user ? sptr->user->realhost : GetIP(sptr),
                reason);
            SetShunned(sptr);
            break;
        case BAN_ACT_SHUN:
        case BAN_ACT_KLINE:
        case BAN_ACT_ZLINE:
        case BAN_ACT_GLINE:
        case BAN_ACT_GZLINE:
        {
            char hostip[128], mo[100], mo2[100];
            char *tkllayer[9] = {
                me.name,    /*0  server.name */
                "+",        /*1  +|- */
                "?",        /*2  type */
                "*",        /*3  user */
                NULL,        /*4  host */
                NULL,
                NULL,        /*6  expire_at */
                NULL,        /*7  set_at */
                NULL        /*8  reason */
            };

            strlcpy(hostip, GetIP(sptr), sizeof(hostip));

            if (action == BAN_ACT_KLINE)
                tkllayer[2] = "k";
            else if (action == BAN_ACT_ZLINE)
                tkllayer[2] = "z";
            else if (action == BAN_ACT_GZLINE)
                tkllayer[2] = "Z";
            else if (action == BAN_ACT_GLINE)
                tkllayer[2] = "G";
            else if (action == BAN_ACT_SHUN)
                tkllayer[2] = "s";
            tkllayer[4] = hostip;
            tkllayer[5] = me.name;
            if (!duration)
                strcpy(mo, "0"); /* perm */
            else
                ircsprintf(mo, "%li", duration + TStime());
            ircsprintf(mo2, "%li", TStime());
            tkllayer[6] = mo;
            tkllayer[7] = mo2;
            tkllayer[8] = reason;
            m_tkl(&me, &me, 9, tkllayer);
            if (action == BAN_ACT_SHUN)
            {
                find_shun(sptr);
                return -1;
            } else
                return find_tkline_match(sptr, 0);
        }
        case BAN_ACT_KILL:
        default:
            return exit_client(sptr, sptr, sptr, reason);
    }
    return -1;
}

/** Checks if 'target' is on the spamfilter exception list.
 * RETURNS 1 if found in list, 0 if not.
 */
int target_is_spamexcept(char *target)
{
SpamExcept *e;

    for (e = iConf.spamexcept; e; e = e->next)
    {
        if (!match(e->name, target))
            return 1;
    }
    return 0;
}

/** dospamfilter: executes the spamfilter onto the string.
 * str:        the text (eg msg text, notice text, part text, quit text, etc
 * type:    the spamfilter type (SPAMF_*)
 * RETURN VALUE:
 * 0 if not matched, non-0 if it should be blocked.
 * Return value can be FLUSH_BUFFER (-2) which means 'sptr' is
 * _NOT_ valid anymore so you should return immediately
 * (like from m_message, m_part, m_quit, etc).
 */
 
int dospamfilter(aClient *sptr, char *str_in, int type, char *target)
{
aTKline *tk;
char *str;

    if (type == SPAMF_USER)
        str = str_in;
    else
        str = (char *)StripControlCodes(str_in);

    /* (note: using sptr->user check here instead of IsPerson()
    * due to SPAMF_USER where user isn't marked as client/person yet.
    */
    if (!sptr->user || IsAnOper(sptr) || IsULine(sptr))
        return 0;

    for (tk = tklines[tkl_hash('F')]; tk; tk = tk->next)
    {
        if (!(tk->subtype & type))
            continue;
        if (!regexec(&tk->ptr.spamf->expr, str, 0, NULL, 0))
        {
            /* matched! */
            char buf[1024];
            char targetbuf[48];
            if (target) {
                targetbuf[0] = ' ';
                strlcpy(targetbuf+1, target, sizeof(targetbuf)-1); /* cut it off */
            } else
                targetbuf[0] = '\0';

            /* Hold on.. perhaps it's on the exceptions list... */
            if (target && target_is_spamexcept(target))
                return 0; /* No problem! */

            ircsprintf(buf, "[Spamfilter] %s!%s@%s matches filter '%s': [%s%s: '%s'] [%s]",
                sptr->name, sptr->user->username, sptr->user->realhost,
                tk->reason,
                spamfilter_inttostring_long(type), targetbuf, str,
                unreal_decodespace(tk->ptr.spamf->tkl_reason));

            sendto_snomask(SNO_SPAMF, "%s", buf);
            sendto_serv_butone_token(NULL, me.name, MSG_SENDSNO, TOK_SENDSNO, "S :%s", buf);
            ircd_log(LOG_SPAMFILTER, "%s", buf);

            if (tk->ptr.spamf->action == BAN_ACT_BLOCK)
            {
                switch(type)
                {
                    case SPAMF_USERMSG:
                    case SPAMF_USERNOTICE:
                        sendnotice(sptr, "Message to %s blocked: %s",
                            target, unreal_decodespace(tk->ptr.spamf->tkl_reason));
                        break;
                    case SPAMF_CHANMSG:
                    case SPAMF_CHANNOTICE:
                        sendto_one(sptr, ":%s 404 %s %s :Message blocked: %s",
                            me.name, sptr->name, target,
                            unreal_decodespace(tk->ptr.spamf->tkl_reason));
                        break;
                    case SPAMF_DCC:
                        sendnotice(sptr, "DCC to %s blocked: %s",
                            target, unreal_decodespace(tk->ptr.spamf->tkl_reason));
                        break;
                    case SPAMF_AWAY:
                        /* hack to deal with 'after-away-was-set-filters' */
                        if (sptr->user->away && !strcmp(str_in, sptr->user->away))
                        {
                            /* free away & broadcast the unset */
                            MyFree(sptr->user->away);
                            sptr->user->away = NULL;
                            sendto_serv_butone_token(sptr, sptr->name, MSG_AWAY, TOK_AWAY, "");
                        }
                        break;
                    case SPAMF_TOPIC:
                        //...
                        sendnotice(sptr, "Setting of topic on %s to that text is blocked: %s",
                            target, unreal_decodespace(tk->ptr.spamf->tkl_reason));
                        break;
                    default:
                        break;
                }
                return -1;
            } else
            if (tk->ptr.spamf->action == BAN_ACT_DCCBLOCK)
            {
                if (type == SPAMF_DCC)
                {
                    sendnotice(sptr, "DCC to %s blocked: %s",
                        target, unreal_decodespace(tk->ptr.spamf->tkl_reason));
                    sendnotice(sptr, "*** You have been blocked from sending files, "
                              "reconnect to regain permission to send files");
                    sptr->flags |= FLAGS_DCCBLOCK;
                }
                return -1;
            } else
            if (tk->ptr.spamf->action == BAN_ACT_VIRUSCHAN)
            {
                char *xparv[3], chbuf[CHANNELLEN + 16];
                aChannel *chptr;
                int ret;
               
                if (IsVirus(sptr)) /* Already tagged */
                    return 0;
                ircsprintf(buf, "0,%s", SPAMFILTER_VIRUSCHAN);
                xparv[0] = sptr->name;
                xparv[1] = buf;
                xparv[2] = NULL;
                /* RECURSIVE CAUTION in case we ever add blacklisted chans */
                spamf_ugly_vchanoverride = 1;
                ret = do_cmd(sptr, sptr, "JOIN", 2, xparv);
                spamf_ugly_vchanoverride = 0;
                if (ret == FLUSH_BUFFER)
                    return FLUSH_BUFFER; /* don't ask me how we could have died... */
                sendnotice(sptr, "You are now restricted to talking in %s: %s",
                    SPAMFILTER_VIRUSCHAN, unreal_decodespace(tk->ptr.spamf->tkl_reason));
                /* todo: send notice to channel? */
                chptr = find_channel(SPAMFILTER_VIRUSCHAN, NULL);
                if (chptr)
                {
                    ircsprintf(chbuf, "@%s", chptr->chname);
                    ircsprintf(buf, "[Spamfilter] %s matched filter '%s' [%s%s] [%s]",
                        sptr->name, tk->reason, spamfilter_inttostring_long(type), targetbuf,
                        unreal_decodespace(tk->ptr.spamf->tkl_reason));
                    sendto_channelprefix_butone_tok(NULL, &me, chptr, PREFIX_OP|PREFIX_ADMIN|PREFIX_OWNER,
                        MSG_NOTICE, TOK_NOTICE, chbuf, buf, 0);
                }
                SetVirus(sptr);
                return -1;
            } else
                return place_host_ban(sptr, tk->ptr.spamf->action,
                    unreal_decodespace(tk->ptr.spamf->tkl_reason), tk->ptr.spamf->tkl_duration);
        }
    }
    return 0;
}


Freak 25 Nisan 2007 07:55

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
Arkadaşlar, neyi nereye atacağınızı bilmiyorsanız daha detaylı bilgi almak için bu başlık altında sorularınızı yöneltebilirsiniz.

Faydalı paylaşımlar..

RooTMasteR 02 Mayıs 2007 22:08

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
öncelikle Paylaşım için tşkler ama Bu ircop.c dosyası nerede ben bulamadım bi yardım etsen

MaRaShaL 13 Mayıs 2007 04:04

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
Bende bunlar kurulu:)

ysfm 13 Mayıs 2007 08:55

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
Alıntı:

MaRaShaL Nickli Üyeden Alıntı
Bende bunlar kurulu:)

nasıl kurulu herkezde kurulu zaten

Nurullahoruc 13 Mayıs 2007 10:36

Yanıt: /* Yuzukchat.Net IRC(d) Dosyaları */
 
evet ) Herkeste KuruLu Yinede Confolarak Ziplese Di Daha iyi Olacaqini saniyordum

raskolnikov 13 Mayıs 2007 13:40

Cevap: /* Yuzukchat.Net IRC(d) Dosyaları */
 
rootmaster m_ircops.c , Unreal/src/modules icinde.


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

Powered by vBulletin® Version 3.8.8 Beta 3
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Search Engine Friendly URLs by vBSEO
Copyright ©2004 - 2024 IRCForumlari.Net