]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/chanserv.c
global message function that will deal with multi languages. Made use of it with...
[irc/evilnet/x3.git] / src / chanserv.c
index e963adec541af791d61ded98c37d15bc7b64077e..6ff9d5fd2ec334c9381374175c7d591174ac4c8e 100644 (file)
@@ -291,7 +291,6 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_SET_CTCPREACTION",  "$bCTCPReaction$b %d - %s" },
     { "CSMSG_SET_TOPICREFRESH",  "$bTopicRefresh$b %d - %s" },
     { "CSMSG_SET_RESYNC",        "$bResync      $b %d - %s" },
-    { "CSMSG_SET_BANTYPE",       "$bBanType     $b %d - %s" },
     { "CSMSG_SET_BANTIMEOUT",    "$bBanTimeout  $b %d - %s" },
 
     { "CSMSG_USET_AUTOOP",       "$bAutoOp      $b %s" },
@@ -351,19 +350,10 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_BANTIMEOUT_1D", "Bans will be removed after 24 hours."},
     { "CSMSG_BANTIMEOUT_1W", "Bans will be removed after 1 week."},
 
-    { "CSMSG_BANTYPE_A", "*!user@host" },
-    { "CSMSG_BANTYPE_B", "*!*user@host" },
-    { "CSMSG_BANTYPE_C", "*!*@host" },
-    { "CSMSG_BANTYPE_D", "*!*user@*.host" },
-    { "CSMSG_BANTYPE_E", "*!*@*.host" },
-    { "CSMSG_BANTYPE_F", "nick!user@host" },
-    { "CSMSG_BANTYPE_G", "nick!*@host" },
-    { "CSMSG_BANTYPE_H", "nick!*user@*.host" },
-    { "CSMSG_BANTYPE_I", "nick!*@*.host" },
-
     { "CSMSG_INVITED_USER", "Invited $b%s$b to join %s." },
     { "CSMSG_INVITING_YOU_REASON", "$b%s$b invites you to join %s: %s" },
     { "CSMSG_INVITING_YOU", "$b%s$b invites you to join %s." },
+    { "CSMSG_CANNOT_INVITE", "You cannot invite %s to %s." },
     { "CSMSG_ALREADY_PRESENT", "%s is already in $b%s$b." },
     { "CSMSG_YOU_ALREADY_PRESENT", "You are already in $b%s$b." },
     { "CSMSG_LOW_CHANNEL_ACCESS", "You lack sufficient access in %s to use this command." },
@@ -523,6 +513,8 @@ static const struct message_entry msgtab[] = {
 /* Other things */
     { "CSMSG_EVENT_SEARCH_RESULTS", "$bChannel Events for %s$b" },
     { "CSMSG_LAST_INVALID", "Invalid argument.  must be 1-200" },
+    { "CSMSG_DEFCON_NO_NEW_CHANNELS", "You cannot register new channels at this time, please try again soon." },
+    { "CSMSG_DEFCON_NO_MODE_CHANGE", "You cannot change the MODE at this time, please try again soon." },
     { NULL, NULL }
 };
 
@@ -560,7 +552,6 @@ extern struct string_list *autojoin_channels;
 static dict_t plain_dnrs, mask_dnrs, handle_dnrs;
 static struct log_type *CS_LOG;
 struct adduserPending* adduser_pendings = NULL;
-extern const char *hidden_host_suffix;
 unsigned int adduser_pendings_count = 0;
 unsigned long god_timeout;
 
