#include "module.h"
#define AUTHOR "Dj-RuFfy"
#define VERSION "$Id: ircd_vhostserv.c v2.0.2 04-03-2008 Dj-RuFfy $"
/* ------------------------------------------------------------------------------------
* Name : ircd_vhostserv.c
* Author : Dj-RuFfy [Dj-RuFfy@easynets.com]
* Version : 2.0.2
* Date : 2nd October, 2006
* Update : 23th March, 2008
* ------------------------------------------------------------------------------------
* Description:
*
* This module create a new services client/bot. The bot have its own fantasy command
* !vhost and !groupvhost. The bot will answer the fantasy commands ONLY on its own channel.
* ------------------------------------------------------------------------------------
* Providing Fantasy Commands:
*
* !vhost some.vhost.here - set a vhost for users
* !groupvhost group.vhost.here - set vhost for all users in group
* !vhost restricted - list all restricted vhosts
* ------------------------------------------------------------------------------------
* 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 2 of the License, 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.
* ------------------------------------------------------------------------------------
* Change Log:
* v1.0.0 - First Public Release
*
* v1.0.1 -
* a) Fixed a few mem leaks
* b) Fixed a bug on vIdent
*
* v1.0.2 -
* a) Minor code update
* b) Added modload prevention for unsupported IRCd's. The module will not load on
* unsupported IRCd's (bahamut, dreamforge, hybrid, ratbox).
* c) Added Tokens support
* d) Added checked for vHost channel before modload. If the vHost channel is not
* registered, the module will not load.
*
* v2.0.0 - Fixed a crash bug when the line starts with a space in it.
*
* v2.0.1 -
* a) Added !groupvhost fantasy command for setting all users vhost in a group
* b) Added configuration directive support
* c) Added vhost flood protection; will now kick/ban users after a vhost is set
* d) Remove !hs on|off fantasy command
* e) Module will not load on version less than 1.7.21
*
* v2.0.2 -
* a) Added check for unallowed vhosts.
* b) Added options to kick-ban users who request unallowed vhosts.
* c) Added fantasy command "!vhost restricted" to list all restricted hosts so that
* a user can be warned first before kickban.
* ------------------------------------------------------------------------------------
* Module made possible using vhost fantasy module by Trystan
* ------------------------------------------------------------------------------------
* This module have 10 configurable options.
*
* Copy/Paste below on services.conf
# BotNick
[REQUIRED]
# Module: ircd_vhostserv
# Define what nick the bot will have.
#
BotNick "vHostServ"
# BotIdent [REQUIRED]
# Define the bot identd.
#
BotIdent "Bot"
# BotHost [REQUIRED]
# Define the bot hostname or vhost.
#
BotHost "LocalHost-IRC.Host.Bot"
# BotReal [REQUIRED]
# Define the bot realname.
#
BotReal "/msg vHostServ Help"
# vHostChannel [REQUIRED]
# Define your network vhost channel.
#
vHostChannel "#vHost"
# BanClearTime [REQUIRED]
# Sets the timeout period after which a particular ban set by
# the bot will be removed.
#
BanClearTime 5h
# BotModes [OPTIONAL]
# Define what modes the bot will have.
#
BotModes "+SqB"
# JoinLogChannel [OPTIONAL]
# Define this if you want the bot to automatically
# join services log channel.
#
JoinLogChannel
# RestrictHosts [RECOMMENDED]
# Define unallowed vhosts which will be match using
# wildcards. This is not case-sensitive.
#
RestrictHosts "*ircop* *admin* *root* *staff* *some.wild.card*"
# KickBanRestrictHosts [OPTIONAL]
# Define this to kick banned users who request
# restricted hosts. If this option is enabled
# RestrictHosts setting is required.
#
KickBanRestrictHosts
# End of config: ircd_vhostserv
*/
char *s_vHostServ;
char *BotIdent;
char *BotHost;
char *BotReal;
char *BotModes;
char *BotChan;
char *RestrictHosts;
char **RestrictHostList;
int RestrictHostNum;
int KickBanRestrictHosts;
int vHostServBanClearTime;
int JoinLogChannel;
int check_banned_vhost(char *vhost);
int mEventReload(int argc, char **argv);
int mLoadConfig(void);
int do_privmsg(char *source, int argc, char **argv);
int vhost_fantasy(User *u, char *cur_buffer);
int vhost_fantasy_group(User *u, char *cur_buffer);
int do_help(User *u);
int delBan(int argc, char **argv);
void addClient(void);
void delClient(void);
void addMessageList(void);
void addBan(Channel *c, time_t timeout, char *nick);
void Vhostserv(User *u, char *buf);
void VBotChanmsgs(User *u, ChannelInfo *ci, char *buf);
CommandHash *Vhostserv_cmdTable[MAX_CMD_HASH];
extern int do_hs_sync(NickCore *nc, char *vIdent, char *hostmask, char *creator, time_t time);
int AnopeInit(int argc, char **argv)
{
Message *msg = NULL;
EvtHook *hook = NULL;
ChannelInfo *ci;
int status = 0;
msg = createMessage("PRIVMSG", do_privmsg);
status = moduleAddMessage(msg, MOD_HEAD);
if (status != MOD_ERR_OK) {
alog("ircd_vhostserv: Unable to bind to PRIVMSG");
return MOD_STOP;
}
hook = createEventHook(EVENT_RELOAD, mEventReload);
status = moduleAddEventHook(hook);
if (status != MOD_ERR_OK) {
alog("ircd_vhostserv: Unable to hook to EVENT_RELOAD");
return MOD_STOP;
}
if (UseTokens) {
msg = createMessage("!", do_privmsg);
status = moduleAddMessage(msg, MOD_HEAD);
if (status != MOD_ERR_OK) {
alog("ircd_vhostserv: Unable to bind to PRIVMSG");
return MOD_STOP;
}
}
if (!ircd->vhost) {
alog("ircd_vhostserv: \2IRCd not supported.\2");
return MOD_STOP;
}
if (!moduleMinVersion(1,7,21,1341)) {
alog("ircd_vhostserv: Your version of Anope isn't supported. This module require Anope-1.7.21 (1341) or later. Please update to a newer release.");
return MOD_STOP;
}
if (mLoadConfig()) {
return MOD_STOP;
}
addClient();
addMessageList();
if (!(ci = cs_findchan(BotChan))) {
alog("ircd_vhostserv: Error: \2vHostChannel\2 is not defined in services configuration file or vHostChannel is not registered. You need to defined or register the vHostChannel first for this module to work.");
return MOD_STOP;
} else {
anope_cmd_join(s_vHostServ, ci->name, time(NULL));
anope_cmd_bot_chan_mode(s_vHostServ, ci->name);
}
if (LogChannel) {
if (JoinLogChannel) {
anope_cmd_join(s_vHostServ, LogChannel, time(NULL));
anope_cmd_bot_chan_mode(s_vHostServ, LogChannel);
}
}
moduleAddAuthor(AUTHOR);
moduleAddVersion(VERSION);
return MOD_CONT;
}
void AnopeFini(void)
{
int idx;
delClient();
if (s_vHostServ)
free(s_vHostServ);
if (BotIdent)
free(BotIdent);
if (BotHost)
free(BotHost);
if (BotReal)
free(BotReal);
if (BotModes)
free(BotModes);
if (BotChan)
free(BotChan);
if (RestrictHostNum) {
for (idx = 0; idx < RestrictHostNum; idx++) {
free(RestrictHostList[idx]);
}
}
alog("ircd_vhostserv: Module Unloaded.");
}
void addClient(void)
{
if (BotModes) {
anope_cmd_bot_nick(s_vHostServ, BotIdent, BotHost, BotReal, BotModes);
} else {
anope_cmd_bot_nick(s_vHostServ, BotIdent, BotHost, BotReal, ircd->botservmode);
}
}
void delClient(void)
{
anope_cmd_quit(s_vHostServ, "Quit: Module Unloaded!");
}
int do_help(User *u)
{
anope_cmd_notice(s_vHostServ, u->nick, "Syntax: \2!vhost \037Your.vHost.Here\037\2");
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "Sets a vhost.");
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "Syntax: \2!groupvhost \037Group.vHost.Here\037\2");
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "This command allows user to set the vhost of their");
anope_cmd_notice(s_vHostServ, u->nick, "CURRENT nick to be the vhost for all nicks in the same");
anope_cmd_notice(s_vHostServ, u->nick, "group.");
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "Syntax: \2!vhost \037restricted\037\2");
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "This command allows user to see all hosts which");
anope_cmd_notice(s_vHostServ, u->nick, "are not allowed to used. If a restricted hosts");
anope_cmd_notice(s_vHostServ, u->nick, "is chosen %s will trigger a \2kick-ban\2", s_vHostServ);
anope_cmd_notice(s_vHostServ, u->nick, "combination depending on the network settings.");
if (ircd->vident) {
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "Note: \2vIdentd\2 is supported by the IRCd.");
} else {
anope_cmd_notice(s_vHostServ, u->nick, " ");
anope_cmd_notice(s_vHostServ, u->nick, "Note: This Network does not support vIdentd.");
}
return MOD_CONT;
}
int do_privmsg(char *source, int argc, char **argv)
{
ChannelInfo *ci;
User *u;
char *s;
if (argc != 2) {
return MOD_CONT;
}
if (!(u = finduser(source))) {
return MOD_CONT;
}
if (!stricmp(BotChan, argv[0])) {
if (s_vHostServ && (ci = cs_findchan(BotChan))) {
if (!(ci->flags & CI_VERBOTEN) && ci->c && s_vHostServ) {
VBotChanmsgs(u, ci, argv[1]);
}
}
}
s = strchr(argv[0], '@');
if (s) {
*s++ = 0;
if (stricmp(s, ServerName) != 0) {
return MOD_CONT;
}
}
if ((stricmp(argv[0], s_vHostServ)) == 0) {
Vhostserv(u, argv[1]);
return MOD_STOP;
} else {
return MOD_CONT;
}
}
void addMessageList(void)
{
Command *c;
c = createCommand("HELP", do_help, NULL, -1, -1, -1, -1, -1);
moduleAddCommand(Vhostserv_cmdTable, c, MOD_HEAD);
}
void Vhostserv(User *u, char *buf)
{
char *cmd, *s;
cmd = myStrGetToken(buf, ' ', 0);
s = myStrGetToken(buf, ' ', 1);
if (!cmd) {
return;
} else if (stricmp(cmd, "\1PING") == 0) {
if (!s)
s = "\1";
anope_cmd_ctcp(s_vHostServ, u->nick, "\1PING %s", s);
} else if (skeleton) {
notice_lang(s_vHostServ, u, SERVICE_OFFLINE, s_vHostServ);
} else {
mod_run_cmd(s_vHostServ, u, Vhostserv_cmdTable, cmd);
}
if (cmd) free(cmd);
if (s) free(s);
}
int mEventReload(int argc, char **argv)
{
int ret = 0;
if (argc >= 1) {
if (!stricmp(argv[0], EVENT_START)) {
ret = mLoadConfig();
}
}
if (ret) {
alog("ircd_vhostserv: \2ERROR\2: An error has occured while reloading the configuration file!");
}
return MOD_CONT;
}
int mLoadConfig(void)
{
int i, idx;
int retval = 0;
char *s;
Directive directives[][1] = {
{{"BotNick", {{PARAM_STRING, 0, &s_vHostServ}}}},
{{"BotIdent", {{PARAM_STRING, 0, &BotIdent}}}},
{{"BotHost", {{PARAM_STRING, 0, &BotHost}}}},
{{"BotReal", {{PARAM_STRING, 0, &BotReal}}}},
{{"BotModes", {{PARAM_STRING, 0, &BotModes}}}},
{{"vHostChannel", {{PARAM_STRING, 0, &BotChan}}}},
{{"JoinLogChannel", {{PARAM_SET, 0, &JoinLogChannel}}}},
{{"BanClearTime", {{PARAM_TIME, 0, &vHostServBanClearTime}}}},
{{"RestrictHosts", {{PARAM_STRING, 0, &RestrictHosts}}}},
{{"KickBanRestrictHosts", {{PARAM_SET, 0, &KickBanRestrictHosts}}}},
};
for (i = 0; i < 10; i++)
moduleGetConfigDirective(directives[i]);
if (!s_vHostServ) {
alog("ircd_vhostserv: Error: \2BotNick\2 is missing on services configuration file");
retval = 1;
}
if (!BotIdent) {
alog("ircd_vhostserv: Error: \2BotIdent\2 is missing on services configuration file");
retval = 1;
}
if (!BotHost) {
alog("ircd_vhostserv: Error: \2BotHost\2 is missing on services configuration file");
retval = 1;
}
if (!BotReal) {
alog("ircd_vhostserv: Error: \2BotReal\2 is missing on services configuration file");
retval = 1;
}
if (!BotChan) {
alog("ircd_vhostserv: Error: \2vHostChannel\2 is missing on services configuration file");
retval = 1;
}
if (!vHostServBanClearTime) {
alog("ircd_vhostserv: Error: \2BanClearTime\2 is missing on services configuration file");
retval = 1;
}
if (RestrictHostNum) {
for (idx = 0; idx < RestrictHostNum; idx++) {
free(RestrictHostList[idx]);
}
}
if (RestrictHosts) {
RestrictHostNum = 0;
s = strtok(RestrictHosts, " ");
do {
if (s) {
RestrictHostNum++;
RestrictHostList = realloc(RestrictHostList, sizeof(char *) * RestrictHostNum);
RestrictHostList[RestrictHostNum - 1] = sstrdup(s);
}
} while ((s = strtok(NULL, " ")));
}
return retval;
}
void VBotChanmsgs(User *u, ChannelInfo *ci, char *buf)
{
int idx, count = 0;
char *cmd = myStrGetToken(buf, ' ', 0);
char *param = myStrGetToken(buf, ' ', 1);
if (!cmd)
return;
if (!stricmp(cmd, "!vhost")) {
if (!param) {
anope_cmd_notice(s_vHostServ, u->nick, "Syntax: \2!vhost\2 \037Your.vHost.Here\037");
} else if (!stricmp(param, "restricted")) {
anope_cmd_notice(s_vHostServ, u->nick, "The following *hosts* are not allowed:");
anope_cmd_notice(s_vHostServ, u->nick, "\037Num\037 \037Restricted\037");
for (idx = 0; idx < RestrictHostNum; idx++) {
count++;
anope_cmd_notice(s_vHostServ, u->nick, "%3d %s", count, RestrictHostList[idx]);
}
anope_cmd_notice(s_vHostServ, u->nick, "End of List.");
} else {
vhost_fantasy(u, param);
}
}
if (!stricmp(cmd, "!groupvhost")) {
if (!param) {
anope_cmd_notice(s_vHostServ, u->nick, "Syntax: \2!groupvhost\2 \037Group.vHost.Here\037");
} else if (!stricmp(param, "restricted")) {
anope_cmd_notice(s_vHostServ, u->nick, "See \2!vhost restricted\2");
} else {
vhost_fantasy_group(u, param);
}
}
if (cmd)
free(cmd);
if (param)
free(param);
}
void addBan(Channel *c, time_t timeout, char *nick)
{
char *av[3];
char *cb[2];
cb[0] = c->name;
cb[1] = nick;
av[0] = sstrdup("+b");
av[1] = nick;
anope_cmd_mode(s_vHostServ, c->name, "+b %s", av[1]);
chan_set_modes(s_vHostServ, c, 2, av, 1);
free(av[0]);
moduleAddCallback("ircd_vhostserv: delBan", time(NULL) + timeout, delBan, 2, cb);
}
int delBan(int argc, char **argv)
{
char *av[3];
Channel *c;
av[0] = sstrdup("-b");
av[1] = argv[1];
if ((c = findchan(BotChan)) && c->ci) {
anope_cmd_mode(s_vHostServ, c->name, "-b %s", av[1]);
chan_set_modes(s_vHostServ, c, 2, av, 1);
}
free(av[0]);
return MOD_CONT;
}
int vhost_fantasy(User *u, char *cur_buffer)
{
Channel *c;
User *u2 = NULL;
char *nick = u->nick;
char *rawhostmask = cur_buffer;
char *hostmask = smalloc(HOSTMAX);
NickAlias *na;
int32 tmp_time;
char *s;
int idx;
char *vIdent = NULL;
if (!nick || !rawhostmask) {
return MOD_STOP;
}
if (!(c = findchan(BotChan))) {
return MOD_STOP;
}
if (!(u2 = finduser(u->nick))) {
return MOD_STOP;
}
vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */
if (vIdent) {
rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */
if (!rawhostmask) {
return MOD_STOP;
}
if (strlen(vIdent) > USERMAX - 1) {
anope_cmd_privmsg(s_vHostServ, BotChan,
"The Ident is too long, please use an ident shorter than %d characters.", USERMAX);
if (vIdent)
free(vIdent);
return MOD_STOP;
} else {
for (s = vIdent; *s; s++) {
if (!isvalidchar(*s)) {
anope_cmd_privmsg(s_vHostServ, BotChan,
"A vhost ident must be in the format of a valid ident.");
if (vIdent)
free(vIdent);
return MOD_STOP;
}
}
}
if (!ircd->vident) {
anope_cmd_privmsg(s_vHostServ, BotChan, "This Network does not support vIdentd.");
if (vIdent)
free(vIdent);
return MOD_STOP;
}
}
if (strlen(rawhostmask) < HOSTMAX - 1) {
snprintf(hostmask, HOSTMAX - 1, "%s", rawhostmask);
} else {
anope_cmd_privmsg(s_vHostServ, BotChan,
"The vhost is too long, please use a host shorter than \2%d\2 characters.", HOSTMAX);
if (vIdent)
free(vIdent);
return MOD_STOP;
}
if (!isValidHost(hostmask, 3)) {
anope_cmd_privmsg(s_vHostServ, BotChan, "A vhost must be in the format of a valid hostmask.");
if (vIdent)
free(vIdent);
free(hostmask);
return MOD_STOP;
}
if (!check_banned_vhost(hostmask)) {
if (KickBanRestrictHosts && RestrictHosts) {
if (vHostServBanClearTime > 0) {
addBan(c, vHostServBanClearTime, nick);
if (is_on_chan(c, u2)) {
anope_cmd_kick(s_vHostServ, c->ci->name, nick,
"The vhost you requested is not allowed. Banned for %d seconds", vHostServBanClearTime);
}
}
} else {
anope_cmd_privmsg(s_vHostServ, BotChan, "The requested vhost is not allowed, please choose another.");
}
if (vIdent) {
free(vIdent);
}
free(hostmask);
return MOD_STOP;
}
tmp_time = time(NULL);
if ((na = findnick(nick))) {
if (na->status & NS_VERBOTEN) {
anope_cmd_privmsg(s_vHostServ, BotChan, "Cannot set vhost for forbidden nick %s", nick);
if (vIdent)
free(vIdent);
if (hostmask)
free(hostmask);
return MOD_STOP;
}
if (!nick_identified(u)) {
notice_lang(s_vHostServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
if (vIdent)
free(vIdent);
if (hostmask)
free(hostmask);
return MOD_STOP;
}
if (vIdent && ircd->vident) {
alog("vHost for user \2%s\2 set to \2%s@%s\2 by %s", nick, vIdent, hostmask, s_vHostServ);
} else {
alog("vHost for user \2%s\2 set to \2%s\2 by %s", nick, hostmask, s_vHostServ);
}
addHostCore(nick, vIdent, hostmask, u->nick, tmp_time);
anope_cmd_vhost_on(nick, vIdent, hostmask);
set_lastmask(u2);
if (vHostServBanClearTime > 0) {
addBan(c, vHostServBanClearTime, nick);
if (is_on_chan(c, u2)) {
anope_cmd_kick(s_vHostServ, c->ci->name, nick, "Done. You can request a new vhost after %d seconds from your last one. Banned for %d seconds", vHostServBanClearTime, vHostServBanClearTime);
}
}
if (vIdent && ircd->vident) {
anope_cmd_notice(s_vHostServ, nick, "vHost for \2%s\2 set to \2%s@%s\2 and activated.", nick, vIdent, hostmask);
} else {
anope_cmd_notice(s_vHostServ, nick, "vHost for \2%s\2 set to \2%s\2 and activated.", nick, hostmask);
}
} else {
anope_cmd_privmsg(s_vHostServ, BotChan, "\2%s\2, please register your nick first.", nick);
}
if (vIdent)
free(vIdent);
if (hostmask)
free(hostmask);
return MOD_CONT;
}
int vhost_fantasy_group(User *u, char *cur_buffer)
{
char *nick = u->nick;
char *rawhostmask = cur_buffer;
char *hostmask = smalloc(HOSTMAX);
User *u2 = NULL;
Channel *c;
NickAlias *na;
int32 tmp_time;
char *s;
char *vIdent = NULL;
if (!nick || !rawhostmask) {
return MOD_STOP;
}
if (!(c = findchan(BotChan))) {
return MOD_CONT;
}
if (!(u2 = finduser(u->nick))) {
return MOD_CONT;
}
if (!(na = findnick(u->nick))) {
return MOD_CONT;
}
vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */
if (vIdent) {
rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */
if (!rawhostmask) {
return MOD_STOP;
}
if (strlen(vIdent) > USERMAX - 1) {
anope_cmd_privmsg(s_vHostServ, BotChan,
"The Ident is too long, please use an ident shorter than %d characters.", USERMAX);
if (vIdent)
free(vIdent);
return MOD_STOP;
} else {
for (s = vIdent; *s; s++) {
if (!isvalidchar(*s)) {
anope_cmd_privmsg(s_vHostServ, BotChan,
"A vhost ident must be in the format of a valid ident.");
if (vIdent)
free(vIdent);
return MOD_STOP;
}
}
}
if (!ircd->vident) {
anope_cmd_privmsg(s_vHostServ, BotChan, "This Network does not support vIdentd.");
if (vIdent)
free(vIdent);
return MOD_STOP;
}
}
if (strlen(rawhostmask) < HOSTMAX - 1) {
snprintf(hostmask, HOSTMAX - 1, "%s", rawhostmask);
} else {
anope_cmd_privmsg(s_vHostServ, BotChan,
"The vhost is too long, please use a host shorter than \2%d\2 characters.", HOSTMAX);
if (vIdent)
free(vIdent);
return MOD_STOP;
}
if (!isValidHost(hostmask, 3)) {
anope_cmd_privmsg(s_vHostServ, BotChan, "A vhost must be in the format of a valid hostmask.");
if (vIdent) {
free(vIdent);
}
free(hostmask);
return MOD_STOP;
}
if (!check_banned_vhost(hostmask)) {
if (KickBanRestrictHosts && RestrictHosts) {
if (vHostServBanClearTime > 0) {
addBan(c, vHostServBanClearTime, nick);
if (is_on_chan(c, u2)) {
anope_cmd_kick(s_vHostServ, c->ci->name, nick,
"The vhost you requested is not allowed. Banned for %d seconds", vHostServBanClearTime);
}
}
} else {
anope_cmd_privmsg(s_vHostServ, BotChan, "The requested vhost is not allowed, please choose another.");
}
if (vIdent) {
free(vIdent);
}
free(hostmask);
return MOD_STOP;
}
tmp_time = time(NULL);
if ((na = findnick(nick))) {
if (na->status & NS_VERBOTEN) {
anope_cmd_privmsg(s_vHostServ, BotChan, "Cannot set vhost for forbidden nick %s", nick);
if (vIdent)
free(vIdent);
if (hostmask)
free(hostmask);
return MOD_STOP;
}
if (!nick_identified(u)) {
notice_lang(s_vHostServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
if (vIdent)
free(vIdent);
if (hostmask)
free(hostmask);
return MOD_STOP;
}
if (vIdent && ircd->vident) {
alog("vHost for all nicks in group \2%s\2 set to \2%s@%s\2 by %s", nick, vIdent, hostmask, s_vHostServ);
} else {
alog("vHost for all nicks in group \2%s\2 set to \2%s\2 by %s", nick, hostmask, s_vHostServ);
}
do_hs_sync(na->nc, vIdent, hostmask, u->nick, tmp_time);
anope_cmd_vhost_on(nick, vIdent, hostmask);
set_lastmask(u2);
if (vHostServBanClearTime > 0) {
addBan(c, vHostServBanClearTime, nick);
if (is_on_chan(c, u2)) {
anope_cmd_kick(s_vHostServ, c->ci->name, nick, "Done. You can request a new vhost after %d seconds from your last one. Banned for %d seconds", vHostServBanClearTime, vHostServBanClearTime);
}
}
if (vIdent && ircd->vident) {
anope_cmd_notice(s_vHostServ, nick, "vHost for all nicks in group \2%s\2 set to \2%s@%s\2 and activated.", nick, vIdent, hostmask);
} else {
anope_cmd_notice(s_vHostServ, nick, "vHost for all nicks in group \2%s\2 set to \2%s\2 and activated.", nick, hostmask);
}
} else {
anope_cmd_privmsg(s_vHostServ, BotChan, "\2%s\2, please register your nick first.", nick);
}
if (vIdent)
free(vIdent);
if (hostmask)
free(hostmask);
return MOD_CONT;
}
int check_banned_vhost(char *vhost)
{
int idx;
for (idx = 0; idx < RestrictHostNum; idx++) {
if (match_wild_nocase(RestrictHostList[idx], vhost)) {
return 0;
}
}
return 1;
}
/* EOF */
Tidak ada komentar:
Posting Komentar