]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands/cmd_topic.cpp
First phase of conversion to dynamic limits on all the lengths, configured via the...
[user/henk/code/inspircd.git] / src / commands / cmd_topic.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "commands/cmd_topic.h"
16
17
18 extern "C" DllExport Command* init_command(InspIRCd* Instance)
19 {
20         return new CommandTopic(Instance);
21 }
22
23 CmdResult CommandTopic::Handle (const std::vector<std::string>& parameters, User *user)
24 {
25         Channel* Ptr;
26
27         if (parameters.size() == 1)
28         {
29                 Ptr = ServerInstance->FindChan(parameters[0]);
30                 if (Ptr)
31                 {
32                         if ((Ptr->IsModeSet('s')) && (!Ptr->HasUser(user)))
33                         {
34                                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), Ptr->name.c_str());
35                                 return CMD_FAILURE;
36                         }
37                         if (Ptr->topicset)
38                         {
39                                 user->WriteNumeric(332, "%s %s :%s", user->nick.c_str(), Ptr->name.c_str(), Ptr->topic.c_str());
40                                 user->WriteNumeric(333, "%s %s %s %lu", user->nick.c_str(), Ptr->name.c_str(), Ptr->setby.c_str(), (unsigned long)Ptr->topicset);
41                         }
42                         else
43                         {
44                                 user->WriteNumeric(331, "%s %s :No topic is set.", user->nick.c_str(), Ptr->name.c_str());
45                         }
46                 }
47                 else
48                 {
49                         user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
50                         return CMD_FAILURE;
51                 }
52                 return CMD_SUCCESS;
53         }
54         else if (parameters.size()>1)
55         {
56                 Ptr = ServerInstance->FindChan(parameters[0]);
57                 if (Ptr)
58                 {
59                         if (IS_LOCAL(user))
60                         {
61                                 if (!Ptr->HasUser(user))
62                                 {
63                                         user->WriteNumeric(442, "%s %s :You're not on that channel!",user->nick.c_str(), Ptr->name.c_str());
64                                         return CMD_FAILURE;
65                                 }
66                                 if ((Ptr->IsModeSet('t')) && (Ptr->GetStatus(user) < STATUS_HOP))
67                                 {
68                                         user->WriteNumeric(482, "%s %s :You must be at least a half-operator to change the topic on this channel", user->nick.c_str(), Ptr->name.c_str());
69                                         return CMD_FAILURE;
70                                 }
71                         }
72
73                         std::string topic;
74
75                         if (IS_LOCAL(user))
76                         {
77                                 /* XXX: we need two string copies for a local topic, because we cant
78                                  * let a module see the topic as longer than it actually is
79                                  */
80                                 int MOD_RESULT = 0;
81
82                                 topic.assign(parameters[1], 0, ServerInstance->Config->Limits.MaxTopic);
83                                 FOREACH_RESULT(I_OnLocalTopicChange,OnLocalTopicChange(user,Ptr,topic));
84                                 if (MOD_RESULT)
85                                         return CMD_FAILURE;
86
87                                 Ptr->topic.assign(topic, 0, ServerInstance->Config->Limits.MaxTopic);
88                         }
89                         else
90                         {
91                                 /* Sneaky shortcut, one string copy for a remote topic */
92                                 Ptr->topic.assign(parameters[1], 0, ServerInstance->Config->Limits.MaxTopic);
93                         }
94
95                         Ptr->setby.assign(ServerInstance->Config->FullHostInTopic ?
96                                         user->GetFullHost() : user->nick,
97                                         0, 128);
98
99                         Ptr->topicset = ServerInstance->Time();
100                         Ptr->WriteChannel(user, "TOPIC %s :%s", Ptr->name.c_str(), Ptr->topic.c_str());
101
102                         if (IS_LOCAL(user))
103                                 /* We know 'topic' will contain valid data here */
104                                 FOREACH_MOD(I_OnPostLocalTopicChange,OnPostLocalTopicChange(user, Ptr, topic));
105                 }
106                 else
107                 {
108                         user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
109                         return CMD_FAILURE;
110                 }
111         }
112         return CMD_SUCCESS;
113 }
114