@@ -724,22 +715,13 @@ struct charOptionValues {
     { '3', "CSMSG_BANTIMEOUT_4H" },
     { '4', "CSMSG_BANTIMEOUT_1D" },
     { '5', "CSMSG_BANTIMEOUT_1W" }
-}, resyncValues[] = {
+},
+resyncValues[] = {
     { 'n', "CSMSG_RESYNC_NEVER" },
     { '1', "CSMSG_RESYNC_3_HOURS" },
     { '2', "CSMSG_RESYNC_6_HOURS" },
     { '3', "CSMSG_RESYNC_12_HOURS" },
     { '4', "CSMSG_RESYNC_24_HOURS" }
-}, banTypeValues[] = {
-    { '1', "CSMSG_BANTYPE_A" },
-    { '2', "CSMSG_BANTYPE_B" },
-    { '3', "CSMSG_BANTYPE_C" },
-    { '4', "CSMSG_BANTYPE_D" },
-    { '5', "CSMSG_BANTYPE_E" },
-    { '6', "CSMSG_BANTYPE_F" },
-    { '7', "CSMSG_BANTYPE_G" },
-    { '8', "CSMSG_BANTYPE_H" },
-    { '9', "CSMSG_BANTYPE_I" }
 };
 
 static const struct {
@@ -757,7 +739,6 @@ static const struct {
     { "CSMSG_SET_CTCPREACTION", "ctcpreaction", 'n', 10, ArrayLength(ctcpReactionValues), ctcpReactionValues },
     { "CSMSG_SET_BANTIMEOUT",   "bantimeout",   '0', 11, ArrayLength(banTimeoutValues), banTimeoutValues },
     { "CSMSG_SET_RESYNC",       "resync",       'n', 12, ArrayLength(resyncValues), resyncValues },
-    { "CSMSG_SET_BANTYPE",      "bantype",      '4', 13, ArrayLength(banTypeValues), banTypeValues },
 };
 
 struct userData *helperList;
@@ -1697,7 +1678,7 @@ protect_user(const struct userNode *victim, const struct userNode *aggressor, st
 }
 
 static int
-validate_op(struct userNode *user, struct chanNode *channel, struct userNode *victim)
+validate_op(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, struct userNode *victim)
 {
     struct chanData *cData = channel->channel_info;
     struct userData *cs_victim;
@@ -1706,7 +1687,10 @@ validate_op(struct userNode *user, struct chanNode *channel, struct userNode *vi
         || (cs_victim->access < UL_OP /* cData->lvlOpts[lvlGiveOps]*/))
        && !check_user_level(channel, user, lvlEnfOps, 0, 0))
     {
-       send_message(user, chanserv, "CSMSG_OPBY_LOCKED");
+        if(cmd)
+           reply("CSMSG_OPBY_LOCKED");
+        else
+            send_message(user, chanserv, "CSMSG_OPBY_LOCKED");
        return 0;
     }
 
@@ -1714,7 +1698,7 @@ validate_op(struct userNode *user, struct chanNode *channel, struct userNode *vi
 }
 
 static int
-validate_halfop(struct userNode *user, struct chanNode *channel, struct userNode *victim)
+validate_halfop(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, struct userNode *victim)
 {
     struct chanData *cData = channel->channel_info;
     struct userData *cs_victim;
@@ -1723,7 +1707,7 @@ validate_halfop(struct userNode *user, struct chanNode *channel, struct userNode
         || (cs_victim->access < UL_HALFOP /* cData->lvlOpts[lvlGiveHalfOps] */))
        && !check_user_level(channel, user, lvlEnfHalfOps, 0, 0))
     {
-        send_message(user, chanserv, "CSMSG_HOPBY_LOCKED");
+        reply("CSMSG_HOPBY_LOCKED");
         return 0;
     }
 
@@ -1732,17 +1716,17 @@ validate_halfop(struct userNode *user, struct chanNode *channel, struct userNode
 
 
 static int
-validate_deop(struct userNode *user, struct chanNode *channel, struct userNode *victim)
+validate_deop(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, struct userNode *victim)
 {
     if(IsService(victim))
     {
-       send_message(user, chanserv, "MSG_SERVICE_IMMUNE", victim->nick);
+       reply("MSG_SERVICE_IMMUNE", victim->nick);
        return 0;
     }
 
     if(protect_user(victim, user, channel->channel_info))
     {
-       send_message(user, chanserv, "CSMSG_USER_PROTECTED", victim->nick);
+       reply("CSMSG_USER_PROTECTED", victim->nick);
        return 0;
     }
 
@@ -1750,17 +1734,17 @@ validate_deop(struct userNode *user, struct chanNode *channel, struct userNode *
 }
 
 static int
-validate_dehop(struct userNode *user, struct chanNode *channel, struct userNode *victim)
+validate_dehop(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, struct userNode *victim)
 {
     if(IsService(victim))
     {
-        send_message(user, chanserv, "MSG_SERVICE_IMMUNE", victim->nick);
+        reply("MSG_SERVICE_IMMUNE", victim->nick);
         return 0;
     }
 
     if(protect_user(victim, user, channel->channel_info))
     {
-        send_message(user, chanserv, "CSMSG_USER_PROTECTED", victim->nick);
+        reply("CSMSG_USER_PROTECTED", victim->nick);
         return 0;
     }
 
@@ -1981,6 +1965,10 @@ static CHANSERV_FUNC(cmd_register)
     struct do_not_register *dnr;
     unsigned int n;
 
+    if (checkDefCon(DEFCON_NO_NEW_CHANNELS) && !IsOper(user)) {
+        reply("CSMSG_DEFCON_NO_NEW_CHANNELS");
+        return 0;
+    }
 
     if(channel)
     {
@@ -2816,7 +2804,7 @@ static CHANSERV_FUNC(cmd_mdelhalfop)
 
 /* trim_lamers.. */
 static int
-cmd_trim_bans(struct userNode *user, struct chanNode *channel, unsigned long duration)
+cmd_trim_bans(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, unsigned long duration)
 {
     struct banData *bData, *next;
     char interval[INTERVALLEN];
@@ -2837,12 +2825,12 @@ cmd_trim_bans(struct userNode *user, struct chanNode *channel, unsigned long dur
     }
 
     intervalString(interval, duration, user->handle_info);
-    send_message(user, chanserv, "CSMSG_TRIMMED_LAMERS", count, channel->name, interval);
+    reply("CSMSG_TRIMMED_LAMERS", count, channel->name, interval);
     return 1;
 }
 
 static int
-cmd_trim_users(struct userNode *user, struct chanNode *channel, unsigned short min_access, unsigned short max_access, unsigned long duration, int vacation)
+cmd_trim_users(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, unsigned short min_access, unsigned short max_access, unsigned long duration, int vacation)
 {
     struct userData *actor, *uData, *next;
     char interval[INTERVALLEN];
@@ -2852,13 +2840,13 @@ cmd_trim_users(struct userNode *user, struct chanNode *channel, unsigned short m
     actor = GetChannelUser(channel->channel_info, user->handle_info);
     if(min_access > max_access)
     {
-        send_message(user, chanserv, "CSMSG_BAD_RANGE", min_access, max_access);
+        reply("CSMSG_BAD_RANGE", min_access, max_access);
         return 0;
     }
 
     if((actor->access <= max_access) && !IsHelping(user))
     {
-       send_message(user, chanserv, "CSMSG_NO_ACCESS");
+       reply("CSMSG_NO_ACCESS");
        return 0;
     }
 
@@ -2886,7 +2874,7 @@ cmd_trim_users(struct userNode *user, struct chanNode *channel, unsigned short m
         min_access = 1;
         max_access = (actor->access > UL_OWNER) ? UL_OWNER : (actor->access - 1);
     }
-    send_message(user, chanserv, "CSMSG_TRIMMED_USERS", count, min_access, max_access, channel->name, intervalString(interval, duration, user->handle_info));
+    reply("CSMSG_TRIMMED_USERS", count, min_access, max_access, channel->name, intervalString(interval, duration, user->handle_info));
     return 1;
 }
 
@@ -2908,22 +2896,22 @@ static CHANSERV_FUNC(cmd_trim)
 
     if(!irccasecmp(argv[1], "lamers"))
     {
-       cmd_trim_bans(user, channel, duration); /* trim_lamers.. */
+       cmd_trim_bans(cmd, user, channel, duration); /* trim_lamers.. */
        return 1;
     }
     else if(!irccasecmp(argv[1], "users"))
     {
-       cmd_trim_users(user, channel, 0, 0, duration, vacation);
+       cmd_trim_users(cmd, user, channel, 0, 0, duration, vacation);
        return 1;
     }
     else if(parse_level_range(&min_level, &max_level, argv[1]))
     {
-       cmd_trim_users(user, channel, min_level, max_level, duration, vacation);
+       cmd_trim_users(cmd, user, channel, min_level, max_level, duration, vacation);
        return 1;
     }
     else if((min_level = user_level_from_name(argv[1], UL_OWNER)))
     {
-       cmd_trim_users(user, channel, min_level, min_level, duration, vacation);
+       cmd_trim_users(cmd, user, channel, min_level, min_level, duration, vacation);
        return 1;
     }
     else
@@ -3043,7 +3031,7 @@ static CHANSERV_FUNC(cmd_downall)
     return cmd_all(CSFUNC_ARGS, cmd_down);
 }
 
-typedef int validate_func_t(struct userNode *user, struct chanNode *channel, struct userNode *victim);
+typedef int validate_func_t(struct svccmd *cmd, struct userNode *user, struct chanNode *channel, struct userNode *victim);
 typedef void process_func_t(unsigned int num, struct userNode **newops, struct chanNode *channel, struct userNode *who, int announce);
 
 static int
@@ -3063,7 +3051,7 @@ modify_users(struct userNode *user, struct chanNode *channel, unsigned int argc,
         change->args[valid].u.member = GetUserMode(channel, victim);
         if(!change->args[valid].u.member)
             continue;
-        if(validate && !validate(user, channel, victim))
+        if(validate && !validate(cmd, user, channel, victim))
            continue;
         valid++;
     }
@@ -3136,113 +3124,13 @@ bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban
     return 0;
 }
 
-#define i_isdigit(x) isdigit((int) (unsigned char) (x))
-
-int is_ipv4_address(const char *host)
-{
-    while (*host != '\0') {
-       if (*host != '.' && !i_isdigit(*host))
-       return 0;
-       host++;
-   }
-    return 1;
-}
-
-static char *get_domain_mask(char *host)
-{
-    char *ptr;
-
-    if (strchr(host, '.') == NULL) {
-       /* no dots - toplevel domain or IPv6 address */
-       ptr = strrchr(host, ':');
-       if (ptr != NULL) {
-          /* IPv6 address, ban the last 64k addresses */
-          if (ptr[1] != '\0') strcpy(ptr+1, "*");
-       }
-       return host;
-    }
-
-    if (is_ipv4_address(host)) {
-       /* it's an IP address, change last digit to * */
-       ptr = strrchr(host, '.');
-       if (ptr != NULL && i_isdigit(ptr[1]))
-           strcpy(ptr+1, "*");
-    } else {
-       /* if more than one dot, skip the first
-          (dyn123.blah.net -> *.blah.net) */
-          ptr = strchr(host, '.');
-          if (ptr != NULL && strchr(ptr+1, '.') != NULL) {
-             host = ptr-1;
-             host[0] = '*';
-          }
-    }
-    return host;
-}
-
-char *generate_ban_hostmask(struct userNode *user, const char banopt)
-{
-    char *nickname = NULL;
-    char *ident = "*";
-    char *hostname = NULL;
-    char *mask = NULL;
-    char *usemask = NULL;
-    int len;
-
-    usemask = user->hostname;
-    if (IsFakeHost(user) && IsHiddenHost(user))
-        usemask = user->fakehost;
-    else if (IsSetHost(user))
-        usemask = strchr(user->sethost, '@') + 1;
-    else if (IsHiddenHost(user) && user->handle_info && hidden_host_suffix) {
-        usemask = alloca(strlen(user->handle_info->handle) + strlen(hidden_host_suffix) + 2);
-        sprintf(usemask, "%s.%s", user->handle_info->handle, hidden_host_suffix);
-    }
-
-    if((banopt == '6') || (banopt == '7') || (banopt == '8') || (banopt == '9'))
-       nickname = user->nick;
-    else
-       nickname = "*";
-
-    if((banopt == '4') || (banopt == '5') || (banopt == '8') || (banopt == '9'))
-        hostname = get_domain_mask(usemask);
-    else
-        hostname = usemask;
-
-    if((banopt == '1') || (banopt == '6')) {
-        if (IsSetHost(user)) {
-            ident = alloca(strcspn(user->sethost, "@")+2);
-            safestrncpy(ident, user->sethost, strcspn(user->sethost, "@")+1);
-        } else
-            ident = user->ident;
-    }
-    else if((banopt == '2') || (banopt == '4') || (banopt == '8')) {
-        if (IsSetHost(user)) {
-            ident = alloca(strcspn(user->sethost, "@")+3);
-            ident[0] = '*';
-            safestrncpy(ident+1, user->sethost, strcspn(user->sethost, "@")+1);
-        } else {
-            ident = malloc(strlen(user->ident)+1);
-            sprintf(ident, "*%s", user->ident);
-        }
-    } else
-        ident = "*";
-
-    /* Put it all together. */
-    len = strlen(ident) + strlen(hostname) + strlen(nickname) + 3;
-    mask = malloc(len);
-    sprintf(mask, "%s!%s@%s", nickname, ident, hostname);
-
-    return mask;
-}
-
 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;
-    struct chanData *cData;
     unsigned int offset, n, victimCount, duration = 0;
-    char *reason = "Bye.", *ban, *name, banopt;
+    char *reason = "Bye.", *ban, *name;
     char interval[INTERVALLEN];
 
     offset = (action & ACTION_ADD_TIMED_LAMER) ? 3 : 2;
@@ -3293,17 +3181,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
            return 0;
        }
 
-        if(!(cData = channel->channel_info)) {
-            banopt = '4';
-        }
-
-        if (!(cData->chOpts[chBanType])) {
-            banopt = '4';
-        } else {
-            banopt = cData->chOpts[chBanType];
-        }
-
-        ban = generate_ban_hostmask(victim, banopt);
+       ban = generate_hostmask(victim, GENMASK_STRICT_HOST|GENMASK_ANY_IDENT);
        name = victim->nick;
     }
     else
@@ -4514,6 +4392,7 @@ static CHANSERV_FUNC(cmd_topic)
     {
         if(cData->topic)
         {
+            /*XXX Why would we ever want to send chanserv as the setter? I dont understand  -Rubin */
             SetChannelTopic(channel, chanserv, p10 ? user : chanserv, cData->topic, 1);
             reply("CSMSG_TOPIC_SET", cData->topic);
             return 1;
@@ -4574,6 +4453,11 @@ static CHANSERV_FUNC(cmd_mode)
     
     if(argc < 2)
     {
+        if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(user)) {
+            reply("CSMSG_DEFCON_NO_MODE_CHANGE");
+            return 0;
+        }
+
         change = &channel->channel_info->modes;
        if(change->modes_set || change->modes_clear) {
             modcmd_chanmode_announce(change);
@@ -4647,6 +4531,17 @@ static CHANSERV_FUNC(cmd_invite)
         else
             send_message(invite, chanserv, "CSMSG_INVITING_YOU", user->nick, channel->name);
     }
+
+    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)) {
+              reply("CSMSG_CANNOT_INVITE", argv[1], channel->name);
+              return 0;
+            }
+        }
+    }
+
     irc_invite(chanserv, invite, channel);
     if(argc > 1)
        reply("CSMSG_INVITED_USER", argv[1], channel->name);
