1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 2012-2013 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 #ifndef LICQICQ_USER_H
21 #define LICQICQ_USER_H
22 
23 #include <licq/icq/user.h>
24 
25 #include "buffer.h"
26 
27 namespace LicqIcq
28 {
29 class DcSocket;
30 
31 /**
32  * An ICQ protocol contact
33  */
34 class User : public virtual Licq::IcqUser
35 {
36 public:
37   /// Constructor
38   User(const Licq::UserId& id, bool temporary = false);
39 
40   /// Destructor
41   virtual ~User();
42 
43   /// Inherited from Licq::User to save local additions
44   virtual void saveLicqInfo();
45   virtual void saveUserInfo();
46   virtual void savePictureInfo();
47 
48   // Inherited from Licq::User to update TLV entry when alias changes
49   virtual void setAlias(const std::string& alias);
50 
51   // Picture Info
buddyIconType()52   unsigned buddyIconType() const                { return myBuddyIconType; }
buddyIconHashType()53   char buddyIconHashType() const                { return myBuddyIconHashType; }
buddyIconHash()54   const std::string& buddyIconHash() const      { return myBuddyIconHash; }
ourBuddyIconHash()55   const std::string& ourBuddyIconHash() const   { return myOurBuddyIconHash; }
setBuddyIconType(unsigned s)56   void setBuddyIconType(unsigned s)     { myBuddyIconType = s; }
setBuddyIconHashType(char s)57   void setBuddyIconHashType(char s)     { myBuddyIconHashType = s; }
setBuddyIconHash(const std::string & s)58   void setBuddyIconHash(const std::string& s) { myBuddyIconHash = s; }
setOurBuddyIconHash(const std::string & s)59   void setOurBuddyIconHash(const std::string& s) { myOurBuddyIconHash = s; }
60 
GetSID()61   unsigned short GetSID() const                 { return myNormalSid; }
GetInvisibleSID()62   unsigned short GetInvisibleSID() const        { return myInvisibleSid; }
GetVisibleSID()63   unsigned short GetVisibleSID() const          { return myVisibleSid; }
GetGSID()64   unsigned short GetGSID() const                { return myGroupSid; }
SetSID(unsigned short s)65   void SetSID(unsigned short s)                 { myNormalSid = s; }
SetInvisibleSID(unsigned short s)66   void SetInvisibleSID(unsigned short s)        { myInvisibleSid = s; }
SetVisibleSID(unsigned short s)67   void SetVisibleSID(unsigned short s)          { myVisibleSid = s; }
68   void SetGSID(unsigned short s);
69 
70   //!True if they have sent the UTF8 Cap
SupportsUTF8()71   bool SupportsUTF8() const                     { return mySupportsUtf8; }
SetSupportsUTF8(bool b)72   void SetSupportsUTF8(bool b)                  { mySupportsUtf8 = b; }
73 
SendLevel()74   unsigned short SendLevel() const              { return mySendLevel; }
SetSendLevel(unsigned short s)75   void SetSendLevel(unsigned short s)           { mySendLevel = s; }
76 
77   unsigned short Sequence(bool = false);
setDirectMode(bool direct)78   void setDirectMode(bool direct)               { myDirectMode = direct; }
79 
directMode()80   bool directMode() const                       { return myDirectMode; }
81 
82   /// Overridden to check for existing connections
83   bool canSendDirect() const;
84 
ClientTimestamp()85   unsigned long ClientTimestamp() const         { return myClientTimestamp; }
OurClientTimestamp()86   unsigned long OurClientTimestamp() const      { return myOurClientTimestamp; }
ClientInfoTimestamp()87   unsigned long ClientInfoTimestamp() const     { return myClientInfoTimestamp; }
OurClientInfoTimestamp()88   unsigned long OurClientInfoTimestamp() const  { return myOurClientInfoTimestamp; }
ClientStatusTimestamp()89   unsigned long ClientStatusTimestamp() const   { return myClientStatusTimestamp; }
OurClientStatusTimestamp()90   unsigned long OurClientStatusTimestamp() const { return myOurClientStatusTimestamp; }
SetClientTimestamp(unsigned long s)91   void SetClientTimestamp(unsigned long s) { myClientTimestamp = s; }
SetOurClientTimestamp(unsigned long s)92   void SetOurClientTimestamp(unsigned long s) { myOurClientTimestamp = s; }
SetClientInfoTimestamp(unsigned long s)93   void SetClientInfoTimestamp(unsigned long s) { myClientInfoTimestamp = s; }
SetOurClientInfoTimestamp(unsigned long s)94   void SetOurClientInfoTimestamp(unsigned long s) { myOurClientInfoTimestamp = s; }
SetClientStatusTimestamp(unsigned long s)95   void SetClientStatusTimestamp(unsigned long s) { myClientStatusTimestamp = s; }
SetOurClientStatusTimestamp(unsigned long s)96   void SetOurClientStatusTimestamp(unsigned long s) { myOurClientStatusTimestamp = s; }
97 
setPhoneFollowMeStatus(unsigned n)98   void setPhoneFollowMeStatus(unsigned n)       { myPhoneFollowMeStatus = n; save(SaveLicqInfo); }
setIcqPhoneStatus(unsigned n)99   void setIcqPhoneStatus(unsigned n)            { myIcqPhoneStatus = n; }
setSharedFilesStatus(unsigned n)100   void setSharedFilesStatus(unsigned n)         { mySharedFilesStatus = n; }
101 
102   // Convert between ICQ timezones and minute based
GetTimezone()103   char GetTimezone() const { return myTimezone==TimezoneUnknown ? -100 : myTimezone/-1800; }
SetTimezone(char tz)104   void SetTimezone(char tz) { setTimezone(tz==-100 ? TimezoneUnknown : ((int)tz)*-1800); }
105 
106   enum DirectFlags
107   {
108     DirectDisabled      = 0,    // Direct contact not possible
109     DirectAnyone        = 1,    // Direct contact with anyone
110     DirectListed        = 2,    // Direct contact only with contacts in list
111     DirectAuth          = 3,    // Direct contact only with authorized contacts
112   };
directFlag()113   unsigned directFlag() const                   { return myDirectFlag; }
setDirectFlag(unsigned n)114   void setDirectFlag(unsigned n)                { myDirectFlag = n; }
115 
Cookie()116   unsigned long Cookie() const                  { return myCookie; }
SetCookie(unsigned long cookie)117   void SetCookie(unsigned long cookie)          { myCookie = cookie; }
118 
119   // User TLV List handling
120   void AddTLV(TlvPtr);
121   void RemoveTLV(unsigned long);
122   void SetTLVList(TlvList& tlvs);
GetTLVList()123   TlvList GetTLVList()                          { return myTLVs; }
GetTLVList()124   const TlvList GetTLVList() const              { return myTLVs; }
125 
126   void SetIpPort(unsigned long nIp, unsigned short nPort);
127   std::string internalIpToString() const;
128 
129   int socketDesc(int channel) const;
130   void setSocketDesc(DcSocket* s);
131   void clearSocketDesc(Licq::INetSocket* s);
clearAllSocketDesc()132   void clearAllSocketDesc() { clearSocketDesc(NULL); }
normalSocketDesc()133   int normalSocketDesc() const { return myNormalSocketDesc; }
infoSocketDesc()134   int infoSocketDesc() const { return myInfoSocketDesc; }
135 
Version()136   unsigned long Version() const { return myVersion; }
137   unsigned short ConnectionVersion() const;
SetVersion(unsigned long s)138   void SetVersion(unsigned long s) { myVersion = s; }
SetConnectionVersion(unsigned short s)139   void SetConnectionVersion(unsigned short s) { myConnectionVersion = s; }
140 
141 private:
142   /**
143    * Save a category list
144    *
145    * @param category The category map to save
146    * @param key Base name of key in file for entries
147    */
148   void saveCategory(const Licq::UserCategoryMap& category, const std::string& key);
149 
150   /**
151    * Load a category list
152    *
153    * @param category The category map to save
154    * @param key Base name of key in file for entries
155    */
156   void loadCategory(Licq::UserCategoryMap& category, const std::string& key);
157 
158   unsigned short mySequence;
159   unsigned long myCookie;
160   unsigned long myClientTimestamp;
161   unsigned long myClientInfoTimestamp;
162   unsigned long myClientStatusTimestamp;
163   unsigned long myOurClientTimestamp;
164   unsigned long myOurClientInfoTimestamp;
165   unsigned long myOurClientStatusTimestamp;
166 
167   unsigned myDirectFlag;
168   bool myDirectMode;
169   bool mySupportsUtf8;
170   unsigned short mySendLevel;
171 
172   unsigned myBuddyIconType;
173   unsigned myBuddyIconHashType;
174   std::string myBuddyIconHash;
175   std::string myOurBuddyIconHash;
176 
177   // Server Side ID, Group SID
178   unsigned myNormalSid;
179   unsigned myInvisibleSid;
180   unsigned myVisibleSid;
181   unsigned myGroupSid;
182 
183   // Extra TLVs attached to this user's SSI info
184   // We use a map to allow fast access to the TLV by type, even though the
185   // actual type is in SOscarTLV as well. Which should make it obvious
186   // that the TLV handling should be fixed in licq_buffer.h/buffer.cpp
187   TlvList myTLVs;
188 
189   // Socket descriptors for direct connections
190   int myNormalSocketDesc;
191   int myInfoSocketDesc;
192   int myStatusSocketDesc;
193 
194   unsigned long myVersion;
195   unsigned myConnectionVersion;
196 };
197 
198 
199 /**
200  * Read mutex guard for LicqIcq::User
201  */
202 class UserReadGuard : public Licq::UserReadGuard
203 {
204 public:
205   // Derived costructors
206   UserReadGuard(const Licq::UserId& userId, bool addUser = false, bool* retWasAdded = NULL)
UserReadGuard(userId,addUser,retWasAdded)207     : Licq::UserReadGuard(userId, addUser, retWasAdded)
208   { }
209   UserReadGuard(const User* user, bool locked = false)
UserReadGuard(user,locked)210     : Licq::UserReadGuard(user, locked)
211   { }
UserReadGuard(UserReadGuard * guard)212   UserReadGuard(UserReadGuard* guard)
213     : Licq::UserReadGuard(guard)
214   { }
215 
216   // Access operators
217   const User* operator*() const
218   { return dynamic_cast<const User*>(Licq::UserReadGuard::operator*()); }
219   const User* operator->() const
220   { return dynamic_cast<const User*>(Licq::UserReadGuard::operator->()); }
221 };
222 
223 /**
224  * Write mutex guard for LicqIcq::User
225  */
226 class UserWriteGuard : public Licq::UserWriteGuard
227 {
228 public:
229   // Derived costructors
230   UserWriteGuard(const Licq::UserId& userId, bool addUser = false, bool* retWasAdded = NULL)
UserWriteGuard(userId,addUser,retWasAdded)231     : Licq::UserWriteGuard(userId, addUser, retWasAdded)
232   { }
233   UserWriteGuard(User* user, bool locked = false)
UserWriteGuard(user,locked)234     : Licq::UserWriteGuard(user, locked)
235   { }
UserWriteGuard(UserWriteGuard * guard)236   UserWriteGuard(UserWriteGuard* guard)
237     : Licq::UserWriteGuard(guard)
238   { }
239 
240   // Access operators
241   User* operator*() const
242   { return dynamic_cast<User*>(Licq::UserWriteGuard::operator*()); }
243   User* operator->() const
244   { return dynamic_cast<User*>(Licq::UserWriteGuard::operator->()); }
245 };
246 
247 } // namespace LicqIcq
248 
249 #endif
250