]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_spanningtree/compat.cpp
Replace copyright headers with headers granting specific authors copyright
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / compat.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "inspircd.h"
21 #include "main.h"
22 #include "treesocket.h"
23
24 static const char* const forge_common_1201[] = {
25         "m_allowinvite.so",
26         "m_alltime.so",
27         "m_auditorium.so",
28         "m_banexception.so",
29         "m_blockcaps.so",
30         "m_blockcolor.so",
31         "m_botmode.so",
32         "m_censor.so",
33         "m_chanfilter.so",
34         "m_chanhistory.so",
35         "m_channelban.so",
36         "m_chanprotect.so",
37         "m_chghost.so",
38         "m_chgname.so",
39         "m_commonchans.so",
40         "m_customtitle.so",
41         "m_deaf.so",
42         "m_delayjoin.so",
43         "m_delaymsg.so",
44         "m_exemptchanops.so",
45         "m_gecosban.so",
46         "m_globops.so",
47         "m_helpop.so",
48         "m_hidechans.so",
49         "m_hideoper.so",
50         "m_invisible.so",
51         "m_inviteexception.so",
52         "m_joinflood.so",
53         "m_kicknorejoin.so",
54         "m_knock.so",
55         "m_messageflood.so",
56         "m_muteban.so",
57         "m_nickflood.so",
58         "m_nicklock.so",
59         "m_noctcp.so",
60         "m_nokicks.so",
61         "m_nonicks.so",
62         "m_nonotice.so",
63         "m_nopartmsg.so",
64         "m_ojoin.so",
65         "m_operprefix.so",
66         "m_permchannels.so",
67         "m_redirect.so",
68         "m_regex_glob.so",
69         "m_regex_pcre.so",
70         "m_regex_posix.so",
71         "m_regex_tre.so",
72         "m_remove.so",
73         "m_sajoin.so",
74         "m_sakick.so",
75         "m_sanick.so",
76         "m_sapart.so",
77         "m_saquit.so",
78         "m_serverban.so",
79         "m_services_account.so",
80         "m_servprotect.so",
81         "m_setident.so",
82         "m_showwhois.so",
83         "m_silence.so",
84         "m_sslmodes.so",
85         "m_stripcolor.so",
86         "m_swhois.so",
87         "m_uninvite.so",
88         "m_watch.so"
89 };
90
91 static std::string wide_newline("\r\n");
92 static std::string newline("\n");
93
94 void TreeSocket::CompatAddModules(std::vector<std::string>& modlist)
95 {
96         if (proto_version < 1202)
97         {
98                 // you MUST have chgident loaded in order to be able to translate FIDENT
99                 modlist.push_back("m_chgident.so");
100                 for(int i=0; i * sizeof(char*) < sizeof(forge_common_1201); i++)
101                 {
102                         if (ServerInstance->Modules->Find(forge_common_1201[i]))
103                                 modlist.push_back(forge_common_1201[i]);
104                 }
105                 // module was merged
106                 if (ServerInstance->Modules->Find("m_operchans.so"))
107                 {
108                         modlist.push_back("m_operchans.so");
109                         modlist.push_back("m_operinvex.so");
110                 }
111         }
112 }
113
114 void TreeSocket::WriteLine(std::string line)
115 {
116         if (LinkState == CONNECTED)
117         {
118                 if (line[0] != ':')
119                 {
120                         ServerInstance->Logs->Log("m_spanningtree", DEFAULT, "Sending line without server prefix!");
121                         line = ":" + ServerInstance->Config->GetSID() + " " + line;
122                 }
123                 if (proto_version != ProtocolVersion)
124                 {
125                         std::string::size_type a = line.find(' ');
126                         std::string::size_type b = line.find(' ', a + 1);
127                         std::string command = line.substr(a + 1, b-a-1);
128                         // now try to find a translation entry
129                         // TODO a more efficient lookup method will be needed later
130                         if (proto_version < 1202 && command == "FIDENT")
131                         {
132                                 ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Rewriting FIDENT for 1201-protocol server");
133                                 line = ":" + ServerInstance->Config->GetSID() + " CHGIDENT " +  line.substr(1,a-1) + line.substr(b);
134                         }
135                         else if (proto_version < 1202 && command == "SAVE")
136                         {
137                                 ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Rewriting SAVE for 1201-protocol server");
138                                 std::string::size_type c = line.find(' ', b + 1);
139                                 std::string uid = line.substr(b, c - b);
140                                 line = ":" + ServerInstance->Config->GetSID() + " SVSNICK" + uid + line.substr(b);
141                         }
142                         else if (proto_version < 1202 && command == "AWAY")
143                         {
144                                 if (b != std::string::npos)
145                                 {
146                                         ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Stripping AWAY timestamp for 1201-protocol server");
147                                         std::string::size_type c = line.find(' ', b + 1);
148                                         line.erase(b,c-b);
149                                 }
150                         }
151                         else if (proto_version < 1202 && command == "ENCAP")
152                         {
153                                 // :src ENCAP target command [args...]
154                                 //     A     B      C       D
155                                 // Therefore B and C cannot be npos in a valid command
156                                 if (b == std::string::npos)
157                                         return;
158                                 std::string::size_type c = line.find(' ', b + 1);
159                                 if (c == std::string::npos)
160                                         return;
161                                 std::string::size_type d = line.find(' ', c + 1);
162                                 std::string subcmd = line.substr(c + 1, d - c - 1);
163
164                                 if (subcmd == "CHGIDENT" && d != std::string::npos)
165                                 {
166                                         std::string::size_type e = line.find(' ', d + 1);
167                                         if (e == std::string::npos)
168                                                 return; // not valid
169                                         std::string target = line.substr(d + 1, e - d - 1);
170
171                                         ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Forging acceptance of CHGIDENT from 1201-protocol server");
172                                         recvq.insert(0, ":" + target + " FIDENT " + line.substr(e) + "\n");
173                                 }
174
175                                 Command* thiscmd = ServerInstance->Parser->GetHandler(subcmd);
176                                 if (thiscmd && subcmd != "WHOISNOTICE")
177                                 {
178                                         Version ver = thiscmd->creator->GetVersion();
179                                         if (ver.Flags & VF_OPTCOMMON)
180                                         {
181                                                 ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Removing ENCAP on '%s' for 1201-protocol server",
182                                                         subcmd.c_str());
183                                                 line.erase(a, c-a);
184                                         }
185                                 }
186                         }
187                 }
188         }
189
190         ServerInstance->Logs->Log("m_spanningtree", RAWIO, "S[%d] O %s", this->GetFd(), line.c_str());
191         this->WriteData(line);
192         if (proto_version < 1202)
193                 this->WriteData(wide_newline);
194         else
195                 this->WriteData(newline);
196 }