]> jfr.im git - solanum.git/blobdiff - modules/um_callerid.c
/accept list should track nick changes when you share channels (#96)
[solanum.git] / modules / um_callerid.c
index 452b7b96364dc940c0130153879af44e0315334d..2fa47db4d064e1465f38dad9adf6635c17875414 100644 (file)
 #include "s_newconf.h"
 #include "hook.h"
 #include "supported.h"
+#include "logger.h"
 
 static int
 um_callerid_modinit(void)
 {
        user_modes['g'] = find_umode_slot();
+       if (!user_modes['g'])
+       {
+               ierror("um_callerid: unable to allocate usermode slot for +g; unloading module.");
+               return -1;
+       }
+
+       user_modes['G'] = find_umode_slot();
+       if (!user_modes['G'])
+       {
+               user_modes['g'] = 0;
+
+               ierror("um_callerid: unable to allocate usermode slot for +G; unloading module.");
+               return -1;
+       }
+
        construct_umodebuf();
 
-        add_isupport("CALLERID", isupport_stringptr, "g");
+       add_isupport("CALLERID", isupport_umode, "g");
 
        return 0;
 }
@@ -58,15 +74,18 @@ static void
 um_callerid_moddeinit(void)
 {
        user_modes['g'] = 0;
+       user_modes['G'] = 0;
        construct_umodebuf();
 
        delete_isupport("CALLERID");
 }
 
-#define IsSetCallerID(c)       ((c->umodes & user_modes['g']) == user_modes['g'])
+#define IsSetStrictCallerID(c) ((c->umodes & user_modes['g']) == user_modes['g'])
+#define IsSetRelaxedCallerID(c)        ((c->umodes & user_modes['G']) == user_modes['G'])
+#define IsSetAnyCallerID(c)    (IsSetStrictCallerID(c) || IsSetRelaxedCallerID(c))
 
 static const char um_callerid_desc[] =
-       "Provides usermode +g which restricts messages from unauthorized users.";
+       "Provides usermodes +g and +G which restrict messages from unauthorized users.";
 
 static bool
 allow_message(struct Client *source_p, struct Client *target_p)
@@ -74,14 +93,17 @@ allow_message(struct Client *source_p, struct Client *target_p)
        if (!MyClient(target_p))
                return true;
 
-       if (!IsSetCallerID(target_p))
+       if (!IsSetAnyCallerID(target_p))
+               return true;
+
+       if (IsSetRelaxedCallerID(target_p) && has_common_channel(source_p, target_p) && !IsSetStrictCallerID(target_p))
                return true;
 
        if (IsServer(source_p))
                return true;
 
        /* XXX: controversial?  allow opers to send through +g */
-       if (IsOper(source_p))
+       if (IsOperGeneral(source_p))
                return true;
 
        if (accept_message(source_p, target_p))
@@ -100,7 +122,7 @@ send_callerid_notice(enum message_type msgtype, struct Client *source_p, struct
                return;
 
        sendto_one_numeric(source_p, ERR_TARGUMODEG, form_str(ERR_TARGUMODEG),
-               target_p->name);
+               target_p->name, IsSetStrictCallerID(target_p) ? "+g" : "+G");
 
        if ((target_p->localClient->last_caller_id_time + ConfigFileEntry.caller_id_wait) < rb_current_time())
        {
@@ -109,7 +131,7 @@ send_callerid_notice(enum message_type msgtype, struct Client *source_p, struct
 
                sendto_one(target_p, form_str(RPL_UMODEGMSG),
                           me.name, target_p->name, source_p->name,
-                          source_p->username, source_p->host);
+                          source_p->username, source_p->host, IsSetStrictCallerID(target_p) ? "+g" : "+G");
 
                target_p->localClient->last_caller_id_time = rb_current_time();
        }
@@ -118,6 +140,10 @@ send_callerid_notice(enum message_type msgtype, struct Client *source_p, struct
 static bool
 add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_p, struct Client *target_p)
 {
+       /* only do this on source_p's server */
+       if (!MyClient(source_p))
+               return true;
+
        /*
         * XXX: Controversial? Allow target users to send replies
         * through a +g.  Rationale is that people can presently use +g
@@ -125,9 +151,9 @@ add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_
         * as a way of griefing.  --nenolod
         */
        if(msgtype != MESSAGE_TYPE_NOTICE &&
-                       IsSetCallerID(source_p) &&
-                       !accept_message(target_p, source_p) &&
-                       !IsOper(target_p))
+               IsSetAnyCallerID(source_p) &&
+               !accept_message(target_p, source_p) &&
+               !IsOperGeneral(target_p))
        {
                if(rb_dlink_list_length(&source_p->localClient->allow_list) <
                                (unsigned long)ConfigFileEntry.max_accept)
@@ -139,7 +165,7 @@ add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_
                {
                        sendto_one_numeric(source_p, ERR_OWNMODE,
                                        form_str(ERR_OWNMODE),
-                                       target_p->name, "+g");
+                                       target_p->name, IsSetStrictCallerID(target_p) ? "+g" : "+G");
                        return false;
                }
        }
@@ -148,11 +174,12 @@ add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_
 }
 
 static void
-h_can_invite(void *vdata)
+h_hdl_invite(void *vdata)
 {
        hook_data_channel_approval *data = vdata;
        struct Client *source_p = data->client;
        struct Client *target_p = data->target;
+       static char errorbuf[BUFSIZE];
 
        if (data->approved)
                return;
@@ -166,9 +193,11 @@ h_can_invite(void *vdata)
        if (allow_message(source_p, target_p))
                return;
 
-       send_callerid_notice(MESSAGE_TYPE_PRIVMSG, source_p, target_p);
+       snprintf(errorbuf, sizeof errorbuf, form_str(ERR_TARGUMODEG),
+                target_p->name, IsSetStrictCallerID(target_p) ? "+g" : "+G");
 
        data->approved = ERR_TARGUMODEG;
+       data->error = errorbuf;
 }
 
 static void
@@ -197,7 +226,7 @@ h_hdl_privmsg_user(void *vdata)
 }
 
 static mapi_hfn_list_av1 um_callerid_hfnlist[] = {
-       { "can_invite", h_can_invite },
+       { "invite", h_hdl_invite },
        { "privmsg_user", h_hdl_privmsg_user },
        { NULL, NULL }
 };