@@ -4795,9 +4690,9 @@ static CHANSERV_FUNC(cmd_info)
     reply("CSMSG_CHANNEL_VISITED", intervalString(buffer, now - cData->visited, user->handle_info));
 
     privileged = IsStaff(user);
-    if(privileged)
+    /* if(privileged) */
         reply("CSMSG_CHANNEL_REGISTERED", intervalString(buffer, now - cData->registered, user->handle_info));
-    if(((uData && uData->access >= UL_COOWNER) || privileged) && cData->registrar)
+    if(/*((uData && uData->access >= UL_COOWNER) || privileged) && */cData->registrar)
         reply("CSMSG_CHANNEL_REGISTRAR", cData->registrar);
 
     if(privileged && (dnr = chanserv_is_dnr(channel->name, NULL)))
@@ -5569,7 +5464,7 @@ typedef struct chanservSearch
 typedef void (*channel_search_func)(struct chanData *channel, void *data);
 
 static search_t
-chanserv_search_create(struct userNode *user, unsigned int argc, char *argv[])
+chanserv_search_create(struct svccmd *cmd, struct userNode *user, unsigned int argc, char *argv[])
 {
     search_t search;
     unsigned int i;
@@ -5583,7 +5478,7 @@ chanserv_search_create(struct userNode *user, unsigned int argc, char *argv[])
        /* Assume all criteria require arguments. */
        if(i == (argc - 1))
        {
-           send_message(user, chanserv, "MSG_MISSING_PARAMS", argv[i]);
+           reply("MSG_MISSING_PARAMS", argv[i]);
             goto fail;
        }
 
@@ -5604,7 +5499,7 @@ chanserv_search_create(struct userNode *user, unsigned int argc, char *argv[])
                search->flags |= CHANNEL_SUSPENDED;
            else
            {
-               send_message(user, chanserv, "CSMSG_INVALID_CFLAG", argv[i]);
+               reply("CSMSG_INVALID_CFLAG", argv[i]);
                goto fail;
            }
        }
