]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/serializable.cpp
Convert the ISO 8859-2 nationalchars files to codepage configs.
[user/henk/code/inspircd.git] / src / serializable.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2019 Sadie Powell <sadie@witchery.services>
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
22 Serializable::Data& Serializable::Data::Load(const std::string& key, std::string& out)
23 {
24         EntryMap::iterator iter = this->entries.find(key);
25         if (iter == this->entries.end())
26         {
27                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Unable to load missing kv %s!", key.c_str());
28         }
29         else
30         {
31                 out = iter->second;
32                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Loaded kv %s: %s", key.c_str(), out.c_str());
33         }
34         return *this;
35 }
36
37 Serializable::Data& Serializable::Data::Load(const std::string& key, Serializable::Data& out)
38 {
39         ChildMap::iterator iter = this->children.find(key);
40         if (iter == this->children.end())
41         {
42                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Unable to load missing data %s!", key.c_str());
43         }
44         else
45         {
46                 out = iter->second;
47                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Loaded data: %s", key.c_str());
48         }
49         return *this;
50 }
51
52 Serializable::Data& Serializable::Data::Store(const std::string& key, const std::string& value)
53 {
54         ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Stored kv %s: %s", key.c_str(), value.c_str());
55         this->entries[key] = value;
56         return *this;
57 }
58
59 Serializable::Data& Serializable::Data::Store(const std::string& key, const Serializable::Data& value)
60 {
61         ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Stored data: %s", key.c_str());
62         this->children[key] = value;
63         return *this;
64 }
65
66 bool Extensible::Deserialize(Serializable::Data& data)
67 {
68         // If the extensible has been culled then it shouldn't be deserialized.
69         if (culled)
70                 return false;
71
72         const Serializable::Data::EntryMap& entries = data.GetEntries();
73         for (Serializable::Data::EntryMap::const_iterator iter = entries.begin(); iter != entries.end(); ++iter)
74         {
75                 const std::string& name = iter->first;
76                 ExtensionItem* item = ServerInstance->Extensions.GetItem(name);
77                 if (item)
78                 {
79                         item->FromInternal(this, iter->second);
80                         continue;
81                 }
82
83                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to deserialize the %s extension item but it doesn't exist",
84                         name.c_str());
85         }
86         return true;
87 }
88
89 bool Extensible::Serialize(Serializable::Data& data)
90 {
91         // If the extensible has been culled then it shouldn't be serialized.
92         if (culled)
93         {
94                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to serialize an extensible which has been culled");
95                 return false;
96         }
97
98         for (Extensible::ExtensibleStore::const_iterator iter = extensions.begin(); iter != extensions.end(); ++iter)
99         {
100                 ExtensionItem* item = iter->first;
101                 const std::string value = item->ToInternal(this, iter->second);
102                 if (!value.empty())
103                         data.Store(item->name, value);
104         }
105         return true;
106 }
107
108 bool User::Deserialize(Serializable::Data& data)
109 {
110         // If the user is quitting they shouldn't be deserialized.
111         if (quitting)
112         {
113                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to deserialize %s who is in the process of quitting",
114                         uuid.c_str());
115                 return false;
116         }
117
118         // Check we're actually deserialising data for this user.
119         std::string client_uuid;
120         data.Load("uuid", client_uuid);
121         if (!client_uuid.empty() && client_uuid != uuid)
122         {
123                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to deserialize %s into %s",
124                         client_uuid.c_str(), uuid.c_str());
125                 return false;
126         }
127
128         // Deserialize the extensions first.
129         Serializable::Data exts;
130         data.Load("extensions", exts);
131         if (!Extensible::Deserialize(exts))
132                 return false;
133
134         long client_port;
135         std::string client_addr;
136         std::string user_modes;
137         std::string user_oper;
138         std::string user_snomasks;
139
140         // Apply the members which can be applied directly.
141         data.Load("age", age)
142                 .Load("awaymsg", awaymsg)
143                 .Load("awaytime", awaytime)
144                 .Load("client_sa.addr", client_addr)
145                 .Load("client_sa.port", client_port)
146                 .Load("displayhost", displayhost)
147                 .Load("ident", ident)
148                 .Load("modes", user_modes)
149                 .Load("nick", nick)
150                 .Load("oper", user_oper)
151                 .Load("realhost", realhost)
152                 .Load("realname", realname)
153                 .Load("signon", signon)
154                 .Load("snomasks", user_snomasks);
155
156         // Apply the rest of the members.
157         modes = std::bitset<ModeParser::MODEID_MAX>(user_modes);
158         snomasks = std::bitset<64>(user_snomasks);
159
160         ServerConfig::OperIndex::const_iterator iter = ServerInstance->Config->OperTypes.find(user_oper);
161         if (iter != ServerInstance->Config->OperTypes.end())
162                 oper = iter->second;
163         else
164                 oper = new OperInfo(user_oper);
165
166         irc::sockets::sockaddrs sa;
167         if (irc::sockets::aptosa(client_addr, client_port, sa) || irc::sockets::untosa(client_addr, sa))
168                 client_sa = sa;
169
170         InvalidateCache();
171         return true;
172 }
173
174 bool User::Serialize(Serializable::Data& data)
175 {
176         // If the user is quitting they shouldn't be serialized.
177         if (quitting)
178         {
179                 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to serialize %s who is in the process of quitting",
180                         uuid.c_str());
181                 return false;
182         }
183
184         // If the user is unregistered they shouldn't be serialised.
185         if (registered != REG_ALL)
186                 return false;
187
188         // Serialize the extensions first.
189         Serializable::Data exts;
190         if (!Extensible::Serialize(exts))
191                 return false;
192         data.Store("extensions", exts);
193
194         // The following member variables not checked above are not serialised:
195         // * cached_fullhost (serialising cache variables is unnecessary)
196         // * cached_fullrealhost (serialising cache variables is unnecessary)
197         // * cached_hostip (serialising cache variables is unnecessary)
198         // * cached_makehost (serialising cache variables is unnecessary)
199         // * cachedip (serialising cache variables is unnecessary)
200         // * server (specific to the origin server)
201         // * usertype (can't be networked reliably)
202         data.Store("age", age)
203                 .Store("awaymsg", awaymsg)
204                 .Store("awaytime", awaytime)
205                 .Store("client_sa.addr", client_sa.addr())
206                 .Store("client_sa.port", client_sa.port())
207                 .Store("displayhost", displayhost)
208                 .Store("ident", ident)
209                 .Store("modes", modes.to_string())
210                 .Store("nick", nick)
211                 .Store("oper", oper ? oper->name : "")
212                 .Store("realhost", realhost)
213                 .Store("realname", realname)
214                 .Store("signon", signon)
215                 .Store("snomasks", snomasks.to_string())
216                 .Store("uuid", uuid);
217
218         return true;
219 }
220
221 bool LocalUser::Deserialize(Serializable::Data& data)
222 {
223
224         // Deserialize the base class first.
225         if (!User::Deserialize(data))
226                 return false;
227
228         bool user_exempt;
229         bool user_lastping;
230         long server_port;
231         std::string server_addr;
232
233         // Apply the members which can be applied directly.
234         data.Load("bytes_in", bytes_in)
235                 .Load("bytes_out", bytes_out)
236                 .Load("cmds_in", cmds_in)
237                 .Load("cmds_out", cmds_out)
238                 .Load("CommandFloodPenalty", CommandFloodPenalty)
239                 .Load("exempt", user_exempt)
240                 .Load("idle_lastmsg", idle_lastmsg)
241                 .Load("lastping", user_lastping)
242                 .Load("nextping", nextping)
243                 .Load("password", password)
244                 .Load("server_sa.addr", server_addr)
245                 .Load("server_sa.port", server_port);
246
247         // Apply the rest of the members.
248         irc::sockets::sockaddrs sa;
249         if (irc::sockets::aptosa(server_addr, server_port, sa) || irc::sockets::untosa(server_addr, sa))
250                 server_sa = sa;
251
252         // These are bitfields so we need to ensure they only get the appropriate bits.
253         exempt = user_exempt ? 1 : 0;
254         lastping = user_lastping ? 1 : 0;
255         return true;
256 }
257
258 bool LocalUser::Serialize(Serializable::Data& data)
259 {
260         // Serialize the base class first.
261         if (!User::Serialize(data))
262                 return false;
263
264         // The following member variables not checked above are not serialised:
265         // * already_sent (can't be networked reliably)
266         // * eh (shouldn't be networked)
267         // * MyClass (might not be the same on a different server)
268         // * serializer (might not be the same on a different connection)
269         data.Store("bytes_in", bytes_in)
270                 .Store("bytes_out", bytes_out)
271                 .Store("cmds_in", cmds_in)
272                 .Store("cmds_out", cmds_out)
273                 .Store("CommandFloodPenalty", CommandFloodPenalty)
274                 .Store("exempt", exempt)
275                 .Store("idle_lastmsg", idle_lastmsg)
276                 .Store("lastping", lastping)
277                 .Store("nextping", nextping)
278                 .Store("password", password)
279                 .Store("server_sa.addr", server_sa.addr())
280                 .Store("server_sa.port", server_sa.port());
281         return true;
282 }