]> jfr.im git - solanum.git/blobdiff - modules/m_topic.c
m_info: Correct description of general::client_exit like in example confs.
[solanum.git] / modules / m_topic.c
index 9c9117014272cce788b174cd79c4d0ad2fc2f606..9effb2abff221562996531a75a27ba2fed3a3d5d 100644 (file)
 #include "ircd.h"
 #include "numeric.h"
 #include "send.h"
+#include "s_newconf.h"
 #include "s_conf.h"
 #include "s_serv.h"
 #include "msg.h"
 #include "parse.h"
 #include "modules.h"
 #include "packet.h"
+#include "tgchange.h"
 
 static int m_topic(struct Client *, struct Client *, int, const char **);
 static int ms_topic(struct Client *, struct Client *, int, const char **);
@@ -52,7 +54,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
  */
@@ -62,26 +63,36 @@ 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';
 
-       if(MyClient(source_p) && !IsFloodDone(source_p))
-               flood_endgrace(source_p);
+       name = parv[1];
 
-       if(!IsChannelName(parv[1]))
+       if(IsOperSpy(source_p) && parv[1][0] == '!')
        {
-               sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
-                                  form_str(ERR_NOSUCHCHANNEL), parv[1]);
-               return 0;
+               name++;
+               operspy = 1;
+
+               if(EmptyString(name))
+               {
+                       sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                                       me.name, source_p->name, "TOPIC");
+                       return 0;
+               }
        }
 
-       chptr = find_channel(parv[1]);
+       if(MyClient(source_p) && !IsFloodDone(source_p))
+               flood_endgrace(source_p);
+
+       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;
        }
 
@@ -93,11 +104,23 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
                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) && !is_chanop_voiced(msptr) &&
+                               !IsOper(source_p) &&
+                               !add_channel_target(source_p, chptr))
+               {
+                       sendto_one(source_p, form_str(ERR_TARGCHANGE),
+                                  me.name, source_p->name, chptr->chname);
+                       return 0;
+               }
+
+               if(((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
+                                       get_channel_access(source_p, msptr) >= CHFL_CHANOP) &&
+                               (!MyClient(source_p) ||
+                                can_send(chptr, source_p, msptr)))
                {
                        char topic_info[USERHOST_REPLYLEN];
                        rb_sprintf(topic_info, "%s!%s@%s",
@@ -108,10 +131,6 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
                                        ":%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,
@@ -120,19 +139,23 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
                }
                else
                        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
-                                       me.name, source_p->name, parv[1]);
+                                       get_id(&me, source_p),
+                                       get_id(source_p, source_p), name);
        }
        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),
@@ -140,7 +163,8 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
 
                        sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
                                        me.name, source_p->name, chptr->chname,
-                                       chptr->topic_info, chptr->topic_time);
+                                       chptr->topic_info,
+                                       (unsigned long)chptr->topic_time);
                }
        }
 
@@ -149,7 +173,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
@@ -162,17 +185,14 @@ ms_topic(struct Client *client_p, struct Client *source_p, int parc, const char
 {
        struct Channel *chptr = NULL;
 
-       if(IsChannelName(parv[1]))
-       {
-               if((chptr = find_channel(parv[1])) == NULL)
-                       return 0;
+       if((chptr = find_channel(parv[1])) == NULL)
+               return 0;
 
-               set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));
+       set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));
 
-               sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
-                                    source_p->name, parv[1], 
-                                    chptr->topic == NULL ? "" : chptr->topic);
-       }
+       sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
+                            source_p->name, parv[1], 
+                            chptr->topic == NULL ? "" : chptr->topic);
 
        return 0;
 }