]> jfr.im git - irc/charybdis-ircd/charybdis.git/commitdiff
Add option to immediately apply nick RESVs by FNC'ing.
authorKeith Buck <redacted>
Sun, 25 Mar 2012 01:34:45 +0000 (01:34 +0000)
committerKeith Buck <redacted>
Sun, 25 Mar 2012 01:34:45 +0000 (01:34 +0000)
doc/example.conf
doc/reference.conf
include/client.h
include/s_conf.h
modules/m_resv.c
src/client.c
src/newconf.c
src/s_conf.c

index c02b3c7d1677a3ff72ca1ea8bf4fa77460cfcc3c..ba010723a753cf0d77bd30a43393724e4f2f3b9f 100755 (executable)
@@ -478,6 +478,7 @@ general {
        ts_max_delta = 5 minutes;
        client_exit = yes;
        collision_fnc = yes;
+       resv_fnc = yes;
        global_snotices = yes;
        dline_with_reason = yes;
        kline_delay = 0 seconds;
index 1e3e8996693756c5600989a270ce0ec51e74740b..38519a97f88ddc9c0e38a8c5d7a9d094ada5fa96 100755 (executable)
@@ -1024,6 +1024,13 @@ general {
         */
        collision_fnc = yes;
 
+       /* resv fnc: change a user's nick to a nick they have recently used
+        * (or their UID, if no such nick can be found) when a resv matching
+        * them is set by services. Only enable this if all servers on the
+        * network allow remote nicks to start with a digit.
+        */
+       resv_fnc = yes;
+
        /* global snotices: send out certain snotices (most +b, +f, +y,
         * some +s) to other servers via ENCAP SNOTE. Received SNOTEs are
         * displayed unconditionally.
index 3856f2f3aad9fa578f69e952b13b1790d1d7e8dc..d394103ad6acecc6b2d9042c5a55d37f0d3c74f3 100644 (file)
@@ -566,6 +566,7 @@ extern void check_klines_event(void *unused);
 extern void check_klines(void);
 extern void check_dlines(void);
 extern void check_xlines(void);
+extern void resv_nick_fnc(const char *mask, const char *reason, int temp_time);
 
 extern const char *get_client_name(struct Client *client, int show_ip);
 extern const char *log_client_name(struct Client *, int);
index 722e9352ce50c27ec53b97a066f120754c175027..2587a42b3f90648488bab3745ea85547a12498e7 100644 (file)
@@ -220,6 +220,7 @@ struct config_file_entry
        int throttle_duration;
        int target_change;
        int collision_fnc;
+       int resv_fnc;
        int default_umodes;
        int global_snotices;
        int operspy_dont_care_user_info;
index 97f9edbae9ae5037d08ad830a64b2557da7480f6..98e61fb4a4750cb2026ab5e29f5c86844c80dab8 100644 (file)
@@ -361,6 +361,7 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
                }
 
                rb_dlinkAddAlloc(aconf, &resv_conf_list);
+               resv_nick_fnc(aconf->host, aconf->passwd, temp_time);
        }
        else
                sendto_one_notice(source_p, ":You have specified an invalid resv: [%s]", name);
index 513e941d36a2c04db163fb16345cd6473d11e86c..8e895dfca325b2ff241095b3bf6e67a11d5ca4dc 100644 (file)
@@ -600,6 +600,86 @@ check_xlines(void)
        }
 }
 
+/* resv_nick_fnc
+ *
+ * inputs              - resv, reason, time
+ * outputs             - NONE
+ * side effects        - all local clients matching resv will be FNC'd
+ */
+void
+resv_nick_fnc(const char *mask, const char *reason, int temp_time)
+{
+       struct Client *client_p, *target_p;
+       rb_dlink_node *ptr;
+       rb_dlink_node *next_ptr;
+       char *nick;
+       char note[NICKLEN+10];
+
+       if (!ConfigFileEntry.resv_fnc)
+               return;
+
+       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+       {
+               client_p = ptr->data;
+
+               if(IsMe(client_p) || !IsPerson(client_p) || IsExemptResv(client_p))
+                       continue;
+
+               if(match_esc(mask, client_p->name))
+               {
+                       nick = client_p->id;
+
+                       /* Tell opers. */
+                       sendto_realops_snomask(SNO_GENERAL, L_ALL,
+                               "RESV forced nick change for %s!%s@%s to %s; nick matched [%s] (%s)",
+                               client_p->name, client_p->username, client_p->host, nick, mask, reason);
+
+                       sendto_realops_snomask(SNO_NCHANGE, L_ALL,
+                               "Nick change: From %s to %s [%s@%s]",
+                               client_p->name, nick, client_p->username, client_p->host);
+
+                       /* Tell the user. */
+                       if (temp_time > 0)
+                       {
+                               sendto_one_notice(client_p,
+                                       ":*** Nick %s is temporarily unavailable on this server.",
+                                       client_p->name);
+                       }
+                       else
+                       {
+                               sendto_one_notice(client_p,
+                                       ":*** Nick %s is no longer available on this server.",
+                                       client_p->name);
+                       }
+
+                       /* Do all of the nick-changing gymnastics. */
+                       client_p->tsinfo = rb_current_time();
+                       add_history(client_p, 1);
+
+                       invalidate_bancache_user(client_p);
+
+                       sendto_common_channels_local(client_p, NOCAPS, ":%s!%s@%s NICK :%s",
+                               client_p->name, client_p->username, client_p->host, nick);
+                       sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
+                               use_id(client_p), nick, (long) client_p->tsinfo);
+
+                       del_from_client_hash(client_p->name, client_p);
+                       rb_strlcpy(client_p->name, nick, sizeof(client_p->name));
+                       add_to_client_hash(nick, client_p);
+
+                       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head)
+                       {
+                               target_p = ptr->data;
+                               rb_dlinkFindDestroy(client_p, &target_p->localClient->allow_list);
+                               rb_dlinkDestroy(ptr, &client_p->on_allow_list);
+                       }
+
+                       rb_snprintf(note, sizeof(note), "Nick: %s", nick);
+                       rb_note(client_p->localClient->F, note);
+               }
+       }
+}
+
 /*
  * update_client_exit_stats
  *
index ddc9f93beb0383f1367514d2e54e56ba17c59ed7..9260024a3d438c7d9613b7d2b0a1ace4f013031b 100644 (file)
@@ -2235,6 +2235,7 @@ static struct ConfEntry conf_general_table[] =
        { "caller_id_wait",     CF_TIME,  NULL, 0, &ConfigFileEntry.caller_id_wait      },
        { "client_exit",        CF_YESNO, NULL, 0, &ConfigFileEntry.client_exit         },
        { "collision_fnc",      CF_YESNO, NULL, 0, &ConfigFileEntry.collision_fnc       },
+       { "resv_fnc",           CF_YESNO, NULL, 0, &ConfigFileEntry.resv_fnc            },
        { "connect_timeout",    CF_TIME,  NULL, 0, &ConfigFileEntry.connect_timeout     },
        { "default_floodcount", CF_INT,   NULL, 0, &ConfigFileEntry.default_floodcount  },
        { "default_ident_timeout",      CF_INT, NULL, 0, &ConfigFileEntry.default_ident_timeout         },
index 93849e028e7536dce8fa971c9189b7f010689419..ca93f05d6885c11b38d71a888cf5c3135bcbeeda 100644 (file)
@@ -742,6 +742,7 @@ set_default_conf(void)
        ConfigFileEntry.use_whois_actually = YES;
        ConfigFileEntry.burst_away = NO;
        ConfigFileEntry.collision_fnc = YES;
+       ConfigFileEntry.resv_fnc = YES;
        ConfigFileEntry.global_snotices = YES;
        ConfigFileEntry.operspy_dont_care_user_info = NO;
        ConfigFileEntry.use_propagated_bans = YES;