X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/8062bfc3ef42bb5b487cf9796be3cd80d44ec709..dc92ef7c98f927c3f3ede840d6510a968467df99:/src/chanserv.c diff --git a/src/chanserv.c b/src/chanserv.c index cc0a92e..5c54290 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -224,7 +224,7 @@ static const struct message_entry msgtab[] = { { "CSMSG_TRIMMED_USERS", "Trimmed $b%d users$b with access from %d to %d from the %s user list who were inactive for at least %s." }, { "CSMSG_INCORRECT_ACCESS", "%s has access $b%s$b, not %s." }, { "CSMSG_USER_EXISTS", "%s is already on the $b%s$b user list (with %s access)." }, - { "CSMSG_ADDUSER_PENDING", "I have sent him/her a message letting them know, and if they auth or register soon, I will finish adding them automatically." }, + { "CSMSG_ADDUSER_PENDING", "I have sent %s a message letting them know, and if they auth or register soon, I will finish adding them automatically." }, { "CSMSG_ADDUSER_PENDING_ALREADY", "He or she is already pending addition to %s once he/she auths with $b$N$b." }, { "CSMSG_ADDUSER_PENDING_HEADER", "Users to add to channels pending logins:" }, /* Remove after testing? */ { "CSMSG_ADDUSER_PENDING_LIST", "Channel %s user %s" }, /* Remove after testing? */ @@ -257,10 +257,12 @@ static const struct message_entry msgtab[] = { { "CSMSG_DURATION_TOO_LOW", "Timed bans must last for at least 15 seconds." }, { "CSMSG_DURATION_TOO_HIGH", "Timed bans must last for less than 2 years." }, { "CSMSG_LAME_MASK", "$b%s$b is a little too general. Try making it more specific." }, + { "CSMSG_NO_EXTBANS", "$b%s$b is an extended ban, which are not allowed." }, { "CSMSG_MASK_PROTECTED", "Sorry, ban for $b%s$b conflicts with a protected user's hostmask." }, { "CSMSG_NO_MATCHING_USERS", "No one in $b%s$b has a hostmask matching $b%s$b." }, { "CSMSG_BAN_NOT_FOUND", "Sorry, no ban or LAMER found: $b%s$b." }, { "CSMSG_BANLIST_FULL", "The $b%s$b channel ban list is $bfull$b." }, + { "CSMSG_BAD_BAN", "The given ban $b%s$b is invalid." }, { "CSMSG_INVALID_TRIM", "$b%s$b isn't a valid trim target." }, @@ -440,7 +442,7 @@ static const struct message_entry msgtab[] = { { "CSMSG_HELPER_NO_ACCESS", "%s lacks access to %s but has $bsecurity override$b enabled." }, { "CSMSG_HELPER_HAS_ACCESS", "%s has $b%s$b access (%d) in %s and has $bsecurity override$b enabled." }, { "CSMSG_LAZY_SMURF_TARGET", "%s is %s ($bIRCOp$b; not logged in)." }, - { "CSMSG_SMURF_TARGET", "%s is %s ($b%s$b)." }, + { "CSMSG_SMURF_TARGET", "%s %s ($b%s$b)." }, { "CSMSG_OPERATOR_TITLE", "IRC operator" }, { "CSMSG_UC_H_TITLE", "network helper" }, { "CSMSG_LC_H_TITLE", "support helper" }, @@ -993,7 +995,7 @@ scan_user_presence(struct userData *uData, struct userNode *user) } static void -chanserv_ctcp_check(struct userNode *user, struct chanNode *channel, const char *text, UNUSED_ARG(struct userNode *bot), UNUSED_ARG(unsigned int is_notice)) +chanserv_ctcp_check(struct userNode *user, struct chanNode *channel, const char *text, UNUSED_ARG(struct userNode *bot), UNUSED_ARG(unsigned int is_notice), UNUSED_ARG(void *extra)) { unsigned int eflags, argc; char *argv[4]; @@ -3165,7 +3167,7 @@ static CHANSERV_FUNC(cmd_adduser) } else { if(IsInChannel(channel, unode)) { - reply("CSMSG_ADDUSER_PENDING"); + reply("CSMSG_ADDUSER_PENDING", unode->nick); tmp = add_adduser_pending(channel, unode, access_level); send_message_type(1,unode, chanserv, "CSMSG_ADDUSER_PENDING_TARGET", user->nick, channel->name); } @@ -3288,6 +3290,7 @@ static CHANSERV_FUNC(cmd_deluser) struct userData *victim; struct userData *actor, *real_actor; unsigned short access_level, override = 0; + unsigned short access_level_user = 0; char *chan_name; REQUIRE_PARAMS(2); @@ -3308,14 +3311,15 @@ static CHANSERV_FUNC(cmd_deluser) { access_level = user_level_from_name(argv[1], UL_OWNER); char *useraccess = user_level_name_from_level(victim->access); + access_level_user = user_level_from_name(useraccess, UL_OWNER); if(!access_level) { reply("CSMSG_INVALID_ACCESS", argv[1]); return 0; } - if(strcasecmp(argv[1], useraccess)) + if(access_level != access_level_user) { - reply("CSMSG_INCORRECT_ACCESS", handle->handle, user_level_name_from_level(victim->access), argv[1]); + reply("CSMSG_INCORRECT_ACCESS", handle->handle, useraccess, argv[1]); return 0; } } @@ -3780,6 +3784,7 @@ static int bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban, unsigned int *victimCount, struct modeNode **victims) { unsigned int ii; + int b = 0; if(victimCount) *victimCount = 0; @@ -3790,7 +3795,10 @@ bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban if(IsService(mn->user)) continue; - if(!user_matches_glob(mn->user, ban, MATCH_USENICK | MATCH_VISIBLE)) + b = user_matches_glob(mn->user, ban, MATCH_USENICK | MATCH_VISIBLE, 0); + if (b == -1) + return -1; + else if (b == 0) continue; if(protect_user(mn->user, user, channel->channel_info, false)) @@ -3802,12 +3810,20 @@ bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban return 0; } +int is_extban(char *b) { + if(*b == '~') { + return 1; + } + return 0; +} + static int eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, char *argv[], struct svccmd *cmd, int action) { struct userNode *victim; struct modeNode **victims; unsigned int offset, n, victimCount, duration = 0; + int b = 0; char *reason = "Bye.", *ban, *name; char interval[INTERVALLEN]; @@ -3877,10 +3893,15 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c snprintf(banmask, sizeof(banmask), "*!*@%s.*", hi->handle); victims = alloca(sizeof(victims[0]) * channel->members.used); - if(bad_channel_ban(channel, user, banmask, &victimCount, victims)) + b = bad_channel_ban(channel, user, banmask, &victimCount, victims); + if(b == 1) { reply("CSMSG_MASK_PROTECTED", banmask); return 0; + }else if(b == -1) + { + reply("CSMSG_BAD_BAN", banmask); + return 0; } if((action == ACTION_KICK) && (victimCount == 0)) @@ -3902,10 +3923,13 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c victims = alloca(sizeof(victims[0]) * channel->members.used); - if(bad_channel_ban(channel, user, argv[1], &victimCount, victims)) - { - if(cmd) - reply("CSMSG_MASK_PROTECTED", argv[1]); + b = bad_channel_ban(channel, user, argv[1], &victimCount, victims); + if(cmd && (b == 1)) { + reply("CSMSG_MASK_PROTECTED", argv[1]); + return 0; + } + else if(cmd && (b == -1)) { + reply("CSMSG_BAD_BAN", argv[1]); return 0; } /* If i want to ban *.nl and theres 5 of them, what is it to the bot?!? @@ -3920,6 +3944,13 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c reply("CSMSG_LAME_MASK", argv[1]); return 0; } + //TODO: We have no support to do protection etc etc so for now we dont let you use x3 to set extended bans. + if(is_extban(argv[1])) + { + if(cmd) + reply("CSMSG_NO_EXTBANS", argv[1]); + return 0; + } if((action == ACTION_KICK) && (victimCount == 0)) { @@ -4193,7 +4224,7 @@ find_matching_bans(struct banList *bans, struct userNode *actee, const char *mas for(ii = count = 0; ii < bans->used; ++ii) { match[ii] = user_matches_glob(actee, bans->list[ii]->ban, - MATCH_USENICK | MATCH_VISIBLE); + MATCH_USENICK | MATCH_VISIBLE, 0); if(match[ii]) count++; } @@ -4244,7 +4275,8 @@ void expire_bans(UNUSED_ARG(void* data)) /* Real bans, not lamers */ count = 0; /* First find out how many bans were going to unset */ for (jj=0; jj < channel->channel->banlist.used; ++jj) { - if(channel->channel->banlist.list[jj]->set < bantimeout) + //TODO: for now, were just not removing extended bans, but ultimately some types we should, some shouldn't...see below + if(channel->channel->banlist.list[jj]->set < bantimeout && !is_extban(channel->channel->banlist.list[jj]->ban)) count++; } if(count > 0) { @@ -4254,7 +4286,8 @@ void expire_bans(UNUSED_ARG(void* data)) /* Real bans, not lamers */ /* Walk over every ban in this channel.. */ for (jj=0; jj < channel->channel->banlist.used; ++jj) { bn = channel->channel->banlist.list[jj]; - if (bn->set < bantimeout) { + //TODO: for now, were just not removing extended bans, but ultimately some types we should, some shouldn't...see above + if (bn->set < bantimeout && !is_extban(bn->ban)) { log_module(CS_LOG, LOG_DEBUG, "Removing ban %s from %s", bn->ban, channel->channel->name); /* Add this ban to the mode change */ @@ -4340,7 +4373,7 @@ unban_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c while(ban) { if(actee) - for( ; ban && !user_matches_glob(actee, ban->mask, MATCH_USENICK | MATCH_VISIBLE); + for( ; ban && !user_matches_glob(actee, ban->mask, MATCH_USENICK | MATCH_VISIBLE, 0); ban = ban->next); else for( ; ban && !match_ircglobs(mask, ban->mask); @@ -4399,6 +4432,7 @@ static CHANSERV_FUNC(cmd_unbanall) return 0; } + // TODO: dont remove some kinds of extended bans such as ~c change = mod_chanmode_alloc(channel->banlist.used); for(ii=0; iibanlist.used; ii++) { @@ -4471,7 +4505,7 @@ static CHANSERV_FUNC(cmd_myaccess) continue; sbuf.used = 0; string_buffer_append_printf(&sbuf, "[%s (%d", cData->channel->name, uData->access); - if(uData->flags == USER_AUTO_OP) + if(uData->flags != 0) string_buffer_append(&sbuf, ','); if(IsUserSuspended(uData)) string_buffer_append(&sbuf, 's'); @@ -4998,7 +5032,7 @@ static CHANSERV_FUNC(cmd_lamers) { if(search_u) { - if(!user_matches_glob(search_u, ban->mask, MATCH_USENICK | MATCH_VISIBLE)) + if(!user_matches_glob(search_u, ban->mask, MATCH_USENICK | MATCH_VISIBLE, 0)) continue; } else if(search) @@ -5302,7 +5336,7 @@ static CHANSERV_FUNC(cmd_invite) if (invite->handle_info && invite->handle_info->ignores->used && (argc > 1)) { unsigned int i; for (i=0; i < invite->handle_info->ignores->used; i++) { - if (user_matches_glob(user, invite->handle_info->ignores->list[i], MATCH_USENICK)) { + if (user_matches_glob(user, invite->handle_info->ignores->list[i], MATCH_USENICK, 0)) { reply("CSMSG_CANNOT_INVITE", argv[1], channel->name); return 0; } @@ -5500,7 +5534,7 @@ static CHANSERV_FUNC(cmd_netinfo) reply("CSMSG_NETWORK_INFO"); reply("CSMSG_NETWORK_SERVERS", dict_size(servers)); reply("CSMSG_NETWORK_USERS", dict_size(clients)); - reply("CSMSG_NETWORK_OPERS", curr_opers.used); + reply("CSMSG_NETWORK_OPERS", count_opers); reply("CSMSG_NETWORK_CHANNELS", registered_channels); reply("CSMSG_NETWORK_LAMERS", banCount); reply("CSMSG_NETWORK_CHANUSERS", userCount); @@ -5526,7 +5560,7 @@ send_staff_list(struct userNode *to, struct userList *list, int skip_flags) user = list->list[nn]; if(user->modes & skip_flags) continue; - if(IsBot(user)) + if(IsBot(user) || IsHideOper(user)) continue; table.contents[table.length] = alloca(table.width*sizeof(**table.contents)); if(IsAway(user)) @@ -5545,14 +5579,14 @@ send_staff_list(struct userNode *to, struct userList *list, int skip_flags) static CHANSERV_FUNC(cmd_ircops) { reply("CSMSG_STAFF_OPERS"); - send_staff_list(user, &curr_opers, FLAGS_SERVICE); + send_staff_list(user, &curr_opers, FLAGS_SERVICE | FLAGS_BOT); return 1; } static CHANSERV_FUNC(cmd_helpers) { reply("CSMSG_STAFF_HELPERS"); - send_staff_list(user, &curr_helpers, FLAGS_OPER); + send_staff_list(user, &curr_helpers, FLAGS_OPER | FLAGS_SERVICE | FLAGS_BOT); return 1; } @@ -5665,7 +5699,18 @@ resync_channel(struct chanNode *channel) } else /* Give various userlevels their modes.. */ { - if(uData && uData->access >= UL_OP ) + /* If the user has autoop/autovoice disabled then ignore them */ + if(uData && !IsUserAutoOp(uData)) + continue; + if(uData && uData->access >= UL_PEON && cData->chOpts[chAutomode] == 'l') + { + if(!(mn->modes & MODE_VOICE)) + { + changes->args[used].mode = MODE_VOICE; + changes->args[used++].u.member = mn; + } + } + else if(uData && uData->access >= UL_OP ) { if(!(mn->modes & MODE_CHANOP)) { @@ -6636,7 +6681,7 @@ static MODCMD_FUNC(chan_opt_maxsetinfo) if(argc > 1) { charmax = atoi(argv[1]); - if ((charmax > 0) && (charmax < chanserv_conf.max_userinfo_length)) + if ((charmax > 0) && (charmax <= chanserv_conf.max_userinfo_length)) channel->channel_info->maxsetinfo = charmax; } @@ -6984,10 +7029,6 @@ channel_multiple_option(enum charOption option, struct userNode *user, struct ch static MODCMD_FUNC(chan_opt_automode) { - if(check_user_level(channel, user, lvlInviteMe, 1, 0)) - { - reply("CSMSG_LOW_CHANNEL_ACCESS", channel->name); - } return channel_multiple_option(chAutomode, CSFUNC_ARGS); } @@ -7024,7 +7065,7 @@ static MODCMD_FUNC(chan_opt_resync) static struct svccmd_list set_shows_list; static void -handle_svccmd_unbind(struct svccmd *target) { +handle_svccmd_unbind(struct svccmd *target, UNUSED_ARG(void *extra)) { unsigned int ii; for(ii=0; iichannel_info, user->handle_info); real_actor = GetChannelAccess(channel->channel_info, user->handle_info); if(!(target = GetTrueChannelAccess(channel->channel_info, hi))) { @@ -7724,26 +7766,26 @@ static CHANSERV_FUNC(cmd_spin) } /* random time gline */ else if (!strcasecmp(wheel, "gline")) { - char target[IRC_NTOP_MAX_SIZE + 3]; + char target[HOSTLEN + 3]; int wtime = 120 + rand() % 600; strcpy(target, "*@"); strcat(target, user->hostname); send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_GLINE"); - gline_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, now, 1, 0); + gline_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, 1, 0); // irc_kill(chanserv, user, "Reward for spinning the wheel of misfortune!"); } /* random shun */ else if (!strcasecmp(wheel, "shun")) { - char target[IRC_NTOP_MAX_SIZE + 3]; + char target[HOSTLEN + 3]; int wtime = 120 + rand() % 600; strcpy(target, "*@"); strcat(target, user->hostname); send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_SHUN"); - shun_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, now, 1); + shun_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, 1); } /* absolutely nothing */ else if (!strcasecmp(wheel, "nothing")) { @@ -7803,14 +7845,12 @@ static CHANSERV_FUNC(cmd_spin) char *oldnick = NULL; char *oldident = NULL; - char *oldhost = NULL; char abusednick[NICKLEN] = ""; int abusednum = 1 + (int) (10000.0 * (rand() / (RAND_MAX + 1.0))); struct userNode *clone; oldnick = strdup(user->nick); oldident = strdup(user->ident); - oldhost = strdup(user->hostname); //snprintf(abusednick, NICKLEN, "Abused%d", abusednum+(1 + rand() % 120)); while (1) { @@ -7822,7 +7862,7 @@ static CHANSERV_FUNC(cmd_spin) SVSNickChange(user, abusednick); irc_svsnick(chanserv, user, abusednick); - clone = AddLocalUser(oldnick, oldident, oldhost, "I got abused by the wheel of misfortune :D", "+i"); + clone = AddLocalUser(oldnick, oldident, "abused.by.wheel.of.misfortune", "I got abused by the wheel of misfortune :D", "+i"); timeq_add(now + 300, chanserv_remove_abuse, clone->nick); } /* kill */ @@ -7835,7 +7875,7 @@ static CHANSERV_FUNC(cmd_spin) /* service ignore */ else if (!strcasecmp(wheel, "svsignore")) { int gagged, ignoretime = 0; - char target[IRC_NTOP_MAX_SIZE + 13]; + char target[HOSTLEN + 13]; if(IsOper(user)) { /* we cant gag opers, so just verbally abuse them */ @@ -7854,7 +7894,7 @@ static CHANSERV_FUNC(cmd_spin) else if (!strcasecmp(wheel, "kickbanall")) { unsigned int count, n; struct modeNode *mn; - //char ban[IRC_NTOP_MAX_SIZE + 1]; + //char ban[HOSTLEN + 1]; send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_KICKBANALL"); @@ -8044,11 +8084,11 @@ static CHANSERV_FUNC(cmd_8ball) word3 = argc>3?argv[3]:""; /*** COLOR *****/ - if((word2) && strcasecmp(word1, "what") == 0 && strcasecmp(word2, "color") == 0) + if((word2) && strcasecmp(word1, "what") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0))) eightball(eb, 1, accum); - else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && strcasecmp(word3, "color") == 0) + else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0))) eightball(eb, 1, accum); - else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && strcasecmp(word3, "color") == 0) + else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0))) eightball(eb, 1, accum); /*** LOCATION *****/ else if( @@ -8223,7 +8263,7 @@ chanserv_adjust_limit(void *data) } static void -handle_new_channel(struct chanNode *channel) +handle_new_channel(struct chanNode *channel, UNUSED_ARG(void *extra)) { struct chanData *cData; @@ -8251,7 +8291,7 @@ trace_check_bans(struct userNode *user, struct chanNode *chan) if (chan->channel_info) { for(bData = chan->channel_info->bans; bData; bData = bData->next) { - if(!user_matches_glob(user, bData->mask, MATCH_USENICK)) + if(!user_matches_glob(user, bData->mask, MATCH_USENICK, 0)) continue; if(bData) @@ -8283,7 +8323,7 @@ check_bans(struct userNode *user, const char *channel) { /* Not joining through a ban. */ for(bData = cData->bans; - bData && !user_matches_glob(user, bData->mask, MATCH_USENICK); + bData && !user_matches_glob(user, bData->mask, MATCH_USENICK, 0); bData = bData->next); if(bData) @@ -8325,7 +8365,7 @@ channel_user_is_exempt(struct userNode *user, struct chanNode *channel) unsigned int ii; for(ii = 0; ii < channel->exemptlist.used; ii++) { - if(user_matches_glob(user, channel->exemptlist.list[ii]->exempt, MATCH_USENICK)) + if(user_matches_glob(user, channel->exemptlist.list[ii]->exempt, MATCH_USENICK, 0)) return true; } return false; @@ -8335,7 +8375,7 @@ channel_user_is_exempt(struct userNode *user, struct chanNode *channel) /* Welcome to my worst nightmare. Warning: Read (or modify) the code below at your own risk. */ static int -handle_join(struct modeNode *mNode) +handle_join(struct modeNode *mNode, UNUSED_ARG(void *extra)) { struct mod_chanmode change; struct userNode *user = mNode->user; @@ -8370,7 +8410,7 @@ handle_join(struct modeNode *mNode) unsigned int ii; for(ii = 0; ii < channel->banlist.used; ii++) { - if(user_matches_glob(user, channel->banlist.list[ii]->ban, MATCH_USENICK)) + if(user_matches_glob(user, channel->banlist.list[ii]->ban, MATCH_USENICK, 0)) { /* Riding a netburst. Naughty. */ KickChannelUser(user, channel, chanserv, "User from far side of netsplit should have been banned - bye."); @@ -8401,7 +8441,7 @@ handle_join(struct modeNode *mNode) { /* Not joining through a ban. */ for(bData = cData->bans; - bData && !user_matches_glob(user, bData->mask, MATCH_USENICK); + bData && !user_matches_glob(user, bData->mask, MATCH_USENICK, 0); bData = bData->next); if(bData) @@ -8566,7 +8606,7 @@ chanserv_autojoin_channels(struct userNode *user) } static void -handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle)) +handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle), UNUSED_ARG(void *extra)) { struct mod_chanmode change; struct userData *channel; @@ -8605,7 +8645,9 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle)) if(IsUserAutoOp(channel) && cData->chOpts[chAutomode] != 'n') { - if(channel->access >= UL_OP ) + if (channel->access >= UL_PEON && cData->chOpts[chAutomode] == 'l') + change.args[0].mode = MODE_VOICE; + else if(channel->access >= UL_OP ) change.args[0].mode = MODE_CHANOP; else if(channel->access >= UL_HALFOP ) change.args[0].mode = MODE_HALFOP; @@ -8634,14 +8676,14 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle)) if(protect_user(user, chanserv, chan->channel_info, true)) continue; for(jj = 0; jj < chan->banlist.used; ++jj) - if(user_matches_glob(user, chan->banlist.list[jj]->ban, MATCH_USENICK)) + if(user_matches_glob(user, chan->banlist.list[jj]->ban, MATCH_USENICK, 0)) break; if(jj < chan->banlist.used) continue; for(ban = chan->channel_info->bans; ban; ban = ban->next) { char kick_reason[MAXLEN]; - if(!user_matches_glob(user, ban->mask,MATCH_USENICK | MATCH_VISIBLE)) + if(!user_matches_glob(user, ban->mask,MATCH_USENICK | MATCH_VISIBLE, 0)) continue; change.args[0].mode = MODE_BAN; change.args[0].u.hostmask = ban->mask; @@ -8681,7 +8723,7 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle)) } static void -handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason)) +handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason), UNUSED_ARG(void *extra)) { struct chanData *cData; struct userData *uData; @@ -8712,16 +8754,25 @@ handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason)) if(IsHelping(mn->user) && IsSupportHelper(mn->user)) { unsigned int ii; - for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii) - if(find_handle_in_channel(chanserv_conf.support_channels.list[ii], mn->user->handle_info, mn->user)) + for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii) { + struct chanNode *channel; + struct userNode *exclude; + /* When looking at the channel that is being /part'ed, we + * have to skip over the client that is leaving. For + * other channels, we must not do that. + */ + channel = chanserv_conf.support_channels.list[ii]; + exclude = (channel == mn->channel) ? mn->user : NULL; + if(find_handle_in_channel(channel, mn->user->handle_info, exclude)) break; - if(ii == chanserv_conf.support_channels.used) + } + if(ii == chanserv_conf.support_channels.used) HANDLE_CLEAR_FLAG(mn->user->handle_info, HELPING); } } static void -handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *channel) +handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *channel, UNUSED_ARG(void *extra)) { struct userData *uData; @@ -8741,7 +8792,7 @@ handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *c } static int -handle_topic(struct userNode *user, struct chanNode *channel, const char *old_topic) +handle_topic(struct userNode *user, struct chanNode *channel, const char *old_topic, UNUSED_ARG(void *extra)) { struct chanData *cData; @@ -8784,7 +8835,7 @@ handle_topic(struct userNode *user, struct chanNode *channel, const char *old_to } static void -handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_chanmode *change) +handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_chanmode *change, UNUSED_ARG(void *extra)) { struct mod_chanmode *bounce = NULL; unsigned int bnc, ii; @@ -8859,7 +8910,7 @@ handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_ch } static void -handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick)) +handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick), UNUSED_ARG(void *extra)) { struct chanNode *channel; struct banData *bData; @@ -8883,7 +8934,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick)) continue; /* Look for a matching ban already on the channel. */ for(jj = 0; jj < channel->banlist.used; ++jj) - if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK)) + if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK, 0)) break; /* Need not act if we found one. */ if(jj < channel->banlist.used) @@ -8894,7 +8945,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick)) /* Look for a matching ban in this channel. */ for(bData = channel->channel_info->bans; bData; bData = bData->next) { - if(!user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE)) + if(!user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE, 0)) continue; change.args[0].u.hostmask = bData->mask; mod_chanmode_announce(chanserv, channel, &change); @@ -8906,7 +8957,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick)) } } -static void handle_rename(struct handle_info *handle, const char *old_handle) +static void handle_rename(struct handle_info *handle, const char *old_handle, UNUSED_ARG(void *extra)) { struct do_not_register *dnr = dict_find(handle_dnrs, old_handle, NULL); @@ -8919,7 +8970,7 @@ static void handle_rename(struct handle_info *handle, const char *old_handle) } static void -handle_unreg(UNUSED_ARG(struct userNode *user), struct handle_info *handle) +handle_unreg(UNUSED_ARG(struct userNode *user), struct handle_info *handle, UNUSED_ARG(void *extra)) { struct userNode *h_user; @@ -8934,7 +8985,7 @@ handle_unreg(UNUSED_ARG(struct userNode *user), struct handle_info *handle) } static int -handle_server_link(UNUSED_ARG(struct server *server)) +handle_server_link(UNUSED_ARG(struct server *server), UNUSED_ARG(void *extra)) { struct chanData *cData; @@ -9891,9 +9942,9 @@ chanserv_saxdb_write(struct saxdb_context *ctx) } static void -chanserv_db_cleanup(void) { +chanserv_db_cleanup(UNUSED_ARG(void *extra)) { unsigned int ii; - unreg_part_func(handle_part); + unreg_part_func(handle_part, NULL); while(channelList) unregister_channel(channelList, "terminating."); for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii) @@ -9935,19 +9986,19 @@ init_chanserv(const char *nick) conf_register_reload(chanserv_conf_read); if (nick) { - reg_server_link_func(handle_server_link); - reg_new_channel_func(handle_new_channel); - reg_join_func(handle_join); - reg_part_func(handle_part); - reg_kick_func(handle_kick); - reg_topic_func(handle_topic); - reg_mode_change_func(handle_mode); - reg_nick_change_func(handle_nick_change); - reg_auth_func(handle_auth); + reg_server_link_func(handle_server_link, NULL); + reg_new_channel_func(handle_new_channel, NULL); + reg_join_func(handle_join, NULL); + reg_part_func(handle_part, NULL); + reg_kick_func(handle_kick, NULL); + reg_topic_func(handle_topic, NULL); + reg_mode_change_func(handle_mode, NULL); + reg_nick_change_func(handle_nick_change, NULL); + reg_auth_func(handle_auth, NULL); } - reg_handle_rename_func(handle_rename); - reg_unreg_func(handle_unreg); + reg_handle_rename_func(handle_rename, NULL); + reg_unreg_func(handle_unreg, NULL); handle_dnrs = dict_new(); dict_set_free_data(handle_dnrs, free); @@ -9956,7 +10007,7 @@ init_chanserv(const char *nick) mask_dnrs = dict_new(); dict_set_free_data(mask_dnrs, free); - reg_svccmd_unbind_func(handle_svccmd_unbind); + reg_svccmd_unbind_func(handle_svccmd_unbind, NULL); chanserv_module = module_register("ChanServ", CS_LOG, "chanserv.help", chanserv_expand_variable); DEFINE_COMMAND(register, 1, MODCMD_REQUIRE_AUTHED, "flags", "+acceptchan,+channel", NULL); DEFINE_COMMAND(noregister, 1, MODCMD_REQUIRE_AUTHED, "flags", "+helping", NULL); @@ -9966,8 +10017,8 @@ init_chanserv(const char *nick) modcmd_register(chanserv_module, "dnrsearch remove", NULL, 0, 0, NULL); modcmd_register(chanserv_module, "dnrsearch count", NULL, 0, 0, NULL); DEFINE_COMMAND(move, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN, "template", "register", NULL); - DEFINE_COMMAND(csuspend, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN, "flags", "+helping", NULL); - DEFINE_COMMAND(cunsuspend, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN, "flags", "+helping", NULL); + DEFINE_COMMAND(csuspend, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN|MODCMD_IGNORE_CSUSPEND, "flags", "+helping", NULL); + DEFINE_COMMAND(cunsuspend, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN|MODCMD_IGNORE_CSUSPEND, "flags", "+helping", NULL); DEFINE_COMMAND(createnote, 5, 0, "level", "800", NULL); DEFINE_COMMAND(removenote, 2, 0, "level", "800", NULL); @@ -10127,7 +10178,7 @@ init_chanserv(const char *nick) const char *modes = conf_get_data("services/chanserv/modes", RECDB_QSTRING); chanserv = AddLocalUser(nick, nick, NULL, "Channel Services", modes); service_register(chanserv)->trigger = '!'; - reg_chanmsg_func('\001', chanserv, chanserv_ctcp_check); + reg_chanmsg_func('\001', chanserv, chanserv_ctcp_check, NULL); } saxdb_register("ChanServ", chanserv_saxdb_read, chanserv_saxdb_write); @@ -10156,7 +10207,7 @@ init_chanserv(const char *nick) } } - reg_exit_func(chanserv_db_cleanup); + reg_exit_func(chanserv_db_cleanup, NULL); message_register_table(msgtab); }