@@ -5612,7 +5507,7 @@ chanserv_search_create(struct userNode *user, unsigned int argc, char *argv[])
            search->limit = strtoul(argv[++i], NULL, 10);
        else
        {
-           send_message(user, chanserv, "MSG_INVALID_CRITERIA", argv[i]);
+           reply("MSG_INVALID_CRITERIA", argv[i]);
            goto fail;
        }
     }
@@ -5689,7 +5584,7 @@ static CHANSERV_FUNC(cmd_search)
        return 0;
     }
 
-    search = chanserv_search_create(user, argc - 2, argv + 2);
+    search = chanserv_search_create(cmd, user, argc - 2, argv + 2);
     if(!search)
         return 0;
 
@@ -5770,7 +5665,7 @@ static MODCMD_FUNC(chan_opt_defaulttopic)
                && !match_ircglob(channel->channel_info->topic, channel->channel_info->topic_mask))
                 reply("CSMSG_TOPIC_MISMATCH", channel->name);
        }
-        SetChannelTopic(channel, chanserv, chanserv, topic ? topic : "", 1);
+        SetChannelTopic(channel, chanserv, user, topic ? topic : "", 1);
     }
 
     if(channel->channel_info->topic)
@@ -5866,6 +5761,11 @@ static MODCMD_FUNC(chan_opt_modes)
 
     if(argc > 1)
     {
+        if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(user)) {
+            reply("CSMSG_DEFCON_NO_MODE_CHANGE");
+            return 0;
+        }
+
         if(!check_user_level(channel, user, lvlEnfModes, 1, 0))
         {
             reply("CSMSG_NO_ACCESS");
@@ -6216,11 +6116,6 @@ static MODCMD_FUNC(chan_opt_resync)
     return channel_multiple_option(chResync, CSFUNC_ARGS);
 }
 
