* Fix typo in CSMSG_ADDED_USER message.
* Fix memory leak in !bans when no bans are shown.
* Fix SAY, EMOTE to user targets.
* Require unsuspended channel for OPCHAN (i.e. ChanServ is in-channel).
* Fix typo in TOPICSNARF help description.
* Fix mod_chanmode argc when reopping services.
* Fix memory leak when rehashing with with an uplink bind address.
* Fix typo in OSMSG_NICK_UNRESERVED message.
* Make *OpServ.op actually op non-ops, instead of just ops.
* Fix kick message translations when shutting down a channel.
* Fix use-after-free if an oper does ?part #badchan.
* Make mod_chanmode_apply() more sensitive to invalid mode changes.
* In create_helper(), let AddChannelUser() decide whether to op the user.
* Remove "Mod" and "Game" from "set_shows" in srvx.conf.example.
* Do not print the status "." in tests when full debug mode is on.
git-archimport-id: srvx@srvx.net--2004-srvx/srvx--devo--1.3--patch-24
{ "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." },
{
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
{
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
{
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;
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);
"ENFOPS: Restrictions for opping users.",
"ENFMODES: Restrictions to change the default modes.",
"ENFTOPIC: Restrictions on changing the topic.",
- "TOPICSNARF: Topics set manually (by /TOPIC #channel ...) by users this level and bove change the default $b$C$b topic.",
+ "TOPICSNARF: Topics set manually (by /TOPIC #channel ...) by users this level and above change the default $b$C$b topic.",
"SETTERS: Who may change channel settings (using $bSET$b).",
"CTCPUSERS: Who is allowed to send CTCPs to the channel.",
"CTCPREACTION: What happens when a disallowed CTCP is sent to the channel.",
/* deop anybody in the channel now, but count services to reop */
for (nn=argc=0; nn<cNode->members.used; nn++) {
struct modeNode *mn = cNode->members.list[nn];
- if (mn->modes & MODE_CHANOP && IsService(mn->user) && IsLocal(mn->user))
+ if ((mn->modes & MODE_CHANOP) && IsService(mn->user) && IsLocal(mn->user))
argc++;
}
if (argc) {
extern struct userNode *opserv;
struct mod_chanmode *change;
- change = mod_chanmode_alloc(nn);
+ change = mod_chanmode_alloc(argc);
change->modes_clear = 0;
change->modes_set = orig_modes;
change->new_limit = orig_limit;
argc++;
}
}
+ assert(argc == change->argc);
if (change->argc > 0)
mod_chanmode_announce(change->args[0].member->user, cNode, change);
else
switch (exp.type) {
case HF_STRING:
free_value = value = exp.value.str;
- if (!value) value = "";
+ if (!value)
+ value = "";
break;
case HF_TABLE:
/* Must send current line, then emit table. */
uplink->bind_addr_len = sizeof(*sin);
if (str && getipbyname(str, &addr))
{
- sin = malloc(uplink->bind_addr_len);
- sin->sin_port = 0;
+ sin = calloc(1, uplink->bind_addr_len);
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = addr;
-#ifdef HAVE_SIN_LEN
- sin->sin_len = 0;
-#endif
- memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
uplink->bind_addr = sin;
}
else
for(uplink = oldUplinks; uplink; uplink = next)
{
next = uplink->next;
+ free(uplink->bind_addr);
free(uplink);
}
}
ioset_cleanup();
for (ul = cManager.uplinks; ul; ul = ul_next) {
ul_next = ul->next;
- if (ul->bind_addr) free(ul->bind_addr);
+ free(ul->bind_addr);
free(ul);
}
tools_cleanup();
{ "OSMSG_RAW_PARSE_ERROR", "Error parsing raw line (not dumping to uplink)." },
{ "OSMSG_COLLIDED_NICK", "Now temporarily holding nick $b%s$b." },
{ "OSMSG_RESERVED_NICK", "Now reserving nick $b%s$b." },
- { "OSMSG_NICK_UNRESERVED", "Nick $b%s$b is no longer reserve." },
+ { "OSMSG_NICK_UNRESERVED", "Nick $b%s$b is no longer reserved." },
{ "OSMSG_NOT_RESERVED", "Nick $b%s$b is not reserved." },
{ "OSMSG_ILLEGAL_REASON", "This channel is illegal." },
{ "OSMSG_ILLEGAL_KILL_REASON", "Joined an illegal modeless channel - do not repeat." },
continue;
if (!(mn = GetUserMode(channel, victim)))
continue;
- if (!(mn->modes & MODE_CHANOP))
+ if (mn->modes & MODE_CHANOP)
continue;
change->args[count].mode = MODE_CHANOP;
change->args[count++].member = mn;
struct modeNode *mNode = channel->members.list[--nn];
if (IsService(mNode->user))
continue;
- KickChannelUser(mNode->user, channel, opserv, reason);
+ KickChannelUser(mNode->user, channel, opserv, user_find_message(mNode->user, reason));
}
timeq_add(now + opserv_conf.purge_lock_delay, opserv_part_channel, channel);
}
newchan->bad_channel = opserv_bad_channel(newchan->name);
}
+static void
+opserv_channel_delete(struct chanNode *chan)
+{
+ timeq_del(0, opserv_part_channel, chan, TIMEQ_IGNORE_WHEN);
+}
+
static int
opserv_join_check(struct modeNode *mNode)
{
if (channel->name[0] != '#')
DelUser(user, opserv, 1, "OSMSG_ILLEGAL_KILL_REASON");
else if (!GetUserMode(channel, opserv))
- opserv_shutdown_channel(channel, user_find_message(user, "OSMSG_ILLEGAL_REASON"));
+ opserv_shutdown_channel(channel, "OSMSG_ILLEGAL_REASON");
else {
send_message(user, opserv, "OSMSG_ILLEGAL_CHANNEL", channel->name);
msg = user_find_message(user, "OSMSG_ILLEGAL_REASON");
reg_nick_change_func(opserv_alert_check_nick);
reg_del_user_func(opserv_user_cleanup);
reg_new_channel_func(opserv_channel_check);
+ reg_del_channel_func(opserv_channel_delete);
reg_join_func(opserv_join_check);
reg_auth_func(opserv_staff_alert);
break;
}
break;
- default:
- assert((change->args[ii].mode & (MODE_REMOVE|MODE_CHANOP|MODE_VOICE)) != 0);
+ case MODE_CHANOP:
+ case MODE_VOICE:
+ case MODE_VOICE|MODE_CHANOP:
+ case MODE_REMOVE|MODE_CHANOP:
+ case MODE_REMOVE|MODE_VOICE:
+ case MODE_REMOVE|MODE_VOICE|MODE_CHANOP:
if (change->args[ii].mode & MODE_REMOVE)
change->args[ii].member->modes &= ~change->args[ii].mode;
else
change->args[ii].member->modes |= change->args[ii].mode;
break;
+ default:
+ assert(0 && "Invalid mode argument");
+ continue;
}
}
}
create_helper(char *name, void *data)
{
struct create_desc *cd = data;
- /* We can't assume the channel create was allowed because of the
- * bad-word channel checking.
- */
- struct chanNode *cn;
- struct modeNode *mn;
+
if (!strcmp(name, "0")) {
while (cd->user->channels.used > 0)
DelChannelUser(cd->user, cd->user->channels.list[0]->channel, 0, 0);
return;
}
- cn = AddChannel(name, cd->when, NULL, NULL);
- mn = AddChannelUser(cd->user, cn);
- if (mn && (cn->members.used == 1))
- mn->modes = MODE_CHANOP;
+
+ AddChannelUser(cd->user, AddChannel(name, cd->when, NULL, NULL));
}
static CMD_FUNC(cmd_create)
// character to make ChanServ pay attention to you
"trigger" "!";
// what !set options should we show when user calls "!set" with no arguments?
- "set_shows" ("DefaultTopic", "TopicMask", "Greeting", "UserGreeting", "Modes", "PubCmd", "StrictOp", "AutoOp", "EnfModes", "EnfTopic", "Protect", "Toys", "Setters", "TopicRefresh", "CtcpUsers", "CtcpReaction", "Mod", "Game",
+ "set_shows" ("DefaultTopic", "TopicMask", "Greeting", "UserGreeting", "Modes", "PubCmd", "StrictOp", "AutoOp", "EnfModes", "EnfTopic", "Protect", "Toys", "Setters", "TopicRefresh", "CtcpUsers", "CtcpReaction",
"Voice", "UserInfo", "DynLimit", "TopicSnarf", "NoDelete");
// A list of !8ball responses
$line = delete $heap->{line};
} elsif (defined($line = <$script>)) {
$heap->{lineno} = $.;
- print ".";
+ print "." unless $heap->{irc_debug};
} else {
# close all connections
foreach my $client (values %{$heap->{clients}}) {