]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands/cmd_notice.cpp
c94dbc87a4f7737e24006b80bca8af9ca3d60012
[user/henk/code/inspircd.git] / src / commands / cmd_notice.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/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
16 #ifndef __CMD_NOTICE_H__
17 #define __CMD_NOTICE_H__
18
19 // include the common header files
20
21 #include "users.h"
22 #include "channels.h"
23
24 /** Handle /NOTICE. These command handlers can be reloaded by the core,
25  * and handle basic RFC1459 commands. Commands within modules work
26  * the same way, however, they can be fully unloaded, where these
27  * may not.
28  */
29 class CommandNotice : public Command
30 {
31  public:
32         /** Constructor for notice.
33          */
34         CommandNotice (InspIRCd* Instance, Module* parent) : Command(Instance,parent,"NOTICE",0,2) { syntax = "<target>{,<target>} <message>"; }
35         /** Handle command.
36          * @param parameters The parameters to the comamnd
37          * @param pcnt The number of parameters passed to teh command
38          * @param user The user issuing the command
39          * @return A value from CmdResult to indicate command success or failure.
40          */
41         CmdResult Handle(const std::vector<std::string>& parameters, User *user);
42 };
43
44 #endif
45
46
47 CmdResult CommandNotice::Handle (const std::vector<std::string>& parameters, User *user)
48 {
49         User *dest;
50         Channel *chan;
51
52         CUList exempt_list;
53
54         user->idle_lastmsg = ServerInstance->Time();
55
56         if (ServerInstance->Parser->LoopCall(user, this, parameters, 0))
57                 return CMD_SUCCESS;
58         if (parameters[0][0] == '$')
59         {
60                 if (!user->HasPrivPermission("users/mass-message"))
61                         return CMD_SUCCESS;
62
63                 ModResult MOD_RESULT;
64                 std::string temp = parameters[1];
65                 FIRST_MOD_RESULT(ServerInstance, OnUserPreNotice, MOD_RESULT, (user, (void*)parameters[0].c_str(), TYPE_SERVER, temp, 0, exempt_list));
66                 if (MOD_RESULT == MOD_RES_DENY)
67                         return CMD_FAILURE;
68                 const char* text = temp.c_str();
69                 const char* servermask = (parameters[0].c_str()) + 1;
70
71                 FOREACH_MOD(I_OnText,OnText(user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, exempt_list));
72                 if (InspIRCd::Match(ServerInstance->Config->ServerName,servermask, NULL))
73                 {
74                         user->SendAll("NOTICE", "%s", text);
75                 }
76                 FOREACH_MOD(I_OnUserNotice,OnUserNotice(user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, exempt_list));
77                 return CMD_SUCCESS;
78         }
79         char status = 0;
80         const char* target = parameters[0].c_str();
81
82         if (ServerInstance->Modes->FindPrefix(*target))
83         {
84                 status = *target;
85                 target++;
86         }
87         if (*target == '#')
88         {
89                 chan = ServerInstance->FindChan(target);
90
91                 exempt_list[user] = user->nick;
92
93                 if (chan)
94                 {
95                         if (IS_LOCAL(user))
96                         {
97                                 if ((chan->IsModeSet('n')) && (!chan->HasUser(user)))
98                                 {
99                                         user->WriteNumeric(404, "%s %s :Cannot send to channel (no external messages)", user->nick.c_str(), chan->name.c_str());
100                                         return CMD_FAILURE;
101                                 }
102                                 if ((chan->IsModeSet('m')) && (chan->GetStatus(user) < STATUS_VOICE))
103                                 {
104                                         user->WriteNumeric(404, "%s %s :Cannot send to channel (+m)", user->nick.c_str(), chan->name.c_str());
105                                         return CMD_FAILURE;
106                                 }
107                         }
108                         ModResult MOD_RESULT;
109
110                         std::string temp = parameters[1];
111                         FIRST_MOD_RESULT(ServerInstance, OnUserPreNotice, MOD_RESULT, (user,chan,TYPE_CHANNEL,temp,status, exempt_list));
112                         if (MOD_RESULT == MOD_RES_DENY)
113                                 return CMD_FAILURE;
114
115                         const char* text = temp.c_str();
116
117                         if (temp.empty())
118                         {
119                                 user->WriteNumeric(412, "%s :No text to send", user->nick.c_str());
120                                 return CMD_FAILURE;
121                         }
122
123                         FOREACH_MOD(I_OnText,OnText(user,chan,TYPE_CHANNEL,text,status,exempt_list));
124
125                         if (status)
126                         {
127                                 if (ServerInstance->Config->UndernetMsgPrefix)
128                                 {
129                                         chan->WriteAllExcept(user, false, status, exempt_list, "NOTICE %c%s :%c %s", status, chan->name.c_str(), status, text);
130                                 }
131                                 else
132                                 {
133                                         chan->WriteAllExcept(user, false, status, exempt_list, "NOTICE %c%s :%s", status, chan->name.c_str(), text);
134                                 }
135                         }
136                         else
137                         {
138                                 chan->WriteAllExcept(user, false, status, exempt_list, "NOTICE %s :%s", chan->name.c_str(), text);
139                         }
140
141                         FOREACH_MOD(I_OnUserNotice,OnUserNotice(user,chan,TYPE_CHANNEL,text,status,exempt_list));
142                 }
143                 else
144                 {
145                         /* no such nick/channel */
146                         user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), target);
147                         return CMD_FAILURE;
148                 }
149                 return CMD_SUCCESS;
150         }
151
152         const char* destnick = parameters[0].c_str();
153
154         if (IS_LOCAL(user))
155         {
156                 const char* targetserver = strchr(destnick, '@');
157
158                 if (targetserver)
159                 {
160                         std::string nickonly;
161
162                         nickonly.assign(destnick, 0, targetserver - destnick);
163                         dest = ServerInstance->FindNickOnly(nickonly);
164                         if (dest && strcasecmp(dest->server, targetserver + 1))
165                         {
166                                 /* Incorrect server for user */
167                                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
168                                 return CMD_FAILURE;
169                         }
170                 }
171                 else
172                         dest = ServerInstance->FindNickOnly(destnick);
173         }
174         else
175                 dest = ServerInstance->FindNick(destnick);
176
177         if (dest)
178         {
179                 if (parameters[1].empty())
180                 {
181                         user->WriteNumeric(412, "%s :No text to send", user->nick.c_str());
182                         return CMD_FAILURE;
183                 }
184
185                 ModResult MOD_RESULT;
186                 std::string temp = parameters[1];
187                 FIRST_MOD_RESULT(ServerInstance, OnUserPreNotice, MOD_RESULT, (user,dest,TYPE_USER,temp,0,exempt_list));
188                 if (MOD_RESULT == MOD_RES_DENY) {
189                         return CMD_FAILURE;
190                 }
191                 const char* text = temp.c_str();
192
193                 FOREACH_MOD(I_OnText,OnText(user,dest,TYPE_USER,text,0,exempt_list));
194
195                 if (IS_LOCAL(dest))
196                 {
197                         // direct write, same server
198                         user->WriteTo(dest, "NOTICE %s :%s", dest->nick.c_str(), text);
199                 }
200
201                 FOREACH_MOD(I_OnUserNotice,OnUserNotice(user,dest,TYPE_USER,text,0,exempt_list));
202         }
203         else
204         {
205                 /* no such nick/channel */
206                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
207                 return CMD_FAILURE;
208         }
209
210         return CMD_SUCCESS;
211
212 }
213
214 COMMAND_INIT(CommandNotice)