-static MODCMD_FUNC(chan_opt_bantype)
-{
-    return channel_multiple_option(chBanType, CSFUNC_ARGS);
-}
-
 static struct svccmd_list set_shows_list;
 
 static void
@@ -7457,12 +7352,12 @@ handle_topic(struct userNode *user, struct chanNode *channel, const char *old_to
         conform_topic(cData->topic_mask, channel->topic, new_topic);
         if(*new_topic)
         {
-           SetChannelTopic(channel, chanserv, chanserv, new_topic, 1);
+           SetChannelTopic(channel, chanserv, user, new_topic, 1);
            /* and fall through to topicsnarf code below.. */
         }
         else /* Topic couldnt fit into mask, was too long */
         {
-            SetChannelTopic(channel, chanserv, chanserv, old_topic, 1);
+            SetChannelTopic(channel, chanserv, user, old_topic, 1);
             send_message(user, chanserv, "CSMSG_TOPICMASK_CONFLICT1", channel->name, cData->topic_mask);
             send_message(user, chanserv, "CSMSG_TOPICMASK_CONFLICT2", TOPICLEN);
             return 1;
@@ -7520,7 +7415,7 @@ handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_ch
         else if(change->args[ii].mode & MODE_CHANOP)
         {
             const struct userNode *victim = change->args[ii].u.member->user;
-            if(IsService(victim) || validate_op(user, channel, (struct userNode*)victim))
+            if(IsService(victim) || validate_op(NULL, user, channel, (struct userNode*)victim))
                 continue;
             if(!bounce)
                 bounce = mod_chanmode_alloc(change->argc + 1 - ii);
@@ -7754,8 +7649,7 @@ chanserv_conf_read(void)
             "PubCmd", "InviteMe", "UserInfo","EnfOps",
             "EnfHalfOps", "EnfModes", "EnfTopic", "TopicSnarf", "Setters", 
             /* multiple choice options */
-            "AutoMode", "CtcpReaction", "Protect", "Toys", "TopicRefresh",
-            "Resync", "BanType"
+            "AutoMode", "CtcpReaction", "Protect", "Toys", "TopicRefresh", "Resync",
             /* binary options */
             "DynLimit", "NoDelete", "BanTimeout",
             /* delimiter */
@@ -8702,7 +8596,6 @@ init_chanserv(const char *nick)
     DEFINE_CHANNEL_OPTION(setters);
     DEFINE_CHANNEL_OPTION(topicrefresh);
     DEFINE_CHANNEL_OPTION(resync);
-    DEFINE_CHANNEL_OPTION(bantype);
     DEFINE_CHANNEL_OPTION(ctcpreaction);
     DEFINE_CHANNEL_OPTION(bantimeout);
     DEFINE_CHANNEL_OPTION(inviteme);