]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/m_list.c
Implement operspy for /LIST.
[irc/rqf/shadowircd.git] / modules / m_list.c
index db397a2b782dc68c225b00f10665a10b976f3c1f..0274443d6842311e5362ff262fbf76922052cbfc 100644 (file)
@@ -30,7 +30,6 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $Id: m_list.c 3372 2007-04-03 10:18:07Z nenolod $
  */
 
 #include "stdinc.h"
@@ -41,6 +40,7 @@
 #include "ircd.h"
 #include "numeric.h"
 #include "s_conf.h"
+#include "s_newconf.h"
 #include "s_serv.h"
 #include "send.h"
 #include "msg.h"
@@ -103,7 +103,6 @@ static void safelist_check_cliexit(hook_data_client_exit * hdata)
 }
 
 /* m_list()
- *      parv[0] = sender prefix
  *      parv[1] = channel
  *
  * XXX - With SAFELIST, do we really need to continue pacing?
@@ -116,7 +115,6 @@ static int m_list(struct Client *client_p, struct Client *source_p, int parc, co
        if (source_p->localClient->safelist_data != NULL)
        {
                sendto_one_notice(source_p, ":/LIST aborted");
-               sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
                safelist_client_release(source_p);
                return 0;
        }
@@ -138,7 +136,6 @@ static int m_list(struct Client *client_p, struct Client *source_p, int parc, co
 }
 
 /* mo_list()
- *      parv[0] = sender prefix
  *      parv[1] = channel
  */
 static int mo_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
@@ -150,21 +147,21 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c
        if (source_p->localClient->safelist_data != NULL)
        {
                sendto_one_notice(source_p, ":/LIST aborted");
-               sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
                safelist_client_release(source_p);
                return 0;
        }
 
-       /* XXX rather arbitrary -- jilles */
-       params.users_min = 3;
+       /* Let the user set it */
+       params.users_min = ConfigFileEntry.hide_channel_below_users;
        params.users_max = INT_MAX;
+       params.operspy = 0;
 
        if (parc > 1 && parv[1] != NULL && !IsChannelName(parv[1]))
        {
                args = LOCAL_COPY(parv[1]);
-               /* Make any specification cancel out defaults */
-               if (*args == '<')
-                       params.users_min = 0;
+
+               /* Cancel out default minimum. */
+               params.users_min = 0;
 
                for (i = 0; i < 2; i++)
                {
@@ -193,6 +190,12 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c
                                else
                                        params.users_min = 0;
                        }
+                       /* Only accept operspy as the first option. */
+                       else if (*args == '!' && IsOperSpy(source_p) && i == 0)
+                       {
+                               params.operspy = 1;
+                               report_operspy(source_p, "LIST", p);
+                       }
 
                        if (EmptyString(p))
                                break;
@@ -254,6 +257,7 @@ static void safelist_client_instantiate(struct Client *client_p, struct ListClie
        self->hash_indice = 0;
        self->users_min = params->users_min;
        self->users_max = params->users_max;
+       self->operspy = params->operspy;
 
        client_p->localClient->safelist_data = self;
 
@@ -324,9 +328,9 @@ static void safelist_channel_named(struct Client *source_p, const char *name)
                return;
        }
 
-       if (ShowChannel(source_p, chptr))
-               sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, chptr->chname,
-                          rb_dlink_list_length(&chptr->members),
+       if (!SecretChannel(chptr) || IsMember(source_p, chptr))
+               sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, "",
+                          chptr->chname, rb_dlink_list_length(&chptr->members),
                           chptr->topic == NULL ? "" : chptr->topic);
 
        sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
@@ -345,15 +349,17 @@ static void safelist_one_channel(struct Client *source_p, struct Channel *chptr)
 {
        struct ListClient *safelist_data = source_p->localClient->safelist_data;
 
-       if (SecretChannel(chptr) && !IsMember(source_p, chptr))
+       if (SecretChannel(chptr) && !IsMember(source_p, chptr) && !safelist_data->operspy)
                return;
 
        if ((unsigned int)chptr->members.length < safelist_data->users_min
            || (unsigned int)chptr->members.length > safelist_data->users_max)
                return;
 
-       sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, chptr->chname,
-                  chptr->members.length, chptr->topic == NULL ? "" : chptr->topic);
+       sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name,
+                  (safelist_data->operspy && SecretChannel(chptr)) ? "!" : "",
+                  chptr->chname, rb_dlink_list_length(&chptr->members),
+                  chptr->topic == NULL ? "" : chptr->topic);
 }
 
 /*