]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/m_topic.c
Allow /ojoin !#channel/%#channel, if admin/halfop are enabled.
[irc/rqf/shadowircd.git] / modules / m_topic.c
index e63f3e426d7de61294e2328d754176be1d3e0c39..ff72fb4c23559e6b0cf7b7da04f51ae5450e6b5a 100644 (file)
  */
 
 #include "stdinc.h"
-#include "tools.h"
 #include "channel.h"
 #include "client.h"
 #include "hash.h"
-#include "irc_string.h"
-#include "sprintf_irc.h"
+#include "match.h"
 #include "ircd.h"
 #include "numeric.h"
 #include "send.h"
+#include "s_newconf.h"
 #include "s_conf.h"
 #include "s_serv.h"
 #include "msg.h"
@@ -54,7 +53,6 @@ DECLARE_MODULE_AV1(topic, NULL, NULL, topic_clist, NULL, NULL, "$Revision: 254 $
 
 /*
  * m_topic
- *      parv[0] = sender prefix
  *      parv[1] = channel name
  *     parv[2] = new topic, if setting topic
  */
@@ -64,77 +62,113 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
        struct Channel *chptr = NULL;
        struct membership *msptr;
        char *p = NULL;
+       const char *name;
+       int operspy = 0;
 
        if((p = strchr(parv[1], ',')))
                *p = '\0';
 
+       name = parv[1];
+
+       if(IsOperSpy(source_p) && parv[1][0] == '!')
+       {
+               name++;
+               operspy = 1;
+
+               if(EmptyString(name))
+               {
+                       sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                                       me.name, source_p->name, "TOPIC");
+                       return 0;
+               }
+       }
+
        if(MyClient(source_p) && !IsFloodDone(source_p))
                flood_endgrace(source_p);
 
-       if(!IsChannelName(parv[1]))
+       if(!IsChannelName(name))
        {
                sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
-                                  form_str(ERR_NOSUCHCHANNEL), parv[1]);
+                                  form_str(ERR_NOSUCHCHANNEL), name);
                return 0;
        }
 
-       chptr = find_channel(parv[1]);
+       chptr = find_channel(name);
 
        if(chptr == NULL)
        {
                sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
-                               form_str(ERR_NOSUCHCHANNEL), parv[1]);
+                               form_str(ERR_NOSUCHCHANNEL), name);
                return 0;
        }
 
        /* setting topic */
        if(parc > 2)
        {
+               char topic_info[USERHOST_REPLYLEN];
+
                msptr = find_channel_membership(chptr, source_p);
 
                if(msptr == NULL)
                {
                        sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
-                                       form_str(ERR_NOTONCHANNEL), parv[1]);
+                                       form_str(ERR_NOTONCHANNEL), name);
                        return 0;
                }
 
-               if((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_chanop(msptr))
+               if(MyClient(source_p) && (chptr->mode.mode & MODE_TOPICLIMIT) && !is_chanop(msptr))
                {
-                       char topic_info[USERHOST_REPLYLEN];
-                       rb_sprintf(topic_info, "%s!%s@%s",
-                                       source_p->name, source_p->username, source_p->host);
-                       set_channel_topic(chptr, parv[2], topic_info, CurrentTime);
+                       if(IsOverride(source_p))
+                       {
+                               sendto_wallops_flags(UMODE_WALLOP, &me,
+                                               "%s is overriding TOPIC on [%s]",
+                                               get_oper_name(source_p), chptr->chname);
+                               sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+                                               ":%s WALLOPS :%s is overriding TOPIC on [%s]",
+                                               me.name, get_oper_name(source_p), chptr->chname);
+                       }
+                       else
+                       {
+                               sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+                                               me.name, source_p->name, parv[1]);
+                               return 0;
+                       }
+
+               }
+
+                       if(ConfigChannel.host_in_topic)
+                               rb_sprintf(topic_info, "%s!%s@%s",
+                                               source_p->name, source_p->username, source_p->host);
+                       else
+                               rb_strlcpy(topic_info, source_p->name, sizeof(topic_info));
+
+                       set_channel_topic(chptr, parv[2], topic_info, rb_current_time());
 
                        sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                                        ":%s TOPIC %s :%s",
                                        use_id(source_p), chptr->chname,
                                        chptr->topic == NULL ? "" : chptr->topic);
-                       sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
-                                       ":%s TOPIC %s :%s",
-                                       source_p->name, chptr->chname,
-                                       chptr->topic == NULL ? "" : chptr->topic);
                        sendto_channel_local(ALL_MEMBERS,
                                        chptr, ":%s!%s@%s TOPIC %s :%s",
                                        source_p->name, source_p->username,
                                        source_p->host, chptr->chname,
                                        chptr->topic == NULL ? "" : chptr->topic);
-               }
-               else
-                       sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
-                                       me.name, source_p->name, parv[1]);
+
        }
        else if(MyClient(source_p))
        {
-               if(!IsMember(source_p, chptr) && SecretChannel(chptr))
+               if(operspy)
+                       report_operspy(source_p, "TOPIC", chptr->chname);
+               if(!IsMember(source_p, chptr) && SecretChannel(chptr) &&
+                               !operspy)
                {
                        sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
-                                       form_str(ERR_NOTONCHANNEL), parv[1]);
+                                       form_str(ERR_NOTONCHANNEL), name);
                        return 0;
                }
                if(chptr->topic == NULL)
                        sendto_one(source_p, form_str(RPL_NOTOPIC),
-                                       me.name, source_p->name, parv[1]);
+                                       me.name, source_p->name, name);
                else
                {
                        sendto_one(source_p, form_str(RPL_TOPIC),
@@ -151,7 +185,6 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
 
 /*
  * ms_topic
- *      parv[0] = sender prefix
  *      parv[1] = channel name
  *     parv[2] = topic_info
  *     parv[3] = topic_info time