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