]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands/cmd_privmsg.cpp
Tie display of realhost in USERHOST to users/auspex priv.
[user/henk/code/inspircd.git] / src / commands / cmd_privmsg.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_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))
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                                 if ((chan->IsModeSet('m')) && (chan->GetStatus(user) < STATUS_VOICE))
79                                 {
80                                         user->WriteNumeric(404, "%s %s :Cannot send to channel (+m)", user->nick.c_str(), chan->name.c_str());
81                                         return CMD_FAILURE;
82                                 }
83                         }
84                         int MOD_RESULT = 0;
85
86                         std::string temp = parameters[1];
87                         FOREACH_RESULT(I_OnUserPreMessage,OnUserPreMessage(user,chan,TYPE_CHANNEL,temp,status,except_list));
88                         if (MOD_RESULT) {
89                                 return CMD_FAILURE;
90                         }
91                         const char* text = temp.c_str();
92
93                         /* Check again, a module may have zapped the input string */
94                         if (temp.empty())
95                         {
96                                 user->WriteNumeric(412, "%s :No text to send", user->nick.c_str());
97                                 return CMD_FAILURE;
98                         }
99
100                         FOREACH_MOD(I_OnText,OnText(user,chan,TYPE_CHANNEL,text,status,except_list));
101
102                         if (status)
103                         {
104                                 if (ServerInstance->Config->UndernetMsgPrefix)
105                                 {
106                                         chan->WriteAllExcept(user, false, status, except_list, "PRIVMSG %c%s :%c %s", status, chan->name.c_str(), status, text);
107                                 }
108                                 else
109                                 {
110                                         chan->WriteAllExcept(user, false, status, except_list, "PRIVMSG %c%s :%s", status, chan->name.c_str(), text);
111                                 }
112                         }
113                         else 
114                         {
115                                 chan->WriteAllExcept(user, false, status, except_list, "PRIVMSG %s :%s", chan->name.c_str(), text);
116                         }
117
118                         FOREACH_MOD(I_OnUserMessage,OnUserMessage(user,chan,TYPE_CHANNEL,text,status,except_list));
119                 }
120                 else
121                 {
122                         /* no such nick/channel */
123                         user->WriteNumeric(401, "%s %s :No such nick/channel", user->nick.c_str(), target);
124                         return CMD_FAILURE;
125                 }
126                 return CMD_SUCCESS;
127         }
128
129         const char* destnick = parameters[0].c_str();
130
131         if (IS_LOCAL(user))
132         {
133                 const char* targetserver = strchr(destnick, '@');
134         
135                 if (targetserver)
136                 {
137                         std::string nickonly;
138
139                         nickonly.assign(destnick, 0, targetserver - destnick + 1);
140                         dest = ServerInstance->FindNickOnly(nickonly);
141                         if (dest && strcasecmp(dest->server, targetserver + 1))
142                         {
143                                 /* Incorrect server for user */
144                                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
145                                 return CMD_FAILURE;
146                         }
147                 }
148                 else
149                         dest = ServerInstance->FindNickOnly(destnick);
150         }
151         else
152                 dest = ServerInstance->FindNick(destnick);
153
154         if (dest)
155         {
156                 if (parameters[1].empty())
157                 {
158                         user->WriteNumeric(412, "%s :No text to send", user->nick.c_str());
159                         return CMD_FAILURE;
160                 }
161
162                 if (IS_AWAY(dest))
163                 {
164                         /* auto respond with aweh msg */
165                         user->WriteNumeric(301, "%s %s :%s", user->nick.c_str(), dest->nick.c_str(), dest->awaymsg.c_str());
166                 }
167
168                 int MOD_RESULT = 0;
169                 
170                 std::string temp = parameters[1];
171                 FOREACH_RESULT(I_OnUserPreMessage,OnUserPreMessage(user, dest, TYPE_USER, temp, 0, except_list));
172                 if (MOD_RESULT) {
173                         return CMD_FAILURE;
174                 }
175                 const char* text = temp.c_str();
176
177                 FOREACH_MOD(I_OnText,OnText(user, dest, TYPE_USER, text, 0, except_list));
178
179                 if (IS_LOCAL(dest))
180                 {
181                         // direct write, same server
182                         user->WriteTo(dest, "PRIVMSG %s :%s", dest->nick.c_str(), text);
183                 }
184
185                 FOREACH_MOD(I_OnUserMessage,OnUserMessage(user, dest, TYPE_USER, text, 0, except_list));
186         }
187         else
188         {
189                 /* no such nick/channel */
190                 user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
191                 return CMD_FAILURE;
192         }
193         return CMD_SUCCESS;
194 }
195