]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands/cmd_notice.cpp
d22bd2fce9f1051ed2af73b8a7d9a81c222050bf
[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://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_notice.h"
16
17 extern "C" DllExport Command* init_command(InspIRCd* Instance)
18 {
19         return new CommandNotice(Instance);
20 }
21
22 CmdResult CommandNotice::Handle (const std::vector<std::string>& parameters, User *user)
23 {
24         User *dest;
25         Channel *chan;
26
27         CUList exempt_list;
28
29         user->idle_lastmsg = ServerInstance->Time();
30         
31         if (ServerInstance->Parser->LoopCall(user, this, parameters, 0))
32                 return CMD_SUCCESS;
33         if (parameters[0][0] == '$')
34         {
35                 if (!user->HasPrivPermission("users/mass-message"))
36                         return CMD_SUCCESS;
37
38                 int MOD_RESULT = 0;
39                 std::string temp = parameters[1];
40                 FOREACH_RESULT(I_OnUserPreNotice,OnUserPreNotice(user, (void*)parameters[0].c_str(), TYPE_SERVER, temp, 0, exempt_list));
41                 if (MOD_RESULT)
42                         return CMD_FAILURE;
43                 const char* text = temp.c_str();
44                 const char* servermask = (parameters[0].c_str()) + 1;
45
46                 FOREACH_MOD(I_OnText,OnText(user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, exempt_list));
47                 if (InspIRCd::Match(ServerInstance->Config->ServerName,servermask, NULL))
48                 {
49                         user->SendAll("NOTICE", "%s", text);
50                 }
51                 FOREACH_MOD(I_OnUserNotice,OnUserNotice(user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, exempt_list));
52                 return CMD_SUCCESS;
53         }
54         char status = 0;
55         const char* target = parameters[0].c_str();
56
57         if (ServerInstance->Modes->FindPrefix(*target))
58         {
59                 status = *target;
60                 target++;
61         }
62         if (*target == '#')
63         {
64                 chan = ServerInstance->FindChan(target);
65
66                 exempt_list[user] = user->nick;
67
68                 if (chan)
69                 {
70                         if (IS_LOCAL(user))
71                         {
72                                 if ((chan->IsModeSet('n')) && (!chan->HasUser(user)))
73                                 {
74                                         user->WriteNumeric(404, "%s %s :Cannot send to channel (no external messages)", user->nick.c_str(), chan->name.c_str());
75                                         return CMD_FAILURE;
76                                 }
77                                 if ((chan->IsModeSet('m')) && (chan->GetStatus(user) < STATUS_VOICE))
78                                 {
79                                         user->WriteNumeric(404, "%s %s :Cannot send to channel (+m)", user->nick.c_str(), chan->name.c_str());
80                                         return CMD_FAILURE;
81                                 }
82                         }
83                         int MOD_RESULT = 0;
84
85                         std::string temp = parameters[1];
86                         FOREACH_RESULT(I_OnUserPreNotice,OnUserPreNotice(user,chan,TYPE_CHANNEL,temp,status, exempt_list));
87                         if (MOD_RESULT) {
88                                 return CMD_FAILURE;
89                         }
90                         const char* text = temp.c_str();
91
92                         if (temp.empty())
93                         {
94                                 user->WriteNumeric(412, "%s :No text to send", user->nick.c_str());
95                                 return CMD_FAILURE;
96                         }
97
98                         FOREACH_MOD(I_OnText,OnText(user,chan,TYPE_CHANNEL,text,status,exempt_list));
99
100                         if (status)
101                         {
102                                 if (ServerInstance->Config->UndernetMsgPrefix)
103                                 {
104                                         chan->WriteAllExcept(user, false, status, exempt_list, "NOTICE %c%s :%c %s", status, chan->name.c_str(), status, text);
105                                 }
106                                 else
107                                 {
108                                         chan->WriteAllExcept(user, false, status, exempt_list, "NOTICE %c%s :%s", status, chan->name.c_str(), text);
109                                 }
110                         }
111                         else
112                         {
113                                 chan->WriteAllExcept(user, false, status, exempt_list, "NOTICE %s :%s", chan->name.c_str(), text);
114                         }
115
116                         FOREACH_MOD(I_OnUserNotice,OnUserNotice(user,chan,TYPE_CHANNEL,text,status,exempt_list));
117                 }
118                 else
119                 {
120                         /* no such nick/channel */
121                         user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), target);
122                         return CMD_FAILURE;
123                 }
124                 return CMD_SUCCESS;
125         }
126         
127         const char* destnick = parameters[0].c_str();
128
129         if (IS_LOCAL(user))
130         {
131                 const char* targetserver = strchr(destnick, '@');
132
133                 if (targetserver)
134                 {
135                         std::string nickonly;
136
137                         nickonly.assign(destnick, 0, targetserver - destnick);
138                         dest = ServerInstance->FindNickOnly(nickonly);
139                         if (dest && strcasecmp(dest->server, targetserver + 1))
140                         {
141                                 /* Incorrect server for user */
142                                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
143                                 return CMD_FAILURE;
144                         }
145                 }
146                 else
147                         dest = ServerInstance->FindNickOnly(destnick);
148         }
149         else
150                 dest = ServerInstance->FindNick(destnick);
151
152         if (dest)
153         {
154                 if (parameters[1].empty())
155                 {
156                         user->WriteNumeric(412, "%s :No text to send", user->nick.c_str());
157                         return CMD_FAILURE;
158                 }
159
160                 int MOD_RESULT = 0;
161                 std::string temp = parameters[1];
162                 FOREACH_RESULT(I_OnUserPreNotice,OnUserPreNotice(user,dest,TYPE_USER,temp,0,exempt_list));
163                 if (MOD_RESULT) {
164                         return CMD_FAILURE;
165                 }
166                 const char* text = temp.c_str();
167
168                 FOREACH_MOD(I_OnText,OnText(user,dest,TYPE_USER,text,0,exempt_list));
169
170                 if (IS_LOCAL(dest))
171                 {
172                         // direct write, same server
173                         user->WriteTo(dest, "NOTICE %s :%s", dest->nick.c_str(), text);
174                 }
175
176                 FOREACH_MOD(I_OnUserNotice,OnUserNotice(user,dest,TYPE_USER,text,0,exempt_list));
177         }
178         else
179         {
180                 /* no such nick/channel */
181                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
182                 return CMD_FAILURE;
183         }
184
185         return CMD_SUCCESS;
186
187 }
188