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

IRCForumları - IRC ve mIRC Kullanıcılarının Buluşma Noktası (https://www.ircforumlari.net/)
-   Unreal IRCd (https://www.ircforumlari.net/unreal-ircd/)
-   -   Kişiye özel HOST (https://www.ircforumlari.net/unreal-ircd/418030-kisiye-ozel-host.html)

Elvent 10 Ekim 2011 17:14

Kişiye özel HOST
 
Araştırma yaptım sunucuda ancak 1 tane konu buldum main.c ile alakalı ve yanlış belkide ben yapamadım.
Sorunum şudur ki ; Network Adminlerden kişiye özel Host Örnek ; Mehmet girdiğinde oper şifresini => [Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]
ALli girdiginde => [Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

gibi olmasını nasıl sağlayabilirim ?
(yanlış yere açtıysam affola)

mStf 10 Ekim 2011 18:46

Cevap: Kişiye özel HOST
 
Kod:

cd irc*
cd modul*
cd nickserv
pico main.c

içerisinde.

Kod:

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

satırı altına

Kod:

send_cmd(s_NickServ, "CHGHOST mStf SystemAdmin.XX.Com", u->nick, u->nick);
olarak ekleye bilirsin.

Elvent 10 Ekim 2011 18:55

Cevap: Kişiye özel HOST
 
Bunun aynısını yapmıştım ama hata vermişti. belkide ben yanlış yaptım. Yine deneyeceğim. Çok teşekkür ederim yardımın için çok sağol

SNOOPY 10 Ekim 2011 19:40

Cevap: Kişiye özel HOST
 
Aldığınız hatayı verirseniz, hatanın nerede olduğunu daha iyi söyleyebiliriz.

A_s_c_i_i--- 13 Ekim 2011 12:08

Cevap: Kişiye özel HOST
 
Örnek : A_s_c_i_i--- Kimlik Bilgisi: [Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

Ne Gereği var mIRC Scripitinin Aliases bölümüne Bu kodu ekle /oper /oper $1- | sethost Admin.Ali.Com.Tr Oper Oldunmu Bu Hostu alırsın..

Elvent 13 Ekim 2011 17:31

Cevap: Kişiye özel HOST
 
Alıntı:

A_s_c_i_i--- Nickli Üyeden Alıntı (Mesaj 1040869651)
Örnek : A_s_c_i_i--- Kimlik Bilgisi: [Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

Ne Gereği var mIRC Scripitinin Aliases bölümüne Bu kodu ekle /oper /oper $1- | sethost Admin.Ali.Com.Tr Oper Oldunmu Bu Hostu alırsın..

Eğer bu lazım olsaydı emin olun bunu isterdim ;)

dEathLeSs 13 Ekim 2011 18:03

Cevap: Kişiye özel HOST
 
cd ircservices-*
cd modules/nickserv
pico main.c

Kod:

notice_lang(s_NickServ, u, NICK_IDENTIFY_SUCCEEDED);
satırının altına

Kod:

if(!stricmp("Ali", u->nick)) {
send_cmd(s_NickServ, "CHGident %s Ali", u->nick);
send_cmd(s_NickServ, "CHGHOST %s Ali.Com.Tr", u->nick);
}

ctrL x + y

make
make install
servisleri restartla.

Rhall 13 Ekim 2011 18:35

Cevap: Kişiye özel HOST
 
Değişmiyor

dEathLeSs 13 Ekim 2011 18:53

Cevap: Kişiye özel HOST
 
Ben de sorunsuz calısıyor.

Elvent 13 Ekim 2011 19:00

Cevap: Kişiye özel HOST
 
Yapmış oldugumu göstereyim size aşağıda

Kod:

/* Main NickServ module.
 *
 * IRC Services is copyright (c) 1996-2007 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 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_admin, -1,
                -1, NICK_OPER_HELP_DROPNICK },
    { "DROPEMAIL",do_dropemail,is_services_admin, -1,
                -1, NICK_OPER_HELP_DROPEMAIL },
    { "DROPEMAIL-CONFIRM", do_dropemail_confirm, is_services_admin, -1,
                -1, NICK_OPER_HELP_DROPEMAIL },
    { "GETPASS",  do_getpass,  is_services_admin, -1,
                -1, NICK_OPER_HELP_GETPASS },
    { "FORBID",  do_forbid,  is_services_admin, -1,
                -1, NICK_OPER_HELP_FORBID },
    { "SUSPEND",  do_suspend,  is_services_admin, -1,
                -1, NICK_OPER_HELP_SUSPEND },
    { "UNSUSPEND",do_unsuspend,is_services_admin, -1,
                -1, NICK_OPER_HELP_UNSUSPEND },
#ifdef DEBUG_COMMANDS
    { "LISTNICK", do_listnick, is_services_root, -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(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);
        if(!stricmp("Ali", u->nick)) {
send_cmd(s_NickServ, "CHGident %s Kahr", u->nick);
send_cmd(s_NickServ, "CHGHOST %s Vatansever.xxxx..gen.tr", 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;

    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;
        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);
            strftime_lang(buf, sizeof(buf), u->ngi,
                          STRFTIME_DATE_TIME_FORMAT, ni->last_seen);
            notice_lang(s_NickServ, u, NICK_INFO_LAST_SEEN, buf);
        }

        strftime_lang(buf, sizeof(buf), u->ngi, STRFTIME_DATE_TIME_FORMAT,
                      ni->time_registered);
        notice_lang(s_NickServ, u, NICK_INFO_TIME_REGGED, buf);
        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->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);
            }
        }
        if (ngi->info)
            notice_lang(s_NickServ, u, NICK_INFO_INFO, ngi->info);
        *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;
}

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


bir yanlışlık mı yapmısım cozemedim


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

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