]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/chanserv.c
Updated ChanServ.netinfo oper count to only include opers who do not have user modes...
[irc/evilnet/x3.git] / src / chanserv.c
index 8f422663c77d55278c1e1cbe054171d87c886860..5c54290d9e7fd096dbca76f5c3ff0f7419f537f5 100644 (file)
@@ -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,6 +257,7 @@ 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." },
@@ -441,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" },
@@ -994,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];
@@ -3166,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);
                 }
@@ -3289,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);
@@ -3309,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;
        }
     }
@@ -3807,6 +3810,13 @@ 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)
 {
@@ -3934,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))
         {
@@ -4258,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) {
@@ -4268,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 */
@@ -4413,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; ii<channel->banlist.used; ii++)
     {
@@ -4485,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');
@@ -5514,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);
@@ -5540,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))
@@ -5559,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;
 }
 
@@ -5679,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))
                 {
@@ -6650,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;
    }
 
@@ -6998,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);
 }
 
@@ -7038,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; ii<set_shows_list.used; ++ii)
         if(target == set_shows_list.list[ii])
@@ -7818,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) {
@@ -7837,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 */
@@ -8059,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(
@@ -8238,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;
 
@@ -8581,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;
@@ -8620,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;
@@ -8696,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;
@@ -8745,7 +8772,7 @@ handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason))
 }
 
 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;
 
@@ -8765,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;
 
@@ -8808,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;
@@ -8943,7 +8970,7 @@ static void handle_rename(struct handle_info *handle, const char *old_handle, UN
 }
 
 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;
 
@@ -9915,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)
@@ -9960,18 +9987,18 @@ init_chanserv(const char *nick)
 
     if (nick) {
         reg_server_link_func(handle_server_link, NULL);
-        reg_new_channel_func(handle_new_channel);
+        reg_new_channel_func(handle_new_channel, NULL);
         reg_join_func(handle_join, NULL);
-        reg_part_func(handle_part);
-        reg_kick_func(handle_kick);
-        reg_topic_func(handle_topic);
-        reg_mode_change_func(handle_mode);
+        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);
+        reg_auth_func(handle_auth, NULL);
     }
 
     reg_handle_rename_func(handle_rename, NULL);
-    reg_unreg_func(handle_unreg);
+    reg_unreg_func(handle_unreg, NULL);
 
     handle_dnrs = dict_new();
     dict_set_free_data(handle_dnrs, free);
@@ -9980,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);
@@ -9990,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);
 
@@ -10151,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);
@@ -10180,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);
 }