/* chanserv.c - Channel service bot
* Copyright 2000-2004 srvx Development Team
*
- * This program is free software; you can redistribute it and/or modify
+ * This file is part of srvx.
+ *
+ * srvx 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. Important limitations are
- * listed in the COPYING file that accompanies this software.
+ * (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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, email srvx-maintainers@srvx.net.
+ * along with srvx; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include "chanserv.h"
{ "CSMSG_DELETED_YOU", "Your $b%d$b access has been deleted from $b%s$b." },
/* User management */
- { "CSMSG_ADDED_USER", "Added new %s to the %s user list with access %d." },
+ { "CSMSG_ADDED_USER", "Added %s to the %s user list with access %d." },
{ "CSMSG_DELETED_USER", "Deleted %s (with access %d) from the %s user list." },
{ "CSMSG_BAD_RANGE", "Invalid access range; minimum (%d) must be greater than maximum (%d)." },
{ "CSMSG_DELETED_USERS", "Deleted accounts matching $b%s$b with access from $b%d$b to $b%d$b from the %s user list." },
/* Access information */
{ "CSMSG_IS_CHANSERV", "$b$C$b is the $bchannel service bot$b." },
- { "CSMSG_ACCESS_SELF_ONLY", "You may only see the list of infolines for yourself (by using $b%s$b with no arguments)." },
- { "CSMSG_SQUAT_ACCESS", "You do not have access to any channels." },
+ { "CSMSG_MYACCESS_SELF_ONLY", "You may only see the list of infolines for yourself (by using $b%s$b with no arguments)." },
+ { "CSMSG_SQUAT_ACCESS", "$b%s$b does not have access to any channels." },
{ "CSMSG_INFOLINE_LIST", "Showing all channel entries for account $b%s$b:" },
{ "CSMSG_USER_NO_ACCESS", "%s lacks access to %s." },
{ "CSMSG_USER_HAS_ACCESS", "%s has access $b%d$b in %s." },
struct mod_chanmode change;
unsigned int ii;
bans = bd->channel->channel->banlist;
- change.modes_set = change.modes_clear = 0;
- change.argc = 0;
+ mod_chanmode_init(&change);
for(ii=0; ii<bans.used; ii++)
{
if(!strcmp(bans.list[ii]->ban, bd->mask))
if(!(target = GetChannel(argv[1])))
{
target = AddChannel(argv[1], now, NULL, NULL);
- LockChannel(target);
if(!IsSuspended(channel->channel_info))
AddChannelUser(chanserv, target);
}
else if(!IsSuspended(channel->channel_info))
{
struct mod_chanmode change;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_CHANOP;
change.args[0].member = AddChannelUser(chanserv, target);
DelChannelUser(chanserv, channel, reason2, 0);
}
UnlockChannel(channel);
+ LockChannel(target);
global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, reason);
return 1;
}
return 0;
}
channel->channel_info->may_opchan = 0;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_CHANOP;
change.args[0].member = GetUserMode(channel, chanserv);
struct userData *uData;
const char *errmsg;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].member = GetUserMode(channel, user);
if(!change.args[0].member)
{
struct mod_chanmode change;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].member = GetUserMode(channel, user);
if(!change.args[0].member)
free(bData->reason);
bData->reason = strdup(reason);
safestrncpy(bData->owner, (user->handle_info ? user->handle_info->handle : user->nick), sizeof(bData->owner));
- reply("CSMSG_REASON_CHANGE", ban);
+ if(cmd)
+ reply("CSMSG_REASON_CHANGE", ban);
if(!bData->expires)
goto post_add_ban;
}
if(bData->expires)
timeq_add(bData->expires, expire_ban, bData);
- if(duration)
+ if(!cmd)
+ {
+ /* automated kickban */
+ }
+ else if(duration)
reply("CSMSG_BAN_EXTENDED", ban, intervalString(interval, duration));
else
reply("CSMSG_BAN_ADDED", name, channel->name);
goto post_add_ban;
}
}
- reply("CSMSG_REDUNDANT_BAN", name, channel->name);
+ if(cmd)
+ reply("CSMSG_REDUNDANT_BAN", name, channel->name);
free(ban);
return 0;
if(channel->banlist.used >= MAXBANS)
{
- reply("CSMSG_BANLIST_FULL", channel->name);
+ if(cmd)
+ reply("CSMSG_BANLIST_FULL", channel->name);
free(ban);
return 0;
}
if(exists && (action == ACTION_BAN))
{
- reply("CSMSG_REDUNDANT_BAN", name, channel->name);
+ if(cmd)
+ reply("CSMSG_REDUNDANT_BAN", name, channel->name);
free(ban);
return 0;
}
return 1;
}
-static CHANSERV_FUNC(cmd_access)
+static CHANSERV_FUNC(cmd_myaccess)
{
- struct userNode *target;
struct handle_info *target_handle;
struct userData *uData;
- int helping;
- char prefix[MAXLEN];
+ const char *chanName;
- if(!channel)
+ if(argc < 2)
+ target_handle = user->handle_info;
+ else if(!IsHelping(user))
{
- struct userData *uData;
- const char *chanName;
- int hide = 0;
+ reply("CSMSG_MYACCESS_SELF_ONLY", argv[0]);
+ return 0;
+ }
+ else if(!(target_handle = modcmd_get_handle_info(user, argv[1])))
+ return 0;
- target_handle = user->handle_info;
- if(!target_handle)
- {
- reply("MSG_AUTHENTICATE");
- return 0;
- }
- if(argc > 1)
- {
- if(!IsHelping(user))
- {
- reply("CSMSG_ACCESS_SELF_ONLY", argv[0]);
- return 0;
- }
+ if(!target_handle->channels)
+ {
+ reply("CSMSG_SQUAT_ACCESS", target_handle->handle);
+ return 1;
+ }
- if(!(target_handle = modcmd_get_handle_info(user, argv[1])))
- return 0;
- hide = 1;
- }
- if(!target_handle->channels)
- {
- reply("CSMSG_SQUAT_ACCESS");
- return 1;
- }
- reply("CSMSG_INFOLINE_LIST", target_handle->handle);
- for(uData = target_handle->channels; uData; uData = uData->u_next)
- {
- struct chanData *cData = uData->channel;
+ reply("CSMSG_INFOLINE_LIST", target_handle->handle);
+ for(uData = target_handle->channels; uData; uData = uData->u_next)
+ {
+ struct chanData *cData = uData->channel;
- if(uData->access > UL_OWNER)
- continue;
- if(IsProtected(cData) && hide && !GetTrueChannelAccess(cData, user->handle_info))
- continue;
- chanName = cData->channel->name;
- if(uData->info)
- send_message_type(4, user, cmd->parent->bot, "[%s (%d)] %s", chanName, uData->access, uData->info);
- else
- send_message_type(4, user, cmd->parent->bot, "[%s (%d)]", chanName, uData->access);
- }
- return 1;
+ if(uData->access > UL_OWNER)
+ continue;
+ if(IsProtected(cData)
+ && (target_handle != user->handle_info)
+ && !GetTrueChannelAccess(cData, user->handle_info))
+ continue;
+ chanName = cData->channel->name;
+ if(uData->info)
+ send_message_type(4, user, cmd->parent->bot, "[%s (%d)] %s", chanName, uData->access, uData->info);
+ else
+ send_message_type(4, user, cmd->parent->bot, "[%s (%d)]", chanName, uData->access);
}
+ return 1;
+}
+
+static CHANSERV_FUNC(cmd_access)
+{
+ struct userNode *target;
+ struct handle_info *target_handle;
+ struct userData *uData;
+ int helping;
+ char prefix[MAXLEN];
+
if(argc < 2)
{
target = user;
{
table_send(cmd->parent->bot, user->nick, 0, NULL, tbl);
reply("MSG_NONE");
+ free(tbl.contents[0]);
+ free(tbl.contents);
return 0;
}
{
REQUIRE_PARAMS(3);
msg = unsplit_string(argv + 2, argc - 2, NULL);
- send_target_message(1, argv[1], cmd->parent->bot, "%s", msg);
+ send_target_message(5, argv[1], cmd->parent->bot, "%s", msg);
}
else
{
- reply("You must specify the name of a channel or user.");
+ reply("MSG_NOT_TARGET_NAME");
return 0;
}
return 1;
else if(GetUserH(argv[1]))
{
msg = unsplit_string(argv + 2, argc - 2, NULL);
- send_target_message(1, argv[1], cmd->parent->bot, "\001ACTION %s\001", msg);
+ send_target_message(5, argv[1], cmd->parent->bot, "\001ACTION %s\001", msg);
}
else
{
- reply("You must specify the name of a channel or user.");
+ reply("MSG_NOT_TARGET_NAME");
return 0;
}
return 1;
channel = suspended->cData->channel;
suspended->cData->channel = channel;
suspended->cData->flags &= ~CHANNEL_SUSPENDED;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_CHANOP;
change.args[0].member = AddChannelUser(chanserv, channel);
CHANNEL_BINARY_OPTION("CSMSG_SET_DYNLIMIT", CHANNEL_DYNAMIC_LIMIT);
}
-/* TODO: reimplement
-
-static MODCMD_FUNC(chan_opt_userinfo)
-{
- CHANNEL_BINARY_OPTION("CSMSG_SET_USERINFO", CHANNEL_INFO_LINES);
-}
-
-static MODCMD_FUNC(chan_opt_voice)
-{
- CHANNEL_BINARY_OPTION("CSMSG_SET_VOICE", CHANNEL_VOICE_ALL);
-}
-
-static MODCMD_FUNC(chan_opt_topicsnarf)
-{
- if((argc > 0) && !check_user_level(channel, user, lvlEnfTopic, 1, 0))
- {
- reply("CSMSG_TOPIC_LOCKED", channel->name);
- return 0;
- }
- CHANNEL_BINARY_OPTION("CSMSG_SET_TOPICSNARF", CHANNEL_TOPIC_SNARF);
-}
-
-static MODCMD_FUNC(chan_opt_peoninvite)
-{
- CHANNEL_BINARY_OPTION("CSMSG_SET_PEONINVITE", CHANNEL_PEON_INVITE);
-}
-
-*/
-
static MODCMD_FUNC(chan_opt_defaults)
{
struct userData *uData;
static CHANSERV_FUNC(cmd_huggle)
{
- char response[MAXLEN];
- const char *fmt;
/* CTCP must be via PRIVMSG, never notice */
if(channel)
- {
- fmt = user_find_message(user, "CSMSG_HUGGLES_HIM");
- sprintf(response, fmt, user->nick);
- irc_privmsg(cmd->parent->bot, channel->name, response);
- }
+ send_target_message(1, channel->name, cmd->parent->bot, "CSMSG_HUGGLES_HIM", user->nick);
else
- {
- fmt = user_find_message(user, "CSMSG_HUGGLES_YOU");
- irc_privmsg(cmd->parent->bot, user->nick, fmt);
- }
+ send_target_message(1, user->nick, cmd->parent->bot, "CSMSG_HUGGLES_YOU");
return 1;
}
return;
}
+ mod_chanmode_init(&change);
change.modes_set = MODE_LIMIT;
- change.modes_clear = 0;
change.new_limit = limit;
- change.argc = 0;
mod_chanmode_announce(chanserv, channel, &change);
}
}
}
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
if(channel->banlist.used < MAXBANS)
{
if(bData != cData->bans)
{
/* Shuffle the ban to the head of the list. */
- if(bData->next) bData->next->prev = bData->prev;
- if(bData->prev) bData->prev->next = bData->next;
+ if(bData->next)
+ bData->next->prev = bData->prev;
+ if(bData->prev)
+ bData->prev->next = bData->next;
bData->prev = NULL;
bData->next = cData->bans;
if(!user->handle_info)
return;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
for(channel = user->handle_info->channels; channel; channel = channel->u_next)
{
change.args[0].mode = MODE_CHANOP;
else if(channel->access >= cn->channel_info->lvlOpts[lvlGiveVoice])
change.args[0].mode = MODE_VOICE;
+ else
+ change.args[0].mode = 0;
change.args[0].member = mn;
- mod_chanmode_announce(chanserv, cn, &change);
+ if(change.args[0].mode)
+ mod_chanmode_announce(chanserv, cn, &change);
}
channel->seen = now;
unsigned int ii, jj;
char kick_reason[MAXLEN];
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_BAN;
for(ii = 0; ii < user->channels.used; ++ii)
if(!(cData->flags & CHANNEL_SUSPENDED))
{
struct mod_chanmode change;
- change.modes_set = change.modes_clear = 0;
+ mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_CHANOP;
change.args[0].member = AddChannelUser(chanserv, cNode);
DEFINE_COMMAND(mdelpeon, 2, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
DEFINE_COMMAND(trim, 3, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
- DEFINE_COMMAND(opchan, 1, MODCMD_REQUIRE_REGCHAN, "access", "1", NULL);
+ DEFINE_COMMAND(opchan, 1, MODCMD_REQUIRE_REGCHAN|MODCMD_NEVER_CSUSPEND, "access", "1", NULL);
DEFINE_COMMAND(clvl, 3, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
DEFINE_COMMAND(giveownership, 2, MODCMD_REQUIRE_CHANUSER, "access", "owner", "flags", "+loghostmask", NULL);
DEFINE_COMMAND(bans, 1, MODCMD_REQUIRE_REGCHAN, "access", "1", "flags", "+nolog", NULL);
DEFINE_COMMAND(peek, 1, MODCMD_REQUIRE_REGCHAN, "access", "op", "flags", "+nolog", NULL);
- DEFINE_COMMAND(access, 1, 0, "flags", "+nolog,+acceptchan", NULL);
+ DEFINE_COMMAND(myaccess, 1, MODCMD_REQUIRE_AUTHED, NULL);
+ DEFINE_COMMAND(access, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_COMMAND(users, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_COMMAND(wlist, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_COMMAND(clist, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);