1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 2010-2014 Licq developers <licq-dev@googlegroups.com>
4  *
5  * Licq is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Licq is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Licq; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "icqprotocolplugin.h"
21 
22 #include <licq/logging/log.h>
23 #include <licq/protocolmanager.h>
24 #include <licq/protocolsignal.h>
25 #include <licq/version.h>
26 
27 #include "chat.h"
28 #include "filetransfer.h"
29 #include "gettext.h"
30 #include "icq.h"
31 #include "owner.h"
32 #include "protocolsignal.h"
33 #include "user.h"
34 
35 using namespace LicqIcq;
36 using Licq::gLog;
37 
38 IcqProtocolPlugin* LicqIcq::gIcqProtocolPlugin(NULL);
39 
IcqProtocolPlugin()40 IcqProtocolPlugin::IcqProtocolPlugin()
41 {
42   gIcqProtocolPlugin = this;
43 }
44 
~IcqProtocolPlugin()45 IcqProtocolPlugin::~IcqProtocolPlugin()
46 {
47   gIcqProtocolPlugin = NULL;
48 }
49 
init(int,char **)50 bool IcqProtocolPlugin::init(int /*argc*/, char** /*argv*/)
51 {
52   gIcqProtocol.initialize();
53   return true;
54 }
55 
run()56 int IcqProtocolPlugin::run()
57 {
58   if (!gIcqProtocol.start())
59     return 1;
60   return 0;
61 }
62 
defaultServerHost() const63 std::string IcqProtocolPlugin::defaultServerHost() const
64 {
65   return "login.icq.com";
66 }
67 
defaultServerPort() const68 int IcqProtocolPlugin::defaultServerPort() const
69 {
70   return 5190;
71 }
72 
processPipe()73 void IcqProtocolPlugin::processPipe()
74 {
75   char c;
76   read(getReadPipe(), &c, 1);
77   switch (c)
78   {
79     case PipeSignal:
80       gIcqProtocol.processSignal(popSignal().get());
81       break;
82     case PipeShutdown:
83       gIcqProtocol.shutdown();
84       break;
85     default:
86       gLog.error(tr("Unknown command via plugin pipe: %c"), c);
87   }
88 }
89 
isOwnerOnline(const Licq::UserId & userId)90 bool IcqProtocolPlugin::isOwnerOnline(const Licq::UserId& userId)
91 {
92   Licq::OwnerReadGuard owner(userId.ownerId());
93   return owner.isLocked() && owner->isOnline();
94 }
95 
pushSignal(Licq::ProtocolSignal * signal)96 void IcqProtocolPlugin::pushSignal(Licq::ProtocolSignal* signal)
97 {
98   pushSignal(boost::shared_ptr<const Licq::ProtocolSignal>(signal));
99 }
100 
icqSendContactList(const Licq::UserId & userId,const Licq::StringList & users,unsigned flags,const Licq::Color * color)101 unsigned long IcqProtocolPlugin::icqSendContactList(const Licq::UserId& userId,
102     const Licq::StringList& users, unsigned flags, const Licq::Color* color)
103 {
104   if (!isOwnerOnline(userId))
105     return 0;
106 
107   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
108   pushSignal(new ProtoSendContactsSignal(eventId, userId, users, flags, color));
109   return eventId;
110 }
111 
icqFetchAutoResponse(const Licq::UserId & userId)112 unsigned long IcqProtocolPlugin::icqFetchAutoResponse(const Licq::UserId& userId)
113 {
114   if (!isOwnerOnline(userId))
115     return 0;
116 
117   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
118   pushSignal(new ProtoFetchAutoResponseSignal(eventId, userId));
119   return eventId;
120 }
121 
icqChatRequest(const Licq::UserId & userId,const std::string & reason,unsigned flags,const std::string & chatUsers,unsigned short port)122 unsigned long IcqProtocolPlugin::icqChatRequest(const Licq::UserId& userId, const std::string& reason,
123     unsigned flags, const std::string& chatUsers, unsigned short port)
124 {
125   if (!isOwnerOnline(userId))
126     return 0;
127 
128   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
129   pushSignal(new ProtoChatRequestSignal(eventId, userId, reason, flags, chatUsers, port));
130   return eventId;
131 }
132 
icqChatRequestRefuse(const Licq::UserId & userId,const std::string & reason,unsigned short sequence,unsigned long msgid1,unsigned long msgid2,bool direct)133 void IcqProtocolPlugin::icqChatRequestRefuse(const Licq::UserId& userId, const std::string& reason,
134     unsigned short sequence, unsigned long msgid1, unsigned long msgid2, bool direct)
135 {
136   if (!isOwnerOnline(userId))
137     return;
138 
139   pushSignal(new ProtoChatRefuseSignal(userId, reason, sequence, msgid1, msgid2, direct));
140 }
141 
icqChatRequestAccept(const Licq::UserId & userId,unsigned short port,const std::string & clients,unsigned short sequence,unsigned long msgid1,unsigned long msgid2,bool direct)142 void IcqProtocolPlugin::icqChatRequestAccept(const Licq::UserId& userId, unsigned short port,
143     const std::string& clients, unsigned short sequence,
144     unsigned long msgid1, unsigned long msgid2, bool direct)
145 {
146   if (!isOwnerOnline(userId))
147     return;
148 
149   pushSignal(new ProtoChatAcceptSignal(userId, port, clients, sequence, msgid1, msgid2, direct));
150 }
151 
icqRequestPluginInfo(const Licq::UserId & userId,Licq::IcqProtocol::PluginType type,bool server)152 unsigned long IcqProtocolPlugin::icqRequestPluginInfo(const Licq::UserId& userId,
153     Licq::IcqProtocol::PluginType type, bool server)
154 {
155   if (!isOwnerOnline(userId))
156     return 0;
157 
158   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
159   pushSignal(new ProtoRequestPluginSignal(eventId, userId, type, server));
160   return eventId;
161 }
162 
icqUpdateInfoTimestamp(const Licq::UserId & ownerId,Licq::IcqProtocol::PluginType type)163 void IcqProtocolPlugin::icqUpdateInfoTimestamp(const Licq::UserId& ownerId, Licq::IcqProtocol::PluginType type)
164 {
165   if (!isOwnerOnline(ownerId))
166     return;
167 
168   pushSignal(new ProtoUpdateTimestampSignal(ownerId, type));
169 }
170 
icqSetWorkInfo(const Licq::UserId & ownerId,const std::string & city,const std::string & state,const std::string & phone,const std::string & fax,const std::string & address,const std::string & zip,unsigned short country,const std::string & name,const std::string & department,const std::string & position,unsigned short occupation,const std::string & homepage)171 unsigned long IcqProtocolPlugin::icqSetWorkInfo(const Licq::UserId& ownerId,
172     const std::string& city, const std::string& state, const std::string& phone,
173     const std::string& fax, const std::string& address, const std::string& zip,
174     unsigned short country, const std::string& name, const std::string& department,
175     const std::string& position, unsigned short occupation, const std::string& homepage)
176 {
177   if (!isOwnerOnline(ownerId))
178     return 0;
179 
180   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
181   pushSignal(new ProtoUpdateWorkSignal(eventId, ownerId, city, state, phone, fax, address,
182       zip, country, name, department, position, occupation, homepage));
183   return eventId;
184 }
185 
icqSetEmailInfo(const Licq::UserId & ownerId,const std::string & emailSecondary,const std::string & emailOld)186 unsigned long IcqProtocolPlugin::icqSetEmailInfo(const Licq::UserId& ownerId,
187     const std::string& emailSecondary, const std::string& emailOld)
188 {
189   if (!isOwnerOnline(ownerId))
190     return 0;
191 
192   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
193   pushSignal(new ProtoUpdateEmailSignal(eventId, ownerId, emailSecondary, emailOld));
194   return eventId;
195 }
196 
icqSetMoreInfo(const Licq::UserId & ownerId,unsigned short age,char gender,const std::string & homepage,unsigned short birthYear,char birthMonth,char birthDay,char language1,char language2,char language3)197 unsigned long IcqProtocolPlugin::icqSetMoreInfo(const Licq::UserId& ownerId,
198     unsigned short age, char gender, const std::string& homepage,
199     unsigned short birthYear, char birthMonth, char birthDay,
200     char language1, char language2, char language3)
201 {
202   if (!isOwnerOnline(ownerId))
203     return 0;
204 
205   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
206   pushSignal(new ProtoUpdateMoreSignal(eventId, ownerId, age, gender, homepage,
207       birthYear, birthMonth, birthDay, language1, language2, language3));
208   return eventId;
209 }
210 
icqSetSecurityInfo(const Licq::UserId & ownerId,bool authorize,bool webAware)211 unsigned long IcqProtocolPlugin::icqSetSecurityInfo(const Licq::UserId& ownerId,
212     bool authorize, bool webAware)
213 {
214   if (!isOwnerOnline(ownerId))
215     return 0;
216 
217   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
218   pushSignal(new ProtoUpdateSecuritySignal(eventId, ownerId, authorize, webAware));
219   return eventId;
220 }
221 
icqSetInterestsInfo(const Licq::UserId & ownerId,const Licq::UserCategoryMap & interests)222 unsigned long IcqProtocolPlugin::icqSetInterestsInfo(const Licq::UserId& ownerId,
223     const Licq::UserCategoryMap& interests)
224 {
225   if (!isOwnerOnline(ownerId))
226     return 0;
227 
228   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
229   pushSignal(new ProtoUpdateInterestsSignal(eventId, ownerId, interests));
230   return eventId;
231 }
232 
icqSetOrgBackInfo(const Licq::UserId & ownerId,const Licq::UserCategoryMap & organisations,const Licq::UserCategoryMap & background)233 unsigned long IcqProtocolPlugin::icqSetOrgBackInfo(const Licq::UserId& ownerId,
234     const Licq::UserCategoryMap& organisations, const Licq::UserCategoryMap& background)
235 {
236   if (!isOwnerOnline(ownerId))
237     return 0;
238 
239   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
240   pushSignal(new ProtoUpdateOrgBackSignal(eventId, ownerId, organisations, background));
241   return eventId;
242 }
243 
icqSetAbout(const Licq::UserId & ownerId,const std::string & about)244 unsigned long IcqProtocolPlugin::icqSetAbout(const Licq::UserId& ownerId, const std::string& about)
245 {
246   if (!isOwnerOnline(ownerId))
247     return 0;
248 
249   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
250   pushSignal(new ProtoUpdateAboutSignal(eventId, ownerId, about));
251   return eventId;
252 }
253 
icqSearchWhitePages(const Licq::UserId & ownerId,const std::string & firstName,const std::string & lastName,const std::string & alias,const std::string & email,unsigned short minAge,unsigned short maxAge,char gender,char language,const std::string & city,const std::string & state,unsigned short country,const std::string & coName,const std::string & coDept,const std::string & coPos,const std::string & keyword,bool onlineOnly)254 unsigned long IcqProtocolPlugin::icqSearchWhitePages(const Licq::UserId& ownerId,
255     const std::string& firstName, const std::string& lastName, const std::string& alias,
256     const std::string& email, unsigned short minAge, unsigned short maxAge, char gender,
257     char language, const std::string& city, const std::string& state, unsigned short country,
258     const std::string& coName, const std::string& coDept, const std::string& coPos,
259     const std::string& keyword, bool onlineOnly)
260 {
261   if (!isOwnerOnline(ownerId))
262     return 0;
263 
264   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
265   pushSignal(new ProtoSearchWhitePagesSignal(eventId, ownerId, firstName, lastName,
266       alias, email, minAge, maxAge, gender, language, city, state, country, coName,
267       coDept, coPos, keyword, onlineOnly));
268   return eventId;
269 }
270 
icqSearchByUin(const Licq::UserId & userId)271 unsigned long IcqProtocolPlugin::icqSearchByUin(const Licq::UserId& userId)
272 {
273   if (!isOwnerOnline(userId))
274     return 0;
275 
276   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
277   pushSignal(new ProtoSearchUinSignal(eventId, userId));
278   return eventId;
279 }
280 
icqAlertUser(const Licq::UserId & userId)281 void IcqProtocolPlugin::icqAlertUser(const Licq::UserId& userId)
282 {
283   if (!isOwnerOnline(userId))
284     return;
285 
286   pushSignal(new ProtoAddedSignal(userId));
287 }
288 
icqSetPhoneFollowMeStatus(const Licq::UserId & ownerId,unsigned status)289 void IcqProtocolPlugin::icqSetPhoneFollowMeStatus(const Licq::UserId& ownerId, unsigned status)
290 {
291   if (!isOwnerOnline(ownerId))
292     return;
293 
294   pushSignal(new ProtoSetPhoneFollowMeSignal(ownerId, status));
295 }
296 
setRandomChatGroup(const Licq::UserId & ownerId,unsigned chatGroup)297 unsigned long IcqProtocolPlugin::setRandomChatGroup(const Licq::UserId& ownerId, unsigned chatGroup)
298 {
299   if (!isOwnerOnline(ownerId))
300     return 0;
301 
302   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
303   pushSignal(new ProtoUpdateRandomChatSignal(eventId, ownerId, chatGroup));
304   return eventId;
305 }
306 
randomChatSearch(const Licq::UserId & ownerId,unsigned chatGroup)307 unsigned long IcqProtocolPlugin::randomChatSearch(const Licq::UserId& ownerId, unsigned chatGroup)
308 {
309   if (!isOwnerOnline(ownerId))
310     return 0;
311 
312   unsigned long eventId = Licq::gProtocolManager.getNextEventId();
313   pushSignal(new ProtoSearchRandomSignal(eventId, ownerId, chatGroup));
314   return eventId;
315 }
316 
updateAllUsersInGroup(const Licq::UserId & ownerId,int groupId)317 void IcqProtocolPlugin::updateAllUsersInGroup(const Licq::UserId& ownerId, int groupId)
318 {
319   if (!isOwnerOnline(ownerId))
320     return;
321 
322   pushSignal(new ProtoUpdateUsersSignal(ownerId, groupId));
323 }
324 
createFileTransferManager(const Licq::UserId & userId)325 Licq::IcqFileTransferManager* IcqProtocolPlugin::createFileTransferManager(const Licq::UserId& userId)
326 {
327   return new FileTransferManager(userId);
328 }
329 
createChatManager(const Licq::UserId & userId)330 Licq::IcqChatManager* IcqProtocolPlugin::createChatManager(const Licq::UserId& userId)
331 {
332   return new ChatManager(userId);
333 }
334