From 6897c90c6003af7b21d271771320999ddfe2d09a Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Mon, 19 Aug 2013 06:23:18 +0000 Subject: files renaming compilation fix git-svn-id: http://svn.miranda-ng.org/main/trunk@5739 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tlen/res/tlen.rc | 2 +- protocols/Tlen/src/jabber.h | 520 ------------ protocols/Tlen/src/jabber_iq.cpp | 114 --- protocols/Tlen/src/jabber_iq.h | 61 -- protocols/Tlen/src/jabber_iqid.cpp | 615 -------------- protocols/Tlen/src/jabber_list.cpp | 315 ------- protocols/Tlen/src/jabber_list.h | 90 -- protocols/Tlen/src/jabber_misc.cpp | 210 ----- protocols/Tlen/src/jabber_opt.cpp | 673 --------------- protocols/Tlen/src/jabber_svc.cpp | 1288 ----------------------------- protocols/Tlen/src/jabber_thread.cpp | 1409 -------------------------------- protocols/Tlen/src/jabber_util.cpp | 500 ------------ protocols/Tlen/src/jabber_ws.cpp | 160 ---- protocols/Tlen/src/jabber_xml.cpp | 568 ------------- protocols/Tlen/src/jabber_xml.h | 79 -- protocols/Tlen/src/tlen.cpp | 16 +- protocols/Tlen/src/tlen.h | 520 ++++++++++++ protocols/Tlen/src/tlen_advsearch.cpp | 2 +- protocols/Tlen/src/tlen_avatar.cpp | 4 +- protocols/Tlen/src/tlen_file.cpp | 4 +- protocols/Tlen/src/tlen_file.h | 2 +- protocols/Tlen/src/tlen_iq.cpp | 114 +++ protocols/Tlen/src/tlen_iq.h | 61 ++ protocols/Tlen/src/tlen_iqid.cpp | 615 ++++++++++++++ protocols/Tlen/src/tlen_list.cpp | 315 +++++++ protocols/Tlen/src/tlen_list.h | 90 ++ protocols/Tlen/src/tlen_misc.cpp | 210 +++++ protocols/Tlen/src/tlen_muc.cpp | 12 +- protocols/Tlen/src/tlen_opt.cpp | 673 +++++++++++++++ protocols/Tlen/src/tlen_p2p_new.cpp | 2 +- protocols/Tlen/src/tlen_p2p_old.cpp | 2 +- protocols/Tlen/src/tlen_p2p_old.h | 2 +- protocols/Tlen/src/tlen_picture.cpp | 4 +- protocols/Tlen/src/tlen_picture.h | 2 +- protocols/Tlen/src/tlen_presence.cpp | 4 +- protocols/Tlen/src/tlen_svc.cpp | 1288 +++++++++++++++++++++++++++++ protocols/Tlen/src/tlen_thread.cpp | 1409 ++++++++++++++++++++++++++++++++ protocols/Tlen/src/tlen_userinfo.cpp | 4 +- protocols/Tlen/src/tlen_util.cpp | 500 ++++++++++++ protocols/Tlen/src/tlen_voice.cpp | 6 +- protocols/Tlen/src/tlen_voice.h | 2 +- protocols/Tlen/src/tlen_ws.cpp | 160 ++++ protocols/Tlen/src/tlen_xml.cpp | 568 +++++++++++++ protocols/Tlen/src/tlen_xml.h | 79 ++ protocols/Tlen/tlen_10.vcxproj | 78 +- protocols/Tlen/tlen_10.vcxproj.filters | 28 +- protocols/Tlen/tlen_11.vcxproj | 78 +- protocols/Tlen/tlen_11.vcxproj.filters | 28 +- 48 files changed, 6709 insertions(+), 6777 deletions(-) delete mode 100644 protocols/Tlen/src/jabber.h delete mode 100644 protocols/Tlen/src/jabber_iq.cpp delete mode 100644 protocols/Tlen/src/jabber_iq.h delete mode 100644 protocols/Tlen/src/jabber_iqid.cpp delete mode 100644 protocols/Tlen/src/jabber_list.cpp delete mode 100644 protocols/Tlen/src/jabber_list.h delete mode 100644 protocols/Tlen/src/jabber_misc.cpp delete mode 100644 protocols/Tlen/src/jabber_opt.cpp delete mode 100644 protocols/Tlen/src/jabber_svc.cpp delete mode 100644 protocols/Tlen/src/jabber_thread.cpp delete mode 100644 protocols/Tlen/src/jabber_util.cpp delete mode 100644 protocols/Tlen/src/jabber_ws.cpp delete mode 100644 protocols/Tlen/src/jabber_xml.cpp delete mode 100644 protocols/Tlen/src/jabber_xml.h create mode 100644 protocols/Tlen/src/tlen.h create mode 100644 protocols/Tlen/src/tlen_iq.cpp create mode 100644 protocols/Tlen/src/tlen_iq.h create mode 100644 protocols/Tlen/src/tlen_iqid.cpp create mode 100644 protocols/Tlen/src/tlen_list.cpp create mode 100644 protocols/Tlen/src/tlen_list.h create mode 100644 protocols/Tlen/src/tlen_misc.cpp create mode 100644 protocols/Tlen/src/tlen_opt.cpp create mode 100644 protocols/Tlen/src/tlen_svc.cpp create mode 100644 protocols/Tlen/src/tlen_thread.cpp create mode 100644 protocols/Tlen/src/tlen_util.cpp create mode 100644 protocols/Tlen/src/tlen_ws.cpp create mode 100644 protocols/Tlen/src/tlen_xml.cpp create mode 100644 protocols/Tlen/src/tlen_xml.h (limited to 'protocols/Tlen') diff --git a/protocols/Tlen/res/tlen.rc b/protocols/Tlen/res/tlen.rc index ab7173bb2b..1e7b53a7de 100644 --- a/protocols/Tlen/res/tlen.rc +++ b/protocols/Tlen/res/tlen.rc @@ -198,7 +198,7 @@ END IDD_PASSWORD DIALOG DISCARDABLE 0, 0, 151, 63 STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Jabber Password" +CAPTION "Tlen Password" FONT 8, "MS Shell Dlg" BEGIN EDITTEXT IDC_JID,7,7,137,12,ES_READONLY | NOT WS_BORDER | NOT diff --git a/protocols/Tlen/src/jabber.h b/protocols/Tlen/src/jabber.h deleted file mode 100644 index e8cd777b74..0000000000 --- a/protocols/Tlen/src/jabber.h +++ /dev/null @@ -1,520 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _JABBER_H_ -#define _JABBER_H_ - -#define MIRANDA_VER 0x0A00 - -#undef _WIN32_WINNT -#undef _WIN32_IE -#define _WIN32_WINNT 0x0501 -#define _WIN32_IE 0x0501 - -#define __try -#define __except(x) if (0) -#define __finally - -#define _try __try -#define _except __except -#define _finally __finally - -#ifdef _DEBUG -#define _CRTDBG_MAP_ALLOC -#include -#include -#endif -#define ENABLE_LOGGING - -/******************************************************************* - * Global compilation flags - *******************************************************************/ - -/******************************************************************* - * Global header files - *******************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "jabber_xml.h" -#include "crypto/polarssl/aes.h" -#include "crypto/polarssl/bignum.h" - -/******************************************************************* - * Global constants - *******************************************************************/ -#define TLEN_DEFAULT_PORT 443 -#define JABBER_IQID "mim_" -#define TLEN_REGISTER "http://reg.tlen.pl/" -#define TLEN_MAX_SEARCH_RESULTS_PER_PAGE 20 - -// User-defined message -#define WM_TLEN_REFRESH (WM_USER + 100) -// Error code -#define JABBER_ERROR_REDIRECT 302 -#define JABBER_ERROR_BAD_REQUEST 400 -#define JABBER_ERROR_UNAUTHORIZED 401 -#define JABBER_ERROR_PAYMENT_REQUIRED 402 -#define JABBER_ERROR_FORBIDDEN 403 -#define JABBER_ERROR_NOT_FOUND 404 -#define JABBER_ERROR_NOT_ALLOWED 405 -#define JABBER_ERROR_NOT_ACCEPTABLE 406 -#define JABBER_ERROR_REGISTRATION_REQUIRED 407 -#define JABBER_ERROR_REQUEST_TIMEOUT 408 -#define JABBER_ERROR_CONFLICT 409 -#define JABBER_ERROR_INTERNAL_SERVER_ERROR 500 -#define JABBER_ERROR_NOT_IMPLEMENTED 501 -#define JABBER_ERROR_REMOTE_SERVER_ERROR 502 -#define JABBER_ERROR_SERVICE_UNAVAILABLE 503 -#define JABBER_ERROR_REMOTE_SERVER_TIMEOUT 504 - -#define TLEN_ALERTS_ACCEPT_ALL 0 -#define TLEN_ALERTS_IGNORE_NIR 1 -#define TLEN_ALERTS_IGNORE_ALL 2 - -#define TLEN_IMAGES_ACCEPT_ALL 0 -#define TLEN_IMAGES_IGNORE_NIR 1 -#define TLEN_IMAGES_IGNORE_ALL 2 - -#define TLEN_MUC_ASK 0 -#define TLEN_MUC_ACCEPT_IR 1 -#define TLEN_MUC_ACCEPT_ALL 2 -#define TLEN_MUC_IGNORE_NIR 3 -#define TLEN_MUC_IGNORE_ALL 4 - -#define IDC_STATIC (-1) - -/******************************************************************* - * Global data structures and data type definitions - *******************************************************************/ -typedef HANDLE JABBER_SOCKET; - -typedef enum { - LIST_ROSTER, // Roster list - LIST_CHATROOM, // Groupchat room currently joined - LIST_FILE, // Current file transfer session - LIST_INVITATIONS,// Invitations to be sent - LIST_SEARCH, // Rooms names being searched - LIST_VOICE, - LIST_PICTURE -} JABBER_LIST; - -typedef enum { - IQ_PROC_NONE, - IQ_PROC_GETSEARCH -} JABBER_IQ_PROCID; - -typedef enum { - SUB_NONE, - SUB_TO, - SUB_FROM, - SUB_BOTH -} JABBER_SUBSCRIPTION; - -typedef struct { - char *szOnline; - char *szAway; - char *szNa; - char *szDnd; - char *szFreechat; - char *szInvisible; -} JABBER_MODEMSGS; - -typedef struct { - char mailBase[256]; - char mailMsg[256]; - int mailMsgMthd; - char mailIndex[256]; - int mailIndexMthd; - char mailLogin[256]; - int mailLoginMthd; - char mailCompose[256]; - int mailComposeMthd; - char avatarGet[256]; - int avatarGetMthd; - char avatarUpload[256]; - int avatarUploadMthd; - char avatarRemove[256]; - int avatarRemoveMthd; -} TlenConfiguration; - -typedef struct { - BOOL useEncryption; - BOOL reconnect; - BOOL rosterSync; - BOOL offlineAsInvisible; - BOOL leaveOfflineMessage; - int offlineMessageOption; - BOOL ignoreAdvertisements; - int alertPolicy; - int groupChatPolicy; - int voiceChatPolicy; - int imagePolicy; - BOOL enableAvatars; - BOOL enableVersion; - BOOL useNudge; - BOOL logAlerts; - BOOL useNewP2P; - BOOL sendKeepAlive; - BOOL savePassword; -} TlenOptions; - - -struct JABBER_IQ_FUNC_STRUCT; -struct JABBER_LIST_ITEM_STRUCT; -struct TLEN_VOICE_CONTROL_STRUCT; - -struct TlenProtocol : public PROTO -{ - TlenProtocol( const char*, const TCHAR* ); - ~TlenProtocol(); - - //==================================================================================== - // PROTO_INTERFACE - //==================================================================================== - - virtual HANDLE __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ); - virtual HANDLE __cdecl AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ); - - virtual int __cdecl Authorize(HANDLE hDbEvent); - virtual int __cdecl AuthDeny(HANDLE hDbEvent, const PROTOCHAR* szReason); - virtual int __cdecl AuthRecv(HANDLE hContact, PROTORECVEVENT*); - virtual int __cdecl AuthRequest(HANDLE hContact, const PROTOCHAR* szMessage); - - virtual HANDLE __cdecl ChangeInfo(int iInfoType, void* pInfoData); - - virtual HANDLE __cdecl FileAllow(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath); - virtual int __cdecl FileCancel(HANDLE hContact, HANDLE hTransfer); - virtual int __cdecl FileDeny(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason); - virtual int __cdecl FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename); - - virtual DWORD_PTR __cdecl GetCaps(int type, HANDLE hContact = NULL); - virtual int __cdecl GetInfo(HANDLE hContact, int infoType); - - virtual HANDLE __cdecl SearchBasic(const PROTOCHAR* id); - virtual HANDLE __cdecl SearchByEmail(const PROTOCHAR* email); - virtual HANDLE __cdecl SearchByName(const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName); - virtual HWND __cdecl SearchAdvanced(HWND owner); - virtual HWND __cdecl CreateExtendedSearchUI(HWND owner); - - virtual int __cdecl RecvContacts(HANDLE hContact, PROTORECVEVENT*); - virtual int __cdecl RecvFile(HANDLE hContact, PROTOFILEEVENT*); - virtual int __cdecl RecvMsg(HANDLE hContact, PROTORECVEVENT*); - virtual int __cdecl RecvUrl(HANDLE hContact, PROTORECVEVENT*); - - virtual int __cdecl SendContacts(HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList); - virtual HANDLE __cdecl SendFile(HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles); - virtual int __cdecl SendMsg(HANDLE hContact, int flags, const char* msg); - virtual int __cdecl SendUrl(HANDLE hContact, int flags, const char* url); - - virtual int __cdecl SetApparentMode(HANDLE hContact, int mode); - virtual int __cdecl SetStatus(int iNewStatus); - - virtual HANDLE __cdecl GetAwayMsg(HANDLE hContact); - virtual int __cdecl RecvAwayMsg(HANDLE hContact, int mode, PROTORECVEVENT* evt); - virtual int __cdecl SendAwayMsg(HANDLE hContact, HANDLE hProcess, const char* msg); - virtual int __cdecl SetAwayMsg(int iStatus, const PROTOCHAR* msg); - - virtual int __cdecl UserIsTyping(HANDLE hContact, int type); - - virtual int __cdecl OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam); - - //==================================================================================== - // Services - - INT_PTR __cdecl GetName(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetAvatarInfo(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SendAlert(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetAvatarCaps(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SetMyAvatar(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetMyAvatar(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetStatus(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl AccMgrUI(WPARAM wParam, LPARAM lParam); - - INT_PTR __cdecl MUCMenuHandleChats(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl MUCMenuHandleMUC(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl MenuHandleInbox(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl ContactMenuHandleSendPicture(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl MUCContactMenuHandleMUC(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl VoiceContactMenuHandleVoice(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl ContactMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl ContactMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam); - - //==================================================================================== - // Events - - int __cdecl OnModulesLoaded(WPARAM wParam, LPARAM lParam); - int __cdecl OptionsInit(WPARAM wParam, LPARAM lParam); - int __cdecl JabberDbSettingChanged(WPARAM wParam, LPARAM lParam); - int __cdecl JabberContactDeleted(WPARAM wParam, LPARAM lParam); - int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam); - int __cdecl PreShutdown(WPARAM wParam, LPARAM lParam); - - int __cdecl UserInfoInit(WPARAM wParam, LPARAM lParam); - - int __cdecl MUCHandleEvent(WPARAM wParam, LPARAM lParam); - - //==================================================================================== - HANDLE hNetlibUser; - HANDLE hFileNetlibUser; - - JABBER_MODEMSGS modeMsgs; - - struct ThreadDataStruct *threadData; - HANDLE hTlenNudge; - HGENMENU hMenuMUC; - HGENMENU hMenuChats; - HGENMENU hMenuInbox; - HGENMENU hMenuContactMUC; - HGENMENU hMenuContactVoice; - HGENMENU hMenuContactGrantAuth; - HGENMENU hMenuContactRequestAuth; - HGENMENU hMenuPicture; - - int listsCount; - struct JABBER_LIST_ITEM_STRUCT *lists; - CRITICAL_SECTION csLists; - - int iqCount; - int iqAlloced; - struct JABBER_IQ_FUNC_STRUCT *iqList; - CRITICAL_SECTION csIqList; - - CRITICAL_SECTION csSerial; - unsigned int serial; - BOOL isOnline; - BOOL isConnected; - - CRITICAL_SECTION modeMsgMutex; - - void initMenuItems(); - HGENMENU hMenuRoot; - - char *searchJID; - int searchID; - int searchIndex; - char *searchQuery; - int searchQueryLen; - - CRITICAL_SECTION csSend; - - HWND voiceDlgHWND; - struct TLEN_VOICE_CONTROL_STRUCT *playbackControl; - struct TLEN_VOICE_CONTROL_STRUCT *recordingControl; - int framesAvailableForPlayback; - int availOverrunValue; - - TlenOptions tlenOptions; - -}; - - - -typedef struct ThreadDataStruct{ - HANDLE hThread; - char *streamId; - char username[128]; - char password[128]; - char server[128]; - char manualHost[128]; - char avatarToken[128]; - char avatarHash[64]; - int avatarFormat; - WORD port; - BOOL useEncryption; - - JABBER_SOCKET s; //HANDLE from CallService(MS_NETLIB_OPENCONNECTION (jabber_ws.c:68) - aes_context aes_in_context; - aes_context aes_out_context; - unsigned char aes_in_iv[16]; - unsigned char aes_out_iv[16]; - - BOOL useAES; - TlenConfiguration tlenConfig; - TlenProtocol *proto; -} ThreadData; - - -typedef enum { FT_CONNECTING, FT_INITIALIZING, FT_RECEIVING, FT_DONE, FT_ERROR, FT_DENIED, FT_SWITCH } JABBER_FILE_STATE; -typedef enum { FT_RECV, FT_SEND} JABBER_FILE_MODE; -typedef struct TLEN_FILE_TRANSFER_STRUCT{ - HANDLE hContact; - JABBER_SOCKET s; - NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2; - JABBER_FILE_STATE state; - char *jid; - int fileId; - char *iqId; - int mode; - - // Used by file receiving only - char *hostName; - WORD wPort; - char *localName; - WORD wLocalPort; - char *szSavePath; - long fileReceivedBytes; - long fileTotalSize; - - // Used by file sending only - HANDLE hFileEvent; - int fileCount; - char **files; - long *filesSize; - //long fileTotalSize; // Size of the current file (file being sent) - long allFileTotalSize; - long allFileReceivedBytes; - char *szDescription; - int currentFile; - - // New p2p - BOOL newP2P; - char *id2; - SOCKET udps; - aes_context aes_context; - unsigned char aes_iv[16]; - TlenProtocol *proto; - -} TLEN_FILE_TRANSFER; - -typedef struct { - PROTOSEARCHRESULT hdr; - char jid[256]; -} JABBER_SEARCH_RESULT; - -typedef struct { - char *iqId; - PROTOSEARCHRESULT hdr; - char jid[256]; -} TLEN_CONFERENCE; - - -typedef struct { - int id; - TCHAR *name; -} JABBER_FIELD_MAP; - - -/******************************************************************* - * Global variables - *******************************************************************/ -extern HINSTANCE hInst; -extern HANDLE hMainThread; - -/******************************************************************* - * Function declarations - *******************************************************************/ -void uninitMenuItems(TlenProtocol *proto); -HICON GetIcolibIcon(int iconId); -void ReleaseIcolibIcon(HICON hIcon); - -void JabberLog(TlenProtocol *proto, const char *fmt, ...); -void __cdecl JabberServerThread(ThreadData *info); -// jabber_ws.cpp -BOOL JabberWsInit(TlenProtocol *proto); -void JabberWsUninit(TlenProtocol *proto); -JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port); -int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen); -int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen); -int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv); -int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv); - -// jabber_util.cpp -void JabberSerialInit(TlenProtocol *proto); -void JabberSerialUninit(TlenProtocol *proto); -unsigned int JabberSerialNext(TlenProtocol *proto); -int JabberSend(TlenProtocol *proto, const char *fmt, ...); -HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid); -char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact); -char *JabberLoginFromJID(const char *jid); -char *JabberResourceFromJID(const char *jid); -char *JabberNickFromJID(const char *jid); -char *JabberLocalNickFromJID(const char *jid); -char *TlenGroupEncode(const char *str); -char *TlenGroupDecode(const char *str); -char *JabberSha1(char *str); -char *TlenSha1(char *str, int len); -char *TlenPasswordHash(const char *str); -void TlenUrlDecode(char *str); -char *TlenUrlEncode(const char *str); -char *JabberTextEncode(const char *str); -char *JabberTextDecode(const char *str); -void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message); -BOOL IsAuthorized(TlenProtocol *proto, const char *jid); -//char *JabberGetVersionText(); -time_t JabberIsoToUnixTime(char *stamp); -time_t TlenTimeToUTC(time_t time); -void JabberSendPresence(TlenProtocol *proto,int status); -void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...); -//char *JabberGetClientJID(char *jid); -// jabber_misc.cpp -void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob); -void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick); -HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary); -void JabberContactListCreateGroup(char *groupName); -unsigned long JabberForkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg); -// jabber_svc.cpp -int TlenRunSearch(TlenProtocol *proto); -// jabber_opt.cpp -void TlenLoadOptions(TlenProtocol *proto); -// tlen_voice.cpp -int TlenVoiceCancelAll(TlenProtocol *proto); -// jabber_advsearch.cpp -extern JABBER_FIELD_MAP tlenFieldGender[]; -extern JABBER_FIELD_MAP tlenFieldLookfor[]; -extern JABBER_FIELD_MAP tlenFieldStatus[]; -extern JABBER_FIELD_MAP tlenFieldOccupation[]; -extern JABBER_FIELD_MAP tlenFieldPlan[]; -// tlen_advsearch.cpp -INT_PTR CALLBACK TlenAdvSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -char *TlenAdvSearchCreateQuery(HWND hwndDlg, int iqId); - - -#endif diff --git a/protocols/Tlen/src/jabber_iq.cpp b/protocols/Tlen/src/jabber_iq.cpp deleted file mode 100644 index 01ce67129b..0000000000 --- a/protocols/Tlen/src/jabber_iq.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_iq.h" - - -void JabberIqInit(TlenProtocol *proto) -{ - InitializeCriticalSection(&proto->csIqList); - proto->iqList = NULL; - proto->iqCount = 0; - proto->iqAlloced = 0; -} - -void JabberIqUninit(TlenProtocol *proto) -{ - if (proto->iqList) mir_free(proto->iqList); - proto->iqList = NULL; - proto->iqCount = 0; - proto->iqAlloced = 0; - DeleteCriticalSection(&proto->csIqList); -} - -static void JabberIqRemove(TlenProtocol *proto, int index) -{ - EnterCriticalSection(&proto->csIqList); - if (index >= 0 && indexiqCount) { - memmove(proto->iqList+index, proto->iqList+index+1, sizeof(JABBER_IQ_FUNC)*(proto->iqCount-index-1)); - proto->iqCount--; - } - LeaveCriticalSection(&proto->csIqList); -} - -static void JabberIqExpire(TlenProtocol *proto) -{ - int i; - time_t expire; - - EnterCriticalSection(&proto->csIqList); - expire = time(NULL) - 120; // 2 minute - i = 0; - while (i < proto->iqCount) { - if (proto->iqList[i].requestTime < expire) - JabberIqRemove(proto, i); - else - i++; - } - LeaveCriticalSection(&proto->csIqList); -} - -JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId) -{ - int i; - JABBER_IQ_PFUNC res; - - EnterCriticalSection(&proto->csIqList); - JabberIqExpire(proto); - for (i=0; iiqCount && proto->iqList[i].iqId != iqId; i++); - if (i < proto->iqCount) { - res = proto->iqList[i].func; - JabberIqRemove(proto, i); - } - else { - res = (JABBER_IQ_PFUNC) NULL; - } - LeaveCriticalSection(&proto->csIqList); - return res; -} - -void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func) -{ - int i; - - EnterCriticalSection(&proto->csIqList); - if (procId == IQ_PROC_NONE) - i = proto->iqCount; - else - for (i=0; iiqCount && proto->iqList[i].procId != procId; i++); - - if (i >= proto->iqCount && proto->iqCount >= proto->iqAlloced) { - proto->iqAlloced = proto->iqCount + 8; - proto->iqList = (JABBER_IQ_FUNC*)mir_realloc(proto->iqList, sizeof(JABBER_IQ_FUNC)*proto->iqAlloced); - } - - if (proto->iqList != NULL) { - proto->iqList[i].iqId = iqId; - proto->iqList[i].procId = procId; - proto->iqList[i].func = func; - proto->iqList[i].requestTime = time(NULL); - if (i == proto->iqCount) proto->iqCount++; - } - LeaveCriticalSection(&proto->csIqList); -} - diff --git a/protocols/Tlen/src/jabber_iq.h b/protocols/Tlen/src/jabber_iq.h deleted file mode 100644 index d521c85c66..0000000000 --- a/protocols/Tlen/src/jabber_iq.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef _JABBER_IQ_H_ -#define _JABBER_IQ_H_ - -#include "jabber_xml.h" -#include "jabber.h" - -typedef void (*JABBER_IQ_PFUNC)(TlenProtocol *proto, XmlNode *iqNode); - -typedef struct JABBER_IQ_FUNC_STRUCT { - int iqId; // id to match IQ get/set with IQ result - JABBER_IQ_PROCID procId; // must be unique in the list, except for IQ_PROC_NONE which can have multiple entries - JABBER_IQ_PFUNC func; // callback function - time_t requestTime; // time the request was sent, used to remove relinquent entries -} JABBER_IQ_FUNC; - -void JabberIqInit(TlenProtocol *proto); -void JabberIqUninit(TlenProtocol *proto); -JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId); -void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func); - -void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode); -void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode); -void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode); - -void TlenIqResultChatGroups(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultChatRooms(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultUserRooms(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultUserNicks(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultRoomSearch(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultRoomInfo(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultChatRoomUsers(TlenProtocol *proto, XmlNode *iqNode); -//void JabberIqResultSetPassword(XmlNode *iqNode, void *userdata); - -#endif - diff --git a/protocols/Tlen/src/jabber_iqid.cpp b/protocols/Tlen/src/jabber_iqid.cpp deleted file mode 100644 index 3a6cb87ec5..0000000000 --- a/protocols/Tlen/src/jabber_iqid.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "resource.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "tlen_muc.h" - -void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode) -{ - char *type; - - // RECVED: authentication result - // ACTION: if successfully logged in, continue by requesting roster list and set my initial status - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - - if (!strcmp(type, "result")) { - DBVARIANT dbv; - - if (db_get(NULL, proto->m_szModuleName, "Nick", &dbv)) - db_set_s(NULL, proto->m_szModuleName, "Nick", proto->threadData->username); - else - db_free(&dbv); -// iqId = JabberSerialNext(); -// JabberIqAdd(iqId, IQ_PROC_NONE, JabberIqResultGetRoster); -// JabberSend(info, "", iqId); - - JabberSend(proto, ""); - JabberSend(proto, ""); - } - // What to do if password error? etc... - else if (!strcmp(type, "error")) { - char text[128]; - - JabberSend(proto, ""); - mir_snprintf(text, sizeof(text), "%s %s@%s.", TranslateT("Authentication failed for"), proto->threadData->username, proto->threadData->server); - MessageBoxA(NULL, text, Translate("Tlen Authentication"), MB_OK|MB_ICONSTOP|MB_SETFOREGROUND); - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_WRONGPASSWORD); - proto->threadData = NULL; // To disallow auto reconnect - } -} - -void JabberResultSetRoster(TlenProtocol *proto, XmlNode *queryNode) { - DBVARIANT dbv; - XmlNode *itemNode, *groupNode; - JABBER_LIST_ITEM *item; - HANDLE hContact; - char *jid, *name, *nick; - int i; - char *str; - - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - str = JabberXmlGetAttrValue(itemNode, "subscription"); - if (!strcmp(str, "remove")) { - if ((hContact=JabberHContactFromJID(proto, jid)) != NULL) { - if (db_get_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - db_set_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); - } - JabberListRemove(proto, LIST_ROSTER, jid); - } else { - item = JabberListAdd(proto, LIST_ROSTER, jid); - if (item != NULL) { - if (str == NULL) item->subscription = SUB_NONE; - else if (!strcmp(str, "both")) item->subscription = SUB_BOTH; - else if (!strcmp(str, "to")) item->subscription = SUB_TO; - else if (!strcmp(str, "from")) item->subscription = SUB_FROM; - else item->subscription = SUB_NONE; - if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { - nick = JabberTextDecode(name); - } else { - nick = JabberLocalNickFromJID(jid); - } - if (nick != NULL) { - if (item->nick) mir_free(item->nick); - item->nick = nick; - - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - // Received roster has a new JID. - // Add the jid (with empty resource) to Miranda contact list. - hContact = JabberDBCreateContact(proto, jid, nick, FALSE); - } - db_set_s(hContact, "CList", "MyHandle", nick); - if (item->group) mir_free(item->group); - if ((groupNode=JabberXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { - item->group = TlenGroupDecode(groupNode->text); - JabberContactListCreateGroup(item->group); - // Don't set group again if already correct, or Miranda may show wrong group count in some case - if (!db_get(hContact, "CList", "Group", &dbv)) { - if (strcmp(dbv.pszVal, item->group)) - db_set_s(hContact, "CList", "Group", item->group); - db_free(&dbv); - } else - db_set_s(hContact, "CList", "Group", item->group); - } else { - item->group = NULL; - db_unset(hContact, "CList", "Group"); - } - } - } - } - } - } - } -} - -void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode; - char *type; - char *str; - - // RECVED: roster information - // ACTION: populate LIST_ROSTER and create contact for any new rosters - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - - if (!strcmp(type, "result")) { - str = JabberXmlGetAttrValue(queryNode, "xmlns"); - if (str != NULL && !strcmp(str, "jabber:iq:roster")) { - DBVARIANT dbv; - XmlNode *itemNode, *groupNode; - JABBER_SUBSCRIPTION sub; - JABBER_LIST_ITEM *item; - char *jid, *name, *nick; - int i, oldStatus; - - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - str = JabberXmlGetAttrValue(itemNode, "subscription"); - if (str == NULL) sub = SUB_NONE; - else if (!strcmp(str, "both")) sub = SUB_BOTH; - else if (!strcmp(str, "to")) sub = SUB_TO; - else if (!strcmp(str, "from")) sub = SUB_FROM; - else sub = SUB_NONE; - //if (str != NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) - nick = JabberTextDecode(name); - else - nick = JabberLocalNickFromJID(jid); - - if (nick != NULL) { - HANDLE hContact; - item = JabberListAdd(proto, LIST_ROSTER, jid); - if (item->nick) mir_free(item->nick); - item->nick = nick; - item->subscription = sub; - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - // Received roster has a new JID. - // Add the jid (with empty resource) to Miranda contact list. - hContact = JabberDBCreateContact(proto, jid, nick, FALSE); - } - db_set_s(hContact, "CList", "MyHandle", nick); - if (item->group) mir_free(item->group); - if ((groupNode=JabberXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { - item->group = TlenGroupDecode(groupNode->text); - JabberContactListCreateGroup(item->group); - // Don't set group again if already correct, or Miranda may show wrong group count in some case - if (!db_get(hContact, "CList", "Group", &dbv)) { - if (strcmp(dbv.pszVal, item->group)) - db_set_s(hContact, "CList", "Group", item->group); - db_free(&dbv); - } - else db_set_s(hContact, "CList", "Group", item->group); - } - else { - item->group = NULL; - db_unset(hContact, "CList", "Group"); - } - if (!db_get(hContact, proto->m_szModuleName, "AvatarHash", &dbv)) { - if (item->avatarHash) mir_free(item->avatarHash); - item->avatarHash = mir_strdup(dbv.pszVal); - JabberLog(proto, "Setting hash [%s] = %s", nick, item->avatarHash); - db_free(&dbv); - } - item->avatarFormat = db_get_dw(hContact, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); - } - } - } - } - - // Delete orphaned contacts (if roster sync is enabled) - if (db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE) == TRUE) { - for (HANDLE hContact = db_find_first(proto->m_szModuleName); hContact; ) { - HANDLE hNext = hContact = db_find_next(hContact, proto->m_szModuleName); - ptrA jid( db_get_sa(hContact, proto->m_szModuleName, "jid")); - if (jid != NULL) { - if (!JabberListExist(proto, LIST_ROSTER, jid)) { - JabberLog(proto, "Syncing roster: deleting 0x%x", hContact); - CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); - } - } - hContact = hNext; - } - } - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIM_FLAGS; - Menu_ModifyItem(proto->hMenuMUC, &mi); - if (proto->hMenuChats != NULL) - Menu_ModifyItem(proto->hMenuChats, &mi); - - proto->isOnline = TRUE; - JabberLog(proto, "Status changed via THREADSTART"); - oldStatus = proto->m_iStatus; - JabberSendPresence(proto, proto->m_iDesiredStatus); - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->m_iStatus); - } - } -} - - -// Tlen actually use jabber:iq:search for other users vCard or jabber:iq:register for own vCard -void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode, *itemNode, *n; - char *type, *jid; - char text[128]; - HANDLE hContact; - char *nText; - -// JabberLog(" iqIdGetVcard (tlen)"); - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - - if (!strcmp(type, "result")) { - BOOL hasFirst, hasLast, hasNick, hasEmail, hasCity, hasAge, hasGender, hasSchool, hasLookFor, hasOccupation; - DBVARIANT dbv; - int i; - - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - if ((itemNode=JabberXmlGetChild(queryNode, "item")) == NULL) return; - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv)) return; - if (strchr(jid, '@') != NULL) { - mir_snprintf(text, SIZEOF(text), "%s", jid); - } else { - mir_snprintf(text, SIZEOF(text), "%s@%s", jid, dbv.pszVal); // Add @tlen.pl - } - db_free(&dbv); - if ((hContact=JabberHContactFromJID(proto, text)) == NULL) { - if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv)) return; - if (strcmp(dbv.pszVal, jid)) { - db_free(&dbv); - return; - } - db_free(&dbv); - } - } else { - hContact = NULL; - } - hasFirst = hasLast = hasNick = hasEmail = hasCity = hasAge = hasGender = hasOccupation = hasLookFor = hasSchool = FALSE; - for (i=0; inumChild; i++) { - n = itemNode->child[i]; - if (n == NULL || n->name == NULL) continue; - if (!strcmp(n->name, "first")) { - if (n->text != NULL) { - hasFirst = TRUE; - nText = JabberTextDecode(n->text); - db_set_s(hContact, proto->m_szModuleName, "FirstName", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "last")) { - if (n->text != NULL) { - hasLast = TRUE; - nText = JabberTextDecode(n->text); - db_set_s(hContact, proto->m_szModuleName, "LastName", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "nick")) { - if (n->text != NULL) { - hasNick = TRUE; - nText = JabberTextDecode(n->text); - db_set_s(hContact, proto->m_szModuleName, "Nick", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "email")) { - if (n->text != NULL) { - hasEmail = TRUE; - nText = JabberTextDecode(n->text); - db_set_s(hContact, proto->m_szModuleName, "e-mail", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "c")) { - if (n->text != NULL) { - hasCity = TRUE; - nText = JabberTextDecode(n->text); - db_set_s(hContact, proto->m_szModuleName, "City", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "b")) { - if (n->text != NULL) { - WORD nAge; - hasAge = TRUE; - nAge = atoi(n->text); - db_set_w(hContact, proto->m_szModuleName, "Age", nAge); - } - } - else if (!strcmp(n->name, "s")) { - if (n->text != NULL && n->text[1] == '\0' && (n->text[0] == '1' || n->text[0] == '2')) { - hasGender = TRUE; - db_set_b(hContact, proto->m_szModuleName, "Gender", (BYTE) (n->text[0] == '1'?'M':'F')); - } - } - else if (!strcmp(n->name, "e")) { - if (n->text != NULL) { - hasSchool = TRUE; - nText = JabberTextDecode(n->text); - db_set_s(hContact, proto->m_szModuleName, "School", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "j")) { - if (n->text != NULL) { - WORD nOccupation; - hasOccupation = TRUE; - nOccupation = atoi(n->text); - db_set_w(hContact, proto->m_szModuleName, "Occupation", nOccupation); - } - } - else if (!strcmp(n->name, "r")) { - if (n->text != NULL) { - WORD nLookFor; - hasLookFor = TRUE; - nLookFor = atoi(n->text); - db_set_w(hContact, proto->m_szModuleName, "LookingFor", nLookFor); - } - } - else if (!strcmp(n->name, "g")) { // voice chat enabled - if (n->text != NULL) { - BYTE bVoice; - bVoice = atoi(n->text); - db_set_w(hContact, proto->m_szModuleName, "VoiceChat", bVoice); - } - } - else if (!strcmp(n->name, "v")) { // status visibility - if (n->text != NULL) { - BYTE bPublic; - bPublic = atoi(n->text); - db_set_w(hContact, proto->m_szModuleName, "PublicStatus", bPublic); - } - } - } - if (!hasFirst) - db_unset(hContact, proto->m_szModuleName, "FirstName"); - if (!hasLast) - db_unset(hContact, proto->m_szModuleName, "LastName"); - // We are not removing "Nick" -// if (!hasNick) -// db_unset(hContact, m_szModuleName, "Nick"); - if (!hasEmail) - db_unset(hContact, proto->m_szModuleName, "e-mail"); - if (!hasCity) - db_unset(hContact, proto->m_szModuleName, "City"); - if (!hasAge) - db_unset(hContact, proto->m_szModuleName, "Age"); - if (!hasGender) - db_unset(hContact, proto->m_szModuleName, "Gender"); - if (!hasSchool) - db_unset(hContact, proto->m_szModuleName, "School"); - if (!hasOccupation) - db_unset(hContact, proto->m_szModuleName, "Occupation"); - if (!hasLookFor) - db_unset(hContact, proto->m_szModuleName, "LookingFor"); - ProtoBroadcastAck(proto->m_szModuleName, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0); - } -} - -void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode, *itemNode, *n; - char *type, *jid, *str; - int id, i, found; - JABBER_SEARCH_RESULT jsr = {0}; - DBVARIANT dbv = {0}; - - found = 0; -// JabberLog(" iqIdGetSearch"); - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - if ((str=JabberXmlGetAttrValue(iqNode, "id")) == NULL) return; - id = atoi(str+strlen(JABBER_IQID)); - - if (!strcmp(type, "result")) { - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - if (!db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { - jsr.hdr.cbSize = sizeof(JABBER_SEARCH_RESULT); - jsr.hdr.flags = PSR_TCHAR; - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if (strchr(jid, '@') != NULL) { - mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s", jid); - } else { - mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", jid, dbv.pszVal); - } - jsr.jid[sizeof(jsr.jid)-1] = '\0'; - jsr.hdr.id = mir_a2t(jid); - if ((n=JabberXmlGetChild(itemNode, "nick")) != NULL && n->text != NULL){ - char* buf = JabberTextDecode(n->text); - jsr.hdr.nick = mir_a2t(buf); - mir_free(buf); - } else { - jsr.hdr.nick = mir_tstrdup(TEXT("")); - } - if ((n=JabberXmlGetChild(itemNode, "first")) != NULL && n->text != NULL){ - char* buf = JabberTextDecode(n->text); - jsr.hdr.firstName = mir_a2t(buf); - mir_free(buf); - } else { - jsr.hdr.firstName = mir_tstrdup(TEXT("")); - } - if ((n=JabberXmlGetChild(itemNode, "last")) != NULL && n->text != NULL){ - char* buf = JabberTextDecode(n->text); - jsr.hdr.lastName = mir_a2t(buf); - mir_free(buf); - } else { - jsr.hdr.lastName = mir_tstrdup(TEXT("")); - } - if ((n=JabberXmlGetChild(itemNode, "email"))!=NULL && n->text!=NULL){ - char* buf = JabberTextDecode(n->text); - jsr.hdr.email = mir_a2t(buf); - mir_free(buf); - } else { - jsr.hdr.email = mir_tstrdup(TEXT("")); - } - - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); - found = 1; - mir_free(jsr.hdr.id); - mir_free(jsr.hdr.nick); - mir_free(jsr.hdr.firstName); - mir_free(jsr.hdr.lastName); - mir_free(jsr.hdr.email); - } - } - } - if (proto->searchJID != NULL) { - if (!found) { - if (strchr(proto->searchJID, '@') != NULL) { - mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s", proto->searchJID); - } else { - mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", proto->searchJID, dbv.pszVal); - } - jsr.jid[sizeof(jsr.jid)-1] = '\0'; - jsr.hdr.nick = mir_tstrdup(TEXT("")); - jsr.hdr.firstName = mir_tstrdup(TEXT("")); - jsr.hdr.lastName = mir_tstrdup(TEXT("")); - jsr.hdr.email = mir_tstrdup(TEXT("")); - jsr.hdr.id = mir_tstrdup(TEXT("")); - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); - mir_free(jsr.hdr.nick); - mir_free(jsr.hdr.firstName); - mir_free(jsr.hdr.lastName); - mir_free(jsr.hdr.email); - } - mir_free(proto->searchJID); - proto->searchJID = NULL; - } - db_free(&dbv); - } - found = 0; - if (queryNode->numChild == TLEN_MAX_SEARCH_RESULTS_PER_PAGE) { - found = TlenRunSearch(proto); - } - if (!found) { - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); - } - } else if (!strcmp(type, "error")) { - // ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE) id, 0); - // There is no ACKRESULT_FAILED for ACKTYPE_SEARCH :) look at findadd.c - // So we will just send a SUCCESS - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); - } -} - - -void GetConfigItem(XmlNode *node, char *dest, BOOL bMethod, int *methodDest) { - strcpy(dest, node->text); - TlenUrlDecode(dest); - if (bMethod) { - char *method = JabberXmlGetAttrValue(node, "method"); - if (method != NULL && !strcmpi(method, "POST")) { - *methodDest = REQUEST_POST; - } else { - *methodDest = REQUEST_GET; - } - } -} - -void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode, *miniMailNode, *node; - char *type; - - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - if (!strcmp(type, "result")) { - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - if ((miniMailNode=JabberXmlGetChild(queryNode, "mini-mail")) == NULL) return; - if ((node=JabberXmlGetChild(miniMailNode, "base")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailBase, FALSE, NULL); - } - if ((node=JabberXmlGetChild(miniMailNode, "msg")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailMsg, TRUE, &proto->threadData->tlenConfig.mailMsgMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "index")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailIndex, TRUE, &proto->threadData->tlenConfig.mailIndexMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "login")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailLogin, TRUE, &proto->threadData->tlenConfig.mailLoginMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "compose")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailCompose, TRUE, &proto->threadData->tlenConfig.mailComposeMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "avatar-get")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.avatarGet, TRUE, &proto->threadData->tlenConfig.avatarGetMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "avatar-upload")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.avatarUpload, TRUE, &proto->threadData->tlenConfig.avatarUploadMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "avatar-remove")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.avatarRemove, TRUE, &proto->threadData->tlenConfig.avatarRemoveMthd); - } - } -} - -void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); - if (queryNode != NULL) { - char* from; - if (( from=JabberXmlGetAttrValue( iqNode, "from" )) != NULL ) { - JABBER_LIST_ITEM *item; - if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) != NULL) { - HANDLE hContact; - XmlNode *n; - if ( item->software ) mir_free( item->software ); - if ( item->version ) mir_free( item->version ); - if ( item->system ) mir_free( item->system ); - if (( n=JabberXmlGetChild( queryNode, "name" )) != NULL && n->text ) { - item->software = JabberTextDecode( n->text ); - } else - item->software = NULL; - if (( n=JabberXmlGetChild( queryNode, "version" )) != NULL && n->text ) - item->version = JabberTextDecode( n->text ); - else - item->version = NULL; - if (( n=JabberXmlGetChild( queryNode, "os" )) != NULL && n->text ) - item->system = JabberTextDecode( n->text ); - else - item->system = NULL; - if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { - if (item->software != NULL) { - db_set_s(hContact, proto->m_szModuleName, "MirVer", item->software); - } else { - db_unset(hContact, proto->m_szModuleName, "MirVer"); - } - } - } - } - } -} - -void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); - if (queryNode != NULL) { - char* from; - if (( from=JabberXmlGetAttrValue( queryNode, "from" )) != NULL ) { - JABBER_LIST_ITEM *item; - if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) != NULL) { - HANDLE hContact; - XmlNode *version = JabberXmlGetChild(queryNode, "version"); - item->protocolVersion = JabberTextDecode(version->text); - if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { - if (item->software == NULL) { - char str[128]; - mir_snprintf(str, sizeof(str), "Tlen Protocol %s", item->protocolVersion); - db_set_s(hContact, proto->m_szModuleName, "MirVer", str); - } - } - } - } - } -} - diff --git a/protocols/Tlen/src/jabber_list.cpp b/protocols/Tlen/src/jabber_list.cpp deleted file mode 100644 index de9fe21c78..0000000000 --- a/protocols/Tlen/src/jabber_list.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" - - -static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item); - -void JabberListInit(TlenProtocol *proto) -{ - proto->lists = NULL; - proto->listsCount = 0; - InitializeCriticalSection(&proto->csLists); -} - -void JabberListUninit(TlenProtocol *proto) -{ - JabberListWipe(proto); - DeleteCriticalSection(&proto->csLists); -} - -void JabberListWipe(TlenProtocol *proto) -{ - int i; - - EnterCriticalSection(&proto->csLists); - for (i=0; ilistsCount; i++) - JabberListFreeItemInternal(&(proto->lists[i])); - if (proto->lists != NULL) { - mir_free(proto->lists); - proto->lists = NULL; - } - proto->listsCount=0; - LeaveCriticalSection(&proto->csLists); -} - -void JabberListWipeSpecial(TlenProtocol *proto) -{ - int i; - EnterCriticalSection(&proto->csLists); - for (i=0; ilistsCount; i++) { - if (proto->lists[i].list != LIST_FILE && proto->lists[i].list != LIST_VOICE) { - JabberListFreeItemInternal(&(proto->lists[i])); - proto->listsCount--; - memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); - i--; - } - } - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); - LeaveCriticalSection(&proto->csLists); -} - -static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item) -{ - if (item == NULL) - return; - - if (item->jid) mir_free(item->jid); - if (item->nick) mir_free(item->nick); - if (item->statusMessage) mir_free(item->statusMessage); - if (item->group) mir_free(item->group); - if (item->messageEventIdStr) mir_free(item->messageEventIdStr); -// if (item->type) mir_free(item->type); - //if (item->ft) JabberFileFreeFt(item->ft); // No need to free (it is always free when exit from JabberFileServerThread()) - if (item->roomName) mir_free(item->roomName); - if (item->version) mir_free(item->version); - if (item->software) mir_free(item->software); - if (item->system) mir_free(item->system); - if (item->avatarHash) mir_free(item->avatarHash); - - if (item->protocolVersion) mir_free(item->protocolVersion); - if (item->id2) mir_free(item->id2); -} - -static char * GetItemId(JABBER_LIST list, const char *jid) -{ - char *s, *p, *q; - s = mir_strdup(jid); - if (list != LIST_PICTURE) { - _strlwr(s); - // strip resouce name if any - if ((p=strchr(s, '@')) != NULL) { - if ((q=strchr(p, '/')) != NULL) - *q = '\0'; - } - } - return s; -} - - -int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - size_t len; - char *s, *p; - s = GetItemId(list, jid); - len = strlen(s); - - EnterCriticalSection(&proto->csLists); - for (i=0; ilistsCount; i++) - if (proto->lists[i].list == list) { - p = proto->lists[i].jid; - if (p && strlen(p) >= len && (p[(int)len] == '\0' || p[(int)len] == '/') && !strncmp(p, s, len)) { - LeaveCriticalSection(&proto->csLists); - mir_free(s); - return i+1; - } - } - LeaveCriticalSection(&proto->csLists); - mir_free(s); - return 0; -} - -JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - char *s; - JABBER_LIST_ITEM *item; - - EnterCriticalSection(&proto->csLists); - if ((item=JabberListGetItemPtr(proto, list, jid)) != NULL) { - LeaveCriticalSection(&proto->csLists); - return item; - } - - s = GetItemId(list, jid); - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*(proto->listsCount+1)); - item = &(proto->lists[proto->listsCount]); - memset(item, 0, sizeof(JABBER_LIST_ITEM)); - item->list = list; - item->jid = s; - item->nick = NULL; - item->status = ID_STATUS_OFFLINE; - item->statusMessage = NULL; - item->group = NULL; - item->messageEventIdStr = NULL; - item->wantComposingEvent = FALSE; - item->isTyping = FALSE; -// item->type = NULL; - item->ft = NULL; - item->roomName = NULL; - item->version = NULL; - item->software = NULL; - item->system = NULL; - item->avatarHash = NULL; - item->avatarFormat = PA_FORMAT_UNKNOWN; - item->newAvatarDownloading = FALSE; - item->versionRequested = FALSE; - item->infoRequested = FALSE; - proto->listsCount++; - LeaveCriticalSection(&proto->csLists); - - return item; -} - -void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return; - } - i--; - JabberListFreeItemInternal(&(proto->lists[i])); - proto->listsCount--; - memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); - LeaveCriticalSection(&proto->csLists); -} - -void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list) -{ - int i; - - i = 0; - while ((i=JabberListFindNext(proto, list, i)) >= 0) { - JabberListRemoveByIndex(proto, i); - } -} - -void JabberListRemoveByIndex(TlenProtocol *proto, int index) -{ - EnterCriticalSection(&proto->csLists); - if (index >= 0 && indexlistsCount) { - JabberListFreeItemInternal(&(proto->lists[index])); - proto->listsCount--; - memmove(proto->lists+index, proto->lists+index+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-index)); - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); - } - LeaveCriticalSection(&proto->csLists); -} - -void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return; - } - i--; - - if (proto->lists[i].statusMessage != NULL) - mir_free(proto->lists[i].statusMessage); - if (statusMessage) - proto->lists[i].statusMessage = mir_strdup(statusMessage); - else - proto->lists[i].statusMessage = NULL; - LeaveCriticalSection(&proto->csLists); -} - -void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return; - } - i--; - LeaveCriticalSection(&proto->csLists); -} - -int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = (fromOffset >= 0) ? fromOffset : 0; - for (; ilistsCount; i++) - if (proto->lists[i].list == list) { - LeaveCriticalSection(&proto->csLists); - return i; - } - LeaveCriticalSection(&proto->csLists); - return -1; -} - -JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return NULL; - } - i--; - LeaveCriticalSection(&proto->csLists); - return &(proto->lists[i]); -} - -JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id) -{ - - int i; - size_t len; - char *p; - - len = strlen(id); - - EnterCriticalSection(&proto->csLists); - for (i=0; ilistsCount; i++) { - if (proto->lists[i].list == list) { - p = proto->lists[i].id2; - if (p != NULL) { - if (!strncmp(p, id, len)) { - LeaveCriticalSection(&proto->csLists); - return &(proto->lists[i]); - } - } - } - } - LeaveCriticalSection(&proto->csLists); - return NULL; -} - -JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index) -{ - EnterCriticalSection(&proto->csLists); - if (index >= 0 && indexlistsCount) { - LeaveCriticalSection(&proto->csLists); - return &(proto->lists[index]); - } - LeaveCriticalSection(&proto->csLists); - return NULL; -} - diff --git a/protocols/Tlen/src/jabber_list.h b/protocols/Tlen/src/jabber_list.h deleted file mode 100644 index 30eb1abbdb..0000000000 --- a/protocols/Tlen/src/jabber_list.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -#ifndef _JABBER_LIST_H_ -#define _JABBER_LIST_H_ - -typedef struct JABBER_LIST_ITEM_STRUCT { - JABBER_LIST list; - char *jid; - char *id2; - - // LIST_ROSTER - // jid = jid of the contact - char *nick; - int status; // Main status, currently useful for transport where no resource information is kept. - // On normal contact, this is the same status as shown on contact list. - JABBER_SUBSCRIPTION subscription; - char *statusMessage; // Status message when the update is to JID with no resource specified (e.g. transport user) - char *software; - char *version; - char *system; - char *group; - char *protocolVersion; - int avatarFormat; - char *avatarHash; - BOOL newAvatarDownloading; - BOOL versionRequested; - BOOL infoRequested; - int idMsgAckPending; - char *messageEventIdStr; - BOOL wantComposingEvent; - BOOL isTyping; - - // LIST_ROOM - // jid = room JID - // char *name; // room name - //char *type; // room type - - // LIST_CHATROOM - // jid = room JID - // char *nick; // my nick in this chat room (SPECIAL: in UTF8) - // JABBER_RESOURCE_STATUS *resource; // participant nicks in this room - char *roomName; - - // LIST_FILE - struct TLEN_FILE_TRANSFER_STRUCT *ft; -} JABBER_LIST_ITEM; - - -void JabberListInit(TlenProtocol *proto); -void JabberListUninit(TlenProtocol *proto); -void JabberListWipe(TlenProtocol *proto); -void JabberListWipeSpecial(TlenProtocol *proto); -int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid); -JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid); -void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid); -void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list); -void JabberListRemoveByIndex(TlenProtocol *proto, int index); -int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset); -JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid); -JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index); -JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id); - -void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage); -void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid); - -#endif - diff --git a/protocols/Tlen/src/jabber_misc.cpp b/protocols/Tlen/src/jabber_misc.cpp deleted file mode 100644 index 631a6d7e99..0000000000 --- a/protocols/Tlen/src/jabber_misc.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" - -void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob) -{ - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = proto->m_szModuleName; - dbei.timestamp = (DWORD) time(NULL); - dbei.flags = flags; - dbei.eventType = eventType; - dbei.cbBlob = cbBlob; - dbei.pBlob = pBlob; - db_event_add(hContact, &dbei); -} - -void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick) -{ - char *s; - PBYTE pCurBlob; - PBYTE pBlob; - DWORD cbBlob; - HANDLE hContact; - - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->m_szModuleName); - // strip resource if present - s = JabberLoginFromJID(jid); - _strlwr(s); - db_set_s(hContact, proto->m_szModuleName, "jid", s); - mir_free(s); - } - else { - db_unset(hContact, proto->m_szModuleName, "Hidden"); - } - db_set_s(hContact, proto->m_szModuleName, "Nick", nick); - JabberLog(proto, "auth request: %s, %s", jid, nick); - //blob is: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ) - //blob is: 0(DWORD), hContact(HANDLE), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ) - cbBlob = sizeof(DWORD) + sizeof(HANDLE) + (int)strlen(nick) + (int)strlen(jid) + 5; - pBlob = pCurBlob = (PBYTE) mir_alloc(cbBlob); - *((PDWORD)pCurBlob) = 0; pCurBlob += sizeof(DWORD); - *((PHANDLE)pCurBlob) = hContact; pCurBlob += sizeof(DWORD); - strcpy((char *) pCurBlob, nick); pCurBlob += strlen(nick)+1; - *pCurBlob = '\0'; pCurBlob++; //firstName - *pCurBlob = '\0'; pCurBlob++; //lastName - strcpy((char *) pCurBlob, jid); pCurBlob += strlen(jid)+1; - *pCurBlob = '\0'; //reason - JabberDBAddEvent(proto, NULL, EVENTTYPE_AUTHREQUEST, 0, pBlob, cbBlob); -} - -char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact) -{ - char *p = NULL; - DBVARIANT dbv; - if (!db_get(hContact, proto->m_szModuleName, "jid", &dbv)) { - p = mir_strdup(dbv.pszVal); - db_free(&dbv); - } - return p; -} - -HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid) -{ - DBVARIANT dbv; - char *p; - if (jid == NULL) - return NULL; - - for (HANDLE hContact = db_find_first(proto->m_szModuleName); hContact; hContact = db_find_next(hContact, proto->m_szModuleName)) { - if ( db_get_s(hContact, proto->m_szModuleName, "jid", &dbv)) - continue; - - if ((p=dbv.pszVal) != NULL) { - if (!stricmp(p, jid)) { // exact match (node@domain/resource) - db_free(&dbv); - return hContact; - } - } - db_free(&dbv); - } - - return NULL; -} - -HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary) -{ - HANDLE hContact; - if (jid == NULL || jid[0] == '\0') - return NULL; - - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->m_szModuleName); - db_set_s(hContact, proto->m_szModuleName, "jid", jid); - if (nick != NULL && nick[0] != '\0') - db_set_s(hContact, proto->m_szModuleName, "Nick", nick); - if (temporary) - db_set_b(hContact, "CList", "NotOnList", 1); - } - return hContact; -} - -static void JabberContactListCreateClistGroup(char *groupName) -{ - char str[33], newName[128]; - int i; - DBVARIANT dbv; - char *name; - - for (i=0;;i++) { - itoa(i, str, 10); - if (db_get(NULL, "CListGroups", str, &dbv)) - break; - name = dbv.pszVal; - if (name[0] != '\0' && !strcmp(name+1, groupName)) { - // Already exist, no need to create - db_free(&dbv); - return; - } - db_free(&dbv); - } - - // Create new group with id = i (str is the text representation of i) - newName[0] = 1 | GROUPF_EXPANDED; - strncpy(newName+1, groupName, sizeof(newName)-1); - newName[sizeof(newName)-1] = '\0'; - db_set_s(NULL, "CListGroups", str, newName); - CallService(MS_CLUI_GROUPADDED, i+1, 0); -} - -void JabberContactListCreateGroup(char *groupName) -{ - char name[128]; - char *p; - - if (groupName == NULL || groupName[0] == '\0' || groupName[0] == '\\') return; - - strncpy(name, groupName, sizeof(name)); - name[sizeof(name)-1] = '\0'; - for (p=name; *p != '\0'; p++) { - if (*p == '\\') { - *p = '\0'; - JabberContactListCreateClistGroup(name); - *p = '\\'; - } - } - JabberContactListCreateClistGroup(name); -} - - -struct FORK_ARG { - HANDLE hEvent; - void (__cdecl *threadcode)(void*); - void *arg; -}; - -static void __cdecl forkthread_r(struct FORK_ARG *fa) -{ - void (*callercode)(void*) = fa->threadcode; - void *arg = fa->arg; - Thread_Push(0); - SetEvent(fa->hEvent); - callercode(arg); - Thread_Pop(); - return; -} - -unsigned long JabberForkThread( - void (__cdecl *threadcode)(void*), - unsigned long stacksize, - void *arg -) -{ - unsigned long rc; - struct FORK_ARG fa; - - fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - fa.threadcode = threadcode; - fa.arg = arg; - rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa); - if ((unsigned long) -1L != rc) { - WaitForSingleObject(fa.hEvent, INFINITE); - } - CloseHandle(fa.hEvent); - return rc; -} diff --git a/protocols/Tlen/src/jabber_opt.cpp b/protocols/Tlen/src/jabber_opt.cpp deleted file mode 100644 index f73ac40f68..0000000000 --- a/protocols/Tlen/src/jabber_opt.cpp +++ /dev/null @@ -1,673 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include "tlen_voice.h" -#include -#include "resource.h" - -static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -typedef struct TabDefStruct { - DLGPROC dlgProc; - DWORD dlgId; - TCHAR *tabName; -} TabDef; - -static TabDef tabPages[] = { - {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, LPGENT("General")}, - {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, LPGENT("Voice Chats")}, - {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, LPGENT("Advanced")}, - {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, LPGENT("Notifications")} - }; - -void TlenLoadOptions(TlenProtocol *proto) -{ - proto->tlenOptions.savePassword = db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE); - proto->tlenOptions.useEncryption = db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE); - proto->tlenOptions.reconnect = db_get_b(NULL, proto->m_szModuleName, "Reconnect", TRUE); - proto->tlenOptions.alertPolicy = db_get_w(NULL, proto->m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR); - proto->tlenOptions.rosterSync = db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE); - proto->tlenOptions.offlineAsInvisible = db_get_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", FALSE); - proto->tlenOptions.leaveOfflineMessage = db_get_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", TRUE); - proto->tlenOptions.offlineMessageOption = db_get_w(NULL, proto->m_szModuleName, "OfflineMessageOption", 0); - proto->tlenOptions.ignoreAdvertisements = db_get_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", TRUE); - proto->tlenOptions.groupChatPolicy = db_get_w(NULL, proto->m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK); - proto->tlenOptions.voiceChatPolicy = db_get_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK); - proto->tlenOptions.imagePolicy = db_get_w(NULL, proto->m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR); - proto->tlenOptions.enableAvatars = db_get_b(NULL, proto->m_szModuleName, "EnableAvatars", TRUE); - proto->tlenOptions.enableVersion = db_get_b(NULL, proto->m_szModuleName, "EnableVersion", TRUE); - proto->tlenOptions.useNudge = db_get_b(NULL, proto->m_szModuleName, "UseNudge", FALSE); - proto->tlenOptions.logAlerts = db_get_b(NULL, proto->m_szModuleName, "LogAlerts", TRUE); - proto->tlenOptions.sendKeepAlive = db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE); - proto->tlenOptions.useNewP2P = TRUE; -} - -static int changed = 0; - -static void ApplyChanges(TlenProtocol *proto, int i) { - changed &= ~i; - if (changed == 0) { - TlenLoadOptions(proto); - } -} - -static void MarkChanges(int i, HWND hWnd) { - SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); - changed |= i; -} - - -int TlenProtocol::OptionsInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { sizeof(odp) }; - odp.hInstance = hInst; - odp.ptszGroup = LPGENT("Network"); - odp.ptszTitle = m_tszUserName; - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; - odp.dwInitParam = (LPARAM)this; - for (int i = 0; i < SIZEOF(tabPages); i++) { - odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId); - odp.pfnDlgProc = tabPages[i].dlgProc; - odp.ptszTab = tabPages[i].tabName; - Options_AddPage(wParam, &odp); - } - return 0; -} - -static LRESULT CALLBACK JabberValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CHAR: - if (strchr("\"&'/:<>@", wParam&0xff) != NULL) - return 0; - break; - } - return mir_callNextSubclass(hwndEdit, JabberValidateUsernameWndProc, msg, wParam, lParam); -} - -INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); - db_free(&dbv); - } - if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); - - mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), JabberValidateUsernameWndProc); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_EDIT_USERNAME: - case IDC_EDIT_PASSWORD: - if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_SAVEPASSWORD: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_REGISTERACCOUNT: - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - - GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); - - if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { - GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); - if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "Password", text); - } - else - db_unset(NULL, proto->m_szModuleName, "Password"); - - db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - TlenLoadOptions(proto); - return TRUE; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - WNDPROC oldProc; - - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); - db_free(&dbv); - } - if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); - - CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); - CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); - CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); - CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); - CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); - CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); - CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); - CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); - CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); - - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); - //SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_ONLINE,GSMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_AWAY,GSMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_NA,GSMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_DND,GSMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_FREECHAT,GSMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_INVISIBLE,GSMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); - - oldProc = (WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_USERDATA, (LONG_PTR) oldProc); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC, (LONG_PTR) JabberValidateUsernameWndProc); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_EDIT_USERNAME: - case IDC_EDIT_PASSWORD: - if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - // Fall through - case IDC_SAVEPASSWORD: - case IDC_RECONNECT: - case IDC_ROSTER_SYNC: - case IDC_IGNORE_ADVERTISEMENTS: - case IDC_SHOW_OFFLINE: - case IDC_OFFLINE_MESSAGE: - MarkChanges(1, hwndDlg); - break; - case IDC_LOG_ALERTS: - CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); - MarkChanges(1, hwndDlg); - break; - case IDC_NUDGE_SUPPORT: - CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); - MarkChanges(1, hwndDlg); - break; - case IDC_REGISTERACCOUNT: - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); - break; - case IDC_OFFLINE_MESSAGE_OPTION: - case IDC_ALERT_POLICY: - case IDC_MUC_POLICY: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(1, hwndDlg); - break; - default: - MarkChanges(1, hwndDlg); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - - GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); - - if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { - GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); - if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "Password", text); - } - else - db_unset(NULL, proto->m_szModuleName, "Password"); - - db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); - db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); - db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); - db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); - db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); - db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); - db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); - db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); - db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); - db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); - db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - ApplyChanges(proto, 1); - return TRUE; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0); - TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN)); - TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT)); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_VOICE_POLICY: - case IDC_VOICE_DEVICE_IN: - case IDC_VOICE_DEVICE_OUT: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(2, hwndDlg); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - db_set_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0)); - ApplyChanges(proto, 2); - return TRUE; - } - } - break; - } - - return FALSE; -} - -static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - BOOL bChecked; - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); - db_free(&dbv); - } else { - SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); - - if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) { - SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); - db_free(&dbv); - } else - SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); - SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); - - CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE)); - - CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE)); - - CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE)); - // File transfer options - bChecked = FALSE; - if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) { - bChecked = TRUE; - CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); - if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE) { - CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); - } else { - bChecked = FALSE; - } - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); - - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS4")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS5")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0); - if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); - db_free(&dbv); - } - SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE); - if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); - db_free(&dbv); - } - if (!db_get(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) { - case IDC_FILE_PROXY_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(4, hwndDlg); - break; - case IDC_EDIT_LOGIN_SERVER: - case IDC_HOST: - case IDC_HOSTPORT: - case IDC_FILE_PROXY_HOST: - case IDC_FILE_PROXY_PORT: - case IDC_FILE_PROXY_USER: - case IDC_FILE_PROXY_PASSWORD: - if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) - MarkChanges(4, hwndDlg); - break; - case IDC_FILE_USE_PROXY: - bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); - case IDC_FILE_PROXY_USE_AUTH: - bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); - MarkChanges(4, hwndDlg); - break; - case IDC_KEEPALIVE: - case IDC_VISIBILITY_SUPPORT: - case IDC_USE_SSL: - MarkChanges(4, hwndDlg); - break; - } - } - break; - case WM_NOTIFY: - { - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - WORD port; - BOOL useEncryption; - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text)); - - GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "ManualHost", text); - - port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); - if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) - reconnectRequired = TRUE; - db_set_w(NULL, proto->m_szModuleName, "ManualPort", port); - - proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); - db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); - - useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); - if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption) - reconnectRequired = TRUE; - db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption); - - db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); - // File transfer options - db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); - db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); - db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text); - db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); - db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); - db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text); - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); - db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - ApplyChanges(proto, 4); - return TRUE; - } - } - } - break; - case WM_DESTROY: - break; - } - - return FALSE; -} - -#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 -#define POPUP_DEFAULT_COLORTXT 0x000000 - -static void MailPopupPreview(DWORD colorBack, DWORD colorText, char *title, char *emailInfo, int delay) -{ - POPUPDATA ppd = { 0 }; - HICON hIcon = GetIcolibIcon(IDI_MAIL); - ppd.lchIcon = CopyIcon(hIcon); - ReleaseIcolibIcon(hIcon); - strcpy(ppd.lpzContactName, title); - strcpy(ppd.lpzText, emailInfo); - ppd.colorBack = colorBack; - ppd.colorText = colorText; - ppd.iSeconds = delay; - if ( ServiceExists(MS_POPUP_ADDPOPUP)) - PUAddPopup(&ppd); -} - -static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - BYTE delayMode; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE)); - SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); - SetDlgItemInt(hwndDlg, IDC_DELAY, db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4), FALSE); - delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0); - if (delayMode == 1) { - CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); - } else if (delayMode == 2) { - CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); - } else { - CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); - } - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COLORTXT: - case IDC_COLORBKG: - case IDC_ENABLEPOPUP: - case IDC_DELAY: - case IDC_DELAY_POPUP: - case IDC_DELAY_CUSTOM: - case IDC_DELAY_PERMANENT: - MarkChanges(8, hwndDlg); - break; - case IDC_PREVIEW: - { - int delay; - char title[256]; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { - delay=0; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delay=-1; - } else { - delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); - } - mir_snprintf(title, sizeof(title), Translate("%s mail"), proto->m_szModuleName); - MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), - (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), - title, - "From: test@test.test\nSubject: test", - delay); - } - - } - break; - - - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BYTE delayMode; - db_set_b(NULL, proto->m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); - db_set_dw(NULL, proto->m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); - db_set_dw(NULL, proto->m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); - db_set_dw(NULL, proto->m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); - delayMode=0; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { - delayMode=1; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delayMode=2; - - } - db_set_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", delayMode); - ApplyChanges(proto, 8); - return TRUE; - } - } - break; - - } - return FALSE; -} - diff --git a/protocols/Tlen/src/jabber_svc.cpp b/protocols/Tlen/src/jabber_svc.cpp deleted file mode 100644 index 56df40f443..0000000000 --- a/protocols/Tlen/src/jabber_svc.cpp +++ /dev/null @@ -1,1288 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include "resource.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "tlen_p2p_old.h" -#include "tlen_avatar.h" -#include "tlen_file.h" - -DWORD_PTR TlenProtocol::GetCaps(int type, HANDLE hContact) -{ - if (type == PFLAGNUM_1) - return PF1_IM|PF1_AUTHREQ|PF1_SERVERCLIST|PF1_MODEMSG|PF1_BASICSEARCH|PF1_SEARCHBYEMAIL|PF1_EXTSEARCH|PF1_EXTSEARCHUI|PF1_SEARCHBYNAME|PF1_FILE;//|PF1_VISLIST|PF1_INVISLIST; - if (type == PFLAGNUM_2) - return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; - if (type == PFLAGNUM_3) - return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; - if (type == PFLAGNUM_4) - return PF4_FORCEAUTH|PF4_NOCUSTOMAUTH|PF4_SUPPORTTYPING|PF4_AVATARS|PF4_IMSENDOFFLINE|PF4_OFFLINEFILES; - if (type == PFLAG_UNIQUEIDTEXT) - return (DWORD_PTR) Translate("Tlen login"); - if (type == PFLAG_UNIQUEIDSETTING) - return (DWORD_PTR) "jid"; - return 0; -} - -INT_PTR TlenProtocol::GetName(WPARAM wParam, LPARAM lParam) -{ - strncpy((char*)lParam, m_szModuleName, wParam); - return 0; -} - -int TlenRunSearch(TlenProtocol *proto) { - int iqId = 0; - if (!proto->isOnline) return 0; - if (proto->searchQuery != NULL && proto->searchIndex < 10) { - iqId = proto->searchID; - JabberIqAdd(proto, iqId, IQ_PROC_GETSEARCH, JabberIqResultSearch); - if (proto->searchIndex == 0) { - JabberSend(proto, "%s", iqId, proto->searchQuery); - } else { - JabberSend(proto, "%s%d", iqId, proto->searchQuery, proto->searchIndex * TLEN_MAX_SEARCH_RESULTS_PER_PAGE); - } - proto->searchIndex ++; - } - return iqId; -} - -void TlenResetSearchQuery(TlenProtocol *proto) { - if (proto->searchQuery != NULL) { - mir_free(proto->searchQuery); - proto->searchQuery = NULL; - } - proto->searchQueryLen = 0; - proto->searchIndex = 0; - proto->searchID = JabberSerialNext(proto); -} - -HANDLE TlenProtocol::SearchBasic(const PROTOCHAR* id) -{ - char *jid; - int iqId = 0; - if (!isOnline) return 0; - if (id == NULL) return 0; - char* id_A = mir_t2a(id); - if ((jid=JabberTextEncode(id_A)) != NULL) { - searchJID = mir_strdup(id_A); - TlenResetSearchQuery(this); - JabberStringAppend(&searchQuery, &searchQueryLen, "%s", jid); - iqId = TlenRunSearch(this); - mir_free(jid); - } - mir_free(id_A); - return (HANDLE)iqId; -} - -HANDLE TlenProtocol::SearchByEmail(const PROTOCHAR* email) -{ - char *emailEnc; - int iqId = 0; - - if (!isOnline) return 0; - if (email == NULL) return 0; - - char* email_A = mir_t2a(email); - if ((emailEnc=JabberTextEncode(email_A)) != NULL) { - TlenResetSearchQuery(this); - JabberStringAppend(&searchQuery, &searchQueryLen, "%s", emailEnc); - iqId = TlenRunSearch(this); - mir_free(emailEnc); - } - mir_free(email_A); - return (HANDLE)iqId; -} - -HANDLE TlenProtocol::SearchByName(const PROTOCHAR* nickT, const PROTOCHAR* firstNameT, const PROTOCHAR* lastNameT) -{ - - char* nick = mir_t2a(nickT); - char* firstName = mir_t2a(firstNameT); - char* lastName = mir_t2a(lastNameT); - - char *p; - int iqId = 0; - - if (!isOnline) return 0; - - TlenResetSearchQuery(this); - - if (nick != NULL && nick[0] != '\0') { - if ((p=JabberTextEncode(nick)) != NULL) { - JabberStringAppend(&searchQuery, &searchQueryLen, "%s", p); - mir_free(p); - } - } - if (firstName != NULL && firstName[0] != '\0') { - if ((p=JabberTextEncode(firstName)) != NULL) { - JabberStringAppend(&searchQuery, &searchQueryLen, "%s", p); - mir_free(p); - } - } - if (lastName != NULL && lastName[0] != '\0') { - if ((p=JabberTextEncode(lastName)) != NULL) { - JabberStringAppend(&searchQuery, &searchQueryLen, "%s", p); - mir_free(p); - } - } - - iqId = TlenRunSearch(this); - return (HANDLE)iqId; -} - -HWND TlenProtocol::CreateExtendedSearchUI(HWND owner) -{ - return (HWND) CreateDialog(hInst, MAKEINTRESOURCE(IDD_ADVSEARCH), owner, TlenAdvSearchDlgProc); -} - -HWND TlenProtocol::SearchAdvanced(HWND owner) -{ - int iqId; - if (!isOnline) return 0; - - TlenResetSearchQuery(this); - iqId = JabberSerialNext(this); - if ((searchQuery = TlenAdvSearchCreateQuery(owner, iqId)) != NULL) { - iqId = TlenRunSearch(this); - } - return (HWND)iqId; -} - - -static HANDLE AddToListByJID(TlenProtocol *proto, const char *newJid, DWORD flags) -{ - HANDLE hContact; - char *jid, *nick; - - if ((hContact=JabberHContactFromJID(proto, newJid)) == NULL) { - // not already there: add - jid = mir_strdup(newJid); _strlwr(jid); - hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->m_szModuleName); - db_set_s(hContact, proto->m_szModuleName, "jid", jid); - if ((nick=JabberNickFromJID(newJid)) == NULL) - nick = mir_strdup(newJid); - db_set_s(hContact, "CList", "MyHandle", nick); - mir_free(nick); - mir_free(jid); - - // Note that by removing or disable the "NotOnList" will trigger - // the plugin to add a particular contact to the roster list. - // See DBSettingChanged hook at the bottom part of this source file. - // But the add module will delete "NotOnList". So we will not do it here. - // Also because we need "MyHandle" and "Group" info, which are set after - // PS_ADDTOLIST is called but before the add dialog issue deletion of - // "NotOnList". - // If temporary add, "NotOnList" won't be deleted, and that's expected. - db_set_b(hContact, "CList", "NotOnList", 1); - if (flags & PALF_TEMPORARY) - db_set_b(hContact, "CList", "Hidden", 1); - } - else { - // already exist - // Set up a dummy "NotOnList" when adding permanently only - if (!(flags&PALF_TEMPORARY)) - db_set_b(hContact, "CList", "NotOnList", 1); - } - - return hContact; -} - -HANDLE TlenProtocol::AddToList(int flags, PROTOSEARCHRESULT *psr) -{ - HANDLE hContact; - JABBER_SEARCH_RESULT *jsr = (JABBER_SEARCH_RESULT*)psr; - if (jsr->hdr.cbSize != sizeof(JABBER_SEARCH_RESULT)) - return (int) NULL; - hContact = AddToListByJID(this, jsr->jid, flags); // wParam is flag e.g. PALF_TEMPORARY - return hContact; -} - -HANDLE TlenProtocol::AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ) -{ - DBEVENTINFO dbei = { sizeof(dbei) }; - if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)(-1)) - return (HANDLE) NULL; - if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) - return (HANDLE) NULL; - if (db_event_get(hDbEvent, &dbei)) { - mir_free(dbei.pBlob); - return (HANDLE) NULL; - } - if (strcmp(dbei.szModule, m_szModuleName)) { - mir_free(dbei.pBlob); - return (HANDLE) NULL; - } - -/* - // EVENTTYPE_CONTACTS is when adding from when we receive contact list (not used in Jabber) - // EVENTTYPE_ADDED is when adding from when we receive "You are added" (also not used in Jabber) - // Jabber will only handle the case of EVENTTYPE_AUTHREQUEST - // EVENTTYPE_AUTHREQUEST is when adding from the authorization request dialog -*/ - - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { - mir_free(dbei.pBlob); - return (HANDLE) NULL; - } - - char *nick = (char *)dbei.pBlob + sizeof(DWORD)*2; - char *firstName = nick + strlen(nick) + 1; - char *lastName = firstName + strlen(firstName) + 1; - char *jid = lastName + strlen(lastName) + 1; - - HANDLE hContact = (HANDLE) AddToListByJID(this, jid, flags); - mir_free(dbei.pBlob); - return hContact; -} - -int TlenProtocol::Authorize(HANDLE hDbEvent) -{ - if (!isOnline) - return 1; - - DBEVENTINFO dbei = { sizeof(dbei) }; - if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)-1) - return 1; - if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) - return 1; - if (db_event_get(hDbEvent, &dbei)){ - mir_free(dbei.pBlob); - return 1; - } - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { - mir_free(dbei.pBlob); - return 1; - } - if (strcmp(dbei.szModule, m_szModuleName)) { - mir_free(dbei.pBlob); - return 1; - } - - char *nick = (char *)dbei.pBlob + sizeof(DWORD)*2; - char *firstName = nick + strlen(nick) + 1; - char *lastName = firstName + strlen(firstName) + 1; - char *jid = lastName + strlen(lastName) + 1; - - JabberSend(this, "", jid); - - // Automatically add this user to my roster if option is enabled - if (db_get_b(NULL, m_szModuleName, "AutoAdd", TRUE) == TRUE) { - HANDLE hContact; - JABBER_LIST_ITEM *item; - - if ((item=JabberListGetItemPtr(this, LIST_ROSTER, jid)) == NULL || (item->subscription != SUB_BOTH && item->subscription != SUB_TO)) { - JabberLog(this, "Try adding contact automatically jid=%s", jid); - if ((hContact=AddToListByJID(this, jid, 0)) != NULL) { - // Trigger actual add by removing the "NotOnList" added by AddToListByJID() - // See AddToListByJID() and JabberDbSettingChanged(). - db_unset(hContact, "CList", "NotOnList"); - } - } - } - - mir_free(dbei.pBlob); - return 0; -} - -int TlenProtocol::AuthDeny(HANDLE hDbEvent, const PROTOCHAR* szReason) -{ - if (!isOnline) - return 1; - - DBEVENTINFO dbei = { sizeof(dbei) }; - if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)(-1)) - return 1; - if ((dbei.pBlob = (PBYTE) mir_alloc(dbei.cbBlob)) == NULL) - return 1; - if (db_event_get(hDbEvent, &dbei)) { - mir_free(dbei.pBlob); - return 1; - } - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { - mir_free(dbei.pBlob); - return 1; - } - if (strcmp(dbei.szModule, m_szModuleName)) { - mir_free(dbei.pBlob); - return 1; - } - - char *nick = (char *)dbei.pBlob + sizeof(DWORD)*2; - char *firstName = nick + strlen(nick) + 1; - char *lastName = firstName + strlen(firstName) + 1; - char *jid = lastName + strlen(lastName) + 1; - - JabberSend(this, "", jid); - JabberSend(this, "", jid); - mir_free(dbei.pBlob); - return 0; -} - -static void TlenConnect(TlenProtocol *proto, int initialStatus) -{ - if (!proto->isConnected) { - ThreadData *thread; - int oldStatus; - - thread = (ThreadData *) mir_alloc(sizeof(ThreadData)); - memset(thread, 0, sizeof(ThreadData)); - thread->proto = proto; - proto->m_iDesiredStatus = initialStatus; - - oldStatus = proto->m_iStatus; - proto->m_iStatus = ID_STATUS_CONNECTING; - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->m_iStatus); - thread->hThread = (HANDLE) JabberForkThread((void (__cdecl *)(void*))JabberServerThread, 0, thread); - } -} - -int TlenProtocol::SetStatus(int iNewStatus) -{ - int oldStatus; - HANDLE s; - - m_iDesiredStatus = iNewStatus; - - if (iNewStatus == ID_STATUS_OFFLINE) { - if (threadData) { - if (isConnected) { - JabberSendPresence(this, ID_STATUS_OFFLINE); - } - - // TODO bug? s = proto; - s = threadData->s; - - threadData = NULL; - if (isConnected) { - Sleep(200); -// JabberSend(s, ""); - // Force closing connection - isConnected = FALSE; - isOnline = FALSE; - Netlib_CloseHandle(s); - } - } - else { - if (m_iStatus != ID_STATUS_OFFLINE) { - oldStatus = m_iStatus; - m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); - } - } - } - else if (iNewStatus != m_iStatus) { - if (!isConnected) - TlenConnect(this, iNewStatus); - else { - // change status - oldStatus = m_iStatus; - // send presence update - JabberSendPresence(this, iNewStatus); - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, m_iStatus); - } - } - return 0; -} - -INT_PTR TlenProtocol::GetStatus(WPARAM wParam, LPARAM lParam) -{ - return m_iStatus; -} - -int TlenProtocol::SetAwayMsg(int iStatus, const PROTOCHAR* msg) -{ - char **szMsg; - char *newModeMsg; - - JabberLog(this, "SetAwayMsg called, wParam=%d lParam=%s", iStatus, msg); - - newModeMsg = JabberTextEncode(mir_t2a(msg)); //TODO TCHAR - - EnterCriticalSection(&modeMsgMutex); - - switch (iStatus) { - case ID_STATUS_ONLINE: - szMsg = &modeMsgs.szOnline; - break; - case ID_STATUS_AWAY: - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - szMsg = &modeMsgs.szAway; - break; - case ID_STATUS_NA: - szMsg = &modeMsgs.szNa; - break; - case ID_STATUS_DND: - case ID_STATUS_OCCUPIED: - szMsg = &modeMsgs.szDnd; - break; - case ID_STATUS_FREECHAT: - szMsg = &modeMsgs.szFreechat; - break; - case ID_STATUS_INVISIBLE: - szMsg = &modeMsgs.szInvisible; - break; - default: - LeaveCriticalSection(&modeMsgMutex); - return 1; - } - - if ((*szMsg == NULL && newModeMsg == NULL) || - (*szMsg != NULL && newModeMsg != NULL && !strcmp(*szMsg, newModeMsg))) { - // Message is the same, no update needed - if (newModeMsg != NULL) mir_free(newModeMsg); - } - else { - // Update with the new mode message - if (*szMsg != NULL) mir_free(*szMsg); - *szMsg = newModeMsg; - // Send a presence update if needed - if (iStatus == m_iStatus) { - JabberSendPresence(this, m_iStatus); - } - } - - LeaveCriticalSection(&modeMsgMutex); - return 0; -} - -int TlenProtocol::GetInfo(HANDLE hContact, int infoType) -{ - DBVARIANT dbv; - int iqId; - char *nick, *pNick; - - if (!isOnline) return 1; - if (hContact == NULL) { - iqId = JabberSerialNext(this); - JabberIqAdd(this, iqId, IQ_PROC_NONE, TlenIqResultVcard); - JabberSend(this, "", iqId); - } else { - if (db_get(hContact, m_szModuleName, "jid", &dbv)) return 1; - if ((nick=JabberNickFromJID(dbv.pszVal)) != NULL) { - if ((pNick=JabberTextEncode(nick)) != NULL) { - iqId = JabberSerialNext(this); - JabberIqAdd(this, iqId, IQ_PROC_NONE, TlenIqResultVcard); - JabberSend(this, "%s", iqId, pNick); - mir_free(pNick); - } - mir_free(nick); - } - db_free(&dbv); - } - return 0; -} - -int TlenProtocol::SetApparentMode(HANDLE hContact, int mode) -{ - DBVARIANT dbv; - int oldMode; - char *jid; - - if (!isOnline) return 0; - if (!db_get_b(NULL, m_szModuleName, "VisibilitySupport", FALSE)) return 0; - if (mode != 0 && mode != ID_STATUS_ONLINE && mode != ID_STATUS_OFFLINE) return 1; - oldMode = db_get_w(hContact, m_szModuleName, "ApparentMode", 0); - if ((int) mode == oldMode) return 1; - db_set_w(hContact, m_szModuleName, "ApparentMode", (WORD) mode); - if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { - jid = dbv.pszVal; - switch (mode) { - case ID_STATUS_ONLINE: - if (m_iStatus == ID_STATUS_INVISIBLE || oldMode == ID_STATUS_OFFLINE) - JabberSend(this, "available", jid); - break; - case ID_STATUS_OFFLINE: - if (m_iStatus != ID_STATUS_INVISIBLE || oldMode == ID_STATUS_ONLINE) - JabberSend(this, "", jid); - break; - case 0: - if (oldMode == ID_STATUS_ONLINE && m_iStatus == ID_STATUS_INVISIBLE) - JabberSend(this, "", jid); - else if (oldMode == ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_INVISIBLE) - JabberSend(this, "available", jid); - break; - } - db_free(&dbv); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -struct SENDACKTHREADDATA -{ - __inline SENDACKTHREADDATA(TlenProtocol *_ppro, HANDLE _hContact, int _msgid=0) : - proto(_ppro), hContact(_hContact), msgid(_msgid) - {} - - TlenProtocol *proto; - HANDLE hContact; - int msgid; -}; - -static void __cdecl JabberSendMessageAckThread(void *ptr) -{ - SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; - SleepEx(10, TRUE); - ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)data->msgid, 0); - delete data; -} - -static void __cdecl TlenSendMessageFailedThread(void *ptr) -{ - SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; - SleepEx(10, TRUE); - ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)data->msgid, 0); - delete data; -} - -static void __cdecl TlenGetAwayMsgThread(void *ptr) -{ - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; - if (!db_get(data->hContact, data->proto->m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(data->proto, LIST_ROSTER, dbv.pszVal)) != NULL) { - db_free(&dbv); - ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, - item->statusMessage==NULL ? (LPARAM)NULL : (LPARAM)(TCHAR*)_A2T(item->statusMessage)); - return; - } - else db_free(&dbv); - } - ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)(TCHAR*)TEXT("")); - delete data; -} - -INT_PTR TlenProtocol::SendAlert(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = ( HANDLE )wParam; - DBVARIANT dbv; - if (isOnline && !db_get(hContact, m_szModuleName, "jid", &dbv)) { - JabberSend(this, "", dbv.pszVal); - - db_free(&dbv); - } - return 0; -} - -int TlenProtocol::SendMsg(HANDLE hContact, int flags, const char* msgRAW) -{ - DBVARIANT dbv; - char *msgEnc; - JABBER_LIST_ITEM *item; - char msgType[16]; - - if (!isOnline || db_get(hContact, m_szModuleName, "jid", &dbv)) { - JabberForkThread(TlenSendMessageFailedThread, 0, new SENDACKTHREADDATA(this, hContact, 2)); - return 2; - } - - char* msg; - if (flags & PREF_UNICODE) - msg = mir_u2a((wchar_t*)&msgRAW[strlen(msgRAW) + 1]); - else if (flags & PREF_UTF) - msg = mir_utf8decodeA(msgRAW); - else - msg = mir_strdup(msgRAW); - - - int id = JabberSerialNext(this); - - if (!strcmp(msg, "")) { - JabberSend(this, "", dbv.pszVal); - JabberForkThread(JabberSendMessageAckThread, 0, new SENDACKTHREADDATA(this, hContact, id)); - } - else if (!strcmp(msg, "")) { - JabberSend(this, "", dbv.pszVal, "pic", 0x757f044, id); - JabberForkThread(JabberSendMessageAckThread, 0, new SENDACKTHREADDATA(this, hContact, id)); - } - else { - if ((msgEnc=JabberTextEncode(msg)) != NULL) { - if (JabberListExist(this, LIST_CHATROOM, dbv.pszVal) && strchr(dbv.pszVal, '/') == NULL) - strcpy(msgType, "groupchat"); - else if (db_get_b(hContact, m_szModuleName, "bChat", FALSE)) - strcpy(msgType, "privchat"); - else - strcpy(msgType, "chat"); - - if (!strcmp(msgType, "groupchat") || db_get_b(NULL, m_szModuleName, "MsgAck", FALSE) == FALSE) { - SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); - tdata->proto = this; - tdata->hContact = hContact; - if (!strcmp(msgType, "groupchat")) - JabberSend(this, "%s", dbv.pszVal, msgType, msgEnc); - else if (!strcmp(msgType, "privchat")) - JabberSend(this, "%s", dbv.pszVal, msgEnc); - else - JabberSend(this, "%s", dbv.pszVal, msgType, id, msgEnc); - - JabberForkThread(JabberSendMessageAckThread, 0, new SENDACKTHREADDATA(this, hContact, id)); - } - else { - if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL) - item->idMsgAckPending = id; - JabberSend(this, "%s", dbv.pszVal, msgType, id, msgEnc); - } - } - mir_free(msgEnc); - } - - mir_free(msg); - db_free(&dbv); - return id; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// JabberGetAvatarInfo - retrieves the avatar info - -INT_PTR TlenProtocol::GetAvatarInfo(WPARAM wParam, LPARAM lParam) -{ - BOOL downloadingAvatar = FALSE; - char *avatarHash = NULL; - JABBER_LIST_ITEM *item = NULL; - DBVARIANT dbv; - PROTO_AVATAR_INFORMATIONT* AI = ( PROTO_AVATAR_INFORMATIONT* )lParam; - if (!tlenOptions.enableAvatars) return GAIR_NOAVATAR; - - if (AI->hContact != NULL) { - if (!db_get(AI->hContact, m_szModuleName, "jid", &dbv)) { - item = JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal); - db_free(&dbv); - if (item != NULL) { - downloadingAvatar = item->newAvatarDownloading; - avatarHash = item->avatarHash; - } - } - } - else if (threadData != NULL) - avatarHash = threadData->avatarHash; - - if ((avatarHash == NULL || avatarHash[0] == '\0') && !downloadingAvatar) - return GAIR_NOAVATAR; - - if (avatarHash != NULL && !downloadingAvatar) { - TlenGetAvatarFileName(this, item, AI->filename, sizeof(AI->filename)); - AI->format = ( AI->hContact == NULL ) ? threadData->avatarFormat : item->avatarFormat; - return GAIR_SUCCESS; - } - - /* get avatar */ - if (( wParam & GAIF_FORCE ) != 0 && AI->hContact != NULL && isOnline) - return GAIR_WAITFOR; - - return GAIR_NOAVATAR; -} - -HANDLE TlenProtocol::GetAwayMsg(HANDLE hContact) -{ - SENDACKTHREADDATA *tdata = new SENDACKTHREADDATA(this, hContact, 0); - JabberForkThread((void (__cdecl *)(void*))TlenGetAwayMsgThread, 0, (void*)tdata); - return (HANDLE)1; -} - -int TlenProtocol::RecvAwayMsg(HANDLE hContact, int mode, PROTORECVEVENT* evt) -{ - return 0; -} - -int TlenProtocol::SendAwayMsg(HANDLE hContact, HANDLE hProcess, const char* msg) -{ - return 0; -} - -HANDLE TlenProtocol::FileAllow(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath) -{ - TLEN_FILE_TRANSFER *ft; - JABBER_LIST_ITEM *item; - char *nick; - - if (!isOnline) return 0; - - ft = (TLEN_FILE_TRANSFER *) hTransfer; - ft->szSavePath = mir_strdup(mir_t2a(szPath)); //TODO convert to PROTOCHAR* - if ((item=JabberListAdd(this, LIST_FILE, ft->iqId)) != NULL) { - item->ft = ft; - } - nick = JabberNickFromJID(ft->jid); - if (ft->newP2P) { - JabberSend(this, "", ft->jid, ft->jid, ft->iqId); - } else { - JabberSend(this, "", nick, ft->iqId); - } - mir_free(nick); - return (HANDLE)hTransfer; -} - -int TlenProtocol::FileDeny(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason) -{ - TLEN_FILE_TRANSFER *ft; - char *nick; - - if (!isOnline) return 1; - - ft = (TLEN_FILE_TRANSFER *) hTransfer; - nick = JabberNickFromJID(ft->jid); - if (ft->newP2P) { - JabberSend(this, "", ft->iqId, nick);\ - } else { - JabberSend(this, "", ft->iqId, nick);\ - } - mir_free(nick); - TlenP2PFreeFileTransfer(ft); - return 0; -} - -int TlenProtocol::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename) { - return 0; -} - -int TlenProtocol::FileCancel(HANDLE hContact, HANDLE hTransfer) -{ - TLEN_FILE_TRANSFER *ft = (TLEN_FILE_TRANSFER *) hTransfer; - JabberLog(this, "Invoking FileCancel()"); - if (ft->s != NULL) { - ft->state = FT_ERROR; - Netlib_CloseHandle(ft->s); - ft->s = NULL; - if (ft->hFileEvent != NULL) { - HANDLE hEvent = ft->hFileEvent; - ft->hFileEvent = NULL; - SetEvent(hEvent); - } - } else { - TlenP2PFreeFileTransfer(ft); - } - return 0; -} - -HANDLE TlenProtocol::SendFile(HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) -{ - TLEN_FILE_TRANSFER *ft; - int i, j; - struct _stat statbuf; - DBVARIANT dbv; - char *nick, *p, idStr[10]; - JABBER_LIST_ITEM *item; - int id; - - if (!isOnline) return 0; -// if (db_get_w(ccs->hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) return 0; - if (db_get(hContact, m_szModuleName, "jid", &dbv)) return 0; - ft = TlenFileCreateFT(this, dbv.pszVal); - for (ft->fileCount=0; ppszFiles[ft->fileCount]; ft->fileCount++); - ft->files = (char **) mir_alloc(sizeof(char *) * ft->fileCount); - ft->filesSize = (long *) mir_alloc(sizeof(long) * ft->fileCount); - ft->allFileTotalSize = 0; - for (i=j=0; ifileCount; i++) { - char* ppszFiles_i_A = mir_t2a(ppszFiles[i]); - if (_stat(ppszFiles_i_A, &statbuf)) - JabberLog(this, "'%s' is an invalid filename", ppszFiles[i]); - else { - ft->filesSize[j] = statbuf.st_size; - ft->files[j++] = mir_strdup(ppszFiles_i_A); - ft->allFileTotalSize += statbuf.st_size; - } - mir_free(ppszFiles_i_A); - } - ft->fileCount = j; - ft->szDescription = mir_t2a(szDescription); - ft->hContact = hContact; - ft->currentFile = 0; - db_free(&dbv); - - id = JabberSerialNext(this); - mir_snprintf(idStr, sizeof(idStr), "%d", id); - if ((item=JabberListAdd(this, LIST_FILE, idStr)) != NULL) { - ft->iqId = mir_strdup(idStr); - nick = JabberNickFromJID(ft->jid); - item->ft = ft; - if (tlenOptions.useNewP2P) { - JabberSend(this, "", - ft->jid, ft->jid, idStr, ft->fileCount, ft->allFileTotalSize, ft->fileCount); - - ft->newP2P = TRUE; - } else { - if (ft->fileCount == 1) { - char* ppszFiles_0_A = mir_t2a(ppszFiles[0]); - if ((p=strrchr(ppszFiles_0_A, '\\')) != NULL) { - p++; - } else { - p = ppszFiles_0_A; - } - p = JabberTextEncode(p); - JabberSend(this, "", nick, p, idStr, ft->allFileTotalSize); - mir_free(ppszFiles[0]); - mir_free(p); - } else { - JabberSend(this, "", nick, idStr, ft->fileCount, ft->allFileTotalSize); - } - } - mir_free(nick); - } - - return (HANDLE) ft; -} - -int TlenProtocol::SendContacts(HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList){ - return 0; -} - -int TlenProtocol::SendUrl(HANDLE hContact, int flags, const char* urlt){ - return 0; -} - -int TlenProtocol::RecvMsg(HANDLE hContact, PROTORECVEVENT* evt) -{ - return Proto_RecvMessage(hContact, evt); -} - -int TlenProtocol::RecvFile(HANDLE hContact, PROTOFILEEVENT* evt) -{ - return Proto_RecvFile(hContact, evt); -} - -int TlenProtocol::RecvUrl(HANDLE hContact, PROTORECVEVENT*) -{ - return 0; -} - -static char* settingToChar( DBCONTACTWRITESETTING* cws ) -{ - switch( cws->value.type ) { - case DBVT_ASCIIZ: - return mir_strdup( cws->value.pszVal ); - case DBVT_UTF8: - return mir_utf8decode(mir_strdup(cws->value.pszVal), NULL); - } - return NULL; -} - -int TlenProtocol::JabberDbSettingChanged(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam; - // no action for hContact == NULL or when offline - if ((HANDLE) wParam == NULL) return 0; - if (!isConnected) return 0; - - if (!strcmp(cws->szModule, "CList")) { - HANDLE hContact; - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - char *szProto, *nick, *jid, *group; - - hContact = (HANDLE) wParam; - szProto = GetContactProto(hContact); - if (szProto == NULL || strcmp(szProto, m_szModuleName)) return 0; - // A contact's group is changed - if (!strcmp(cws->szSetting, "Group")) { - if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL) { - db_free(&dbv); - if (!db_get(hContact, "CList", "MyHandle", &dbv)) { - nick = JabberTextEncode(dbv.pszVal); - db_free(&dbv); - } - else if (!db_get(hContact, this->m_szModuleName, "Nick", &dbv)) { - nick = JabberTextEncode(dbv.pszVal); - db_free(&dbv); - } - else nick = JabberNickFromJID(item->jid); - - if (nick != NULL) { - // Note: we need to compare with item->group to prevent infinite loop - if (cws->value.type == DBVT_DELETED && item->group != NULL) { - JabberLog(this, "Group set to nothing"); - JabberSend(this, "", nick, item->jid); - } - else if (cws->value.pszVal != NULL) { - char *newGroup = settingToChar(cws); - if (item->group == NULL || strcmp(newGroup, item->group)) { - JabberLog(this, "Group set to %s", newGroup); - if ((group=TlenGroupEncode(newGroup)) != NULL) { - JabberSend(this, "%s", nick, item->jid, group); - mir_free(group); - } - } - mir_free(newGroup); - } - mir_free(nick); - } - } - else { - db_free(&dbv); - } - } - } - // A contact is renamed - else if (!strcmp(cws->szSetting, "MyHandle")) { - char *newNick; - -// hContact = (HANDLE) wParam; -// szProto = GetContactProto(hContact); -// if (szProto == NULL || strcmp(szProto, proto->m_szModuleName)) return 0; - - if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { - jid = dbv.pszVal; - if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL) { - if (cws->value.type == DBVT_DELETED) { - newNick = mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_NOMYHANDLE)); - } else if (cws->value.pszVal != NULL) { - newNick = settingToChar(cws); - } else { - newNick = NULL; - } - // Note: we need to compare with item->nick to prevent infinite loop - if (newNick != NULL && (item->nick == NULL || (item->nick != NULL && strcmp(item->nick, newNick)))) { - if ((nick=JabberTextEncode(newNick)) != NULL) { - JabberLog(this, "Nick set to %s", newNick); - if (item->group != NULL && (group=TlenGroupEncode(item->group)) != NULL) { - JabberSend(this, "%s", nick, jid, group); - mir_free(group); - } else { - JabberSend(this, "", nick, jid); - } - mir_free(nick); - } - } - if (newNick != NULL) mir_free(newNick); - } - db_free(&dbv); - } - } - // A temporary contact has been added permanently - else if (!strcmp(cws->szSetting, "NotOnList")) { - char *jid, *nick, *pGroup; - - if (cws->value.type==DBVT_DELETED || (cws->value.type==DBVT_BYTE && cws->value.bVal==0)) { - if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { - jid = mir_strdup(dbv.pszVal); - db_free(&dbv); - JabberLog(this, "Add %s permanently to list", jid); - if (!db_get(hContact, "CList", "MyHandle", &dbv)) { - nick = JabberTextEncode(dbv.pszVal); //Utf8Encode - db_free(&dbv); - } - else { - nick = JabberNickFromJID(jid); - } - if (nick != NULL) { - JabberLog(this, "jid=%s nick=%s", jid, nick); - if (!db_get(hContact, "CList", "Group", &dbv)) { - if ((pGroup=TlenGroupEncode(dbv.pszVal)) != NULL) { - JabberSend(this, "%s", nick, jid, pGroup); - JabberSend(this, "", jid); - mir_free(pGroup); - } - db_free(&dbv); - } - else { - JabberSend(this, "", nick, jid); - JabberSend(this, "", jid); - } - mir_free(nick); - db_unset(hContact, "CList", "Hidden"); - } - mir_free(jid); - } - } - } - } - - return 0; -} - -int TlenProtocol::JabberContactDeleted(WPARAM wParam, LPARAM lParam) -{ - if (!isOnline) // should never happen - return 0; - - char *szProto = GetContactProto((HANDLE)wParam); - if (szProto == NULL || strcmp(szProto, m_szModuleName)) - return 0; - - DBVARIANT dbv; - if (!db_get((HANDLE) wParam, m_szModuleName, "jid", &dbv)) { - char *jid, *p, *q; - - jid = dbv.pszVal; - if ((p=strchr(jid, '@')) != NULL) { - if ((q=strchr(p, '/')) != NULL) - *q = '\0'; - } - - // Remove from roster, server also handles the presence unsubscription process. - if (JabberListExist(this, LIST_ROSTER, jid)) - JabberSend(this, "", jid); - - db_free(&dbv); - } - return 0; -} - -int TlenProtocol::UserIsTyping(HANDLE hContact, int type) -{ - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - - if (!isOnline) return 0; - if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL /*&& item->wantComposingEvent == TRUE*/) { - switch (type) { - case PROTOTYPE_SELFTYPING_OFF: - JabberSend(this, "", dbv.pszVal); - break; - case PROTOTYPE_SELFTYPING_ON: - JabberSend(this, "", dbv.pszVal); - break; - } - } - db_free(&dbv); - } - return 0; -} - -INT_PTR TlenProtocol::GetMyAvatar(WPARAM wParam, LPARAM lParam) -{ - TCHAR* buf = (TCHAR*)wParam; - int size = ( int )lParam; - if ( buf == NULL || size <= 0 ) - return -1; - - TlenGetAvatarFileName(this, NULL, buf, size); - return 0; -} - -static INT_PTR CALLBACK TlenChangeAvatarDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) -{ - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - { - HICON hIcon = GetIcolibIcon(IDI_TLEN); - SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon); - ReleaseIcolibIcon(hIcon); - } - CheckDlgButton(hwndDlg, IDC_PUBLICAVATAR, TRUE); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - { - int result = LOWORD(wParam); - if (IsDlgButtonChecked(hwndDlg, IDC_PUBLICAVATAR)) { - result |= 0x10000; - } - EndDialog(hwndDlg, result); - } - return TRUE; - } - break; - } - return 0; -} - -INT_PTR TlenProtocol::SetMyAvatar(WPARAM wParam, LPARAM lParam) -{ - TCHAR* szFileName = ( TCHAR* )lParam; - TCHAR tFileName[ MAX_PATH ]; - if (!isOnline) return 1; - if (szFileName != NULL) { - int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_USER_CHANGEAVATAR), NULL, TlenChangeAvatarDlgProc, (LPARAM) NULL); - TlenGetAvatarFileName(this, NULL, tFileName, MAX_PATH); - if ( CopyFile( szFileName, tFileName, FALSE ) == FALSE ) - return 1; - - char* tFileNameA = mir_t2a(tFileName); //TODO - drop io.h - int fileIn = open( tFileNameA, O_RDWR | O_BINARY, S_IREAD | S_IWRITE ); - if ( fileIn != -1 ) { - long dwPngSize = filelength(fileIn); - BYTE* pResult = (BYTE *)mir_alloc(dwPngSize); - if (pResult != NULL) { - read( fileIn, pResult, dwPngSize ); - close( fileIn ); - TlenUploadAvatar(this, pResult, dwPngSize, (result & 0x10000) != 0); - mir_free(pResult); - } - } - mir_free(tFileName); - mir_free(tFileNameA); - } - else TlenRemoveAvatar(this); - - return 0; -} - -INT_PTR TlenProtocol::GetAvatarCaps(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) { - case AF_MAXSIZE: - { - POINT* size = (POINT*)lParam; - if ( size ) - size->x = size->y = 64; - } - return 0; - case AF_PROPORTION: - return PIP_SQUARE; - case AF_FORMATSUPPORTED: - return (lParam == PA_FORMAT_PNG) ? 1 : 0; - case AF_ENABLED: - return (tlenOptions.enableAvatars && isOnline) ? 1 : 0; - case AF_DONTNEEDDELAYS: - return 1; - case AF_MAXFILESIZE: - return 10 * 1024; - case AF_DELAYAFTERFAIL: - return 0; - } - return 0; -} - -int TlenProtocol::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam) -{ - //TlenProtocol *proto = (TlenProtocol *)ptr; - switch( iEventType ) { - case EV_PROTO_ONLOAD: return OnModulesLoaded(0, 0); - case EV_PROTO_ONOPTIONS: return OptionsInit(wParam, lParam); - case EV_PROTO_ONEXIT: return PreShutdown(0, 0); - case EV_PROTO_ONRENAME: - { - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIM_NAME | CMIF_TCHAR; - mi.ptszName = m_tszUserName; - Menu_ModifyItem(hMenuRoot, &mi); - /* FIXME: Rename network user as well */ - } - } - return 1; -} - -// PSS_ADDED -int TlenProtocol::AuthRecv(HANDLE hContact, PROTORECVEVENT* evt) -{ - return 1; -} - -// PSS_AUTHREQUEST -int TlenProtocol::AuthRequest(HANDLE hContact, const PROTOCHAR* szMessage) -{ - return 1; -} - -HANDLE TlenProtocol::ChangeInfo(int iInfoType, void* pInfoData) -{ - return NULL; -} - - -int TlenProtocol::RecvContacts(HANDLE hContact, PROTORECVEVENT* evt) -{ - return 1; -} - -extern INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -INT_PTR TlenProtocol::AccMgrUI(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, TlenAccMgrUIDlgProc, (LPARAM)this); -} - -void TlenInitServicesVTbl(TlenProtocol *proto) -{ - proto->CreateProtoService(PS_GETNAME, &TlenProtocol::GetName); - proto->CreateProtoService(PS_GETAVATARINFO, &TlenProtocol::GetAvatarInfo); - proto->CreateProtoService(PS_SEND_NUDGE, &TlenProtocol::SendAlert); - proto->CreateProtoService(PS_GETAVATARCAPS, &TlenProtocol::GetAvatarCaps); - proto->CreateProtoService(PS_SETMYAVATART, &TlenProtocol::SetMyAvatar); - proto->CreateProtoService(PS_GETMYAVATART, &TlenProtocol::GetMyAvatar); - proto->CreateProtoService(PS_GETSTATUS, &TlenProtocol::GetStatus); - proto->CreateProtoService(PS_CREATEACCMGRUI, &TlenProtocol::AccMgrUI); -} - -TlenProtocol::TlenProtocol( const char *aProtoName, const TCHAR *aUserName) : - PROTO(aProtoName, aUserName) -{ - TlenInitServicesVTbl(this); - - InitializeCriticalSection(&modeMsgMutex); - InitializeCriticalSection(&csSend); - - hTlenNudge = CreateProtoEvent("/Nudge"); - - HookProtoEvent(ME_OPT_INITIALISE, &TlenProtocol::OptionsInit); - HookProtoEvent(ME_DB_CONTACT_SETTINGCHANGED, &TlenProtocol::JabberDbSettingChanged); - HookProtoEvent(ME_DB_CONTACT_DELETED, &TlenProtocol::JabberContactDeleted); - HookProtoEvent(ME_CLIST_PREBUILDCONTACTMENU, &TlenProtocol::PrebuildContactMenu); - HookProtoEvent(ME_SYSTEM_PRESHUTDOWN, &TlenProtocol::PreShutdown); - - DBVARIANT dbv; - if (!db_get(NULL, m_szModuleName, "LoginServer", &dbv)) - db_free(&dbv); - else - db_set_s(NULL, m_szModuleName, "LoginServer", "tlen.pl"); - - if (!db_get(NULL, m_szModuleName, "ManualHost", &dbv)) - db_free(&dbv); - else - db_set_s(NULL, m_szModuleName, "ManualHost", "s1.tlen.pl"); - - TlenLoadOptions(this); - - JabberWsInit(this); - JabberSerialInit(this); - JabberIqInit(this); - JabberListInit(this); - - initMenuItems(); -} - -TlenProtocol::~TlenProtocol() -{ - uninitMenuItems(this); - TlenVoiceCancelAll(this); - TlenFileCancelAll(this); - if (hTlenNudge) - DestroyHookableEvent(hTlenNudge); - JabberListUninit(this); - JabberIqUninit(this); - JabberSerialUninit(this); - DeleteCriticalSection(&modeMsgMutex); - DeleteCriticalSection(&csSend); - JabberWsUninit(this); - - mir_free(modeMsgs.szOnline); - mir_free(modeMsgs.szAway); - mir_free(modeMsgs.szNa); - mir_free(modeMsgs.szDnd); - mir_free(modeMsgs.szFreechat); - mir_free(modeMsgs.szInvisible); -} diff --git a/protocols/Tlen/src/jabber_thread.cpp b/protocols/Tlen/src/jabber_thread.cpp deleted file mode 100644 index ab6130d1c5..0000000000 --- a/protocols/Tlen/src/jabber_thread.cpp +++ /dev/null @@ -1,1409 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -#include "commons.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "resource.h" -#include "tlen_p2p_old.h" -#include "tlen_file.h" -#include "tlen_muc.h" -#include "tlen_voice.h" -#include "tlen_avatar.h" -#include "tlen_presence.h" -#include "tlen_picture.h" -#include -#include -#include - - -extern void __cdecl TlenProcessP2P(XmlNode *node, ThreadData *info); - - -//static void __cdecl TlenProcessInvitation(struct ThreadData *info); -static void __cdecl JabberKeepAliveThread(void *ptr); -static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info); -static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info); -static void JabberProcessProtocol(XmlNode *node, ThreadData *info); -static void JabberProcessMessage(XmlNode *node, ThreadData *info); -static void JabberProcessIq(XmlNode *node, ThreadData *info); -static void TlenProcessW(XmlNode *node, ThreadData *info); -static void TlenProcessM(XmlNode *node, ThreadData *info); -static void TlenProcessN(XmlNode *node, ThreadData *info); -static void TlenProcessP(XmlNode *node, ThreadData *info); -static void TlenProcessV(XmlNode *node, ThreadData *info); -static void TlenProcessAvatar(XmlNode* node, ThreadData *info); -static void TlenProcessCipher(XmlNode *node, ThreadData *info); - -static VOID NTAPI JabberDummyApcFunc(ULONG_PTR param) -{ - return; -} - -static char onlinePassword[128]; -static HANDLE hEventPasswdDlg; - -static INT_PTR CALLBACK JabberPasswordDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[128]; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - mir_snprintf(text, SIZEOF(text), "%s %s", Translate("Enter password for"), (char *) lParam); - SetDlgItemTextA(hwndDlg, IDC_JID, text); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - GetDlgItemTextA(hwndDlg, IDC_PASSWORD, onlinePassword, sizeof(onlinePassword)); - //EndDialog(hwndDlg, (int) onlinePassword); - //return TRUE; - // Fall through - case IDCANCEL: - //EndDialog(hwndDlg, 0); - SetEvent(hEventPasswdDlg); - DestroyWindow(hwndDlg); - return TRUE; - } - break; - } - - return FALSE; -} - -static VOID NTAPI JabberPasswordCreateDialogApcProc(ULONG_PTR param) -{ - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) param); -} - -void __cdecl JabberServerThread(ThreadData *info) -{ - DBVARIANT dbv; - char jidStr[128]; - char *connectHost; - char *buffer; - int datalen; - XmlState xmlState; - int jabberNetworkBufferSize; - int oldStatus = ID_STATUS_OFFLINE; - int reconnectMaxTime; - int numRetry; - int reconnectTime; - int loginErr = 0; - JabberLog(info->proto, "Thread started"); - - // Normal server connection, we will fetch all connection parameters - // e.g. username, password, etc. from the database. - - if (info->proto->threadData != NULL) { - // Will not start another connection thread if a thread is already running. - // Make APC call to the main thread. This will immediately wake the thread up - // in case it is asleep in the reconnect loop so that it will immediately - // reconnect. - QueueUserAPC(JabberDummyApcFunc, info->proto->threadData->hThread, 0); - JabberLog(info->proto, "Thread ended, another normal thread is running"); - mir_free(info); - return; - } - - info->proto->threadData = info; - - if (!db_get(NULL, info->proto->m_szModuleName, "LoginName", &dbv)) { - strncpy(info->username, dbv.pszVal, sizeof(info->username)); - info->username[sizeof(info->username)-1] = '\0'; - _strlwr(info->username); - db_set_s(NULL, info->proto->m_szModuleName, "LoginName", info->username); - db_free(&dbv); - - } else { - JabberLog(info->proto, "Thread ended, login name is not configured"); - loginErr = LOGINERR_BADUSERID; - } - - if (loginErr == 0) { - if (!db_get(NULL, info->proto->m_szModuleName, "LoginServer", &dbv)) { - strncpy(info->server, dbv.pszVal, sizeof(info->server)); - info->server[sizeof(info->server)-1] = '\0'; - _strlwr(info->server); - db_set_s(NULL, info->proto->m_szModuleName, "LoginServer", info->server); - db_free(&dbv); - } else { - JabberLog(info->proto, "Thread ended, login server is not configured"); - loginErr = LOGINERR_NONETWORK; - } - } - - if (loginErr == 0) { - if (!info->proto->tlenOptions.savePassword) { - // Ugly hack: continue logging on only the return value is &(onlinePassword[0]) - // because if WM_QUIT while dialog box is still visible, p is returned with some - // exit code which may not be NULL. - // Should be better with modeless. - onlinePassword[0] = (char) -1; - hEventPasswdDlg = CreateEvent(NULL, FALSE, FALSE, NULL); - QueueUserAPC(JabberPasswordCreateDialogApcProc, hMainThread, (DWORD) jidStr); - WaitForSingleObject(hEventPasswdDlg, INFINITE); - CloseHandle(hEventPasswdDlg); - //if ((p=(char *)DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) jidStr)) != onlinePassword) { - if (onlinePassword[0] != (char) -1) { - strncpy(info->password, onlinePassword, sizeof(info->password)); - info->password[sizeof(info->password)-1] = '\0'; - } else { - JabberLog(info->proto, "Thread ended, password request dialog was canceled"); - loginErr = LOGINERR_BADUSERID; - } - } else { - if (!db_get(NULL, info->proto->m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - strncpy(info->password, dbv.pszVal, sizeof(info->password)); - info->password[sizeof(info->password)-1] = '\0'; - db_free(&dbv); - } else { - JabberLog(info->proto, "Thread ended, password is not configured"); - loginErr = LOGINERR_BADUSERID; - } - } - } - - jabberNetworkBufferSize = 2048; - if ((buffer=(char *) mir_alloc(jabberNetworkBufferSize+1)) == NULL) { // +1 is for '\0' when debug logging this buffer - JabberLog(info->proto, "Thread ended, network buffer cannot be allocated"); - loginErr = LOGINERR_NONETWORK; - } - - if (loginErr != 0) { - info->proto->threadData = NULL; - oldStatus = info->proto->m_iStatus; - info->proto->m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, loginErr); - mir_free(info); - return; - } - - mir_snprintf(jidStr, sizeof(jidStr), "%s@%s", info->username, info->server); - db_set_s(NULL, info->proto->m_szModuleName, "jid", jidStr); - - if (!db_get(NULL, info->proto->m_szModuleName, "ManualHost", &dbv)) { - strncpy(info->manualHost, dbv.pszVal, sizeof(info->manualHost)); - info->manualHost[sizeof(info->manualHost)-1] = '\0'; - db_free(&dbv); - } - info->port = db_get_w(NULL, info->proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT); - info->useEncryption = info->proto->tlenOptions.useEncryption; - - if (info->manualHost[0]) - connectHost = info->manualHost; - else - connectHost = info->server; - - JabberLog(info->proto, "Thread server='%s' port='%d'", connectHost, info->port); - - - if (!db_get(NULL, info->proto->m_szModuleName, "AvatarHash", &dbv)) { - strcpy(info->proto->threadData->avatarHash, dbv.pszVal); - db_free(&dbv); - } - info->avatarFormat = db_get_dw(NULL, info->proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); - - - reconnectMaxTime = 10; - numRetry = 0; - - for (;;) { // Reconnect loop - - info->s = JabberWsConnect(info->proto, connectHost, info->port); - if (info->s == NULL) { - JabberLog(info->proto, "Connection failed (%d)", WSAGetLastError()); - if (info->proto->threadData == info) { - oldStatus = info->proto->m_iStatus; - info->proto->m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NONETWORK); - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); - if (info->proto->tlenOptions.reconnect == TRUE) { - reconnectTime = rand() % reconnectMaxTime; - JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); - SleepEx(reconnectTime * 1000, TRUE); - if (reconnectMaxTime < 10*60) // Maximum is 10 minutes - reconnectMaxTime *= 2; - if (info->proto->threadData == info) { // Make sure this is still the active thread for the main Jabber connection - JabberLog(info->proto, "Reconnecting to the network..."); - if (numRetry < MAX_CONNECT_RETRIES) - numRetry++; - oldStatus = info->proto->m_iStatus; - info->proto->m_iStatus = ID_STATUS_CONNECTING + numRetry; - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); - continue; - } - else { - JabberLog(info->proto, "Thread ended, connection failed"); - mir_free(buffer); - mir_free(info); - return; - } - } - info->proto->threadData = NULL; - } - JabberLog(info->proto, "Thread ended, connection failed"); - mir_free(buffer); - mir_free(info); - return; - } - - // User may change status to OFFLINE while we are connecting above - if (info->proto->m_iDesiredStatus != ID_STATUS_OFFLINE) { - - info->proto->isConnected = TRUE; - JabberForkThread(JabberKeepAliveThread, 0, info->proto); - - JabberXmlInitState(&xmlState); - JabberXmlSetCallback(&xmlState, 1, ELEM_OPEN, (void (__cdecl *)(XmlNode *,void *))JabberProcessStreamOpening, info); - JabberXmlSetCallback(&xmlState, 1, ELEM_CLOSE, (void (__cdecl *)(XmlNode *,void *))JabberProcessStreamClosing, info); - JabberXmlSetCallback(&xmlState, 2, ELEM_CLOSE, (void (__cdecl *)(XmlNode *,void *))JabberProcessProtocol, info); - - info->useAES = FALSE; - - if (info->useEncryption) { - JabberSend(info->proto, ""); - - } else { - JabberSend(info->proto, ""); - } - - JabberLog(info->proto, "Entering main recv loop"); - datalen = 0; - - for (;;) { - int recvResult, bytesParsed; - - if (info->useAES) { - recvResult = JabberWsRecvAES(info->proto, buffer+datalen, jabberNetworkBufferSize-datalen, &info->aes_in_context, info->aes_in_iv); - } else { - recvResult = JabberWsRecv(info->proto, info->s, buffer+datalen, jabberNetworkBufferSize-datalen); - } - - if (recvResult <= 0) - break; - datalen += recvResult; - - buffer[datalen] = '\0'; - JabberLog(info->proto, "RECV:%s", buffer); - - bytesParsed = JabberXmlParse(&xmlState, buffer, datalen); - JabberLog(info->proto, "bytesParsed = %d", bytesParsed); - if (bytesParsed > 0) { - if (bytesParsed < datalen) - memmove(buffer, buffer+bytesParsed, datalen-bytesParsed); - datalen -= bytesParsed; - } - else if (datalen == jabberNetworkBufferSize) { - jabberNetworkBufferSize += 2048; - JabberLog(info->proto, "Increasing network buffer size to %d", jabberNetworkBufferSize); - if ((buffer=(char *) mir_realloc(buffer, jabberNetworkBufferSize+1)) == NULL) { - JabberLog(info->proto, "Cannot reallocate more network buffer, go offline now"); - break; - } - } - else { - JabberLog(info->proto, "Unknown state: bytesParsed=%d, datalen=%d, jabberNetworkBufferSize=%d", bytesParsed, datalen, jabberNetworkBufferSize); - } - } - - JabberXmlDestroyState(&xmlState); - - info->proto->isOnline = FALSE; - info->proto->isConnected = FALSE; - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIM_FLAGS | CMIF_GRAYED; - Menu_ModifyItem(info->proto->hMenuMUC, &mi); - if (info->proto->hMenuChats != NULL) - Menu_ModifyItem(info->proto->hMenuChats, &mi); - - // Set status to offline - char *szProto = info->proto->m_szModuleName; - oldStatus = info->proto->m_iStatus; - info->proto->m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(szProto, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); - - // Set all contacts to offline - for (HANDLE hContact = db_find_first(szProto); hContact; hContact = db_find_next(hContact, szProto)) - if (db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - db_set_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); - - JabberListWipeSpecial(info->proto); - } - else { - oldStatus = info->proto->m_iStatus; - info->proto->m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); - } - - Netlib_CloseHandle(info->s); - - if (info->proto->tlenOptions.reconnect == FALSE) - break; - - if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread - break; - reconnectTime = rand() % 10; - JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); - SleepEx(reconnectTime * 1000, TRUE); - reconnectMaxTime = 20; - if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread - break; - JabberLog(info->proto, "Reconnecting to the network..."); - info->proto->m_iDesiredStatus = oldStatus; // Reconnect to my last status - oldStatus = info->proto->m_iStatus; - info->proto->m_iStatus = ID_STATUS_CONNECTING; - numRetry = 1; - ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); - } - - JabberLog(info->proto, "Thread ended: server='%s'", info->server); - - if (info->proto->threadData == info) { - info->proto->threadData = NULL; - } - - mir_free(buffer); - if (info->streamId) mir_free(info->streamId); - JabberLog(info->proto, "Exiting ServerThread"); - mir_free(info); -} - -static void TlenSendAuth(TlenProtocol *proto) { - int iqId; - char *p; - char *str; - char text[128]; - str = TlenPasswordHash(proto->threadData->password); - mir_snprintf(text, SIZEOF(text), "%s%s", proto->threadData->streamId, str); - mir_free(str); - str = JabberSha1(text); - if ((p=JabberTextEncode(proto->threadData->username)) != NULL) { - iqId = JabberSerialNext(proto->threadData->proto); - JabberIqAdd(proto, iqId, IQ_PROC_NONE, JabberIqResultAuth); - JabberSend(proto, "%s%sttlen.pl", iqId, p /*info->username*/, str); - mir_free(p); - } - mir_free(str); -} - -static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info) -{ - char *sid, *s; - - if (node->name == NULL || strcmp(node->name, "s")) - return; - - if ((sid=JabberXmlGetAttrValue(node, "i")) != NULL) { - if (info->streamId) mir_free(info->streamId); - info->streamId = mir_strdup(sid); - } - if ((s=JabberXmlGetAttrValue(node, "s")) != NULL && !strcmp(s, "1")) { - int i; - char *k1, *k2, *k3; - unsigned char aes_key[32]; - char aes_key_str[140], aes_iv_str[40]; - mpi k1_mpi, k2_mpi, aes_mpi; - size_t slen; - - k1=JabberXmlGetAttrValue(node, "k1"); - k2=JabberXmlGetAttrValue(node, "k2"); - k3=JabberXmlGetAttrValue(node, "k3"); - - memset(&info->aes_in_context, 0, sizeof (aes_context)); - memset(&info->aes_out_context, 0, sizeof (aes_context)); - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_string(&aes_mpi, 16, k3); - mpi_write_binary(&aes_mpi, info->aes_in_iv, 16); - for (i = 0; i < 16; i++) { - info->aes_out_iv[i] = rand(); - aes_key[i] = rand(); - } - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_binary(&aes_mpi, info->aes_out_iv, 16); - slen = 40; - mpi_write_string(&aes_mpi, 16, aes_iv_str, &slen); - aes_setkey_dec(&info->aes_in_context, aes_key, 128); - aes_setkey_enc(&info->aes_out_context, aes_key, 128); - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_binary(&aes_mpi, aes_key, 16); - memset(&k1_mpi, 0, sizeof (mpi)); - mpi_read_string( &k1_mpi, 16, k1 ); - memset(&k2_mpi, 0, sizeof (mpi)); - mpi_read_string( &k2_mpi, 16, k2 ); - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_binary(&aes_mpi, (unsigned char *)aes_key, 16); - mpi_exp_mod( &aes_mpi, &aes_mpi, &k1_mpi, &k2_mpi, NULL ); - slen = 140; - mpi_write_string(&aes_mpi, 16, aes_key_str, &slen); - JabberSend(info->proto, "", aes_key_str, aes_iv_str); - } else { - TlenSendAuth(info->proto); - } -} - -static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info) -{ - Netlib_CloseHandle(info->proto); - if (node->name && !strcmp(node->name, "stream:error") && node->text) - MessageBoxA(NULL, Translate(node->text), Translate("Jabber Connection Error"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND); -} - -static void JabberProcessProtocol(XmlNode *node, ThreadData *info) -{ - if (!strcmp(node->name, "message")) - JabberProcessMessage(node, info); - else if (!strcmp(node->name, "presence")) - TlenProcessPresence(node, info->proto); - else if (!strcmp(node->name, "iq")) - JabberProcessIq(node, info); - else if (!strcmp(node->name, "f")) - TlenProcessF(node, info); - else if (!strcmp(node->name, "w")) - TlenProcessW(node, info); - else if (!strcmp(node->name, "m")) - TlenProcessM(node, info); - else if (!strcmp(node->name, "n")) - TlenProcessN(node, info); - else if (!strcmp(node->name, "p")) - TlenProcessP(node, info); - else if (!strcmp(node->name, "v")) - TlenProcessV(node, info); - else if (!strcmp(node->name, "avatar")) - TlenProcessAvatar(node, info); - else if (!strcmp(node->name, "cipher")) - TlenProcessCipher(node, info); - else - JabberLog(info->proto, "Invalid top-level tag (only

and allowed)"); - -} - -static void TlenProcessCipher(XmlNode *node, ThreadData *info) -{ - char *type; - type=JabberXmlGetAttrValue(node, "type"); - info->useAES = TRUE; - JabberSend(info->proto, ""); - TlenSendAuth(info->proto); -} - -static void TlenProcessIqGetVersion(TlenProtocol *proto, XmlNode* node) -{ - OSVERSIONINFO osvi = { 0 }; - char mversion[256]; - char* from, *version, *mver; - char* os = NULL; - JABBER_LIST_ITEM *item; - - if (proto->m_iStatus == ID_STATUS_INVISIBLE) return; - if (!proto->tlenOptions.enableVersion) return; - if (( from=JabberXmlGetAttrValue( node, "from" )) == NULL ) return; - if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) ==NULL) return; - version = JabberTextEncode( TLEN_VERSION_STRING ); - osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); - if ( GetVersionEx( &osvi )) { - switch ( osvi.dwPlatformId ) { - case VER_PLATFORM_WIN32_NT: - if ( osvi.dwMajorVersion == 5 ) { - if ( osvi.dwMinorVersion == 2 ) os = JabberTextEncode( Translate( "Windows Server 2003" )); - else if ( osvi.dwMinorVersion == 1 ) os = JabberTextEncode( Translate( "Windows XP" )); - else if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 2000" )); - } - else if ( osvi.dwMajorVersion <= 4 ) { - os = JabberTextEncode( Translate( "Windows NT" )); - } - break; - case VER_PLATFORM_WIN32_WINDOWS: - if ( osvi.dwMajorVersion == 4 ) { - if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 95" )); - if ( osvi.dwMinorVersion == 10 ) os = JabberTextEncode( Translate( "Windows 98" )); - if ( osvi.dwMinorVersion == 90 ) os = JabberTextEncode( Translate( "Windows ME" )); - } - break; - } } - - if ( os == NULL ) os = JabberTextEncode( Translate( "Windows" )); - - strcpy(mversion, "Miranda NG "); - CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof( mversion ) - 11, ( LPARAM )mversion + 11 ); - strcat(mversion, " (Tlen v."); - strcat(mversion, TLEN_VERSION_STRING); - strcat(mversion, ")"); - mver = JabberTextEncode( mversion ); - JabberSend( proto, "%s%s%s", from, mver?mver:"", version?version:"", os?os:"" ); - if (!item->versionRequested) { - item->versionRequested = TRUE; - JabberSend(proto, "", from); - } - - if ( mver ) mir_free( mver ); - if ( version ) mir_free( version ); - if ( os ) mir_free( os ); -} - -// Support for Tlen avatars - avatar token used to access web interface -static void TlenProcessAvatar(XmlNode* node, ThreadData *info) -{ - XmlNode *tokenNode, *aNode; - tokenNode = JabberXmlGetChild(node, "token"); - aNode = JabberXmlGetChild(node, "a"); - if (tokenNode != NULL) { - char *token = tokenNode->text; - strcpy(info->avatarToken, token); - } - if (aNode != NULL) { - if (TlenProcessAvatarNode(info->proto, node, NULL)) { - } - } -} - -static void JabberProcessMessage(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - PROTORECVEVENT recv; - XmlNode *bodyNode, *subjectNode, *xNode, *n; - char *from, *type, *nick, *p, *localMessage, *idStr; - DWORD msgTime; - BOOL delivered, composing; - int i; - JABBER_LIST_ITEM *item; - BOOL isChatRoomJid; - - if (!node->name || strcmp(node->name, "message")) return; - - if ((type=JabberXmlGetAttrValue(node, "type")) != NULL && !strcmp(type, "error")) { - } - else { - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - char *fromJid = JabberLoginFromJID(from); - if (info->proto->tlenOptions.ignoreAdvertisements && strstr(from, "b73@tlen.pl") == from) { - return; - } - // If message is from a stranger (not in roster), item is NULL - item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fromJid); - isChatRoomJid = JabberListExist(info->proto, LIST_CHATROOM, from); - - if (isChatRoomJid && type != NULL && !strcmp(type, "groupchat")) { - //JabberGroupchatProcessMessage(node, userdata); - } else if (type != NULL && !strcmp(type, "pic")) { - TlenProcessPic(node, info->proto); - } else if (type != NULL && !strcmp(type, "iq")) { - XmlNode *iqNode; - // Jabber-compatible iq - if ((iqNode=JabberXmlGetChild(node, "iq")) != NULL) { - JabberXmlAddAttr(iqNode, "from", from); - JabberProcessIq(iqNode, info); - } - } else { - if ((bodyNode=JabberXmlGetChild(node, "body")) != NULL) { - if (bodyNode->text != NULL) { - if ((subjectNode=JabberXmlGetChild(node, "subject")) != NULL && subjectNode->text != NULL && subjectNode->text[0] != '\0') { - int size = strlen(subjectNode->text)+strlen(bodyNode->text)+5; - p = (char *)mir_alloc(size); - mir_snprintf(p, size, "%s\r\n%s", subjectNode->text, bodyNode->text); - localMessage = JabberTextDecode(p); - mir_free(p); - } else { - localMessage = JabberTextDecode(bodyNode->text); - } - - msgTime = 0; - delivered = composing = FALSE; - i = 1; - while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { - if ((p=JabberXmlGetAttrValue(xNode, "xmlns")) != NULL) { - if (!strcmp(p, "jabber:x:delay") && msgTime==0) { - if ((p=JabberXmlGetAttrValue(xNode, "stamp")) != NULL) { - msgTime = JabberIsoToUnixTime(p); - } - } - else if (!strcmp(p, "jabber:x:event")) { - // Check whether any event is requested - if (!delivered && (n=JabberXmlGetChild(xNode, "delivered")) != NULL) { - delivered = TRUE; - idStr = JabberXmlGetAttrValue(node, "id"); - JabberSend(info->proto, "%s", from, (idStr != NULL)?idStr:""); - } - if (item != NULL && JabberXmlGetChild(xNode, "composing") != NULL) { - composing = TRUE; - if (item->messageEventIdStr) - mir_free(item->messageEventIdStr); - idStr = JabberXmlGetAttrValue(node, "id"); - item->messageEventIdStr = (idStr == NULL)?NULL:mir_strdup(idStr); - } - } - } - i++; - } - - if (item != NULL) { - item->wantComposingEvent = composing; - if (item->isTyping) { - item->isTyping = FALSE; - if ((hContact=JabberHContactFromJID(info->proto, fromJid)) != NULL) - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); - } - } - - if ((hContact=JabberHContactFromJID(info->proto, fromJid)) == NULL) { - // Create a temporary contact - if (isChatRoomJid) { - if ((p=strchr(from, '/')) != NULL && p[1]!='\0') - p++; - else - p = from; - nick = JabberTextEncode(p); - hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); - } - else { - nick = JabberLocalNickFromJID(from); - hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); - } - mir_free(nick); - } - - if (msgTime == 0) { - msgTime = time(NULL); - } else { - HANDLE hDbEvent = db_event_last(hContact); - if (hDbEvent != NULL) { - DBEVENTINFO dbei = { sizeof(dbei) }; - db_event_get( hDbEvent, &dbei); - if (msgTime < dbei.timestamp) { - msgTime = dbei.timestamp + 1; - } - } - if (msgTime > (DWORD)time(NULL)) { - msgTime = time(NULL); - } - } - recv.flags = 0; - recv.timestamp = (DWORD) msgTime; - recv.szMessage = localMessage; - recv.lParam = 0; - ProtoChainRecvMsg(hContact, &recv); - mir_free(localMessage); - } - } - } - mir_free(fromJid); - } - } -} - -static void JabberProcessIq(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - XmlNode *queryNode = NULL; - char *type, *jid, *nick; - char *xmlns = NULL; - char *idStr, *str; - int id; - int i; - JABBER_IQ_PFUNC pfunc; - - if (!node->name || strcmp(node->name, "iq")) return; - type=JabberXmlGetAttrValue(node, "type"); -// if ((type=JabberXmlGetAttrValue(node, "type")) == NULL) return; - - id = -1; - if ((idStr=JabberXmlGetAttrValue(node, "id")) != NULL) { - if (!strncmp(idStr, JABBER_IQID, strlen(JABBER_IQID))) - id = atoi(idStr+strlen(JABBER_IQID)); - } - - queryNode = JabberXmlGetChild(node, "query"); - if (queryNode != NULL) { - xmlns = JabberXmlGetAttrValue(queryNode, "xmlns"); - } - - - ///////////////////////////////////////////////////////////////////////// - // MATCH BY ID - ///////////////////////////////////////////////////////////////////////// - if ((pfunc=JabberIqFetchFunc(info->proto, id)) != NULL) { - JabberLog(info->proto, "Handling iq request for id=%d", id); - pfunc(info->proto, node); - ///////////////////////////////////////////////////////////////////////// - // MORE GENERAL ROUTINES, WHEN ID DOES NOT MATCH - ///////////////////////////////////////////////////////////////////////// - // new p2p connections - } else if (xmlns != NULL && !strcmp(xmlns, "p2p")) { - if (info->proto->tlenOptions.useNewP2P) { - TlenProcessP2P(node, info); - } - } - // RECVED: proto, " Got roster push, query has %d children", queryNode->numChild); - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if ((str=JabberXmlGetAttrValue(itemNode, "subscription")) != NULL) { - // we will not add new account when subscription=remove - if (!strcmp(str, "to") || !strcmp(str, "both") || !strcmp(str, "from") || !strcmp(str, "none")) { - if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { - nick = JabberTextDecode(name); - } else { - nick = JabberLocalNickFromJID(jid); - } - if (nick != NULL) { - if ((item=JabberListAdd(info->proto, LIST_ROSTER, jid)) != NULL) { - if (item->nick) mir_free(item->nick); - item->nick = nick; - if ((hContact=JabberHContactFromJID(info->proto, jid)) == NULL) { - // Received roster has a new JID. - // Add the jid (with empty resource) to Miranda contact list. - hContact = JabberDBCreateContact(info->proto, jid, nick, FALSE); - } - db_set_s(hContact, "CList", "MyHandle", nick); - if (item->group) mir_free(item->group); - if ((groupNode=JabberXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { - item->group = TlenGroupDecode(groupNode->text); - JabberContactListCreateGroup(item->group); - db_set_s(hContact, "CList", "Group", item->group); - } - else { - item->group = NULL; - db_unset(hContact, "CList", "Group"); - } - if (!strcmp(str, "none") || (!strcmp(str, "from") && strchr(jid, '@') != NULL)) { - if (db_get_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - db_set_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); - } - } - else { - mir_free(nick); - } - } - } - if ((item=JabberListGetItemPtr(info->proto, LIST_ROSTER, jid)) != NULL) { - if (!strcmp(str, "both")) item->subscription = SUB_BOTH; - else if (!strcmp(str, "to")) item->subscription = SUB_TO; - else if (!strcmp(str, "from")) item->subscription = SUB_FROM; - else item->subscription = SUB_NONE; - JabberLog(info->proto, "Roster push for jid=%s, set subscription to %s", jid, str); - // subscription = remove is to remove from roster list - // but we will just set the contact to offline and not actually - // remove, so that history will be retained. - if (!strcmp(str, "remove")) { - if ((hContact=JabberHContactFromJID(info->proto, jid)) != NULL) { - if (db_get_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - db_set_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); - JabberListRemove(info->proto, LIST_ROSTER, jid); - } - } - } - } - } - } - } - } - - } - // RECVED: proto, node); - } - // RECVED: proto, node); - } else if ( !strcmp( xmlns, "jabber:iq:version" )) { - TlenIqResultVersion(info->proto, node); - } else if ( !strcmp( xmlns, "jabber:iq:info" )) { - TlenIqResultInfo(info->proto, node); - } - } else { - char *from; - if (( from=JabberXmlGetAttrValue( node, "from" )) != NULL ) { - if ( !strcmp(from, "tcfg" )) { - TlenIqResultTcfg(info->proto, node); - } - } - } - } - // RECVED: ... - else if (!strcmp(type, "error")) { - JABBER_LIST_ITEM *item; - // Check for multi-user chat errors - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strstr(from, "@c") != NULL || !strcmp(from, "c")) { - TlenMUCRecvError(info->proto, from, node); - return; - } - } - - // Check for file transfer deny by comparing idStr with ft->iqId - i = 0; - while ((i=JabberListFindNext(info->proto, LIST_FILE, i)) >= 0) { - item = JabberListGetItemPtrFromIndex(info->proto,i); - if (item->ft->state==FT_CONNECTING && !strcmp(idStr, item->ft->iqId)) { - item->ft->state = FT_DENIED; - if (item->ft->hFileEvent != NULL) - SetEvent(item->ft->hFileEvent); // Simulate the termination of file server connection - } - i++; - } - } - // RECVED: ... - else if (!strcmp(type, "1")) { // Chat groups list result - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c") == 0) { - TlenIqResultChatGroups(info->proto, node); - } - } - } - else if (!strcmp(type, "2")) { // Chat rooms list result - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c") == 0) { - TlenIqResultChatRooms(info->proto, node); - } - } - } else if (!strcmp(type, "3")) { // room search result - result to iq type 3 query - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c") == 0) { - TlenIqResultRoomSearch(info->proto, node); - } - } - } else if (!strcmp(type, "4")) { // chat room users list - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strstr(from, "@c") != NULL) { - TlenIqResultChatRoomUsers(info->proto, node); - } - } - } else if (!strcmp(type, "5")) { // room name & group & flags info - sent on joining the room - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strstr(from, "@c") != NULL) { - TlenIqResultRoomInfo(info->proto, node); - } - } - } else if (!strcmp(type, "6")) { // new nick registered - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c") == 0) { - TlenIqResultUserNicks(info->proto, node); - } - } - } else if (!strcmp(type, "7")) { // user nicknames list - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c") == 0) { - TlenIqResultUserNicks(info->proto, node); - } - } - } else if (!strcmp(type, "8")) { // user chat rooms list - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c") == 0) { - TlenIqResultUserRooms(info->proto, node); - } - } - } -} - -/* - * Web messages - */ -static void TlenProcessW(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - PROTORECVEVENT recv; - char *f, *e, *s, *body; - char *str, *localMessage; - int strSize; - - if (!node->name || strcmp(node->name, "w")) return; - if ((body=node->text) == NULL) return; - - if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { - - char webContactName[128]; - mir_snprintf(webContactName, SIZEOF(webContactName), Translate("%s Web Messages"), info->proto->m_szModuleName); - if ((hContact=JabberHContactFromJID(info->proto, webContactName)) == NULL) { - hContact = JabberDBCreateContact(info->proto, webContactName, webContactName, TRUE); - } - - s = JabberXmlGetAttrValue(node, "s"); - e = JabberXmlGetAttrValue(node, "e"); - - str = NULL; - strSize = 0; - JabberStringAppend(&str, &strSize, "%s\r\n%s: ", Translate("Web message"), Translate("From")); - - if (f != NULL) - JabberStringAppend(&str, &strSize, "%s", f); - JabberStringAppend(&str, &strSize, "\r\n%s: ", Translate("E-mail")); - if (e != NULL) - JabberStringAppend(&str, &strSize, "%s", e); - JabberStringAppend(&str, &strSize, "\r\n\r\n%s", body); - - localMessage = JabberTextDecode(str); - - recv.flags = 0; - recv.timestamp = (DWORD) time(NULL); - recv.szMessage = localMessage; - recv.lParam = 0; - ProtoChainRecvMsg(hContact, &recv); - - mir_free(localMessage); - mir_free(str); - } -} - -/* - * Typing notification, multi-user conference messages and invitations - */ -static void TlenProcessM(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - PROTORECVEVENT recv; - char *f;//, *from;//username - char *tp;//typing start/stop - char *p, *n, *r, *s, *str, *localMessage; - int i; - XmlNode *xNode, *invNode, *bNode, *subjectNode; - - if (!node->name || strcmp(node->name, "m")) return; - - if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { - char *fLogin = JabberLoginFromJID(f); - if ((hContact=JabberHContactFromJID(info->proto, fLogin)) != NULL) { - if ((tp=JabberXmlGetAttrValue(node, "tp")) != NULL) { - JABBER_LIST_ITEM *item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fLogin); - if (!strcmp(tp, "t")) { //contact is writing - if (item != NULL ) { - item->isTyping = TRUE; - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_INFINITE); - } - } - else if (!strcmp(tp, "u")) {//contact stopped writing - if (item != NULL) { - item->isTyping = FALSE; - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); - } - } - else if (!strcmp(tp, "a")) {//alert was received - int bAlert = TRUE; - if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_ALL) { - bAlert = FALSE; - } else if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_NIR) { - bAlert = IsAuthorized(info->proto, fLogin); - } - if (bAlert) { - if (info->proto->tlenOptions.useNudge) { - NotifyEventHooks(info->proto->hTlenNudge,(WPARAM) hContact,0); - } else { - if (info->proto->tlenOptions.logAlerts) { - TlenLogMessage(info->proto, hContact, 0, Translate("An alert has been received.")); - } - SkinPlaySound("TlenAlertNotify"); - } - } - } - } - } - mir_free(fLogin); - if ((p=strchr(f, '@')) != NULL) { - if ((p=strchr(p, '/')) != NULL && p[1]!='\0') { // message from user - time_t timestamp; - s = JabberXmlGetAttrValue(node, "s"); - if (s != NULL) { - timestamp = TlenTimeToUTC(atol(s)); - if (timestamp > time(NULL)) { - timestamp = time(NULL); - } - } else { - timestamp = time(NULL); - } - tp=JabberXmlGetAttrValue(node, "tp"); - bNode = JabberXmlGetChild(node, "b"); - f = JabberTextDecode(f); - if (bNode != NULL && bNode->text != NULL) { - if (tp != NULL && !strcmp(tp, "p")) { - /* MUC private message */ - str = JabberResourceFromJID(f); - hContact = JabberDBCreateContact(info->proto, f, str, TRUE); - db_set_b(hContact, info->proto->m_szModuleName, "bChat", TRUE); - mir_free(str); - localMessage = JabberTextDecode(bNode->text); - recv.flags = 0; - recv.timestamp = (DWORD) timestamp; - recv.szMessage = localMessage; - recv.lParam = 0; - ProtoChainRecvMsg(hContact, &recv); - mir_free(localMessage); - } else { - /* MUC message */ - TlenMUCRecvMessage(info->proto, f, timestamp, bNode); - } - } - mir_free(f); - } else { // message from chat room (system) - subjectNode = JabberXmlGetChild(node, "subject"); - if (subjectNode != NULL) { - f = JabberTextDecode(f); - localMessage = ""; - if (subjectNode->text != NULL) { - localMessage = subjectNode->text; - } - localMessage = JabberTextDecode(localMessage); - TlenMUCRecvTopic(info->proto, f, localMessage); - mir_free(localMessage); - mir_free(f); - } - } - } - i=1; - while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { - invNode=JabberXmlGetChild(xNode, "inv"); - if (invNode != NULL) { - r = JabberTextDecode(f); - f = JabberXmlGetAttrValue(invNode, "f"); - f = JabberTextDecode(f); - n = JabberXmlGetAttrValue(invNode, "n"); - if (n != NULL && strstr(r, n) != r) { - n = JabberTextDecode(n); - } else { - n = mir_strdup(Translate("Private conference")); - //n = JabberNickFromJID(r); - } - TlenMUCRecvInvitation(info->proto, r, n, f, ""); - mir_free(n); - mir_free(r); - mir_free(f); - break; - } - i++; - } - } -} - -static void TlenMailPopup(TlenProtocol *proto, char *title, char *emailInfo) -{ - if ( !ServiceExists(MS_POPUP_ADDPOPUP)) - return; - if (!db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE)) - return; - - POPUPDATA ppd = { 0 }; - ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIL)); - strcpy(ppd.lpzContactName, title); - strcpy(ppd.lpzText, emailInfo); - ppd.colorBack = db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", 0); - ppd.colorText = db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", 0); - BYTE delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0); - if (delayMode == 1) - ppd.iSeconds = db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4); - else if (delayMode == 2) - ppd.iSeconds = -1; - PUAddPopup(&ppd); -} -/* - * Incoming e-mail notification - */ -static void TlenProcessN(XmlNode *node, ThreadData *info) -{ - char *f, *s; - char *str, *popupTitle, *popupText; - int strSize; - - if (!node->name || strcmp(node->name, "n")) return; - - s = JabberXmlGetAttrValue(node, "s"); - f = JabberXmlGetAttrValue(node, "f"); - if (s != NULL && f != NULL) { - str = NULL; - strSize = 0; - - JabberStringAppend(&str, &strSize, Translate("%s mail"), info->proto->m_szModuleName); - popupTitle = JabberTextDecode(str); - mir_free(str); - - str = NULL; - strSize = 0; - - JabberStringAppend(&str, &strSize, "%s: %s\n", Translate("From"), f); - JabberStringAppend(&str, &strSize, "%s: %s", Translate("Subject"), s); - popupText = JabberTextDecode(str); - TlenMailPopup(info->proto, popupTitle, popupText); - SkinPlaySound("TlenMailNotify"); - - mir_free(popupTitle); - mir_free(popupText); - mir_free(str); - } -} - -/* - * Presence is chat rooms - */ -static void TlenProcessP(XmlNode *node, ThreadData *info) -{ - char jid[512]; - char *f, *id, *tp, *a, *n, *k; - XmlNode *sNode, *xNode, *iNode, *kNode; - int status, flags; - - if (!node->name || strcmp(node->name, "p")) return; - -// presence from users in chat room - flags = 0; - status = ID_STATUS_ONLINE; - f = JabberXmlGetAttrValue(node, "f"); - xNode = JabberXmlGetChild(node, "x"); - if (xNode != NULL) { // x subtag present (message from chat room) - change user rights only - char *temp, *iStr; - iNode = JabberXmlGetChild(xNode, "i"); - if (iNode != NULL) { - iStr = JabberXmlGetAttrValue(iNode, "i"); - temp = (char*)mir_alloc(strlen(f)+strlen(iStr)+2); - strcpy(temp, f); - strcat(temp, "/"); - strcat(temp, iStr); - f = JabberTextDecode(temp); - mir_free(temp); - node = iNode; - status = 0; - } else { - f = JabberTextDecode(f); - } - } else { - f = JabberTextDecode(f); - } - a = JabberXmlGetAttrValue(node, "z"); - if (a != NULL) { - if (atoi(a) &1 ) { - flags |= USER_FLAGS_REGISTERED; - } - } - a = JabberXmlGetAttrValue(node, "a"); - if (a != NULL) { - if (atoi(a) == 2) { - flags |= USER_FLAGS_ADMIN; - } - if (atoi(a) == 1) { - flags |= USER_FLAGS_OWNER; - } - if (atoi(a) == 3) { - //flags |= USER_FLAGS_MEMBER; - } - if (atoi(a) == 5) { - flags |= USER_FLAGS_GLOBALOWNER; - } - } - sNode = JabberXmlGetChild(node, "s"); - if (sNode != NULL) { - if (!strcmp(sNode->text, "unavailable")) { - status = ID_STATUS_OFFLINE; - } - } - kNode = JabberXmlGetChild(node, "kick"); - k = NULL; - if (kNode != NULL) { - k = JabberXmlGetAttrValue(kNode, "r"); - if (k == NULL) { - k = ""; - } - k = JabberTextDecode(k); - } - tp = JabberXmlGetAttrValue(node, "tp"); - if (tp != NULL && !strcmp(tp, "c")) { // new chat room has just been created - id = JabberXmlGetAttrValue(node, "id"); - if (id != NULL) { - n = JabberXmlGetAttrValue(node, "n"); - if (n != NULL) { - n = JabberTextDecode(n); - } else { - n = mir_strdup(Translate("Private conference"));// JabberNickFromJID(f); - } - mir_snprintf(jid, SIZEOF(jid), "%s/%s", f, info->username); -// if (!db_get(NULL, info->proto->m_szModuleName, "LoginName", &dbv)) { - // always real username -// sprintf(jid, "%s/%s", f, dbv.pszVal); - TlenMUCCreateWindow(info->proto, f, n, 0, NULL, id); - TlenMUCRecvPresence(info->proto, jid, ID_STATUS_ONLINE, flags, k); -// db_free(&dbv); -// } - mir_free(n); - } - } else { - TlenMUCRecvPresence(info->proto, f, status, flags, k); // user presence - } - if (k != NULL) { - mir_free(k); - } - mir_free(f); -} -/* - * Voice chat - */ -static void TlenProcessV(XmlNode *node, ThreadData *info) -{ - char jid[128]; - JABBER_LIST_ITEM *item; - char *from, *id, *e, *p; -// if (!node->name || strcmp(node->name, "v")) return; - - if ((from=JabberXmlGetAttrValue(node, "f")) != NULL) { - if (strchr(from, '@') == NULL) { - mir_snprintf(jid, sizeof(jid), "%s@%s", from, info->server); - } else { - mir_snprintf(jid, sizeof(jid), "%s", from); - } - if ((e=JabberXmlGetAttrValue(node, "e")) != NULL) { - if (!strcmp(e, "1")) { - if ((id=JabberXmlGetAttrValue(node, "i")) != NULL) { - SkinPlaySound("TlenVoiceNotify"); - TlenVoiceAccept(info->proto, id, from); - } - } else if (!strcmp(e, "3")) { - // FILE_RECV : e='3' : invalid transfer error - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if (item->ft != NULL) { - HANDLE hEvent = item->ft->hFileEvent; - item->ft->hFileEvent = NULL; - item->ft->state = FT_ERROR; - if (item->ft->s != NULL) { - Netlib_CloseHandle(item->ft->s); - item->ft->s = NULL; - if (hEvent != NULL) { - SetEvent(hEvent); - } - } else { - TlenP2PFreeFileTransfer(item->ft); - } - } else { - JabberListRemove(info->proto, LIST_VOICE, p); - } - } - } - } else if (!strcmp(e, "4")) { - // FILE_SEND : e='4' : File sending request was denied by the remote client - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if (!strcmp(item->ft->jid, jid)) { - TlenVoiceCancelAll(info->proto); - //JabberListRemove(info->proto, LIST_VOICE, p); - } - } - } - } else if (!strcmp(e, "5")) { - // FILE_SEND : e='5' : Voice request was accepted - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - JabberLog(info->proto, "should start voice 1 ? %s ?? %s", jid, item->ft->jid); - if (!strcmp(item->ft->jid, jid)) { - JabberLog(info->proto, "starting voice 1"); - TlenVoiceStart(item->ft, 1); - } - } - } - } else if (!strcmp(e, "6")) { - // FILE_RECV : e='6' : IP and port information to connect to get file - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { - item->ft->hostName = mir_strdup(p); - if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { - item->ft->wPort = atoi(p); - TlenVoiceStart(item->ft, 0); - //JabberForkThread((void (__cdecl *)(void*))TlenVoiceReceiveThread, 0, item->ft); - } - } - } - } - } - else if (!strcmp(e, "7")) { - // FILE_RECV : e='7' : IP and port information to connect to send file - // in case the conection to the given server was not successful - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { - if (item->ft->hostName != NULL) mir_free(item->ft->hostName); - item->ft->hostName = mir_strdup(p); - if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { - item->ft->wPort = atoi(p); - item->ft->state = FT_SWITCH; - SetEvent(item->ft->hFileEvent); - } - } - } - } - } - else if (!strcmp(e, "8")) { - // FILE_RECV : e='8' : transfer error - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - item->ft->state = FT_ERROR; - SetEvent(item->ft->hFileEvent); - } - } - } - - } - } -} - -static void __cdecl JabberKeepAliveThread(void *ptr) -{ - NETLIBSELECT nls = {0}; - - TlenProtocol *proto = (TlenProtocol *)ptr; - nls.cbSize = sizeof(NETLIBSELECT); - nls.dwTimeout = 60000; // 60000 millisecond (1 minute) - nls.hExceptConns[0] = proto->threadData->s; - for (;;) { - if (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls) != 0) - break; - if (proto->tlenOptions.sendKeepAlive) - JabberSend(proto, " \t "); - } - JabberLog(proto, "Exiting KeepAliveThread"); -} - diff --git a/protocols/Tlen/src/jabber_util.cpp b/protocols/Tlen/src/jabber_util.cpp deleted file mode 100644 index 71a18155b6..0000000000 --- a/protocols/Tlen/src/jabber_util.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include -#include - -void JabberSerialInit(TlenProtocol *proto) -{ - InitializeCriticalSection(&proto->csSerial); - proto->serial = 0; -} - -void JabberSerialUninit(TlenProtocol *proto) -{ - DeleteCriticalSection(&proto->csSerial); -} - - -unsigned int JabberSerialNext(TlenProtocol *proto) -{ - unsigned int ret; - - EnterCriticalSection(&proto->csSerial); - ret = proto->serial; - proto->serial++; - LeaveCriticalSection(&proto->csSerial); - return ret; -} - - -void JabberLog(TlenProtocol *proto, const char *fmt, ...) -{ -#ifdef ENABLE_LOGGING - char *str; - va_list vararg; - int strsize; - char *text; - char *p, *q; - int extra; - - va_start(vararg, fmt); - str = (char *) mir_alloc(strsize=2048); - while (mir_vsnprintf(str, strsize, fmt, vararg) == -1) - str = (char *) mir_realloc(str, strsize+=2048); - va_end(vararg); - - extra = 0; - for (p=str; *p != '\0'; p++) - if (*p == '\n' || *p == '\r') - extra++; - size_t size = strlen("TLEN") + 2 + strlen(str) + 2 + extra; - text = (char *) mir_alloc(size); - mir_snprintf(text, size, "[%s]", "TLEN"); - for (p=str,q=text+strlen(text); *p != '\0'; p++,q++) { - if (*p == '\r') { - *q = '\\'; - *(q+1) = 'r'; - q++; - } - else if (*p == '\n') { - *q = '\\'; - *(q+1) = 'n'; - q++; - } - else - *q = *p; - } - *q = '\n'; - *(q+1) = '\0'; - if (proto->hNetlibUser != NULL) { - CallService(MS_NETLIB_LOG, (WPARAM) proto->hNetlibUser, (LPARAM) text); - } - //OutputDebugString(text); - mir_free(text); - mir_free(str); -#endif -} - -// Caution: DO NOT use JabberSend() to send binary (non-string) data - -int JabberSend(TlenProtocol *proto, const char *fmt, ...) -{ - char *str; - int size; - va_list vararg; - int result = 0; - - EnterCriticalSection(&proto->csSend); - - va_start(vararg,fmt); - size = 512; - str = (char *) mir_alloc(size); - while (mir_vsnprintf(str, size, fmt, vararg) == -1) { - size += 512; - str = (char *) mir_realloc(str, size); - } - va_end(vararg); - - JabberLog(proto, "SEND:%s", str); - size = (int)strlen(str); - if (proto->threadData != NULL) { - if (proto->threadData->useAES) { - result = JabberWsSendAES(proto, str, size, &proto->threadData->aes_out_context, proto->threadData->aes_out_iv); - } else { - result = JabberWsSend(proto, proto->threadData->s, str, size); - } - } - LeaveCriticalSection(&proto->csSend); - - mir_free(str); - return result; -} - -char *JabberResourceFromJID(const char *jid2) -{ - char *p; - char *nick; - char* jid = mir_strdup(jid2); - - p=strchr(jid, '/'); - if (p != NULL && p[1] != '\0') { - p++; - if ((nick=(char *) mir_alloc(1+strlen(jid)-(p-jid))) != NULL) { - strncpy(nick, p, strlen(jid)-(p-jid)); - nick[strlen(jid)-(p-jid)] = '\0'; - } - } - else { - nick = mir_strdup(jid); - } - - mir_free(jid); - return nick; -} - -char *JabberNickFromJID(const char *jid2) -{ - char *p; - char *nick; - char* jid = mir_strdup(jid2); - - if ((p=strchr(jid, '@')) == NULL) - p = strchr(jid, '/'); - if (p != NULL) { - if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { - strncpy(nick, jid, p-jid); - nick[p-jid] = '\0'; - } - } - else { - nick = mir_strdup(jid); - } - - mir_free(jid); - return nick; -} - -char *JabberLoginFromJID(const char *jid2) -{ - char *p; - char *nick; - char* jid = mir_strdup(jid2); - - p = strchr(jid, '/'); - if (p != NULL) { - if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { - strncpy(nick, jid, p-jid); - nick[p-jid] = '\0'; - } - } - else { - nick = mir_strdup(jid); - } - - mir_free(jid); - return nick; -} - -char *JabberLocalNickFromJID(const char *jid) -{ - char *p; - char *localNick; - - p = JabberNickFromJID(jid); - localNick = JabberTextDecode(p); - mir_free(p); - return localNick; -} - -char *JabberSha1(char *str) -{ - mir_sha1_ctx sha; - DWORD digest[5]; - char* result; - - if ( str == NULL ) - return NULL; - - mir_sha1_init( &sha ); - mir_sha1_append( &sha, (BYTE* )str, (int)strlen( str )); - mir_sha1_finish( &sha, (BYTE* )digest ); - if ((result=(char *)mir_alloc(41)) == NULL) - return NULL; - sprintf(result, "%08x%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4])); //!!!!!!!!!!! - return result; -} - -char *TlenSha1(char *str, int len) -{ - mir_sha1_ctx sha; - BYTE digest[20]; - char* result; - int i; - - if ( str == NULL ) - return NULL; - - mir_sha1_init( &sha ); - mir_sha1_append( &sha, (BYTE* )str, len); - mir_sha1_finish( &sha, digest ); - if (( result=( char* )mir_alloc( 20 )) == NULL ) - return NULL; - for (i=0; i<20; i++) - result[i]=digest[4*(i>>2)+(3-(i&0x3))]; - return result; -} - -char *TlenPasswordHash(const char *str) -{ - int magic1 = 0x50305735, magic2 = 0x12345671, sum = 7; - char *p, *res; - - if (str == NULL) return NULL; - for (p=(char *)str; *p != '\0'; p++) { - if (*p != ' ' && *p != '\t') { - magic1 ^= (((magic1 & 0x3f) + sum) * ((char) *p)) + (magic1 << 8); - magic2 += (magic2 << 8) ^ magic1; - sum += ((char) *p); - } - } - magic1 &= 0x7fffffff; - magic2 &= 0x7fffffff; - res = (char *) mir_alloc(17); - sprintf(res, "%08x%08x", magic1, magic2); //!!!!!!!!!!! - return res; -} - -char *TlenUrlEncode(const char *str) -{ - char *p, *q, *res; - unsigned char c; - - if (str == NULL) return NULL; - res = (char *) mir_alloc(3*strlen(str) + 1); - for (p=(char *)str,q=res; *p != '\0'; p++,q++) { - if (*p == ' ') { - *q = '+'; - } - else if (*p < 0x20 || *p >= 0x7f || strchr("%&+:'<>\"", *p) != NULL) { - // Convert first from CP1252 to ISO8859-2 - switch ((unsigned char) *p) { - case 0xa5: c = (unsigned char) 0xa1; break; - case 0x8c: c = (unsigned char) 0xa6; break; - case 0x8f: c = (unsigned char) 0xac; break; - case 0xb9: c = (unsigned char) 0xb1; break; - case 0x9c: c = (unsigned char) 0xb6; break; - case 0x9f: c = (unsigned char) 0xbc; break; - default: c = (unsigned char) *p; break; - } - sprintf(q, "%%%02X", c); //!!!!!!!!!!! - q += 2; - } - else { - *q = *p; - } - } - *q = '\0'; - return res; -} - -void TlenUrlDecode(char *str) -{ - char *p, *q; - unsigned int code; - - if (str == NULL) return; - for (p=q=str; *p != '\0'; p++,q++) { - if (*p == '+') { - *q = ' '; - } - else if (*p == '%' && *(p+1) != '\0' && isxdigit(*(p+1)) && *(p+2) != '\0' && isxdigit(*(p+2))) { - sscanf(p+1, "%2x", &code); - *q = (char) code; - // Convert from ISO8859-2 to CP1252 - switch ((unsigned char) *q) { - case 0xa1: *q = (char) 0xa5; break; - case 0xa6: *q = (char) 0x8c; break; - case 0xac: *q = (char) 0x8f; break; - case 0xb1: *q = (char) 0xb9; break; - case 0xb6: *q = (char) 0x9c; break; - case 0xbc: *q = (char) 0x9f; break; - } - p += 2; - } - else { - *q = *p; - } - } - *q = '\0'; -} - -char * TlenGroupDecode(const char *str) -{ - char *p, *q; - if (str == NULL) return NULL; - p = q = JabberTextDecode(str); - for (; *p != '\0'; p++) { - if (*p == '/') { - *p = '\\'; - } - } - return q; -} - -char * TlenGroupEncode(const char *str) -{ - char *p, *q; - if (str == NULL) return NULL; - p = q = mir_strdup(str); - for (; *p != '\0'; p++) { - if (*p == '\\') { - *p = '/'; - } - } - p = JabberTextEncode(q); - mir_free(q); - return p; -} - -char *JabberTextEncode(const char *str) -{ - char *s1; - - if (str == NULL) return NULL; - if ((s1=TlenUrlEncode(str)) == NULL) - return NULL; - return s1; -} - -char *JabberTextDecode(const char *str) -{ - char *s1; - - if (str == NULL) return NULL; - s1 = mir_strdup(str); - TlenUrlDecode(s1); - return s1; -} - -/* - * Apply Polish Daylight Saving Time rules to get "DST-unbiased" timestamp - */ - -time_t TlenTimeToUTC(time_t time) { - struct tm *timestamp; - timestamp = gmtime(&time); - if ( (timestamp->tm_mon > 2 && timestamp->tm_mon < 9) || - (timestamp->tm_mon == 2 && timestamp->tm_mday - timestamp->tm_wday >= 25) || - (timestamp->tm_mon == 9 && timestamp->tm_mday - timestamp->tm_wday < 25)) { - //time -= 3600; - } else { - //time += 3600; - } - return time; -} - -time_t JabberIsoToUnixTime(char *stamp) -{ - struct tm timestamp; - char date[9]; - char *p; - int i, y; - time_t t; - - if (stamp == NULL) return (time_t) 0; - - p = stamp; - - // Get the date part - for (i=0; *p != '\0' && i<8 && isdigit(*p); p++,i++) - date[i] = *p; - - // Parse year - if (i == 6) { - // 2-digit year (1970-2069) - y = (date[0]-'0')*10 + (date[1]-'0'); - if (y < 70) y += 100; - } - else if (i == 8) { - // 4-digit year - y = (date[0]-'0')*1000 + (date[1]-'0')*100 + (date[2]-'0')*10 + date[3]-'0'; - y -= 1900; - } - else - return (time_t) 0; - timestamp.tm_year = y; - // Parse month - timestamp.tm_mon = (date[i-4]-'0')*10 + date[i-3]-'0' - 1; - // Parse date - timestamp.tm_mday = (date[i-2]-'0')*10 + date[i-1]-'0'; - - // Skip any date/time delimiter - for (; *p != '\0' && !isdigit(*p); p++); - - // Parse time - if (sscanf(p, "%d:%d:%d", &(timestamp.tm_hour), &(timestamp.tm_min), &(timestamp.tm_sec)) != 3) - return (time_t) 0; - - timestamp.tm_isdst = 0; // DST is already present in _timezone below - _tzset(); - t = mktime(×tamp); - t -= _timezone; - t = TlenTimeToUTC(t); - - if (t >= 0) - return t; - else - return (time_t) 0; -} - -void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) -{ - va_list vararg; - char *p; - int size, len; - - if (str == NULL) return; - - if (*str == NULL || *sizeAlloced <= 0) { - *sizeAlloced = size = 2048; - *str = (char *) mir_alloc(size); - len = 0; - } - else { - len = (int)strlen(*str); - size = *sizeAlloced - (int)strlen(*str); - } - - p = *str + len; - va_start(vararg, fmt); - while (mir_vsnprintf(p, size, fmt, vararg) == -1) { - size += 2048; - (*sizeAlloced) += 2048; - *str = (char *) mir_realloc(*str, *sizeAlloced); - p = *str + len; - } - va_end(vararg); -} - -BOOL IsAuthorized(TlenProtocol *proto, const char *jid) -{ - JABBER_LIST_ITEM *item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); - if (item != NULL) { - return item->subscription == SUB_BOTH || item->subscription == SUB_FROM; - } - return FALSE; -} - - -void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message) -{ - int size = (int)strlen(message) + 2; - char *localMessage = (char *)mir_alloc(size); - strcpy(localMessage, message); - localMessage[size - 1] = '\0'; - JabberDBAddEvent(proto, hContact, EVENTTYPE_MESSAGE, flags, (PBYTE)message, (DWORD)size); - mir_free(localMessage); -} diff --git a/protocols/Tlen/src/jabber_ws.cpp b/protocols/Tlen/src/jabber_ws.cpp deleted file mode 100644 index b1cb066d7a..0000000000 --- a/protocols/Tlen/src/jabber_ws.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -BOOL JabberWsInit(TlenProtocol *proto) -{ - NETLIBUSER nlu = {0}; - NETLIBUSERSETTINGS nlus = {0}; - TCHAR name[128]; - - - nlu.cbSize = sizeof(nlu); - nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_TCHAR; // | NUF_HTTPGATEWAY; - mir_sntprintf(name, SIZEOF(name), TranslateT("%s connection"), proto->m_tszUserName); - nlu.ptszDescriptiveName = name; - nlu.szSettingsModule = proto->m_szModuleName; - proto->hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); - - nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_NOOPTIONS | NUF_TCHAR; - mir_sntprintf(name, SIZEOF(name), TranslateT("%s SOCKS connection"), proto->m_tszUserName); - nlu.ptszDescriptiveName = name; - proto->hFileNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); - nlus.cbSize = sizeof(nlus); - nlus.useProxy = 0; - CallService(MS_NETLIB_SETUSERSETTINGS, (WPARAM) proto->hFileNetlibUser, (LPARAM) &nlus); - - return (proto->hNetlibUser != NULL)?TRUE:FALSE; -} - -void JabberWsUninit(TlenProtocol *proto) -{ - if (proto->hNetlibUser != NULL) Netlib_CloseHandle(proto->hNetlibUser); - if (proto->hFileNetlibUser != NULL) Netlib_CloseHandle(proto->hFileNetlibUser); - proto->hNetlibUser = NULL; - proto->hFileNetlibUser = NULL; -} - -JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port) -{ - NETLIBOPENCONNECTION nloc = {0}; - - nloc.cbSize = sizeof(NETLIBOPENCONNECTION); //NETLIBOPENCONNECTION_V1_SIZE; - nloc.szHost = host; - nloc.wPort = port; - nloc.flags = 0; - nloc.timeout = 6; - return (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) proto->hNetlibUser, (LPARAM) &nloc); -} - - -int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen) -{ - int len; - if ((len=Netlib_Send(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT)) == SOCKET_ERROR || len != datalen) { - JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); - return FALSE; - } - return TRUE; -} - -int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen) -{ - int ret; - ret = Netlib_Recv(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT); - if (ret == SOCKET_ERROR) { - JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); - return 0; - } - if (ret == 0) { - JabberLog(proto, "Connection closed gracefully"); - return 0; - } - return ret; -} - - -int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv) -{ - int len, sendlen; - unsigned char aes_input[16]; - unsigned char aes_output[256]; - if (proto->threadData == NULL) { - return FALSE; - } - while (datalen > 0) { - len = 0; - while (datalen > 0 && len < 256) { - int pad = datalen < 16 ? 16 - datalen : 0; - memcpy(aes_input, data, datalen < 16 ? datalen : 16); - memset(aes_input + 16 - pad, ' ', pad); - aes_crypt_cbc(aes_ctx, AES_ENCRYPT, 16, aes_iv, aes_input, aes_output + len); - datalen -= 16; - data += 16; - len += 16; - } - if (len > 0) { - JabberLog(proto, "Sending %d bytes", len); - if ((sendlen=Netlib_Send(proto->threadData->s, (char *)aes_output, len, MSG_NODUMP)) == SOCKET_ERROR || len != sendlen) { - JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); - return FALSE; - } - } - } - return TRUE; -} - -int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv) -{ - int ret, len = 0, maxlen = datalen; - unsigned char aes_input[16]; - unsigned char *aes_output = (unsigned char *)data; - if (proto->threadData == NULL) { - return 0; - } - for (maxlen = maxlen & ~0xF; maxlen != 0; maxlen = maxlen & 0xF) { - ret = Netlib_Recv(proto->threadData->s, data, maxlen, MSG_NODUMP); - if (ret == SOCKET_ERROR) { - JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); - return 0; - } - if (ret == 0) { - JabberLog(proto, "Connection closed gracefully"); - return 0; - } - data += ret; - len += ret; - maxlen -= ret; - } - - ret = len; - while (len > 15) { - memcpy(aes_input, aes_output, 16); - aes_crypt_cbc(aes_ctx, AES_DECRYPT, 16, aes_iv, aes_input, aes_output); - aes_output += 16; - len -= 16; - } - return ret; -} - diff --git a/protocols/Tlen/src/jabber_xml.cpp b/protocols/Tlen/src/jabber_xml.cpp deleted file mode 100644 index 5786404dc6..0000000000 --- a/protocols/Tlen/src/jabber_xml.cpp +++ /dev/null @@ -1,568 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include - -static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr); -static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child); - -void JabberXmlInitState(XmlState *xmlState) -{ - if (xmlState == NULL) return; - xmlState->root.name = NULL; - xmlState->root.depth = 0; - xmlState->root.numAttr = 0; - xmlState->root.maxNumAttr = 0; - xmlState->root.attr = NULL; - xmlState->root.numChild = 0; - xmlState->root.maxNumChild = 0; - xmlState->root.child = NULL; - xmlState->root.text = NULL; - xmlState->root.state = NODE_OPEN; - xmlState->callback1_open = NULL; - xmlState->callback1_close = NULL; - xmlState->callback2_open = NULL; - xmlState->callback2_close = NULL; - xmlState->userdata1_open = NULL; - xmlState->userdata1_close = NULL; - xmlState->userdata2_open = NULL; - xmlState->userdata2_close = NULL; -} - -void JabberXmlDestroyState(XmlState *xmlState) -{ - int i; - XmlNode *node; - - if (xmlState == NULL) return; - // Note: cannot use JabberXmlFreeNode() to free xmlState->root - // because it will do mir_free(xmlState->root) which is not freeable. - node = &(xmlState->root); - // Free all children first - for (i=0; inumChild; i++) - JabberXmlFreeNode(node->child[i]); - if (node->child) mir_free(node->child); - // Free all attributes - for (i=0; inumAttr; i++) { - if (node->attr[i]->name) mir_free(node->attr[i]->name); - if (node->attr[i]->value) mir_free(node->attr[i]->value); - mir_free(node->attr[i]); - } - if (node->attr) mir_free(node->attr); - // Free string field - if (node->text) mir_free(node->text); - if (node->name) mir_free(node->name); -} - -BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata) -{ - if (depth == 1 && type == ELEM_OPEN) { - xmlState->callback1_open = callback; - xmlState->userdata1_open = userdata; - } - else if (depth == 1 && type == ELEM_CLOSE) { - xmlState->callback1_close = callback; - xmlState->userdata1_close = userdata; - } - else if (depth == 2 && type == ELEM_OPEN) { - xmlState->callback2_open = callback; - xmlState->userdata2_open = userdata; - } - else if (depth == 2 && type == ELEM_CLOSE) { - xmlState->callback2_close = callback; - xmlState->userdata2_close = userdata; - } - else - return FALSE; - - return TRUE; -} - -#define TAG_MAX_LEN 50 -#define ATTR_MAX_LEN 1024 -int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen) -{ - char *p, *q, *r, *eob; - char *str; - int num; - char tag[TAG_MAX_LEN]; - char attr[ATTR_MAX_LEN]; - XmlElemType elemType = ELEM_OPEN; - - eob = buffer + datalen; - num = 0; - // Skip leading whitespaces - for (p=buffer; p TAG_MAX_LEN) { -// JabberLog("TAG_MAX_LEN too small, ignore current tag"); - } - else { - if (*(p+1) == '/') { // closing tag - strncpy(tag, p+2, r-(p+2)); - tag[r-(p+2)] = '\0'; - elemType = ELEM_CLOSE; - } - else { - if (*(r-1) == '/') { // single open/close tag - strncpy(tag, p+1, r-(p+1)-1); - tag[r-(p+1)-1] = '\0'; - elemType = ELEM_OPENCLOSE; - } - else { - strncpy(tag, p+1, r-(p+1)); - tag[r-(p+1)] = '\0'; - elemType = ELEM_OPEN; - } - } - for (;r ATTR_MAX_LEN) { -// JabberLog("ATTR_MAX_LEN too small, ignore current tag"); - } - else { - strncpy(attr, r, q-r); - if ((q-r)>0 && attr[q-r-1] == '/') { - attr[q-r-1] = '\0'; - elemType = ELEM_OPENCLOSE; - } - else - attr[q-r] = '\0'; - JabberXmlProcessElem(xmlState, elemType, tag, attr); - } - } - num += (q-p+1); - p = q + 1; - if (elemType == ELEM_CLOSE || elemType == ELEM_OPENCLOSE) { - // Skip whitespaces after end tags - for (; pnumAttr >= node->maxNumAttr) { - node->maxNumAttr = node->numAttr + 20; - node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *)); - } - a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - node->numAttr++; - - // Skip possible whitespaces between key and '=' - for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); - - if (*p == '\0') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - break; - } - - if (*p != '=') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - continue; - } - - // Found '=' - p++; - - // Skip possible whitespaces between '=' and value - for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); - - if (*p == '\0') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - break; - } - - // Fetch value - if (*p == '\'' || *p == '"') { - p++; - vstart = p; - for (;*p != '\0' && *p != *(vstart-1); p++); - vlen = p-vstart; - if (*p != '\0') p++; - } - else { - vstart = p; - for (;*p != '\0' && *p != ' ' && *p != '\t'; p++); - vlen = p-vstart; - } - - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = (char *) mir_alloc(vlen+1); - strncpy(a->value, vstart, vlen); - a->value[vlen] = '\0'; - } -} - -static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr) -{ - XmlNode *node, *parentNode, *n; - //BOOL activateCallback = FALSE; - char *text, *attr; - - if (elemText == NULL) return FALSE; - - if (elemType == ELEM_OPEN && !strcmp(elemText, "?xml")) { -// JabberLog("XML: skip tag"); - return TRUE; - } - - // Find active node - node = &(xmlState->root); - parentNode = NULL; - while (node->numChild>0 && node->child[node->numChild-1]->state == NODE_OPEN) { - parentNode = node; - node = node->child[node->numChild-1]; - } - - if (node->state != NODE_OPEN) return FALSE; - - text = mir_strdup(elemText); - - if (elemAttr) - attr = mir_strdup(elemAttr); - else - attr = NULL; - - switch (elemType) { - case ELEM_OPEN: - if (node->numChild >= node->maxNumChild) { - node->maxNumChild = node->numChild + 20; - node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); - } - n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - node->numChild++; - n->name = text; - n->depth = node->depth + 1; - n->state = NODE_OPEN; - n->numChild = n->maxNumChild = 0; - n->child = NULL; - n->numAttr = n->maxNumAttr = 0; - n->attr = NULL; - JabberXmlParseAttr(n, attr); - n->text = NULL; - if (n->depth == 1 && xmlState->callback1_open != NULL) - (*(xmlState->callback1_open))(n, xmlState->userdata1_open); - if (n->depth == 2 && xmlState->callback2_open != NULL) - (*xmlState->callback2_open)(n, xmlState->userdata2_open); - break; - case ELEM_OPENCLOSE: - if (node->numChild >= node->maxNumChild) { - node->maxNumChild = node->numChild + 20; - node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); - } - n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - node->numChild++; - n->name = text; - n->depth = node->depth + 1; - n->state = NODE_CLOSE; - n->numChild = n->maxNumAttr = 0; - n->child = NULL; - n->numAttr = n->maxNumAttr = 0; - n->attr = NULL; - JabberXmlParseAttr(n, attr); - n->text = NULL; - if (n->depth == 1 && xmlState->callback1_close != NULL) { - (*(xmlState->callback1_close))(n, xmlState->userdata1_close); - JabberXmlRemoveChild(node, n); - } - if (n->depth == 2 && xmlState->callback2_close != NULL) { - (*xmlState->callback2_close)(n, xmlState->userdata2_close); - JabberXmlRemoveChild(node, n); - } - break; - case ELEM_CLOSE: - if (node->name != NULL && !strcmp(node->name, text)) { - node->state = NODE_CLOSE; - if (node->depth == 1 && xmlState->callback1_close != NULL) { - (*(xmlState->callback1_close))(node, xmlState->userdata1_close); - JabberXmlRemoveChild(parentNode, node); - } - if (node->depth == 2 && xmlState->callback2_close != NULL) { - (*xmlState->callback2_close)(node, xmlState->userdata2_close); - JabberXmlRemoveChild(parentNode, node); - } - mir_free(text); - } - else { -// JabberLog("XML: Closing without opening tag", text); - mir_free(text); - if (attr) mir_free(attr); - return FALSE; - } - break; - case ELEM_TEXT: - node->text = text; - break; - default: - mir_free(text); - if (attr) mir_free(attr); - return FALSE; - } - - if (attr) mir_free(attr); - - return TRUE; -} - -char *JabberXmlGetAttrValue(XmlNode *node, char *key) -{ - int i; - - if (node == NULL || node->numAttr <= 0 || key == NULL || strlen(key) <= 0) - return NULL; - for (i=0; inumAttr; i++) { - if (node->attr[i]->name && !strcmp(key, node->attr[i]->name)) - return node->attr[i]->value; - } - return NULL; -} - -XmlNode *JabberXmlGetChild(XmlNode *node, char *tag) -{ - return JabberXmlGetNthChild(node, tag, 1); -} - -XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth) -{ - int i, num; - - if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || nth < 1) - return NULL; - num = 1; - for (i=0; inumChild; i++) { - if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { - if (num == nth) { - return node->child[i]; - } - num++; - } - } - return NULL; -} - -XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue) -{ - int i; - char *str; - - if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || attrKey == NULL || strlen(attrKey) <= 0 || attrValue == NULL || strlen(attrValue) <= 0) - return NULL; - for (i=0; inumChild; i++) { - if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { - if ((str=JabberXmlGetAttrValue(node->child[i], attrKey)) != NULL) - if (!strcmp(str, attrValue)) - return node->child[i]; - } - } - return NULL; -} - -static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child) -{ - int i; - - if (node == NULL || child == NULL || node->numChild <= 0) return; - for (i=0; inumChild; i++) { - if (node->child[i] == child) - break; - } - if (i < node->numChild) { - for (++i; inumChild; i++) - node->child[i-1] = node->child[i]; - node->numChild--; - JabberXmlFreeNode(child); - } -} - -void JabberXmlFreeNode(XmlNode *node) -{ - int i; - - if (node == NULL) return; - // Free all children first - for (i=0; inumChild; i++) - JabberXmlFreeNode(node->child[i]); - if (node->child) mir_free(node->child); - // Free all attributes - for (i=0; inumAttr; i++) { - if (node->attr[i]->name) mir_free(node->attr[i]->name); - if (node->attr[i]->value) mir_free(node->attr[i]->value); - mir_free(node->attr[i]); - } - if (node->attr) mir_free(node->attr); - // Free string field - if (node->text) mir_free(node->text); - if (node->name) mir_free(node->name); - // Free the node itself - mir_free(node); -} - -XmlNode *JabberXmlCopyNode(XmlNode *node) -{ - XmlNode *n; - int i; - - if (node == NULL) return NULL; - n = (XmlNode *) mir_alloc(sizeof(XmlNode)); - // Copy attributes - if (node->numAttr > 0) { - n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *)); - for (i=0; inumAttr; i++) { - n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name); - else n->attr[i]->name = NULL; - if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value); - else n->attr[i]->value = NULL; - } - } - else - n->attr = NULL; - // Recursively copy children - if (node->numChild > 0) { - n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *)); - for (i=0; inumChild; i++) - n->child[i] = JabberXmlCopyNode(node->child[i]); - } - else - n->child = NULL; - // Copy other fields - n->numAttr = node->numAttr; - n->maxNumAttr = node->numAttr; - n->numChild = node->numChild; - n->maxNumChild = node->numChild; - n->depth = node->depth; - n->state = node->state; - n->name = (node->name)?mir_strdup(node->name):NULL; - n->text = (node->text)?mir_strdup(node->text):NULL; - - return n; -} - -XmlNode *JabberXmlCreateNode(char *name) -{ - XmlNode *n; - - if (name == NULL) - return NULL; - - n = (XmlNode *) mir_alloc(sizeof(XmlNode)); - memset(n, 0, sizeof(XmlNode)); - n->name = mir_strdup(name); - return n; -} - -void JabberXmlAddAttr(XmlNode *n, char *name, char *value) -{ - int i; - - if (n == NULL || name == NULL || value == NULL) - return; - - i = n->numAttr; - (n->numAttr)++; - n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr); - n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - n->attr[i]->name = mir_strdup(name); - n->attr[i]->value = mir_strdup(value); -} - -XmlNode *JabberXmlAddChild(XmlNode *n, char *name) -{ - int i; - - if (n == NULL || name == NULL) - return NULL; - - i = n->numChild; - n->numChild++; - n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild); - n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - memset(n->child[i], 0, sizeof(XmlNode)); - n->child[i]->name = mir_strdup(name); - return n->child[i]; -} - -void JabberXmlAddText(XmlNode *n, char *text) -{ - if (n != NULL && text != NULL) { - if (n->text) mir_free(n->text); - n->text = mir_strdup(text); - } -} - diff --git a/protocols/Tlen/src/jabber_xml.h b/protocols/Tlen/src/jabber_xml.h deleted file mode 100644 index 165a8fadc5..0000000000 --- a/protocols/Tlen/src/jabber_xml.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _JABBER_XML_H_ -#define _JABBER_XML_H_ - -typedef enum { ELEM_OPEN, ELEM_CLOSE, ELEM_OPENCLOSE, ELEM_TEXT } XmlElemType; -typedef enum { NODE_OPEN, NODE_CLOSE } XmlNodeType; - -typedef struct tagXmlAttr { - char *name; - char *value; -} XmlAttr; - -typedef struct tagXmlNode { - int depth; // depth of the current node (1=root) - char *name; // tag name of the current node - int numAttr; // number of attributes - int maxNumAttr; // internal use (num of slots currently allocated to attr) - XmlAttr **attr; // attribute list - int numChild; // number of direct child nodes - int maxNumChild; // internal use (num of slots currently allocated to child) - struct tagXmlNode **child; // child node list - char *text; - XmlNodeType state; // internal use by parser -} XmlNode; - - -typedef struct tagXmlState { - XmlNode root; // root is the document (depth = 0); - // callback for depth=n element on opening/closing - void (*callback1_open)(XmlNode *,void *); - void (*callback1_close)(XmlNode *,void *); - void (*callback2_open)(XmlNode *,void *); - void (*callback2_close)(XmlNode *,void *); - void *userdata1_open; - void *userdata1_close; - void *userdata2_open; - void *userdata2_close; -} XmlState; - -void JabberXmlInitState(XmlState *xmlState); -void JabberXmlDestroyState(XmlState *xmlState); -BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata); -int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen); -char *JabberXmlGetAttrValue(XmlNode *node, char *key); -XmlNode *JabberXmlGetChild(XmlNode *node, char *tag); -XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth); -XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue); -void JabberXmlFreeNode(XmlNode *node); -XmlNode *JabberXmlCopyNode(XmlNode *node); - -XmlNode *JabberXmlCreateNode(char *name); -void JabberXmlAddAttr(XmlNode *n, char *name, char *value); -XmlNode *JabberXmlAddChild(XmlNode *n, char *name); -void JabberXmlAddText(XmlNode *n, char *text); - -#endif - diff --git a/protocols/Tlen/src/tlen.cpp b/protocols/Tlen/src/tlen.cpp index d03ad838b1..1206d4016c 100644 --- a/protocols/Tlen/src/tlen.cpp +++ b/protocols/Tlen/src/tlen.cpp @@ -21,12 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "commons.h" -#include "jabber.h" +#include "tlen.h" #include "tlen_muc.h" #include "tlen_file.h" #include "tlen_voice.h" -#include "jabber_list.h" -#include "jabber_iq.h" +#include "tlen_list.h" +#include "tlen_iq.h" #include "resource.h" #include "tlen_picture.h" #include @@ -53,7 +53,7 @@ PLUGININFOEX pluginInfoEx = { {0x748f8934, 0x781a, 0x528d, { 0x52, 0x08, 0x00, 0x12, 0x65, 0x40, 0x4a, 0xb3 }} }; -// Main jabber server connection thread global variables +// Main tlen server connection thread global variables BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved) { @@ -137,7 +137,7 @@ int TlenProtocol::PrebuildContactMenu(WPARAM wParam, LPARAM lParam) return 0; } -int TlenProtocol::ContactMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::ContactMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; if (hContact != NULL && isOnline) { @@ -150,7 +150,7 @@ int TlenProtocol::ContactMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam) return 0; } -int TlenProtocol::ContactMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::ContactMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; if (hContact != NULL && isOnline) { @@ -163,7 +163,7 @@ int TlenProtocol::ContactMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam) return 0; } -int TlenProtocol::ContactMenuHandleSendPicture(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::ContactMenuHandleSendPicture(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; if (hContact != NULL && isOnline) @@ -172,7 +172,7 @@ int TlenProtocol::ContactMenuHandleSendPicture(WPARAM wParam, LPARAM lParam) return 0; } -int TlenProtocol::MenuHandleInbox(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::MenuHandleInbox(WPARAM wParam, LPARAM lParam) { char szFileName[ MAX_PATH ]; DBVARIANT dbv; diff --git a/protocols/Tlen/src/tlen.h b/protocols/Tlen/src/tlen.h new file mode 100644 index 0000000000..c2caef4230 --- /dev/null +++ b/protocols/Tlen/src/tlen.h @@ -0,0 +1,520 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _JABBER_H_ +#define _JABBER_H_ + +#define MIRANDA_VER 0x0A00 + +#undef _WIN32_WINNT +#undef _WIN32_IE +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0501 + +#define __try +#define __except(x) if (0) +#define __finally + +#define _try __try +#define _except __except +#define _finally __finally + +#ifdef _DEBUG +#define _CRTDBG_MAP_ALLOC +#include +#include +#endif +#define ENABLE_LOGGING + +/******************************************************************* + * Global compilation flags + *******************************************************************/ + +/******************************************************************* + * Global header files + *******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tlen_xml.h" +#include "crypto/polarssl/aes.h" +#include "crypto/polarssl/bignum.h" + +/******************************************************************* + * Global constants + *******************************************************************/ +#define TLEN_DEFAULT_PORT 443 +#define JABBER_IQID "mim_" +#define TLEN_REGISTER "http://reg.tlen.pl/" +#define TLEN_MAX_SEARCH_RESULTS_PER_PAGE 20 + +// User-defined message +#define WM_TLEN_REFRESH (WM_USER + 100) +// Error code +#define JABBER_ERROR_REDIRECT 302 +#define JABBER_ERROR_BAD_REQUEST 400 +#define JABBER_ERROR_UNAUTHORIZED 401 +#define JABBER_ERROR_PAYMENT_REQUIRED 402 +#define JABBER_ERROR_FORBIDDEN 403 +#define JABBER_ERROR_NOT_FOUND 404 +#define JABBER_ERROR_NOT_ALLOWED 405 +#define JABBER_ERROR_NOT_ACCEPTABLE 406 +#define JABBER_ERROR_REGISTRATION_REQUIRED 407 +#define JABBER_ERROR_REQUEST_TIMEOUT 408 +#define JABBER_ERROR_CONFLICT 409 +#define JABBER_ERROR_INTERNAL_SERVER_ERROR 500 +#define JABBER_ERROR_NOT_IMPLEMENTED 501 +#define JABBER_ERROR_REMOTE_SERVER_ERROR 502 +#define JABBER_ERROR_SERVICE_UNAVAILABLE 503 +#define JABBER_ERROR_REMOTE_SERVER_TIMEOUT 504 + +#define TLEN_ALERTS_ACCEPT_ALL 0 +#define TLEN_ALERTS_IGNORE_NIR 1 +#define TLEN_ALERTS_IGNORE_ALL 2 + +#define TLEN_IMAGES_ACCEPT_ALL 0 +#define TLEN_IMAGES_IGNORE_NIR 1 +#define TLEN_IMAGES_IGNORE_ALL 2 + +#define TLEN_MUC_ASK 0 +#define TLEN_MUC_ACCEPT_IR 1 +#define TLEN_MUC_ACCEPT_ALL 2 +#define TLEN_MUC_IGNORE_NIR 3 +#define TLEN_MUC_IGNORE_ALL 4 + +#define IDC_STATIC (-1) + +/******************************************************************* + * Global data structures and data type definitions + *******************************************************************/ +typedef HANDLE JABBER_SOCKET; + +typedef enum { + LIST_ROSTER, // Roster list + LIST_CHATROOM, // Groupchat room currently joined + LIST_FILE, // Current file transfer session + LIST_INVITATIONS,// Invitations to be sent + LIST_SEARCH, // Rooms names being searched + LIST_VOICE, + LIST_PICTURE +} JABBER_LIST; + +typedef enum { + IQ_PROC_NONE, + IQ_PROC_GETSEARCH +} JABBER_IQ_PROCID; + +typedef enum { + SUB_NONE, + SUB_TO, + SUB_FROM, + SUB_BOTH +} JABBER_SUBSCRIPTION; + +typedef struct { + char *szOnline; + char *szAway; + char *szNa; + char *szDnd; + char *szFreechat; + char *szInvisible; +} JABBER_MODEMSGS; + +typedef struct { + char mailBase[256]; + char mailMsg[256]; + int mailMsgMthd; + char mailIndex[256]; + int mailIndexMthd; + char mailLogin[256]; + int mailLoginMthd; + char mailCompose[256]; + int mailComposeMthd; + char avatarGet[256]; + int avatarGetMthd; + char avatarUpload[256]; + int avatarUploadMthd; + char avatarRemove[256]; + int avatarRemoveMthd; +} TlenConfiguration; + +typedef struct { + BOOL useEncryption; + BOOL reconnect; + BOOL rosterSync; + BOOL offlineAsInvisible; + BOOL leaveOfflineMessage; + int offlineMessageOption; + BOOL ignoreAdvertisements; + int alertPolicy; + int groupChatPolicy; + int voiceChatPolicy; + int imagePolicy; + BOOL enableAvatars; + BOOL enableVersion; + BOOL useNudge; + BOOL logAlerts; + BOOL useNewP2P; + BOOL sendKeepAlive; + BOOL savePassword; +} TlenOptions; + + +struct JABBER_IQ_FUNC_STRUCT; +struct JABBER_LIST_ITEM_STRUCT; +struct TLEN_VOICE_CONTROL_STRUCT; + +struct TlenProtocol : public PROTO +{ + TlenProtocol( const char*, const TCHAR* ); + ~TlenProtocol(); + + //==================================================================================== + // PROTO_INTERFACE + //==================================================================================== + + virtual HANDLE __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ); + virtual HANDLE __cdecl AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ); + + virtual int __cdecl Authorize(HANDLE hDbEvent); + virtual int __cdecl AuthDeny(HANDLE hDbEvent, const PROTOCHAR* szReason); + virtual int __cdecl AuthRecv(HANDLE hContact, PROTORECVEVENT*); + virtual int __cdecl AuthRequest(HANDLE hContact, const PROTOCHAR* szMessage); + + virtual HANDLE __cdecl ChangeInfo(int iInfoType, void* pInfoData); + + virtual HANDLE __cdecl FileAllow(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath); + virtual int __cdecl FileCancel(HANDLE hContact, HANDLE hTransfer); + virtual int __cdecl FileDeny(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason); + virtual int __cdecl FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename); + + virtual DWORD_PTR __cdecl GetCaps(int type, HANDLE hContact = NULL); + virtual int __cdecl GetInfo(HANDLE hContact, int infoType); + + virtual HANDLE __cdecl SearchBasic(const PROTOCHAR* id); + virtual HANDLE __cdecl SearchByEmail(const PROTOCHAR* email); + virtual HANDLE __cdecl SearchByName(const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName); + virtual HWND __cdecl SearchAdvanced(HWND owner); + virtual HWND __cdecl CreateExtendedSearchUI(HWND owner); + + virtual int __cdecl RecvContacts(HANDLE hContact, PROTORECVEVENT*); + virtual int __cdecl RecvFile(HANDLE hContact, PROTOFILEEVENT*); + virtual int __cdecl RecvMsg(HANDLE hContact, PROTORECVEVENT*); + virtual int __cdecl RecvUrl(HANDLE hContact, PROTORECVEVENT*); + + virtual int __cdecl SendContacts(HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList); + virtual HANDLE __cdecl SendFile(HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles); + virtual int __cdecl SendMsg(HANDLE hContact, int flags, const char* msg); + virtual int __cdecl SendUrl(HANDLE hContact, int flags, const char* url); + + virtual int __cdecl SetApparentMode(HANDLE hContact, int mode); + virtual int __cdecl SetStatus(int iNewStatus); + + virtual HANDLE __cdecl GetAwayMsg(HANDLE hContact); + virtual int __cdecl RecvAwayMsg(HANDLE hContact, int mode, PROTORECVEVENT* evt); + virtual int __cdecl SendAwayMsg(HANDLE hContact, HANDLE hProcess, const char* msg); + virtual int __cdecl SetAwayMsg(int iStatus, const PROTOCHAR* msg); + + virtual int __cdecl UserIsTyping(HANDLE hContact, int type); + + virtual int __cdecl OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam); + + //==================================================================================== + // Services + + INT_PTR __cdecl GetName(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl GetAvatarInfo(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl SendAlert(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl GetAvatarCaps(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl SetMyAvatar(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl GetMyAvatar(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl GetStatus(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl AccMgrUI(WPARAM wParam, LPARAM lParam); + + INT_PTR __cdecl MUCMenuHandleChats(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl MUCMenuHandleMUC(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl MenuHandleInbox(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl ContactMenuHandleSendPicture(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl MUCContactMenuHandleMUC(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl VoiceContactMenuHandleVoice(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl ContactMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam); + INT_PTR __cdecl ContactMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam); + + //==================================================================================== + // Events + + int __cdecl OnModulesLoaded(WPARAM wParam, LPARAM lParam); + int __cdecl OptionsInit(WPARAM wParam, LPARAM lParam); + int __cdecl JabberDbSettingChanged(WPARAM wParam, LPARAM lParam); + int __cdecl JabberContactDeleted(WPARAM wParam, LPARAM lParam); + int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam); + int __cdecl PreShutdown(WPARAM wParam, LPARAM lParam); + + int __cdecl UserInfoInit(WPARAM wParam, LPARAM lParam); + + int __cdecl MUCHandleEvent(WPARAM wParam, LPARAM lParam); + + //==================================================================================== + HANDLE hNetlibUser; + HANDLE hFileNetlibUser; + + JABBER_MODEMSGS modeMsgs; + + struct ThreadDataStruct *threadData; + HANDLE hTlenNudge; + HGENMENU hMenuMUC; + HGENMENU hMenuChats; + HGENMENU hMenuInbox; + HGENMENU hMenuContactMUC; + HGENMENU hMenuContactVoice; + HGENMENU hMenuContactGrantAuth; + HGENMENU hMenuContactRequestAuth; + HGENMENU hMenuPicture; + + int listsCount; + struct JABBER_LIST_ITEM_STRUCT *lists; + CRITICAL_SECTION csLists; + + int iqCount; + int iqAlloced; + struct JABBER_IQ_FUNC_STRUCT *iqList; + CRITICAL_SECTION csIqList; + + CRITICAL_SECTION csSerial; + unsigned int serial; + BOOL isOnline; + BOOL isConnected; + + CRITICAL_SECTION modeMsgMutex; + + void initMenuItems(); + HGENMENU hMenuRoot; + + char *searchJID; + int searchID; + int searchIndex; + char *searchQuery; + int searchQueryLen; + + CRITICAL_SECTION csSend; + + HWND voiceDlgHWND; + struct TLEN_VOICE_CONTROL_STRUCT *playbackControl; + struct TLEN_VOICE_CONTROL_STRUCT *recordingControl; + int framesAvailableForPlayback; + int availOverrunValue; + + TlenOptions tlenOptions; + +}; + + + +typedef struct ThreadDataStruct{ + HANDLE hThread; + char *streamId; + char username[128]; + char password[128]; + char server[128]; + char manualHost[128]; + char avatarToken[128]; + char avatarHash[64]; + int avatarFormat; + WORD port; + BOOL useEncryption; + + JABBER_SOCKET s; //HANDLE from CallService(MS_NETLIB_OPENCONNECTION (jabber_ws.c:68) + aes_context aes_in_context; + aes_context aes_out_context; + unsigned char aes_in_iv[16]; + unsigned char aes_out_iv[16]; + + BOOL useAES; + TlenConfiguration tlenConfig; + TlenProtocol *proto; +} ThreadData; + + +typedef enum { FT_CONNECTING, FT_INITIALIZING, FT_RECEIVING, FT_DONE, FT_ERROR, FT_DENIED, FT_SWITCH } JABBER_FILE_STATE; +typedef enum { FT_RECV, FT_SEND} JABBER_FILE_MODE; +typedef struct TLEN_FILE_TRANSFER_STRUCT{ + HANDLE hContact; + JABBER_SOCKET s; + NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2; + JABBER_FILE_STATE state; + char *jid; + int fileId; + char *iqId; + int mode; + + // Used by file receiving only + char *hostName; + WORD wPort; + char *localName; + WORD wLocalPort; + char *szSavePath; + long fileReceivedBytes; + long fileTotalSize; + + // Used by file sending only + HANDLE hFileEvent; + int fileCount; + char **files; + long *filesSize; + //long fileTotalSize; // Size of the current file (file being sent) + long allFileTotalSize; + long allFileReceivedBytes; + char *szDescription; + int currentFile; + + // New p2p + BOOL newP2P; + char *id2; + SOCKET udps; + aes_context aes_context; + unsigned char aes_iv[16]; + TlenProtocol *proto; + +} TLEN_FILE_TRANSFER; + +typedef struct { + PROTOSEARCHRESULT hdr; + char jid[256]; +} JABBER_SEARCH_RESULT; + +typedef struct { + char *iqId; + PROTOSEARCHRESULT hdr; + char jid[256]; +} TLEN_CONFERENCE; + + +typedef struct { + int id; + TCHAR *name; +} JABBER_FIELD_MAP; + + +/******************************************************************* + * Global variables + *******************************************************************/ +extern HINSTANCE hInst; +extern HANDLE hMainThread; + +/******************************************************************* + * Function declarations + *******************************************************************/ +void uninitMenuItems(TlenProtocol *proto); +HICON GetIcolibIcon(int iconId); +void ReleaseIcolibIcon(HICON hIcon); + +void JabberLog(TlenProtocol *proto, const char *fmt, ...); +void __cdecl JabberServerThread(ThreadData *info); +// jabber_ws.cpp +BOOL JabberWsInit(TlenProtocol *proto); +void JabberWsUninit(TlenProtocol *proto); +JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port); +int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen); +int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen); +int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv); +int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv); + +// jabber_util.cpp +void JabberSerialInit(TlenProtocol *proto); +void JabberSerialUninit(TlenProtocol *proto); +unsigned int JabberSerialNext(TlenProtocol *proto); +int JabberSend(TlenProtocol *proto, const char *fmt, ...); +HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid); +char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact); +char *JabberLoginFromJID(const char *jid); +char *JabberResourceFromJID(const char *jid); +char *JabberNickFromJID(const char *jid); +char *JabberLocalNickFromJID(const char *jid); +char *TlenGroupEncode(const char *str); +char *TlenGroupDecode(const char *str); +char *JabberSha1(char *str); +char *TlenSha1(char *str, int len); +char *TlenPasswordHash(const char *str); +void TlenUrlDecode(char *str); +char *TlenUrlEncode(const char *str); +char *JabberTextEncode(const char *str); +char *JabberTextDecode(const char *str); +void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message); +BOOL IsAuthorized(TlenProtocol *proto, const char *jid); +//char *JabberGetVersionText(); +time_t JabberIsoToUnixTime(char *stamp); +time_t TlenTimeToUTC(time_t time); +void JabberSendPresence(TlenProtocol *proto,int status); +void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...); +//char *JabberGetClientJID(char *jid); +// jabber_misc.cpp +void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob); +void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick); +HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary); +void JabberContactListCreateGroup(char *groupName); +unsigned long JabberForkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg); +// jabber_svc.cpp +int TlenRunSearch(TlenProtocol *proto); +// jabber_opt.cpp +void TlenLoadOptions(TlenProtocol *proto); +// tlen_voice.cpp +int TlenVoiceCancelAll(TlenProtocol *proto); +// jabber_advsearch.cpp +extern JABBER_FIELD_MAP tlenFieldGender[]; +extern JABBER_FIELD_MAP tlenFieldLookfor[]; +extern JABBER_FIELD_MAP tlenFieldStatus[]; +extern JABBER_FIELD_MAP tlenFieldOccupation[]; +extern JABBER_FIELD_MAP tlenFieldPlan[]; +// tlen_advsearch.cpp +INT_PTR CALLBACK TlenAdvSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +char *TlenAdvSearchCreateQuery(HWND hwndDlg, int iqId); + + +#endif diff --git a/protocols/Tlen/src/tlen_advsearch.cpp b/protocols/Tlen/src/tlen_advsearch.cpp index 5a338a3bd6..92611ac126 100644 --- a/protocols/Tlen/src/tlen_advsearch.cpp +++ b/protocols/Tlen/src/tlen_advsearch.cpp @@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" +#include "tlen.h" #include "resource.h" static void InitComboBox(HWND hwndCombo, JABBER_FIELD_MAP *fieldMap) diff --git a/protocols/Tlen/src/tlen_avatar.cpp b/protocols/Tlen/src/tlen_avatar.cpp index 340be5869c..a55c0321f0 100644 --- a/protocols/Tlen/src/tlen_avatar.cpp +++ b/protocols/Tlen/src/tlen_avatar.cpp @@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" -#include "jabber_list.h" +#include "tlen.h" +#include "tlen_list.h" #include "tlen_avatar.h" #include #include diff --git a/protocols/Tlen/src/tlen_file.cpp b/protocols/Tlen/src/tlen_file.cpp index d45b2b014f..81bbbf298f 100644 --- a/protocols/Tlen/src/tlen_file.cpp +++ b/protocols/Tlen/src/tlen_file.cpp @@ -19,12 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" +#include "tlen.h" #include #include #include #include -#include "jabber_list.h" +#include "tlen_list.h" #include "tlen_p2p_old.h" static void TlenFileReceiveParse(TLEN_FILE_TRANSFER *ft) diff --git a/protocols/Tlen/src/tlen_file.h b/protocols/Tlen/src/tlen_file.h index 1cd0704ea5..170c1b75ec 100644 --- a/protocols/Tlen/src/tlen_file.h +++ b/protocols/Tlen/src/tlen_file.h @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define _TLEN_FILE_H_ #include -#include "jabber.h" +#include "tlen.h" extern int TlenFileCancelAll(TlenProtocol *proto); extern void TlenProcessF(XmlNode *node, ThreadData *userdata); diff --git a/protocols/Tlen/src/tlen_iq.cpp b/protocols/Tlen/src/tlen_iq.cpp new file mode 100644 index 0000000000..2b3431165e --- /dev/null +++ b/protocols/Tlen/src/tlen_iq.cpp @@ -0,0 +1,114 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include "tlen_iq.h" + + +void JabberIqInit(TlenProtocol *proto) +{ + InitializeCriticalSection(&proto->csIqList); + proto->iqList = NULL; + proto->iqCount = 0; + proto->iqAlloced = 0; +} + +void JabberIqUninit(TlenProtocol *proto) +{ + if (proto->iqList) mir_free(proto->iqList); + proto->iqList = NULL; + proto->iqCount = 0; + proto->iqAlloced = 0; + DeleteCriticalSection(&proto->csIqList); +} + +static void JabberIqRemove(TlenProtocol *proto, int index) +{ + EnterCriticalSection(&proto->csIqList); + if (index >= 0 && indexiqCount) { + memmove(proto->iqList+index, proto->iqList+index+1, sizeof(JABBER_IQ_FUNC)*(proto->iqCount-index-1)); + proto->iqCount--; + } + LeaveCriticalSection(&proto->csIqList); +} + +static void JabberIqExpire(TlenProtocol *proto) +{ + int i; + time_t expire; + + EnterCriticalSection(&proto->csIqList); + expire = time(NULL) - 120; // 2 minute + i = 0; + while (i < proto->iqCount) { + if (proto->iqList[i].requestTime < expire) + JabberIqRemove(proto, i); + else + i++; + } + LeaveCriticalSection(&proto->csIqList); +} + +JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId) +{ + int i; + JABBER_IQ_PFUNC res; + + EnterCriticalSection(&proto->csIqList); + JabberIqExpire(proto); + for (i=0; iiqCount && proto->iqList[i].iqId != iqId; i++); + if (i < proto->iqCount) { + res = proto->iqList[i].func; + JabberIqRemove(proto, i); + } + else { + res = (JABBER_IQ_PFUNC) NULL; + } + LeaveCriticalSection(&proto->csIqList); + return res; +} + +void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func) +{ + int i; + + EnterCriticalSection(&proto->csIqList); + if (procId == IQ_PROC_NONE) + i = proto->iqCount; + else + for (i=0; iiqCount && proto->iqList[i].procId != procId; i++); + + if (i >= proto->iqCount && proto->iqCount >= proto->iqAlloced) { + proto->iqAlloced = proto->iqCount + 8; + proto->iqList = (JABBER_IQ_FUNC*)mir_realloc(proto->iqList, sizeof(JABBER_IQ_FUNC)*proto->iqAlloced); + } + + if (proto->iqList != NULL) { + proto->iqList[i].iqId = iqId; + proto->iqList[i].procId = procId; + proto->iqList[i].func = func; + proto->iqList[i].requestTime = time(NULL); + if (i == proto->iqCount) proto->iqCount++; + } + LeaveCriticalSection(&proto->csIqList); +} + diff --git a/protocols/Tlen/src/tlen_iq.h b/protocols/Tlen/src/tlen_iq.h new file mode 100644 index 0000000000..35be984430 --- /dev/null +++ b/protocols/Tlen/src/tlen_iq.h @@ -0,0 +1,61 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef _JABBER_IQ_H_ +#define _JABBER_IQ_H_ + +#include "tlen_xml.h" +#include "tlen.h" + +typedef void (*JABBER_IQ_PFUNC)(TlenProtocol *proto, XmlNode *iqNode); + +typedef struct JABBER_IQ_FUNC_STRUCT { + int iqId; // id to match IQ get/set with IQ result + JABBER_IQ_PROCID procId; // must be unique in the list, except for IQ_PROC_NONE which can have multiple entries + JABBER_IQ_PFUNC func; // callback function + time_t requestTime; // time the request was sent, used to remove relinquent entries +} JABBER_IQ_FUNC; + +void JabberIqInit(TlenProtocol *proto); +void JabberIqUninit(TlenProtocol *proto); +JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId); +void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func); + +void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode); +void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode); +void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode); + +void TlenIqResultChatGroups(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultChatRooms(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultUserRooms(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultUserNicks(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultRoomSearch(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultRoomInfo(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultChatRoomUsers(TlenProtocol *proto, XmlNode *iqNode); +//void JabberIqResultSetPassword(XmlNode *iqNode, void *userdata); + +#endif + diff --git a/protocols/Tlen/src/tlen_iqid.cpp b/protocols/Tlen/src/tlen_iqid.cpp new file mode 100644 index 0000000000..87893e2fc5 --- /dev/null +++ b/protocols/Tlen/src/tlen_iqid.cpp @@ -0,0 +1,615 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include "resource.h" +#include "tlen_list.h" +#include "tlen_iq.h" +#include "tlen_muc.h" + +void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode) +{ + char *type; + + // RECVED: authentication result + // ACTION: if successfully logged in, continue by requesting roster list and set my initial status + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + + if (!strcmp(type, "result")) { + DBVARIANT dbv; + + if (db_get(NULL, proto->m_szModuleName, "Nick", &dbv)) + db_set_s(NULL, proto->m_szModuleName, "Nick", proto->threadData->username); + else + db_free(&dbv); +// iqId = JabberSerialNext(); +// JabberIqAdd(iqId, IQ_PROC_NONE, JabberIqResultGetRoster); +// JabberSend(info, "", iqId); + + JabberSend(proto, ""); + JabberSend(proto, ""); + } + // What to do if password error? etc... + else if (!strcmp(type, "error")) { + char text[128]; + + JabberSend(proto, ""); + mir_snprintf(text, sizeof(text), "%s %s@%s.", TranslateT("Authentication failed for"), proto->threadData->username, proto->threadData->server); + MessageBoxA(NULL, text, Translate("Tlen Authentication"), MB_OK|MB_ICONSTOP|MB_SETFOREGROUND); + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_WRONGPASSWORD); + proto->threadData = NULL; // To disallow auto reconnect + } +} + +void JabberResultSetRoster(TlenProtocol *proto, XmlNode *queryNode) { + DBVARIANT dbv; + XmlNode *itemNode, *groupNode; + JABBER_LIST_ITEM *item; + HANDLE hContact; + char *jid, *name, *nick; + int i; + char *str; + + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + str = JabberXmlGetAttrValue(itemNode, "subscription"); + if (!strcmp(str, "remove")) { + if ((hContact=JabberHContactFromJID(proto, jid)) != NULL) { + if (db_get_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + db_set_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); + } + JabberListRemove(proto, LIST_ROSTER, jid); + } else { + item = JabberListAdd(proto, LIST_ROSTER, jid); + if (item != NULL) { + if (str == NULL) item->subscription = SUB_NONE; + else if (!strcmp(str, "both")) item->subscription = SUB_BOTH; + else if (!strcmp(str, "to")) item->subscription = SUB_TO; + else if (!strcmp(str, "from")) item->subscription = SUB_FROM; + else item->subscription = SUB_NONE; + if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { + nick = JabberTextDecode(name); + } else { + nick = JabberLocalNickFromJID(jid); + } + if (nick != NULL) { + if (item->nick) mir_free(item->nick); + item->nick = nick; + + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + // Received roster has a new JID. + // Add the jid (with empty resource) to Miranda contact list. + hContact = JabberDBCreateContact(proto, jid, nick, FALSE); + } + db_set_s(hContact, "CList", "MyHandle", nick); + if (item->group) mir_free(item->group); + if ((groupNode=JabberXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { + item->group = TlenGroupDecode(groupNode->text); + JabberContactListCreateGroup(item->group); + // Don't set group again if already correct, or Miranda may show wrong group count in some case + if (!db_get(hContact, "CList", "Group", &dbv)) { + if (strcmp(dbv.pszVal, item->group)) + db_set_s(hContact, "CList", "Group", item->group); + db_free(&dbv); + } else + db_set_s(hContact, "CList", "Group", item->group); + } else { + item->group = NULL; + db_unset(hContact, "CList", "Group"); + } + } + } + } + } + } + } +} + +void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode; + char *type; + char *str; + + // RECVED: roster information + // ACTION: populate LIST_ROSTER and create contact for any new rosters + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + + if (!strcmp(type, "result")) { + str = JabberXmlGetAttrValue(queryNode, "xmlns"); + if (str != NULL && !strcmp(str, "jabber:iq:roster")) { + DBVARIANT dbv; + XmlNode *itemNode, *groupNode; + JABBER_SUBSCRIPTION sub; + JABBER_LIST_ITEM *item; + char *jid, *name, *nick; + int i, oldStatus; + + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + str = JabberXmlGetAttrValue(itemNode, "subscription"); + if (str == NULL) sub = SUB_NONE; + else if (!strcmp(str, "both")) sub = SUB_BOTH; + else if (!strcmp(str, "to")) sub = SUB_TO; + else if (!strcmp(str, "from")) sub = SUB_FROM; + else sub = SUB_NONE; + //if (str != NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) + nick = JabberTextDecode(name); + else + nick = JabberLocalNickFromJID(jid); + + if (nick != NULL) { + HANDLE hContact; + item = JabberListAdd(proto, LIST_ROSTER, jid); + if (item->nick) mir_free(item->nick); + item->nick = nick; + item->subscription = sub; + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + // Received roster has a new JID. + // Add the jid (with empty resource) to Miranda contact list. + hContact = JabberDBCreateContact(proto, jid, nick, FALSE); + } + db_set_s(hContact, "CList", "MyHandle", nick); + if (item->group) mir_free(item->group); + if ((groupNode=JabberXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { + item->group = TlenGroupDecode(groupNode->text); + JabberContactListCreateGroup(item->group); + // Don't set group again if already correct, or Miranda may show wrong group count in some case + if (!db_get(hContact, "CList", "Group", &dbv)) { + if (strcmp(dbv.pszVal, item->group)) + db_set_s(hContact, "CList", "Group", item->group); + db_free(&dbv); + } + else db_set_s(hContact, "CList", "Group", item->group); + } + else { + item->group = NULL; + db_unset(hContact, "CList", "Group"); + } + if (!db_get(hContact, proto->m_szModuleName, "AvatarHash", &dbv)) { + if (item->avatarHash) mir_free(item->avatarHash); + item->avatarHash = mir_strdup(dbv.pszVal); + JabberLog(proto, "Setting hash [%s] = %s", nick, item->avatarHash); + db_free(&dbv); + } + item->avatarFormat = db_get_dw(hContact, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); + } + } + } + } + + // Delete orphaned contacts (if roster sync is enabled) + if (db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE) == TRUE) { + for (HANDLE hContact = db_find_first(proto->m_szModuleName); hContact; ) { + HANDLE hNext = hContact = db_find_next(hContact, proto->m_szModuleName); + ptrA jid( db_get_sa(hContact, proto->m_szModuleName, "jid")); + if (jid != NULL) { + if (!JabberListExist(proto, LIST_ROSTER, jid)) { + JabberLog(proto, "Syncing roster: deleting 0x%x", hContact); + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + } + } + hContact = hNext; + } + } + + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_FLAGS; + Menu_ModifyItem(proto->hMenuMUC, &mi); + if (proto->hMenuChats != NULL) + Menu_ModifyItem(proto->hMenuChats, &mi); + + proto->isOnline = TRUE; + JabberLog(proto, "Status changed via THREADSTART"); + oldStatus = proto->m_iStatus; + JabberSendPresence(proto, proto->m_iDesiredStatus); + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->m_iStatus); + } + } +} + + +// Tlen actually use jabber:iq:search for other users vCard or jabber:iq:register for own vCard +void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode, *itemNode, *n; + char *type, *jid; + char text[128]; + HANDLE hContact; + char *nText; + +// JabberLog(" iqIdGetVcard (tlen)"); + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + + if (!strcmp(type, "result")) { + BOOL hasFirst, hasLast, hasNick, hasEmail, hasCity, hasAge, hasGender, hasSchool, hasLookFor, hasOccupation; + DBVARIANT dbv; + int i; + + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + if ((itemNode=JabberXmlGetChild(queryNode, "item")) == NULL) return; + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv)) return; + if (strchr(jid, '@') != NULL) { + mir_snprintf(text, SIZEOF(text), "%s", jid); + } else { + mir_snprintf(text, SIZEOF(text), "%s@%s", jid, dbv.pszVal); // Add @tlen.pl + } + db_free(&dbv); + if ((hContact=JabberHContactFromJID(proto, text)) == NULL) { + if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv)) return; + if (strcmp(dbv.pszVal, jid)) { + db_free(&dbv); + return; + } + db_free(&dbv); + } + } else { + hContact = NULL; + } + hasFirst = hasLast = hasNick = hasEmail = hasCity = hasAge = hasGender = hasOccupation = hasLookFor = hasSchool = FALSE; + for (i=0; inumChild; i++) { + n = itemNode->child[i]; + if (n == NULL || n->name == NULL) continue; + if (!strcmp(n->name, "first")) { + if (n->text != NULL) { + hasFirst = TRUE; + nText = JabberTextDecode(n->text); + db_set_s(hContact, proto->m_szModuleName, "FirstName", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "last")) { + if (n->text != NULL) { + hasLast = TRUE; + nText = JabberTextDecode(n->text); + db_set_s(hContact, proto->m_szModuleName, "LastName", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "nick")) { + if (n->text != NULL) { + hasNick = TRUE; + nText = JabberTextDecode(n->text); + db_set_s(hContact, proto->m_szModuleName, "Nick", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "email")) { + if (n->text != NULL) { + hasEmail = TRUE; + nText = JabberTextDecode(n->text); + db_set_s(hContact, proto->m_szModuleName, "e-mail", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "c")) { + if (n->text != NULL) { + hasCity = TRUE; + nText = JabberTextDecode(n->text); + db_set_s(hContact, proto->m_szModuleName, "City", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "b")) { + if (n->text != NULL) { + WORD nAge; + hasAge = TRUE; + nAge = atoi(n->text); + db_set_w(hContact, proto->m_szModuleName, "Age", nAge); + } + } + else if (!strcmp(n->name, "s")) { + if (n->text != NULL && n->text[1] == '\0' && (n->text[0] == '1' || n->text[0] == '2')) { + hasGender = TRUE; + db_set_b(hContact, proto->m_szModuleName, "Gender", (BYTE) (n->text[0] == '1'?'M':'F')); + } + } + else if (!strcmp(n->name, "e")) { + if (n->text != NULL) { + hasSchool = TRUE; + nText = JabberTextDecode(n->text); + db_set_s(hContact, proto->m_szModuleName, "School", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "j")) { + if (n->text != NULL) { + WORD nOccupation; + hasOccupation = TRUE; + nOccupation = atoi(n->text); + db_set_w(hContact, proto->m_szModuleName, "Occupation", nOccupation); + } + } + else if (!strcmp(n->name, "r")) { + if (n->text != NULL) { + WORD nLookFor; + hasLookFor = TRUE; + nLookFor = atoi(n->text); + db_set_w(hContact, proto->m_szModuleName, "LookingFor", nLookFor); + } + } + else if (!strcmp(n->name, "g")) { // voice chat enabled + if (n->text != NULL) { + BYTE bVoice; + bVoice = atoi(n->text); + db_set_w(hContact, proto->m_szModuleName, "VoiceChat", bVoice); + } + } + else if (!strcmp(n->name, "v")) { // status visibility + if (n->text != NULL) { + BYTE bPublic; + bPublic = atoi(n->text); + db_set_w(hContact, proto->m_szModuleName, "PublicStatus", bPublic); + } + } + } + if (!hasFirst) + db_unset(hContact, proto->m_szModuleName, "FirstName"); + if (!hasLast) + db_unset(hContact, proto->m_szModuleName, "LastName"); + // We are not removing "Nick" +// if (!hasNick) +// db_unset(hContact, m_szModuleName, "Nick"); + if (!hasEmail) + db_unset(hContact, proto->m_szModuleName, "e-mail"); + if (!hasCity) + db_unset(hContact, proto->m_szModuleName, "City"); + if (!hasAge) + db_unset(hContact, proto->m_szModuleName, "Age"); + if (!hasGender) + db_unset(hContact, proto->m_szModuleName, "Gender"); + if (!hasSchool) + db_unset(hContact, proto->m_szModuleName, "School"); + if (!hasOccupation) + db_unset(hContact, proto->m_szModuleName, "Occupation"); + if (!hasLookFor) + db_unset(hContact, proto->m_szModuleName, "LookingFor"); + ProtoBroadcastAck(proto->m_szModuleName, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0); + } +} + +void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode, *itemNode, *n; + char *type, *jid, *str; + int id, i, found; + JABBER_SEARCH_RESULT jsr = {0}; + DBVARIANT dbv = {0}; + + found = 0; +// JabberLog(" iqIdGetSearch"); + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + if ((str=JabberXmlGetAttrValue(iqNode, "id")) == NULL) return; + id = atoi(str+strlen(JABBER_IQID)); + + if (!strcmp(type, "result")) { + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + if (!db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { + jsr.hdr.cbSize = sizeof(JABBER_SEARCH_RESULT); + jsr.hdr.flags = PSR_TCHAR; + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if (strchr(jid, '@') != NULL) { + mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s", jid); + } else { + mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", jid, dbv.pszVal); + } + jsr.jid[sizeof(jsr.jid)-1] = '\0'; + jsr.hdr.id = mir_a2t(jid); + if ((n=JabberXmlGetChild(itemNode, "nick")) != NULL && n->text != NULL){ + char* buf = JabberTextDecode(n->text); + jsr.hdr.nick = mir_a2t(buf); + mir_free(buf); + } else { + jsr.hdr.nick = mir_tstrdup(TEXT("")); + } + if ((n=JabberXmlGetChild(itemNode, "first")) != NULL && n->text != NULL){ + char* buf = JabberTextDecode(n->text); + jsr.hdr.firstName = mir_a2t(buf); + mir_free(buf); + } else { + jsr.hdr.firstName = mir_tstrdup(TEXT("")); + } + if ((n=JabberXmlGetChild(itemNode, "last")) != NULL && n->text != NULL){ + char* buf = JabberTextDecode(n->text); + jsr.hdr.lastName = mir_a2t(buf); + mir_free(buf); + } else { + jsr.hdr.lastName = mir_tstrdup(TEXT("")); + } + if ((n=JabberXmlGetChild(itemNode, "email"))!=NULL && n->text!=NULL){ + char* buf = JabberTextDecode(n->text); + jsr.hdr.email = mir_a2t(buf); + mir_free(buf); + } else { + jsr.hdr.email = mir_tstrdup(TEXT("")); + } + + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); + found = 1; + mir_free(jsr.hdr.id); + mir_free(jsr.hdr.nick); + mir_free(jsr.hdr.firstName); + mir_free(jsr.hdr.lastName); + mir_free(jsr.hdr.email); + } + } + } + if (proto->searchJID != NULL) { + if (!found) { + if (strchr(proto->searchJID, '@') != NULL) { + mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s", proto->searchJID); + } else { + mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", proto->searchJID, dbv.pszVal); + } + jsr.jid[sizeof(jsr.jid)-1] = '\0'; + jsr.hdr.nick = mir_tstrdup(TEXT("")); + jsr.hdr.firstName = mir_tstrdup(TEXT("")); + jsr.hdr.lastName = mir_tstrdup(TEXT("")); + jsr.hdr.email = mir_tstrdup(TEXT("")); + jsr.hdr.id = mir_tstrdup(TEXT("")); + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); + mir_free(jsr.hdr.nick); + mir_free(jsr.hdr.firstName); + mir_free(jsr.hdr.lastName); + mir_free(jsr.hdr.email); + } + mir_free(proto->searchJID); + proto->searchJID = NULL; + } + db_free(&dbv); + } + found = 0; + if (queryNode->numChild == TLEN_MAX_SEARCH_RESULTS_PER_PAGE) { + found = TlenRunSearch(proto); + } + if (!found) { + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); + } + } else if (!strcmp(type, "error")) { + // ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE) id, 0); + // There is no ACKRESULT_FAILED for ACKTYPE_SEARCH :) look at findadd.c + // So we will just send a SUCCESS + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); + } +} + + +void GetConfigItem(XmlNode *node, char *dest, BOOL bMethod, int *methodDest) { + strcpy(dest, node->text); + TlenUrlDecode(dest); + if (bMethod) { + char *method = JabberXmlGetAttrValue(node, "method"); + if (method != NULL && !strcmpi(method, "POST")) { + *methodDest = REQUEST_POST; + } else { + *methodDest = REQUEST_GET; + } + } +} + +void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode, *miniMailNode, *node; + char *type; + + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + if (!strcmp(type, "result")) { + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + if ((miniMailNode=JabberXmlGetChild(queryNode, "mini-mail")) == NULL) return; + if ((node=JabberXmlGetChild(miniMailNode, "base")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailBase, FALSE, NULL); + } + if ((node=JabberXmlGetChild(miniMailNode, "msg")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailMsg, TRUE, &proto->threadData->tlenConfig.mailMsgMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "index")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailIndex, TRUE, &proto->threadData->tlenConfig.mailIndexMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "login")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailLogin, TRUE, &proto->threadData->tlenConfig.mailLoginMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "compose")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailCompose, TRUE, &proto->threadData->tlenConfig.mailComposeMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "avatar-get")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.avatarGet, TRUE, &proto->threadData->tlenConfig.avatarGetMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "avatar-upload")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.avatarUpload, TRUE, &proto->threadData->tlenConfig.avatarUploadMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "avatar-remove")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.avatarRemove, TRUE, &proto->threadData->tlenConfig.avatarRemoveMthd); + } + } +} + +void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); + if (queryNode != NULL) { + char* from; + if (( from=JabberXmlGetAttrValue( iqNode, "from" )) != NULL ) { + JABBER_LIST_ITEM *item; + if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) != NULL) { + HANDLE hContact; + XmlNode *n; + if ( item->software ) mir_free( item->software ); + if ( item->version ) mir_free( item->version ); + if ( item->system ) mir_free( item->system ); + if (( n=JabberXmlGetChild( queryNode, "name" )) != NULL && n->text ) { + item->software = JabberTextDecode( n->text ); + } else + item->software = NULL; + if (( n=JabberXmlGetChild( queryNode, "version" )) != NULL && n->text ) + item->version = JabberTextDecode( n->text ); + else + item->version = NULL; + if (( n=JabberXmlGetChild( queryNode, "os" )) != NULL && n->text ) + item->system = JabberTextDecode( n->text ); + else + item->system = NULL; + if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { + if (item->software != NULL) { + db_set_s(hContact, proto->m_szModuleName, "MirVer", item->software); + } else { + db_unset(hContact, proto->m_szModuleName, "MirVer"); + } + } + } + } + } +} + +void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); + if (queryNode != NULL) { + char* from; + if (( from=JabberXmlGetAttrValue( queryNode, "from" )) != NULL ) { + JABBER_LIST_ITEM *item; + if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) != NULL) { + HANDLE hContact; + XmlNode *version = JabberXmlGetChild(queryNode, "version"); + item->protocolVersion = JabberTextDecode(version->text); + if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { + if (item->software == NULL) { + char str[128]; + mir_snprintf(str, sizeof(str), "Tlen Protocol %s", item->protocolVersion); + db_set_s(hContact, proto->m_szModuleName, "MirVer", str); + } + } + } + } + } +} + diff --git a/protocols/Tlen/src/tlen_list.cpp b/protocols/Tlen/src/tlen_list.cpp new file mode 100644 index 0000000000..7010a8e101 --- /dev/null +++ b/protocols/Tlen/src/tlen_list.cpp @@ -0,0 +1,315 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include "tlen_list.h" + + +static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item); + +void JabberListInit(TlenProtocol *proto) +{ + proto->lists = NULL; + proto->listsCount = 0; + InitializeCriticalSection(&proto->csLists); +} + +void JabberListUninit(TlenProtocol *proto) +{ + JabberListWipe(proto); + DeleteCriticalSection(&proto->csLists); +} + +void JabberListWipe(TlenProtocol *proto) +{ + int i; + + EnterCriticalSection(&proto->csLists); + for (i=0; ilistsCount; i++) + JabberListFreeItemInternal(&(proto->lists[i])); + if (proto->lists != NULL) { + mir_free(proto->lists); + proto->lists = NULL; + } + proto->listsCount=0; + LeaveCriticalSection(&proto->csLists); +} + +void JabberListWipeSpecial(TlenProtocol *proto) +{ + int i; + EnterCriticalSection(&proto->csLists); + for (i=0; ilistsCount; i++) { + if (proto->lists[i].list != LIST_FILE && proto->lists[i].list != LIST_VOICE) { + JabberListFreeItemInternal(&(proto->lists[i])); + proto->listsCount--; + memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); + i--; + } + } + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); + LeaveCriticalSection(&proto->csLists); +} + +static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item) +{ + if (item == NULL) + return; + + if (item->jid) mir_free(item->jid); + if (item->nick) mir_free(item->nick); + if (item->statusMessage) mir_free(item->statusMessage); + if (item->group) mir_free(item->group); + if (item->messageEventIdStr) mir_free(item->messageEventIdStr); +// if (item->type) mir_free(item->type); + //if (item->ft) JabberFileFreeFt(item->ft); // No need to free (it is always free when exit from JabberFileServerThread()) + if (item->roomName) mir_free(item->roomName); + if (item->version) mir_free(item->version); + if (item->software) mir_free(item->software); + if (item->system) mir_free(item->system); + if (item->avatarHash) mir_free(item->avatarHash); + + if (item->protocolVersion) mir_free(item->protocolVersion); + if (item->id2) mir_free(item->id2); +} + +static char * GetItemId(JABBER_LIST list, const char *jid) +{ + char *s, *p, *q; + s = mir_strdup(jid); + if (list != LIST_PICTURE) { + _strlwr(s); + // strip resouce name if any + if ((p=strchr(s, '@')) != NULL) { + if ((q=strchr(p, '/')) != NULL) + *q = '\0'; + } + } + return s; +} + + +int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + size_t len; + char *s, *p; + s = GetItemId(list, jid); + len = strlen(s); + + EnterCriticalSection(&proto->csLists); + for (i=0; ilistsCount; i++) + if (proto->lists[i].list == list) { + p = proto->lists[i].jid; + if (p && strlen(p) >= len && (p[(int)len] == '\0' || p[(int)len] == '/') && !strncmp(p, s, len)) { + LeaveCriticalSection(&proto->csLists); + mir_free(s); + return i+1; + } + } + LeaveCriticalSection(&proto->csLists); + mir_free(s); + return 0; +} + +JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + char *s; + JABBER_LIST_ITEM *item; + + EnterCriticalSection(&proto->csLists); + if ((item=JabberListGetItemPtr(proto, list, jid)) != NULL) { + LeaveCriticalSection(&proto->csLists); + return item; + } + + s = GetItemId(list, jid); + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*(proto->listsCount+1)); + item = &(proto->lists[proto->listsCount]); + memset(item, 0, sizeof(JABBER_LIST_ITEM)); + item->list = list; + item->jid = s; + item->nick = NULL; + item->status = ID_STATUS_OFFLINE; + item->statusMessage = NULL; + item->group = NULL; + item->messageEventIdStr = NULL; + item->wantComposingEvent = FALSE; + item->isTyping = FALSE; +// item->type = NULL; + item->ft = NULL; + item->roomName = NULL; + item->version = NULL; + item->software = NULL; + item->system = NULL; + item->avatarHash = NULL; + item->avatarFormat = PA_FORMAT_UNKNOWN; + item->newAvatarDownloading = FALSE; + item->versionRequested = FALSE; + item->infoRequested = FALSE; + proto->listsCount++; + LeaveCriticalSection(&proto->csLists); + + return item; +} + +void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return; + } + i--; + JabberListFreeItemInternal(&(proto->lists[i])); + proto->listsCount--; + memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); + LeaveCriticalSection(&proto->csLists); +} + +void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list) +{ + int i; + + i = 0; + while ((i=JabberListFindNext(proto, list, i)) >= 0) { + JabberListRemoveByIndex(proto, i); + } +} + +void JabberListRemoveByIndex(TlenProtocol *proto, int index) +{ + EnterCriticalSection(&proto->csLists); + if (index >= 0 && indexlistsCount) { + JabberListFreeItemInternal(&(proto->lists[index])); + proto->listsCount--; + memmove(proto->lists+index, proto->lists+index+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-index)); + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); + } + LeaveCriticalSection(&proto->csLists); +} + +void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return; + } + i--; + + if (proto->lists[i].statusMessage != NULL) + mir_free(proto->lists[i].statusMessage); + if (statusMessage) + proto->lists[i].statusMessage = mir_strdup(statusMessage); + else + proto->lists[i].statusMessage = NULL; + LeaveCriticalSection(&proto->csLists); +} + +void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return; + } + i--; + LeaveCriticalSection(&proto->csLists); +} + +int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = (fromOffset >= 0) ? fromOffset : 0; + for (; ilistsCount; i++) + if (proto->lists[i].list == list) { + LeaveCriticalSection(&proto->csLists); + return i; + } + LeaveCriticalSection(&proto->csLists); + return -1; +} + +JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return NULL; + } + i--; + LeaveCriticalSection(&proto->csLists); + return &(proto->lists[i]); +} + +JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id) +{ + + int i; + size_t len; + char *p; + + len = strlen(id); + + EnterCriticalSection(&proto->csLists); + for (i=0; ilistsCount; i++) { + if (proto->lists[i].list == list) { + p = proto->lists[i].id2; + if (p != NULL) { + if (!strncmp(p, id, len)) { + LeaveCriticalSection(&proto->csLists); + return &(proto->lists[i]); + } + } + } + } + LeaveCriticalSection(&proto->csLists); + return NULL; +} + +JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index) +{ + EnterCriticalSection(&proto->csLists); + if (index >= 0 && indexlistsCount) { + LeaveCriticalSection(&proto->csLists); + return &(proto->lists[index]); + } + LeaveCriticalSection(&proto->csLists); + return NULL; +} + diff --git a/protocols/Tlen/src/tlen_list.h b/protocols/Tlen/src/tlen_list.h new file mode 100644 index 0000000000..80b294e459 --- /dev/null +++ b/protocols/Tlen/src/tlen_list.h @@ -0,0 +1,90 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" + +#ifndef _JABBER_LIST_H_ +#define _JABBER_LIST_H_ + +typedef struct JABBER_LIST_ITEM_STRUCT { + JABBER_LIST list; + char *jid; + char *id2; + + // LIST_ROSTER + // jid = jid of the contact + char *nick; + int status; // Main status, currently useful for transport where no resource information is kept. + // On normal contact, this is the same status as shown on contact list. + JABBER_SUBSCRIPTION subscription; + char *statusMessage; // Status message when the update is to JID with no resource specified (e.g. transport user) + char *software; + char *version; + char *system; + char *group; + char *protocolVersion; + int avatarFormat; + char *avatarHash; + BOOL newAvatarDownloading; + BOOL versionRequested; + BOOL infoRequested; + int idMsgAckPending; + char *messageEventIdStr; + BOOL wantComposingEvent; + BOOL isTyping; + + // LIST_ROOM + // jid = room JID + // char *name; // room name + //char *type; // room type + + // LIST_CHATROOM + // jid = room JID + // char *nick; // my nick in this chat room (SPECIAL: in UTF8) + // JABBER_RESOURCE_STATUS *resource; // participant nicks in this room + char *roomName; + + // LIST_FILE + struct TLEN_FILE_TRANSFER_STRUCT *ft; +} JABBER_LIST_ITEM; + + +void JabberListInit(TlenProtocol *proto); +void JabberListUninit(TlenProtocol *proto); +void JabberListWipe(TlenProtocol *proto); +void JabberListWipeSpecial(TlenProtocol *proto); +int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid); +JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid); +void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid); +void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list); +void JabberListRemoveByIndex(TlenProtocol *proto, int index); +int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset); +JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid); +JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index); +JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id); + +void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage); +void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid); + +#endif + diff --git a/protocols/Tlen/src/tlen_misc.cpp b/protocols/Tlen/src/tlen_misc.cpp new file mode 100644 index 0000000000..f90bf62509 --- /dev/null +++ b/protocols/Tlen/src/tlen_misc.cpp @@ -0,0 +1,210 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include "tlen_list.h" + +void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob) +{ + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = proto->m_szModuleName; + dbei.timestamp = (DWORD) time(NULL); + dbei.flags = flags; + dbei.eventType = eventType; + dbei.cbBlob = cbBlob; + dbei.pBlob = pBlob; + db_event_add(hContact, &dbei); +} + +void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick) +{ + char *s; + PBYTE pCurBlob; + PBYTE pBlob; + DWORD cbBlob; + HANDLE hContact; + + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->m_szModuleName); + // strip resource if present + s = JabberLoginFromJID(jid); + _strlwr(s); + db_set_s(hContact, proto->m_szModuleName, "jid", s); + mir_free(s); + } + else { + db_unset(hContact, proto->m_szModuleName, "Hidden"); + } + db_set_s(hContact, proto->m_szModuleName, "Nick", nick); + JabberLog(proto, "auth request: %s, %s", jid, nick); + //blob is: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ) + //blob is: 0(DWORD), hContact(HANDLE), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ) + cbBlob = sizeof(DWORD) + sizeof(HANDLE) + (int)strlen(nick) + (int)strlen(jid) + 5; + pBlob = pCurBlob = (PBYTE) mir_alloc(cbBlob); + *((PDWORD)pCurBlob) = 0; pCurBlob += sizeof(DWORD); + *((PHANDLE)pCurBlob) = hContact; pCurBlob += sizeof(DWORD); + strcpy((char *) pCurBlob, nick); pCurBlob += strlen(nick)+1; + *pCurBlob = '\0'; pCurBlob++; //firstName + *pCurBlob = '\0'; pCurBlob++; //lastName + strcpy((char *) pCurBlob, jid); pCurBlob += strlen(jid)+1; + *pCurBlob = '\0'; //reason + JabberDBAddEvent(proto, NULL, EVENTTYPE_AUTHREQUEST, 0, pBlob, cbBlob); +} + +char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact) +{ + char *p = NULL; + DBVARIANT dbv; + if (!db_get(hContact, proto->m_szModuleName, "jid", &dbv)) { + p = mir_strdup(dbv.pszVal); + db_free(&dbv); + } + return p; +} + +HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid) +{ + DBVARIANT dbv; + char *p; + if (jid == NULL) + return NULL; + + for (HANDLE hContact = db_find_first(proto->m_szModuleName); hContact; hContact = db_find_next(hContact, proto->m_szModuleName)) { + if ( db_get_s(hContact, proto->m_szModuleName, "jid", &dbv)) + continue; + + if ((p=dbv.pszVal) != NULL) { + if (!stricmp(p, jid)) { // exact match (node@domain/resource) + db_free(&dbv); + return hContact; + } + } + db_free(&dbv); + } + + return NULL; +} + +HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary) +{ + HANDLE hContact; + if (jid == NULL || jid[0] == '\0') + return NULL; + + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->m_szModuleName); + db_set_s(hContact, proto->m_szModuleName, "jid", jid); + if (nick != NULL && nick[0] != '\0') + db_set_s(hContact, proto->m_szModuleName, "Nick", nick); + if (temporary) + db_set_b(hContact, "CList", "NotOnList", 1); + } + return hContact; +} + +static void JabberContactListCreateClistGroup(char *groupName) +{ + char str[33], newName[128]; + int i; + DBVARIANT dbv; + char *name; + + for (i=0;;i++) { + itoa(i, str, 10); + if (db_get(NULL, "CListGroups", str, &dbv)) + break; + name = dbv.pszVal; + if (name[0] != '\0' && !strcmp(name+1, groupName)) { + // Already exist, no need to create + db_free(&dbv); + return; + } + db_free(&dbv); + } + + // Create new group with id = i (str is the text representation of i) + newName[0] = 1 | GROUPF_EXPANDED; + strncpy(newName+1, groupName, sizeof(newName)-1); + newName[sizeof(newName)-1] = '\0'; + db_set_s(NULL, "CListGroups", str, newName); + CallService(MS_CLUI_GROUPADDED, i+1, 0); +} + +void JabberContactListCreateGroup(char *groupName) +{ + char name[128]; + char *p; + + if (groupName == NULL || groupName[0] == '\0' || groupName[0] == '\\') return; + + strncpy(name, groupName, sizeof(name)); + name[sizeof(name)-1] = '\0'; + for (p=name; *p != '\0'; p++) { + if (*p == '\\') { + *p = '\0'; + JabberContactListCreateClistGroup(name); + *p = '\\'; + } + } + JabberContactListCreateClistGroup(name); +} + + +struct FORK_ARG { + HANDLE hEvent; + void (__cdecl *threadcode)(void*); + void *arg; +}; + +static void __cdecl forkthread_r(struct FORK_ARG *fa) +{ + void (*callercode)(void*) = fa->threadcode; + void *arg = fa->arg; + Thread_Push(0); + SetEvent(fa->hEvent); + callercode(arg); + Thread_Pop(); + return; +} + +unsigned long JabberForkThread( + void (__cdecl *threadcode)(void*), + unsigned long stacksize, + void *arg +) +{ + unsigned long rc; + struct FORK_ARG fa; + + fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + fa.threadcode = threadcode; + fa.arg = arg; + rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa); + if ((unsigned long) -1L != rc) { + WaitForSingleObject(fa.hEvent, INFINITE); + } + CloseHandle(fa.hEvent); + return rc; +} diff --git a/protocols/Tlen/src/tlen_muc.cpp b/protocols/Tlen/src/tlen_muc.cpp index fbf72e8ee6..393a19be27 100644 --- a/protocols/Tlen/src/tlen_muc.cpp +++ b/protocols/Tlen/src/tlen_muc.cpp @@ -19,9 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" -#include "jabber_list.h" -#include "jabber_iq.h" +#include "tlen.h" +#include "tlen_list.h" +#include "tlen_iq.h" #include "resource.h" #include "tlen_muc.h" @@ -1000,7 +1000,7 @@ static int TlenMUCQueryContacts(TlenProtocol *proto, const char *roomId) { return 1; } -int TlenProtocol::MUCMenuHandleMUC(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::MUCMenuHandleMUC(WPARAM wParam, LPARAM lParam) { if (!isOnline) return 1; @@ -1009,7 +1009,7 @@ int TlenProtocol::MUCMenuHandleMUC(WPARAM wParam, LPARAM lParam) return 0; } -int TlenProtocol::MUCMenuHandleChats(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::MUCMenuHandleChats(WPARAM wParam, LPARAM lParam) { if (!isOnline) return 1; @@ -1023,7 +1023,7 @@ int TlenProtocol::MUCMenuHandleChats(WPARAM wParam, LPARAM lParam) return 0; } -int TlenProtocol::MUCContactMenuHandleMUC(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::MUCContactMenuHandleMUC(WPARAM wParam, LPARAM lParam) { HANDLE hContact; DBVARIANT dbv; diff --git a/protocols/Tlen/src/tlen_opt.cpp b/protocols/Tlen/src/tlen_opt.cpp new file mode 100644 index 0000000000..4c0be5e564 --- /dev/null +++ b/protocols/Tlen/src/tlen_opt.cpp @@ -0,0 +1,673 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include "tlen_list.h" +#include "tlen_voice.h" +#include +#include "resource.h" + +static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +typedef struct TabDefStruct { + DLGPROC dlgProc; + DWORD dlgId; + TCHAR *tabName; +} TabDef; + +static TabDef tabPages[] = { + {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, LPGENT("General")}, + {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, LPGENT("Voice Chats")}, + {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, LPGENT("Advanced")}, + {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, LPGENT("Notifications")} + }; + +void TlenLoadOptions(TlenProtocol *proto) +{ + proto->tlenOptions.savePassword = db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE); + proto->tlenOptions.useEncryption = db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE); + proto->tlenOptions.reconnect = db_get_b(NULL, proto->m_szModuleName, "Reconnect", TRUE); + proto->tlenOptions.alertPolicy = db_get_w(NULL, proto->m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR); + proto->tlenOptions.rosterSync = db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE); + proto->tlenOptions.offlineAsInvisible = db_get_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", FALSE); + proto->tlenOptions.leaveOfflineMessage = db_get_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", TRUE); + proto->tlenOptions.offlineMessageOption = db_get_w(NULL, proto->m_szModuleName, "OfflineMessageOption", 0); + proto->tlenOptions.ignoreAdvertisements = db_get_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", TRUE); + proto->tlenOptions.groupChatPolicy = db_get_w(NULL, proto->m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK); + proto->tlenOptions.voiceChatPolicy = db_get_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK); + proto->tlenOptions.imagePolicy = db_get_w(NULL, proto->m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR); + proto->tlenOptions.enableAvatars = db_get_b(NULL, proto->m_szModuleName, "EnableAvatars", TRUE); + proto->tlenOptions.enableVersion = db_get_b(NULL, proto->m_szModuleName, "EnableVersion", TRUE); + proto->tlenOptions.useNudge = db_get_b(NULL, proto->m_szModuleName, "UseNudge", FALSE); + proto->tlenOptions.logAlerts = db_get_b(NULL, proto->m_szModuleName, "LogAlerts", TRUE); + proto->tlenOptions.sendKeepAlive = db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE); + proto->tlenOptions.useNewP2P = TRUE; +} + +static int changed = 0; + +static void ApplyChanges(TlenProtocol *proto, int i) { + changed &= ~i; + if (changed == 0) { + TlenLoadOptions(proto); + } +} + +static void MarkChanges(int i, HWND hWnd) { + SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); + changed |= i; +} + + +int TlenProtocol::OptionsInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = hInst; + odp.ptszGroup = LPGENT("Network"); + odp.ptszTitle = m_tszUserName; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.dwInitParam = (LPARAM)this; + for (int i = 0; i < SIZEOF(tabPages); i++) { + odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId); + odp.pfnDlgProc = tabPages[i].dlgProc; + odp.ptszTab = tabPages[i].tabName; + Options_AddPage(wParam, &odp); + } + return 0; +} + +static LRESULT CALLBACK JabberValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_CHAR: + if (strchr("\"&'/:<>@", wParam&0xff) != NULL) + return 0; + break; + } + return mir_callNextSubclass(hwndEdit, JabberValidateUsernameWndProc, msg, wParam, lParam); +} + +INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); + db_free(&dbv); + } + if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); + + mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), JabberValidateUsernameWndProc); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_EDIT_USERNAME: + case IDC_EDIT_PASSWORD: + if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_SAVEPASSWORD: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_REGISTERACCOUNT: + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); + if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); + + if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { + GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); + if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "Password", text); + } + else + db_unset(NULL, proto->m_szModuleName, "Password"); + + db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + TlenLoadOptions(proto); + return TRUE; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + WNDPROC oldProc; + + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); + db_free(&dbv); + } + if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); + + CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); + CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); + CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); + CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); + CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); + CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); + CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); + CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); + CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); + + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); + //SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_ONLINE,GSMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_AWAY,GSMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_NA,GSMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_DND,GSMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_FREECHAT,GSMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,ID_STATUS_INVISIBLE,GSMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); + + oldProc = (WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_USERDATA, (LONG_PTR) oldProc); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC, (LONG_PTR) JabberValidateUsernameWndProc); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_EDIT_USERNAME: + case IDC_EDIT_PASSWORD: + if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + // Fall through + case IDC_SAVEPASSWORD: + case IDC_RECONNECT: + case IDC_ROSTER_SYNC: + case IDC_IGNORE_ADVERTISEMENTS: + case IDC_SHOW_OFFLINE: + case IDC_OFFLINE_MESSAGE: + MarkChanges(1, hwndDlg); + break; + case IDC_LOG_ALERTS: + CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); + MarkChanges(1, hwndDlg); + break; + case IDC_NUDGE_SUPPORT: + CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); + MarkChanges(1, hwndDlg); + break; + case IDC_REGISTERACCOUNT: + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); + break; + case IDC_OFFLINE_MESSAGE_OPTION: + case IDC_ALERT_POLICY: + case IDC_MUC_POLICY: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(1, hwndDlg); + break; + default: + MarkChanges(1, hwndDlg); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); + if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); + + if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { + GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); + if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "Password", text); + } + else + db_unset(NULL, proto->m_szModuleName, "Password"); + + db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); + db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); + db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); + db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); + db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); + db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); + db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); + db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); + db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); + db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); + db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + ApplyChanges(proto, 1); + return TRUE; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0); + TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN)); + TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT)); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_VOICE_POLICY: + case IDC_VOICE_DEVICE_IN: + case IDC_VOICE_DEVICE_OUT: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(2, hwndDlg); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + db_set_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0)); + ApplyChanges(proto, 2); + return TRUE; + } + } + break; + } + + return FALSE; +} + +static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + BOOL bChecked; + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); + db_free(&dbv); + } else { + SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); + + if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) { + SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); + db_free(&dbv); + } else + SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); + SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); + + CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE)); + + CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE)); + + CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE)); + // File transfer options + bChecked = FALSE; + if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) { + bChecked = TRUE; + CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); + if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE) { + CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); + } else { + bChecked = FALSE; + } + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); + + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS4")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS5")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0); + if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); + db_free(&dbv); + } + SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE); + if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); + db_free(&dbv); + } + if (!db_get(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + return TRUE; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) { + case IDC_FILE_PROXY_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(4, hwndDlg); + break; + case IDC_EDIT_LOGIN_SERVER: + case IDC_HOST: + case IDC_HOSTPORT: + case IDC_FILE_PROXY_HOST: + case IDC_FILE_PROXY_PORT: + case IDC_FILE_PROXY_USER: + case IDC_FILE_PROXY_PASSWORD: + if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) + MarkChanges(4, hwndDlg); + break; + case IDC_FILE_USE_PROXY: + bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); + case IDC_FILE_PROXY_USE_AUTH: + bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); + MarkChanges(4, hwndDlg); + break; + case IDC_KEEPALIVE: + case IDC_VISIBILITY_SUPPORT: + case IDC_USE_SSL: + MarkChanges(4, hwndDlg); + break; + } + } + break; + case WM_NOTIFY: + { + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + WORD port; + BOOL useEncryption; + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); + if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text)); + + GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); + if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "ManualHost", text); + + port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); + if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) + reconnectRequired = TRUE; + db_set_w(NULL, proto->m_szModuleName, "ManualPort", port); + + proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); + db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); + + useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); + if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption) + reconnectRequired = TRUE; + db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption); + + db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); + // File transfer options + db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); + db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); + db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text); + db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); + db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); + db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text); + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); + db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + ApplyChanges(proto, 4); + return TRUE; + } + } + } + break; + case WM_DESTROY: + break; + } + + return FALSE; +} + +#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 +#define POPUP_DEFAULT_COLORTXT 0x000000 + +static void MailPopupPreview(DWORD colorBack, DWORD colorText, char *title, char *emailInfo, int delay) +{ + POPUPDATA ppd = { 0 }; + HICON hIcon = GetIcolibIcon(IDI_MAIL); + ppd.lchIcon = CopyIcon(hIcon); + ReleaseIcolibIcon(hIcon); + strcpy(ppd.lpzContactName, title); + strcpy(ppd.lpzText, emailInfo); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.iSeconds = delay; + if ( ServiceExists(MS_POPUP_ADDPOPUP)) + PUAddPopup(&ppd); +} + +static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + BYTE delayMode; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE)); + SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); + SetDlgItemInt(hwndDlg, IDC_DELAY, db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4), FALSE); + delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0); + if (delayMode == 1) { + CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); + } else if (delayMode == 2) { + CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); + } else { + CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); + } + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COLORTXT: + case IDC_COLORBKG: + case IDC_ENABLEPOPUP: + case IDC_DELAY: + case IDC_DELAY_POPUP: + case IDC_DELAY_CUSTOM: + case IDC_DELAY_PERMANENT: + MarkChanges(8, hwndDlg); + break; + case IDC_PREVIEW: + { + int delay; + char title[256]; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { + delay=0; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delay=-1; + } else { + delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); + } + mir_snprintf(title, sizeof(title), Translate("%s mail"), proto->m_szModuleName); + MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), + (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), + title, + "From: test@test.test\nSubject: test", + delay); + } + + } + break; + + + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BYTE delayMode; + db_set_b(NULL, proto->m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); + db_set_dw(NULL, proto->m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); + db_set_dw(NULL, proto->m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); + db_set_dw(NULL, proto->m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); + delayMode=0; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { + delayMode=1; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delayMode=2; + + } + db_set_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", delayMode); + ApplyChanges(proto, 8); + return TRUE; + } + } + break; + + } + return FALSE; +} + diff --git a/protocols/Tlen/src/tlen_p2p_new.cpp b/protocols/Tlen/src/tlen_p2p_new.cpp index 70ec288959..c09a1f61ba 100644 --- a/protocols/Tlen/src/tlen_p2p_new.cpp +++ b/protocols/Tlen/src/tlen_p2p_new.cpp @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include -#include "jabber_list.h" +#include "tlen_list.h" static void logInfo(const char *filename, const char *fmt, ...) { diff --git a/protocols/Tlen/src/tlen_p2p_old.cpp b/protocols/Tlen/src/tlen_p2p_old.cpp index da6217abbc..1f51178bd1 100644 --- a/protocols/Tlen/src/tlen_p2p_old.cpp +++ b/protocols/Tlen/src/tlen_p2p_old.cpp @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include -#include "jabber_list.h" +#include "tlen_list.h" void TlenP2PFreeFileTransfer(TLEN_FILE_TRANSFER *ft) diff --git a/protocols/Tlen/src/tlen_p2p_old.h b/protocols/Tlen/src/tlen_p2p_old.h index 4e2305310f..620d091351 100644 --- a/protocols/Tlen/src/tlen_p2p_old.h +++ b/protocols/Tlen/src/tlen_p2p_old.h @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" +#include "tlen.h" #ifndef _TLEN_P2P_OLD_H_ #define _TLEN_P2P_OLD_H_ diff --git a/protocols/Tlen/src/tlen_picture.cpp b/protocols/Tlen/src/tlen_picture.cpp index 55c4a1c07d..407eb6067d 100644 --- a/protocols/Tlen/src/tlen_picture.cpp +++ b/protocols/Tlen/src/tlen_picture.cpp @@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" -#include "jabber_list.h" +#include "tlen.h" +#include "tlen_list.h" #include "tlen_file.h" #include "tlen_p2p_old.h" diff --git a/protocols/Tlen/src/tlen_picture.h b/protocols/Tlen/src/tlen_picture.h index ef98b02405..178134007d 100644 --- a/protocols/Tlen/src/tlen_picture.h +++ b/protocols/Tlen/src/tlen_picture.h @@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define _TLEN_PICTURE_H #include -#include "jabber.h" +#include "tlen.h" void TlenProcessPic(XmlNode *node, TlenProtocol *proto); BOOL SendPicture(TlenProtocol *, HANDLE hContact); diff --git a/protocols/Tlen/src/tlen_presence.cpp b/protocols/Tlen/src/tlen_presence.cpp index 1207857241..a896635c59 100644 --- a/protocols/Tlen/src/tlen_presence.cpp +++ b/protocols/Tlen/src/tlen_presence.cpp @@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" -#include "jabber_list.h" +#include "tlen.h" +#include "tlen_list.h" #include "tlen_avatar.h" void TlenProcessPresence(XmlNode *node, TlenProtocol *proto) diff --git a/protocols/Tlen/src/tlen_svc.cpp b/protocols/Tlen/src/tlen_svc.cpp new file mode 100644 index 0000000000..01388e7074 --- /dev/null +++ b/protocols/Tlen/src/tlen_svc.cpp @@ -0,0 +1,1288 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include +#include +#include +#include +#include "resource.h" +#include "tlen_list.h" +#include "tlen_iq.h" +#include "tlen_p2p_old.h" +#include "tlen_avatar.h" +#include "tlen_file.h" + +DWORD_PTR TlenProtocol::GetCaps(int type, HANDLE hContact) +{ + if (type == PFLAGNUM_1) + return PF1_IM|PF1_AUTHREQ|PF1_SERVERCLIST|PF1_MODEMSG|PF1_BASICSEARCH|PF1_SEARCHBYEMAIL|PF1_EXTSEARCH|PF1_EXTSEARCHUI|PF1_SEARCHBYNAME|PF1_FILE;//|PF1_VISLIST|PF1_INVISLIST; + if (type == PFLAGNUM_2) + return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; + if (type == PFLAGNUM_3) + return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; + if (type == PFLAGNUM_4) + return PF4_FORCEAUTH|PF4_NOCUSTOMAUTH|PF4_SUPPORTTYPING|PF4_AVATARS|PF4_IMSENDOFFLINE|PF4_OFFLINEFILES; + if (type == PFLAG_UNIQUEIDTEXT) + return (DWORD_PTR) Translate("Tlen login"); + if (type == PFLAG_UNIQUEIDSETTING) + return (DWORD_PTR) "jid"; + return 0; +} + +INT_PTR TlenProtocol::GetName(WPARAM wParam, LPARAM lParam) +{ + strncpy((char*)lParam, m_szModuleName, wParam); + return 0; +} + +int TlenRunSearch(TlenProtocol *proto) { + int iqId = 0; + if (!proto->isOnline) return 0; + if (proto->searchQuery != NULL && proto->searchIndex < 10) { + iqId = proto->searchID; + JabberIqAdd(proto, iqId, IQ_PROC_GETSEARCH, JabberIqResultSearch); + if (proto->searchIndex == 0) { + JabberSend(proto, "%s", iqId, proto->searchQuery); + } else { + JabberSend(proto, "%s%d", iqId, proto->searchQuery, proto->searchIndex * TLEN_MAX_SEARCH_RESULTS_PER_PAGE); + } + proto->searchIndex ++; + } + return iqId; +} + +void TlenResetSearchQuery(TlenProtocol *proto) { + if (proto->searchQuery != NULL) { + mir_free(proto->searchQuery); + proto->searchQuery = NULL; + } + proto->searchQueryLen = 0; + proto->searchIndex = 0; + proto->searchID = JabberSerialNext(proto); +} + +HANDLE TlenProtocol::SearchBasic(const PROTOCHAR* id) +{ + char *jid; + int iqId = 0; + if (!isOnline) return 0; + if (id == NULL) return 0; + char* id_A = mir_t2a(id); + if ((jid=JabberTextEncode(id_A)) != NULL) { + searchJID = mir_strdup(id_A); + TlenResetSearchQuery(this); + JabberStringAppend(&searchQuery, &searchQueryLen, "%s", jid); + iqId = TlenRunSearch(this); + mir_free(jid); + } + mir_free(id_A); + return (HANDLE)iqId; +} + +HANDLE TlenProtocol::SearchByEmail(const PROTOCHAR* email) +{ + char *emailEnc; + int iqId = 0; + + if (!isOnline) return 0; + if (email == NULL) return 0; + + char* email_A = mir_t2a(email); + if ((emailEnc=JabberTextEncode(email_A)) != NULL) { + TlenResetSearchQuery(this); + JabberStringAppend(&searchQuery, &searchQueryLen, "%s", emailEnc); + iqId = TlenRunSearch(this); + mir_free(emailEnc); + } + mir_free(email_A); + return (HANDLE)iqId; +} + +HANDLE TlenProtocol::SearchByName(const PROTOCHAR* nickT, const PROTOCHAR* firstNameT, const PROTOCHAR* lastNameT) +{ + + char* nick = mir_t2a(nickT); + char* firstName = mir_t2a(firstNameT); + char* lastName = mir_t2a(lastNameT); + + char *p; + int iqId = 0; + + if (!isOnline) return 0; + + TlenResetSearchQuery(this); + + if (nick != NULL && nick[0] != '\0') { + if ((p=JabberTextEncode(nick)) != NULL) { + JabberStringAppend(&searchQuery, &searchQueryLen, "%s", p); + mir_free(p); + } + } + if (firstName != NULL && firstName[0] != '\0') { + if ((p=JabberTextEncode(firstName)) != NULL) { + JabberStringAppend(&searchQuery, &searchQueryLen, "%s", p); + mir_free(p); + } + } + if (lastName != NULL && lastName[0] != '\0') { + if ((p=JabberTextEncode(lastName)) != NULL) { + JabberStringAppend(&searchQuery, &searchQueryLen, "%s", p); + mir_free(p); + } + } + + iqId = TlenRunSearch(this); + return (HANDLE)iqId; +} + +HWND TlenProtocol::CreateExtendedSearchUI(HWND owner) +{ + return (HWND) CreateDialog(hInst, MAKEINTRESOURCE(IDD_ADVSEARCH), owner, TlenAdvSearchDlgProc); +} + +HWND TlenProtocol::SearchAdvanced(HWND owner) +{ + int iqId; + if (!isOnline) return 0; + + TlenResetSearchQuery(this); + iqId = JabberSerialNext(this); + if ((searchQuery = TlenAdvSearchCreateQuery(owner, iqId)) != NULL) { + iqId = TlenRunSearch(this); + } + return (HWND)iqId; +} + + +static HANDLE AddToListByJID(TlenProtocol *proto, const char *newJid, DWORD flags) +{ + HANDLE hContact; + char *jid, *nick; + + if ((hContact=JabberHContactFromJID(proto, newJid)) == NULL) { + // not already there: add + jid = mir_strdup(newJid); _strlwr(jid); + hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->m_szModuleName); + db_set_s(hContact, proto->m_szModuleName, "jid", jid); + if ((nick=JabberNickFromJID(newJid)) == NULL) + nick = mir_strdup(newJid); + db_set_s(hContact, "CList", "MyHandle", nick); + mir_free(nick); + mir_free(jid); + + // Note that by removing or disable the "NotOnList" will trigger + // the plugin to add a particular contact to the roster list. + // See DBSettingChanged hook at the bottom part of this source file. + // But the add module will delete "NotOnList". So we will not do it here. + // Also because we need "MyHandle" and "Group" info, which are set after + // PS_ADDTOLIST is called but before the add dialog issue deletion of + // "NotOnList". + // If temporary add, "NotOnList" won't be deleted, and that's expected. + db_set_b(hContact, "CList", "NotOnList", 1); + if (flags & PALF_TEMPORARY) + db_set_b(hContact, "CList", "Hidden", 1); + } + else { + // already exist + // Set up a dummy "NotOnList" when adding permanently only + if (!(flags&PALF_TEMPORARY)) + db_set_b(hContact, "CList", "NotOnList", 1); + } + + return hContact; +} + +HANDLE TlenProtocol::AddToList(int flags, PROTOSEARCHRESULT *psr) +{ + HANDLE hContact; + JABBER_SEARCH_RESULT *jsr = (JABBER_SEARCH_RESULT*)psr; + if (jsr->hdr.cbSize != sizeof(JABBER_SEARCH_RESULT)) + return (int) NULL; + hContact = AddToListByJID(this, jsr->jid, flags); // wParam is flag e.g. PALF_TEMPORARY + return hContact; +} + +HANDLE TlenProtocol::AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ) +{ + DBEVENTINFO dbei = { sizeof(dbei) }; + if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)(-1)) + return (HANDLE) NULL; + if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) + return (HANDLE) NULL; + if (db_event_get(hDbEvent, &dbei)) { + mir_free(dbei.pBlob); + return (HANDLE) NULL; + } + if (strcmp(dbei.szModule, m_szModuleName)) { + mir_free(dbei.pBlob); + return (HANDLE) NULL; + } + +/* + // EVENTTYPE_CONTACTS is when adding from when we receive contact list (not used in Jabber) + // EVENTTYPE_ADDED is when adding from when we receive "You are added" (also not used in Jabber) + // Jabber will only handle the case of EVENTTYPE_AUTHREQUEST + // EVENTTYPE_AUTHREQUEST is when adding from the authorization request dialog +*/ + + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { + mir_free(dbei.pBlob); + return (HANDLE) NULL; + } + + char *nick = (char *)dbei.pBlob + sizeof(DWORD)*2; + char *firstName = nick + strlen(nick) + 1; + char *lastName = firstName + strlen(firstName) + 1; + char *jid = lastName + strlen(lastName) + 1; + + HANDLE hContact = (HANDLE) AddToListByJID(this, jid, flags); + mir_free(dbei.pBlob); + return hContact; +} + +int TlenProtocol::Authorize(HANDLE hDbEvent) +{ + if (!isOnline) + return 1; + + DBEVENTINFO dbei = { sizeof(dbei) }; + if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)-1) + return 1; + if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) + return 1; + if (db_event_get(hDbEvent, &dbei)){ + mir_free(dbei.pBlob); + return 1; + } + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { + mir_free(dbei.pBlob); + return 1; + } + if (strcmp(dbei.szModule, m_szModuleName)) { + mir_free(dbei.pBlob); + return 1; + } + + char *nick = (char *)dbei.pBlob + sizeof(DWORD)*2; + char *firstName = nick + strlen(nick) + 1; + char *lastName = firstName + strlen(firstName) + 1; + char *jid = lastName + strlen(lastName) + 1; + + JabberSend(this, "", jid); + + // Automatically add this user to my roster if option is enabled + if (db_get_b(NULL, m_szModuleName, "AutoAdd", TRUE) == TRUE) { + HANDLE hContact; + JABBER_LIST_ITEM *item; + + if ((item=JabberListGetItemPtr(this, LIST_ROSTER, jid)) == NULL || (item->subscription != SUB_BOTH && item->subscription != SUB_TO)) { + JabberLog(this, "Try adding contact automatically jid=%s", jid); + if ((hContact=AddToListByJID(this, jid, 0)) != NULL) { + // Trigger actual add by removing the "NotOnList" added by AddToListByJID() + // See AddToListByJID() and JabberDbSettingChanged(). + db_unset(hContact, "CList", "NotOnList"); + } + } + } + + mir_free(dbei.pBlob); + return 0; +} + +int TlenProtocol::AuthDeny(HANDLE hDbEvent, const PROTOCHAR* szReason) +{ + if (!isOnline) + return 1; + + DBEVENTINFO dbei = { sizeof(dbei) }; + if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)(-1)) + return 1; + if ((dbei.pBlob = (PBYTE) mir_alloc(dbei.cbBlob)) == NULL) + return 1; + if (db_event_get(hDbEvent, &dbei)) { + mir_free(dbei.pBlob); + return 1; + } + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { + mir_free(dbei.pBlob); + return 1; + } + if (strcmp(dbei.szModule, m_szModuleName)) { + mir_free(dbei.pBlob); + return 1; + } + + char *nick = (char *)dbei.pBlob + sizeof(DWORD)*2; + char *firstName = nick + strlen(nick) + 1; + char *lastName = firstName + strlen(firstName) + 1; + char *jid = lastName + strlen(lastName) + 1; + + JabberSend(this, "", jid); + JabberSend(this, "", jid); + mir_free(dbei.pBlob); + return 0; +} + +static void TlenConnect(TlenProtocol *proto, int initialStatus) +{ + if (!proto->isConnected) { + ThreadData *thread; + int oldStatus; + + thread = (ThreadData *) mir_alloc(sizeof(ThreadData)); + memset(thread, 0, sizeof(ThreadData)); + thread->proto = proto; + proto->m_iDesiredStatus = initialStatus; + + oldStatus = proto->m_iStatus; + proto->m_iStatus = ID_STATUS_CONNECTING; + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->m_iStatus); + thread->hThread = (HANDLE) JabberForkThread((void (__cdecl *)(void*))JabberServerThread, 0, thread); + } +} + +int TlenProtocol::SetStatus(int iNewStatus) +{ + int oldStatus; + HANDLE s; + + m_iDesiredStatus = iNewStatus; + + if (iNewStatus == ID_STATUS_OFFLINE) { + if (threadData) { + if (isConnected) { + JabberSendPresence(this, ID_STATUS_OFFLINE); + } + + // TODO bug? s = proto; + s = threadData->s; + + threadData = NULL; + if (isConnected) { + Sleep(200); +// JabberSend(s, ""); + // Force closing connection + isConnected = FALSE; + isOnline = FALSE; + Netlib_CloseHandle(s); + } + } + else { + if (m_iStatus != ID_STATUS_OFFLINE) { + oldStatus = m_iStatus; + m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); + } + } + } + else if (iNewStatus != m_iStatus) { + if (!isConnected) + TlenConnect(this, iNewStatus); + else { + // change status + oldStatus = m_iStatus; + // send presence update + JabberSendPresence(this, iNewStatus); + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, m_iStatus); + } + } + return 0; +} + +INT_PTR TlenProtocol::GetStatus(WPARAM wParam, LPARAM lParam) +{ + return m_iStatus; +} + +int TlenProtocol::SetAwayMsg(int iStatus, const PROTOCHAR* msg) +{ + char **szMsg; + char *newModeMsg; + + JabberLog(this, "SetAwayMsg called, wParam=%d lParam=%s", iStatus, msg); + + newModeMsg = JabberTextEncode(mir_t2a(msg)); //TODO TCHAR + + EnterCriticalSection(&modeMsgMutex); + + switch (iStatus) { + case ID_STATUS_ONLINE: + szMsg = &modeMsgs.szOnline; + break; + case ID_STATUS_AWAY: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + szMsg = &modeMsgs.szAway; + break; + case ID_STATUS_NA: + szMsg = &modeMsgs.szNa; + break; + case ID_STATUS_DND: + case ID_STATUS_OCCUPIED: + szMsg = &modeMsgs.szDnd; + break; + case ID_STATUS_FREECHAT: + szMsg = &modeMsgs.szFreechat; + break; + case ID_STATUS_INVISIBLE: + szMsg = &modeMsgs.szInvisible; + break; + default: + LeaveCriticalSection(&modeMsgMutex); + return 1; + } + + if ((*szMsg == NULL && newModeMsg == NULL) || + (*szMsg != NULL && newModeMsg != NULL && !strcmp(*szMsg, newModeMsg))) { + // Message is the same, no update needed + if (newModeMsg != NULL) mir_free(newModeMsg); + } + else { + // Update with the new mode message + if (*szMsg != NULL) mir_free(*szMsg); + *szMsg = newModeMsg; + // Send a presence update if needed + if (iStatus == m_iStatus) { + JabberSendPresence(this, m_iStatus); + } + } + + LeaveCriticalSection(&modeMsgMutex); + return 0; +} + +int TlenProtocol::GetInfo(HANDLE hContact, int infoType) +{ + DBVARIANT dbv; + int iqId; + char *nick, *pNick; + + if (!isOnline) return 1; + if (hContact == NULL) { + iqId = JabberSerialNext(this); + JabberIqAdd(this, iqId, IQ_PROC_NONE, TlenIqResultVcard); + JabberSend(this, "", iqId); + } else { + if (db_get(hContact, m_szModuleName, "jid", &dbv)) return 1; + if ((nick=JabberNickFromJID(dbv.pszVal)) != NULL) { + if ((pNick=JabberTextEncode(nick)) != NULL) { + iqId = JabberSerialNext(this); + JabberIqAdd(this, iqId, IQ_PROC_NONE, TlenIqResultVcard); + JabberSend(this, "%s", iqId, pNick); + mir_free(pNick); + } + mir_free(nick); + } + db_free(&dbv); + } + return 0; +} + +int TlenProtocol::SetApparentMode(HANDLE hContact, int mode) +{ + DBVARIANT dbv; + int oldMode; + char *jid; + + if (!isOnline) return 0; + if (!db_get_b(NULL, m_szModuleName, "VisibilitySupport", FALSE)) return 0; + if (mode != 0 && mode != ID_STATUS_ONLINE && mode != ID_STATUS_OFFLINE) return 1; + oldMode = db_get_w(hContact, m_szModuleName, "ApparentMode", 0); + if ((int) mode == oldMode) return 1; + db_set_w(hContact, m_szModuleName, "ApparentMode", (WORD) mode); + if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { + jid = dbv.pszVal; + switch (mode) { + case ID_STATUS_ONLINE: + if (m_iStatus == ID_STATUS_INVISIBLE || oldMode == ID_STATUS_OFFLINE) + JabberSend(this, "available", jid); + break; + case ID_STATUS_OFFLINE: + if (m_iStatus != ID_STATUS_INVISIBLE || oldMode == ID_STATUS_ONLINE) + JabberSend(this, "", jid); + break; + case 0: + if (oldMode == ID_STATUS_ONLINE && m_iStatus == ID_STATUS_INVISIBLE) + JabberSend(this, "", jid); + else if (oldMode == ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_INVISIBLE) + JabberSend(this, "available", jid); + break; + } + db_free(&dbv); + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +struct SENDACKTHREADDATA +{ + __inline SENDACKTHREADDATA(TlenProtocol *_ppro, HANDLE _hContact, int _msgid=0) : + proto(_ppro), hContact(_hContact), msgid(_msgid) + {} + + TlenProtocol *proto; + HANDLE hContact; + int msgid; +}; + +static void __cdecl JabberSendMessageAckThread(void *ptr) +{ + SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; + SleepEx(10, TRUE); + ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)data->msgid, 0); + delete data; +} + +static void __cdecl TlenSendMessageFailedThread(void *ptr) +{ + SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; + SleepEx(10, TRUE); + ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)data->msgid, 0); + delete data; +} + +static void __cdecl TlenGetAwayMsgThread(void *ptr) +{ + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; + if (!db_get(data->hContact, data->proto->m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(data->proto, LIST_ROSTER, dbv.pszVal)) != NULL) { + db_free(&dbv); + ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, + item->statusMessage==NULL ? (LPARAM)NULL : (LPARAM)(TCHAR*)_A2T(item->statusMessage)); + return; + } + else db_free(&dbv); + } + ProtoBroadcastAck(data->proto->m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)(TCHAR*)TEXT("")); + delete data; +} + +INT_PTR TlenProtocol::SendAlert(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = ( HANDLE )wParam; + DBVARIANT dbv; + if (isOnline && !db_get(hContact, m_szModuleName, "jid", &dbv)) { + JabberSend(this, "", dbv.pszVal); + + db_free(&dbv); + } + return 0; +} + +int TlenProtocol::SendMsg(HANDLE hContact, int flags, const char* msgRAW) +{ + DBVARIANT dbv; + char *msgEnc; + JABBER_LIST_ITEM *item; + char msgType[16]; + + if (!isOnline || db_get(hContact, m_szModuleName, "jid", &dbv)) { + JabberForkThread(TlenSendMessageFailedThread, 0, new SENDACKTHREADDATA(this, hContact, 2)); + return 2; + } + + char* msg; + if (flags & PREF_UNICODE) + msg = mir_u2a((wchar_t*)&msgRAW[strlen(msgRAW) + 1]); + else if (flags & PREF_UTF) + msg = mir_utf8decodeA(msgRAW); + else + msg = mir_strdup(msgRAW); + + + int id = JabberSerialNext(this); + + if (!strcmp(msg, "")) { + JabberSend(this, "", dbv.pszVal); + JabberForkThread(JabberSendMessageAckThread, 0, new SENDACKTHREADDATA(this, hContact, id)); + } + else if (!strcmp(msg, "")) { + JabberSend(this, "", dbv.pszVal, "pic", 0x757f044, id); + JabberForkThread(JabberSendMessageAckThread, 0, new SENDACKTHREADDATA(this, hContact, id)); + } + else { + if ((msgEnc=JabberTextEncode(msg)) != NULL) { + if (JabberListExist(this, LIST_CHATROOM, dbv.pszVal) && strchr(dbv.pszVal, '/') == NULL) + strcpy(msgType, "groupchat"); + else if (db_get_b(hContact, m_szModuleName, "bChat", FALSE)) + strcpy(msgType, "privchat"); + else + strcpy(msgType, "chat"); + + if (!strcmp(msgType, "groupchat") || db_get_b(NULL, m_szModuleName, "MsgAck", FALSE) == FALSE) { + SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); + tdata->proto = this; + tdata->hContact = hContact; + if (!strcmp(msgType, "groupchat")) + JabberSend(this, "%s", dbv.pszVal, msgType, msgEnc); + else if (!strcmp(msgType, "privchat")) + JabberSend(this, "%s", dbv.pszVal, msgEnc); + else + JabberSend(this, "%s", dbv.pszVal, msgType, id, msgEnc); + + JabberForkThread(JabberSendMessageAckThread, 0, new SENDACKTHREADDATA(this, hContact, id)); + } + else { + if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL) + item->idMsgAckPending = id; + JabberSend(this, "%s", dbv.pszVal, msgType, id, msgEnc); + } + } + mir_free(msgEnc); + } + + mir_free(msg); + db_free(&dbv); + return id; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// JabberGetAvatarInfo - retrieves the avatar info + +INT_PTR TlenProtocol::GetAvatarInfo(WPARAM wParam, LPARAM lParam) +{ + BOOL downloadingAvatar = FALSE; + char *avatarHash = NULL; + JABBER_LIST_ITEM *item = NULL; + DBVARIANT dbv; + PROTO_AVATAR_INFORMATIONT* AI = ( PROTO_AVATAR_INFORMATIONT* )lParam; + if (!tlenOptions.enableAvatars) return GAIR_NOAVATAR; + + if (AI->hContact != NULL) { + if (!db_get(AI->hContact, m_szModuleName, "jid", &dbv)) { + item = JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal); + db_free(&dbv); + if (item != NULL) { + downloadingAvatar = item->newAvatarDownloading; + avatarHash = item->avatarHash; + } + } + } + else if (threadData != NULL) + avatarHash = threadData->avatarHash; + + if ((avatarHash == NULL || avatarHash[0] == '\0') && !downloadingAvatar) + return GAIR_NOAVATAR; + + if (avatarHash != NULL && !downloadingAvatar) { + TlenGetAvatarFileName(this, item, AI->filename, sizeof(AI->filename)); + AI->format = ( AI->hContact == NULL ) ? threadData->avatarFormat : item->avatarFormat; + return GAIR_SUCCESS; + } + + /* get avatar */ + if (( wParam & GAIF_FORCE ) != 0 && AI->hContact != NULL && isOnline) + return GAIR_WAITFOR; + + return GAIR_NOAVATAR; +} + +HANDLE TlenProtocol::GetAwayMsg(HANDLE hContact) +{ + SENDACKTHREADDATA *tdata = new SENDACKTHREADDATA(this, hContact, 0); + JabberForkThread((void (__cdecl *)(void*))TlenGetAwayMsgThread, 0, (void*)tdata); + return (HANDLE)1; +} + +int TlenProtocol::RecvAwayMsg(HANDLE hContact, int mode, PROTORECVEVENT* evt) +{ + return 0; +} + +int TlenProtocol::SendAwayMsg(HANDLE hContact, HANDLE hProcess, const char* msg) +{ + return 0; +} + +HANDLE TlenProtocol::FileAllow(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath) +{ + TLEN_FILE_TRANSFER *ft; + JABBER_LIST_ITEM *item; + char *nick; + + if (!isOnline) return 0; + + ft = (TLEN_FILE_TRANSFER *) hTransfer; + ft->szSavePath = mir_strdup(mir_t2a(szPath)); //TODO convert to PROTOCHAR* + if ((item=JabberListAdd(this, LIST_FILE, ft->iqId)) != NULL) { + item->ft = ft; + } + nick = JabberNickFromJID(ft->jid); + if (ft->newP2P) { + JabberSend(this, "", ft->jid, ft->jid, ft->iqId); + } else { + JabberSend(this, "", nick, ft->iqId); + } + mir_free(nick); + return (HANDLE)hTransfer; +} + +int TlenProtocol::FileDeny(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason) +{ + TLEN_FILE_TRANSFER *ft; + char *nick; + + if (!isOnline) return 1; + + ft = (TLEN_FILE_TRANSFER *) hTransfer; + nick = JabberNickFromJID(ft->jid); + if (ft->newP2P) { + JabberSend(this, "", ft->iqId, nick);\ + } else { + JabberSend(this, "", ft->iqId, nick);\ + } + mir_free(nick); + TlenP2PFreeFileTransfer(ft); + return 0; +} + +int TlenProtocol::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename) { + return 0; +} + +int TlenProtocol::FileCancel(HANDLE hContact, HANDLE hTransfer) +{ + TLEN_FILE_TRANSFER *ft = (TLEN_FILE_TRANSFER *) hTransfer; + JabberLog(this, "Invoking FileCancel()"); + if (ft->s != NULL) { + ft->state = FT_ERROR; + Netlib_CloseHandle(ft->s); + ft->s = NULL; + if (ft->hFileEvent != NULL) { + HANDLE hEvent = ft->hFileEvent; + ft->hFileEvent = NULL; + SetEvent(hEvent); + } + } else { + TlenP2PFreeFileTransfer(ft); + } + return 0; +} + +HANDLE TlenProtocol::SendFile(HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) +{ + TLEN_FILE_TRANSFER *ft; + int i, j; + struct _stat statbuf; + DBVARIANT dbv; + char *nick, *p, idStr[10]; + JABBER_LIST_ITEM *item; + int id; + + if (!isOnline) return 0; +// if (db_get_w(ccs->hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) return 0; + if (db_get(hContact, m_szModuleName, "jid", &dbv)) return 0; + ft = TlenFileCreateFT(this, dbv.pszVal); + for (ft->fileCount=0; ppszFiles[ft->fileCount]; ft->fileCount++); + ft->files = (char **) mir_alloc(sizeof(char *) * ft->fileCount); + ft->filesSize = (long *) mir_alloc(sizeof(long) * ft->fileCount); + ft->allFileTotalSize = 0; + for (i=j=0; ifileCount; i++) { + char* ppszFiles_i_A = mir_t2a(ppszFiles[i]); + if (_stat(ppszFiles_i_A, &statbuf)) + JabberLog(this, "'%s' is an invalid filename", ppszFiles[i]); + else { + ft->filesSize[j] = statbuf.st_size; + ft->files[j++] = mir_strdup(ppszFiles_i_A); + ft->allFileTotalSize += statbuf.st_size; + } + mir_free(ppszFiles_i_A); + } + ft->fileCount = j; + ft->szDescription = mir_t2a(szDescription); + ft->hContact = hContact; + ft->currentFile = 0; + db_free(&dbv); + + id = JabberSerialNext(this); + mir_snprintf(idStr, sizeof(idStr), "%d", id); + if ((item=JabberListAdd(this, LIST_FILE, idStr)) != NULL) { + ft->iqId = mir_strdup(idStr); + nick = JabberNickFromJID(ft->jid); + item->ft = ft; + if (tlenOptions.useNewP2P) { + JabberSend(this, "", + ft->jid, ft->jid, idStr, ft->fileCount, ft->allFileTotalSize, ft->fileCount); + + ft->newP2P = TRUE; + } else { + if (ft->fileCount == 1) { + char* ppszFiles_0_A = mir_t2a(ppszFiles[0]); + if ((p=strrchr(ppszFiles_0_A, '\\')) != NULL) { + p++; + } else { + p = ppszFiles_0_A; + } + p = JabberTextEncode(p); + JabberSend(this, "", nick, p, idStr, ft->allFileTotalSize); + mir_free(ppszFiles[0]); + mir_free(p); + } else { + JabberSend(this, "", nick, idStr, ft->fileCount, ft->allFileTotalSize); + } + } + mir_free(nick); + } + + return (HANDLE) ft; +} + +int TlenProtocol::SendContacts(HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList){ + return 0; +} + +int TlenProtocol::SendUrl(HANDLE hContact, int flags, const char* urlt){ + return 0; +} + +int TlenProtocol::RecvMsg(HANDLE hContact, PROTORECVEVENT* evt) +{ + return Proto_RecvMessage(hContact, evt); +} + +int TlenProtocol::RecvFile(HANDLE hContact, PROTOFILEEVENT* evt) +{ + return Proto_RecvFile(hContact, evt); +} + +int TlenProtocol::RecvUrl(HANDLE hContact, PROTORECVEVENT*) +{ + return 0; +} + +static char* settingToChar( DBCONTACTWRITESETTING* cws ) +{ + switch( cws->value.type ) { + case DBVT_ASCIIZ: + return mir_strdup( cws->value.pszVal ); + case DBVT_UTF8: + return mir_utf8decode(mir_strdup(cws->value.pszVal), NULL); + } + return NULL; +} + +int TlenProtocol::JabberDbSettingChanged(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam; + // no action for hContact == NULL or when offline + if ((HANDLE) wParam == NULL) return 0; + if (!isConnected) return 0; + + if (!strcmp(cws->szModule, "CList")) { + HANDLE hContact; + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + char *szProto, *nick, *jid, *group; + + hContact = (HANDLE) wParam; + szProto = GetContactProto(hContact); + if (szProto == NULL || strcmp(szProto, m_szModuleName)) return 0; + // A contact's group is changed + if (!strcmp(cws->szSetting, "Group")) { + if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL) { + db_free(&dbv); + if (!db_get(hContact, "CList", "MyHandle", &dbv)) { + nick = JabberTextEncode(dbv.pszVal); + db_free(&dbv); + } + else if (!db_get(hContact, this->m_szModuleName, "Nick", &dbv)) { + nick = JabberTextEncode(dbv.pszVal); + db_free(&dbv); + } + else nick = JabberNickFromJID(item->jid); + + if (nick != NULL) { + // Note: we need to compare with item->group to prevent infinite loop + if (cws->value.type == DBVT_DELETED && item->group != NULL) { + JabberLog(this, "Group set to nothing"); + JabberSend(this, "", nick, item->jid); + } + else if (cws->value.pszVal != NULL) { + char *newGroup = settingToChar(cws); + if (item->group == NULL || strcmp(newGroup, item->group)) { + JabberLog(this, "Group set to %s", newGroup); + if ((group=TlenGroupEncode(newGroup)) != NULL) { + JabberSend(this, "%s", nick, item->jid, group); + mir_free(group); + } + } + mir_free(newGroup); + } + mir_free(nick); + } + } + else { + db_free(&dbv); + } + } + } + // A contact is renamed + else if (!strcmp(cws->szSetting, "MyHandle")) { + char *newNick; + +// hContact = (HANDLE) wParam; +// szProto = GetContactProto(hContact); +// if (szProto == NULL || strcmp(szProto, proto->m_szModuleName)) return 0; + + if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { + jid = dbv.pszVal; + if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL) { + if (cws->value.type == DBVT_DELETED) { + newNick = mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_NOMYHANDLE)); + } else if (cws->value.pszVal != NULL) { + newNick = settingToChar(cws); + } else { + newNick = NULL; + } + // Note: we need to compare with item->nick to prevent infinite loop + if (newNick != NULL && (item->nick == NULL || (item->nick != NULL && strcmp(item->nick, newNick)))) { + if ((nick=JabberTextEncode(newNick)) != NULL) { + JabberLog(this, "Nick set to %s", newNick); + if (item->group != NULL && (group=TlenGroupEncode(item->group)) != NULL) { + JabberSend(this, "%s", nick, jid, group); + mir_free(group); + } else { + JabberSend(this, "", nick, jid); + } + mir_free(nick); + } + } + if (newNick != NULL) mir_free(newNick); + } + db_free(&dbv); + } + } + // A temporary contact has been added permanently + else if (!strcmp(cws->szSetting, "NotOnList")) { + char *jid, *nick, *pGroup; + + if (cws->value.type==DBVT_DELETED || (cws->value.type==DBVT_BYTE && cws->value.bVal==0)) { + if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { + jid = mir_strdup(dbv.pszVal); + db_free(&dbv); + JabberLog(this, "Add %s permanently to list", jid); + if (!db_get(hContact, "CList", "MyHandle", &dbv)) { + nick = JabberTextEncode(dbv.pszVal); //Utf8Encode + db_free(&dbv); + } + else { + nick = JabberNickFromJID(jid); + } + if (nick != NULL) { + JabberLog(this, "jid=%s nick=%s", jid, nick); + if (!db_get(hContact, "CList", "Group", &dbv)) { + if ((pGroup=TlenGroupEncode(dbv.pszVal)) != NULL) { + JabberSend(this, "%s", nick, jid, pGroup); + JabberSend(this, "", jid); + mir_free(pGroup); + } + db_free(&dbv); + } + else { + JabberSend(this, "", nick, jid); + JabberSend(this, "", jid); + } + mir_free(nick); + db_unset(hContact, "CList", "Hidden"); + } + mir_free(jid); + } + } + } + } + + return 0; +} + +int TlenProtocol::JabberContactDeleted(WPARAM wParam, LPARAM lParam) +{ + if (!isOnline) // should never happen + return 0; + + char *szProto = GetContactProto((HANDLE)wParam); + if (szProto == NULL || strcmp(szProto, m_szModuleName)) + return 0; + + DBVARIANT dbv; + if (!db_get((HANDLE) wParam, m_szModuleName, "jid", &dbv)) { + char *jid, *p, *q; + + jid = dbv.pszVal; + if ((p=strchr(jid, '@')) != NULL) { + if ((q=strchr(p, '/')) != NULL) + *q = '\0'; + } + + // Remove from roster, server also handles the presence unsubscription process. + if (JabberListExist(this, LIST_ROSTER, jid)) + JabberSend(this, "", jid); + + db_free(&dbv); + } + return 0; +} + +int TlenProtocol::UserIsTyping(HANDLE hContact, int type) +{ + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + + if (!isOnline) return 0; + if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(this, LIST_ROSTER, dbv.pszVal)) != NULL /*&& item->wantComposingEvent == TRUE*/) { + switch (type) { + case PROTOTYPE_SELFTYPING_OFF: + JabberSend(this, "", dbv.pszVal); + break; + case PROTOTYPE_SELFTYPING_ON: + JabberSend(this, "", dbv.pszVal); + break; + } + } + db_free(&dbv); + } + return 0; +} + +INT_PTR TlenProtocol::GetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + TCHAR* buf = (TCHAR*)wParam; + int size = ( int )lParam; + if ( buf == NULL || size <= 0 ) + return -1; + + TlenGetAvatarFileName(this, NULL, buf, size); + return 0; +} + +static INT_PTR CALLBACK TlenChangeAvatarDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + { + HICON hIcon = GetIcolibIcon(IDI_TLEN); + SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon); + ReleaseIcolibIcon(hIcon); + } + CheckDlgButton(hwndDlg, IDC_PUBLICAVATAR, TRUE); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + { + int result = LOWORD(wParam); + if (IsDlgButtonChecked(hwndDlg, IDC_PUBLICAVATAR)) { + result |= 0x10000; + } + EndDialog(hwndDlg, result); + } + return TRUE; + } + break; + } + return 0; +} + +INT_PTR TlenProtocol::SetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + TCHAR* szFileName = ( TCHAR* )lParam; + TCHAR tFileName[ MAX_PATH ]; + if (!isOnline) return 1; + if (szFileName != NULL) { + int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_USER_CHANGEAVATAR), NULL, TlenChangeAvatarDlgProc, (LPARAM) NULL); + TlenGetAvatarFileName(this, NULL, tFileName, MAX_PATH); + if ( CopyFile( szFileName, tFileName, FALSE ) == FALSE ) + return 1; + + char* tFileNameA = mir_t2a(tFileName); //TODO - drop io.h + int fileIn = open( tFileNameA, O_RDWR | O_BINARY, S_IREAD | S_IWRITE ); + if ( fileIn != -1 ) { + long dwPngSize = filelength(fileIn); + BYTE* pResult = (BYTE *)mir_alloc(dwPngSize); + if (pResult != NULL) { + read( fileIn, pResult, dwPngSize ); + close( fileIn ); + TlenUploadAvatar(this, pResult, dwPngSize, (result & 0x10000) != 0); + mir_free(pResult); + } + } + mir_free(tFileName); + mir_free(tFileNameA); + } + else TlenRemoveAvatar(this); + + return 0; +} + +INT_PTR TlenProtocol::GetAvatarCaps(WPARAM wParam, LPARAM lParam) +{ + switch (wParam) { + case AF_MAXSIZE: + { + POINT* size = (POINT*)lParam; + if ( size ) + size->x = size->y = 64; + } + return 0; + case AF_PROPORTION: + return PIP_SQUARE; + case AF_FORMATSUPPORTED: + return (lParam == PA_FORMAT_PNG) ? 1 : 0; + case AF_ENABLED: + return (tlenOptions.enableAvatars && isOnline) ? 1 : 0; + case AF_DONTNEEDDELAYS: + return 1; + case AF_MAXFILESIZE: + return 10 * 1024; + case AF_DELAYAFTERFAIL: + return 0; + } + return 0; +} + +int TlenProtocol::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam) +{ + //TlenProtocol *proto = (TlenProtocol *)ptr; + switch( iEventType ) { + case EV_PROTO_ONLOAD: return OnModulesLoaded(0, 0); + case EV_PROTO_ONOPTIONS: return OptionsInit(wParam, lParam); + case EV_PROTO_ONEXIT: return PreShutdown(0, 0); + case EV_PROTO_ONRENAME: + { + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_NAME | CMIF_TCHAR; + mi.ptszName = m_tszUserName; + Menu_ModifyItem(hMenuRoot, &mi); + /* FIXME: Rename network user as well */ + } + } + return 1; +} + +// PSS_ADDED +int TlenProtocol::AuthRecv(HANDLE hContact, PROTORECVEVENT* evt) +{ + return 1; +} + +// PSS_AUTHREQUEST +int TlenProtocol::AuthRequest(HANDLE hContact, const PROTOCHAR* szMessage) +{ + return 1; +} + +HANDLE TlenProtocol::ChangeInfo(int iInfoType, void* pInfoData) +{ + return NULL; +} + + +int TlenProtocol::RecvContacts(HANDLE hContact, PROTORECVEVENT* evt) +{ + return 1; +} + +extern INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +INT_PTR TlenProtocol::AccMgrUI(WPARAM wParam, LPARAM lParam) +{ + return (INT_PTR)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, TlenAccMgrUIDlgProc, (LPARAM)this); +} + +void TlenInitServicesVTbl(TlenProtocol *proto) +{ + proto->CreateProtoService(PS_GETNAME, &TlenProtocol::GetName); + proto->CreateProtoService(PS_GETAVATARINFO, &TlenProtocol::GetAvatarInfo); + proto->CreateProtoService(PS_SEND_NUDGE, &TlenProtocol::SendAlert); + proto->CreateProtoService(PS_GETAVATARCAPS, &TlenProtocol::GetAvatarCaps); + proto->CreateProtoService(PS_SETMYAVATART, &TlenProtocol::SetMyAvatar); + proto->CreateProtoService(PS_GETMYAVATART, &TlenProtocol::GetMyAvatar); + proto->CreateProtoService(PS_GETSTATUS, &TlenProtocol::GetStatus); + proto->CreateProtoService(PS_CREATEACCMGRUI, &TlenProtocol::AccMgrUI); +} + +TlenProtocol::TlenProtocol( const char *aProtoName, const TCHAR *aUserName) : + PROTO(aProtoName, aUserName) +{ + TlenInitServicesVTbl(this); + + InitializeCriticalSection(&modeMsgMutex); + InitializeCriticalSection(&csSend); + + hTlenNudge = CreateProtoEvent("/Nudge"); + + HookProtoEvent(ME_OPT_INITIALISE, &TlenProtocol::OptionsInit); + HookProtoEvent(ME_DB_CONTACT_SETTINGCHANGED, &TlenProtocol::JabberDbSettingChanged); + HookProtoEvent(ME_DB_CONTACT_DELETED, &TlenProtocol::JabberContactDeleted); + HookProtoEvent(ME_CLIST_PREBUILDCONTACTMENU, &TlenProtocol::PrebuildContactMenu); + HookProtoEvent(ME_SYSTEM_PRESHUTDOWN, &TlenProtocol::PreShutdown); + + DBVARIANT dbv; + if (!db_get(NULL, m_szModuleName, "LoginServer", &dbv)) + db_free(&dbv); + else + db_set_s(NULL, m_szModuleName, "LoginServer", "tlen.pl"); + + if (!db_get(NULL, m_szModuleName, "ManualHost", &dbv)) + db_free(&dbv); + else + db_set_s(NULL, m_szModuleName, "ManualHost", "s1.tlen.pl"); + + TlenLoadOptions(this); + + JabberWsInit(this); + JabberSerialInit(this); + JabberIqInit(this); + JabberListInit(this); + + initMenuItems(); +} + +TlenProtocol::~TlenProtocol() +{ + uninitMenuItems(this); + TlenVoiceCancelAll(this); + TlenFileCancelAll(this); + if (hTlenNudge) + DestroyHookableEvent(hTlenNudge); + JabberListUninit(this); + JabberIqUninit(this); + JabberSerialUninit(this); + DeleteCriticalSection(&modeMsgMutex); + DeleteCriticalSection(&csSend); + JabberWsUninit(this); + + mir_free(modeMsgs.szOnline); + mir_free(modeMsgs.szAway); + mir_free(modeMsgs.szNa); + mir_free(modeMsgs.szDnd); + mir_free(modeMsgs.szFreechat); + mir_free(modeMsgs.szInvisible); +} diff --git a/protocols/Tlen/src/tlen_thread.cpp b/protocols/Tlen/src/tlen_thread.cpp new file mode 100644 index 0000000000..4e26a83193 --- /dev/null +++ b/protocols/Tlen/src/tlen_thread.cpp @@ -0,0 +1,1409 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" + +#include "commons.h" +#include "tlen_list.h" +#include "tlen_iq.h" +#include "resource.h" +#include "tlen_p2p_old.h" +#include "tlen_file.h" +#include "tlen_muc.h" +#include "tlen_voice.h" +#include "tlen_avatar.h" +#include "tlen_presence.h" +#include "tlen_picture.h" +#include +#include +#include + + +extern void __cdecl TlenProcessP2P(XmlNode *node, ThreadData *info); + + +//static void __cdecl TlenProcessInvitation(struct ThreadData *info); +static void __cdecl JabberKeepAliveThread(void *ptr); +static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info); +static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info); +static void JabberProcessProtocol(XmlNode *node, ThreadData *info); +static void JabberProcessMessage(XmlNode *node, ThreadData *info); +static void JabberProcessIq(XmlNode *node, ThreadData *info); +static void TlenProcessW(XmlNode *node, ThreadData *info); +static void TlenProcessM(XmlNode *node, ThreadData *info); +static void TlenProcessN(XmlNode *node, ThreadData *info); +static void TlenProcessP(XmlNode *node, ThreadData *info); +static void TlenProcessV(XmlNode *node, ThreadData *info); +static void TlenProcessAvatar(XmlNode* node, ThreadData *info); +static void TlenProcessCipher(XmlNode *node, ThreadData *info); + +static VOID NTAPI JabberDummyApcFunc(ULONG_PTR param) +{ + return; +} + +static char onlinePassword[128]; +static HANDLE hEventPasswdDlg; + +static INT_PTR CALLBACK JabberPasswordDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[128]; + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + mir_snprintf(text, SIZEOF(text), "%s %s", Translate("Enter password for"), (char *) lParam); + SetDlgItemTextA(hwndDlg, IDC_JID, text); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + GetDlgItemTextA(hwndDlg, IDC_PASSWORD, onlinePassword, sizeof(onlinePassword)); + //EndDialog(hwndDlg, (int) onlinePassword); + //return TRUE; + // Fall through + case IDCANCEL: + //EndDialog(hwndDlg, 0); + SetEvent(hEventPasswdDlg); + DestroyWindow(hwndDlg); + return TRUE; + } + break; + } + + return FALSE; +} + +static VOID NTAPI JabberPasswordCreateDialogApcProc(ULONG_PTR param) +{ + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) param); +} + +void __cdecl JabberServerThread(ThreadData *info) +{ + DBVARIANT dbv; + char jidStr[128]; + char *connectHost; + char *buffer; + int datalen; + XmlState xmlState; + int jabberNetworkBufferSize; + int oldStatus = ID_STATUS_OFFLINE; + int reconnectMaxTime; + int numRetry; + int reconnectTime; + int loginErr = 0; + JabberLog(info->proto, "Thread started"); + + // Normal server connection, we will fetch all connection parameters + // e.g. username, password, etc. from the database. + + if (info->proto->threadData != NULL) { + // Will not start another connection thread if a thread is already running. + // Make APC call to the main thread. This will immediately wake the thread up + // in case it is asleep in the reconnect loop so that it will immediately + // reconnect. + QueueUserAPC(JabberDummyApcFunc, info->proto->threadData->hThread, 0); + JabberLog(info->proto, "Thread ended, another normal thread is running"); + mir_free(info); + return; + } + + info->proto->threadData = info; + + if (!db_get(NULL, info->proto->m_szModuleName, "LoginName", &dbv)) { + strncpy(info->username, dbv.pszVal, sizeof(info->username)); + info->username[sizeof(info->username)-1] = '\0'; + _strlwr(info->username); + db_set_s(NULL, info->proto->m_szModuleName, "LoginName", info->username); + db_free(&dbv); + + } else { + JabberLog(info->proto, "Thread ended, login name is not configured"); + loginErr = LOGINERR_BADUSERID; + } + + if (loginErr == 0) { + if (!db_get(NULL, info->proto->m_szModuleName, "LoginServer", &dbv)) { + strncpy(info->server, dbv.pszVal, sizeof(info->server)); + info->server[sizeof(info->server)-1] = '\0'; + _strlwr(info->server); + db_set_s(NULL, info->proto->m_szModuleName, "LoginServer", info->server); + db_free(&dbv); + } else { + JabberLog(info->proto, "Thread ended, login server is not configured"); + loginErr = LOGINERR_NONETWORK; + } + } + + if (loginErr == 0) { + if (!info->proto->tlenOptions.savePassword) { + // Ugly hack: continue logging on only the return value is &(onlinePassword[0]) + // because if WM_QUIT while dialog box is still visible, p is returned with some + // exit code which may not be NULL. + // Should be better with modeless. + onlinePassword[0] = (char) -1; + hEventPasswdDlg = CreateEvent(NULL, FALSE, FALSE, NULL); + QueueUserAPC(JabberPasswordCreateDialogApcProc, hMainThread, (DWORD) jidStr); + WaitForSingleObject(hEventPasswdDlg, INFINITE); + CloseHandle(hEventPasswdDlg); + //if ((p=(char *)DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) jidStr)) != onlinePassword) { + if (onlinePassword[0] != (char) -1) { + strncpy(info->password, onlinePassword, sizeof(info->password)); + info->password[sizeof(info->password)-1] = '\0'; + } else { + JabberLog(info->proto, "Thread ended, password request dialog was canceled"); + loginErr = LOGINERR_BADUSERID; + } + } else { + if (!db_get(NULL, info->proto->m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + strncpy(info->password, dbv.pszVal, sizeof(info->password)); + info->password[sizeof(info->password)-1] = '\0'; + db_free(&dbv); + } else { + JabberLog(info->proto, "Thread ended, password is not configured"); + loginErr = LOGINERR_BADUSERID; + } + } + } + + jabberNetworkBufferSize = 2048; + if ((buffer=(char *) mir_alloc(jabberNetworkBufferSize+1)) == NULL) { // +1 is for '\0' when debug logging this buffer + JabberLog(info->proto, "Thread ended, network buffer cannot be allocated"); + loginErr = LOGINERR_NONETWORK; + } + + if (loginErr != 0) { + info->proto->threadData = NULL; + oldStatus = info->proto->m_iStatus; + info->proto->m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, loginErr); + mir_free(info); + return; + } + + mir_snprintf(jidStr, sizeof(jidStr), "%s@%s", info->username, info->server); + db_set_s(NULL, info->proto->m_szModuleName, "jid", jidStr); + + if (!db_get(NULL, info->proto->m_szModuleName, "ManualHost", &dbv)) { + strncpy(info->manualHost, dbv.pszVal, sizeof(info->manualHost)); + info->manualHost[sizeof(info->manualHost)-1] = '\0'; + db_free(&dbv); + } + info->port = db_get_w(NULL, info->proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT); + info->useEncryption = info->proto->tlenOptions.useEncryption; + + if (info->manualHost[0]) + connectHost = info->manualHost; + else + connectHost = info->server; + + JabberLog(info->proto, "Thread server='%s' port='%d'", connectHost, info->port); + + + if (!db_get(NULL, info->proto->m_szModuleName, "AvatarHash", &dbv)) { + strcpy(info->proto->threadData->avatarHash, dbv.pszVal); + db_free(&dbv); + } + info->avatarFormat = db_get_dw(NULL, info->proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); + + + reconnectMaxTime = 10; + numRetry = 0; + + for (;;) { // Reconnect loop + + info->s = JabberWsConnect(info->proto, connectHost, info->port); + if (info->s == NULL) { + JabberLog(info->proto, "Connection failed (%d)", WSAGetLastError()); + if (info->proto->threadData == info) { + oldStatus = info->proto->m_iStatus; + info->proto->m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NONETWORK); + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); + if (info->proto->tlenOptions.reconnect == TRUE) { + reconnectTime = rand() % reconnectMaxTime; + JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); + SleepEx(reconnectTime * 1000, TRUE); + if (reconnectMaxTime < 10*60) // Maximum is 10 minutes + reconnectMaxTime *= 2; + if (info->proto->threadData == info) { // Make sure this is still the active thread for the main Jabber connection + JabberLog(info->proto, "Reconnecting to the network..."); + if (numRetry < MAX_CONNECT_RETRIES) + numRetry++; + oldStatus = info->proto->m_iStatus; + info->proto->m_iStatus = ID_STATUS_CONNECTING + numRetry; + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); + continue; + } + else { + JabberLog(info->proto, "Thread ended, connection failed"); + mir_free(buffer); + mir_free(info); + return; + } + } + info->proto->threadData = NULL; + } + JabberLog(info->proto, "Thread ended, connection failed"); + mir_free(buffer); + mir_free(info); + return; + } + + // User may change status to OFFLINE while we are connecting above + if (info->proto->m_iDesiredStatus != ID_STATUS_OFFLINE) { + + info->proto->isConnected = TRUE; + JabberForkThread(JabberKeepAliveThread, 0, info->proto); + + JabberXmlInitState(&xmlState); + JabberXmlSetCallback(&xmlState, 1, ELEM_OPEN, (void (__cdecl *)(XmlNode *,void *))JabberProcessStreamOpening, info); + JabberXmlSetCallback(&xmlState, 1, ELEM_CLOSE, (void (__cdecl *)(XmlNode *,void *))JabberProcessStreamClosing, info); + JabberXmlSetCallback(&xmlState, 2, ELEM_CLOSE, (void (__cdecl *)(XmlNode *,void *))JabberProcessProtocol, info); + + info->useAES = FALSE; + + if (info->useEncryption) { + JabberSend(info->proto, ""); + + } else { + JabberSend(info->proto, ""); + } + + JabberLog(info->proto, "Entering main recv loop"); + datalen = 0; + + for (;;) { + int recvResult, bytesParsed; + + if (info->useAES) { + recvResult = JabberWsRecvAES(info->proto, buffer+datalen, jabberNetworkBufferSize-datalen, &info->aes_in_context, info->aes_in_iv); + } else { + recvResult = JabberWsRecv(info->proto, info->s, buffer+datalen, jabberNetworkBufferSize-datalen); + } + + if (recvResult <= 0) + break; + datalen += recvResult; + + buffer[datalen] = '\0'; + JabberLog(info->proto, "RECV:%s", buffer); + + bytesParsed = JabberXmlParse(&xmlState, buffer, datalen); + JabberLog(info->proto, "bytesParsed = %d", bytesParsed); + if (bytesParsed > 0) { + if (bytesParsed < datalen) + memmove(buffer, buffer+bytesParsed, datalen-bytesParsed); + datalen -= bytesParsed; + } + else if (datalen == jabberNetworkBufferSize) { + jabberNetworkBufferSize += 2048; + JabberLog(info->proto, "Increasing network buffer size to %d", jabberNetworkBufferSize); + if ((buffer=(char *) mir_realloc(buffer, jabberNetworkBufferSize+1)) == NULL) { + JabberLog(info->proto, "Cannot reallocate more network buffer, go offline now"); + break; + } + } + else { + JabberLog(info->proto, "Unknown state: bytesParsed=%d, datalen=%d, jabberNetworkBufferSize=%d", bytesParsed, datalen, jabberNetworkBufferSize); + } + } + + JabberXmlDestroyState(&xmlState); + + info->proto->isOnline = FALSE; + info->proto->isConnected = FALSE; + + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_FLAGS | CMIF_GRAYED; + Menu_ModifyItem(info->proto->hMenuMUC, &mi); + if (info->proto->hMenuChats != NULL) + Menu_ModifyItem(info->proto->hMenuChats, &mi); + + // Set status to offline + char *szProto = info->proto->m_szModuleName; + oldStatus = info->proto->m_iStatus; + info->proto->m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(szProto, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); + + // Set all contacts to offline + for (HANDLE hContact = db_find_first(szProto); hContact; hContact = db_find_next(hContact, szProto)) + if (db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + db_set_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); + + JabberListWipeSpecial(info->proto); + } + else { + oldStatus = info->proto->m_iStatus; + info->proto->m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); + } + + Netlib_CloseHandle(info->s); + + if (info->proto->tlenOptions.reconnect == FALSE) + break; + + if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread + break; + reconnectTime = rand() % 10; + JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); + SleepEx(reconnectTime * 1000, TRUE); + reconnectMaxTime = 20; + if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread + break; + JabberLog(info->proto, "Reconnecting to the network..."); + info->proto->m_iDesiredStatus = oldStatus; // Reconnect to my last status + oldStatus = info->proto->m_iStatus; + info->proto->m_iStatus = ID_STATUS_CONNECTING; + numRetry = 1; + ProtoBroadcastAck(info->proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->m_iStatus); + } + + JabberLog(info->proto, "Thread ended: server='%s'", info->server); + + if (info->proto->threadData == info) { + info->proto->threadData = NULL; + } + + mir_free(buffer); + if (info->streamId) mir_free(info->streamId); + JabberLog(info->proto, "Exiting ServerThread"); + mir_free(info); +} + +static void TlenSendAuth(TlenProtocol *proto) { + int iqId; + char *p; + char *str; + char text[128]; + str = TlenPasswordHash(proto->threadData->password); + mir_snprintf(text, SIZEOF(text), "%s%s", proto->threadData->streamId, str); + mir_free(str); + str = JabberSha1(text); + if ((p=JabberTextEncode(proto->threadData->username)) != NULL) { + iqId = JabberSerialNext(proto->threadData->proto); + JabberIqAdd(proto, iqId, IQ_PROC_NONE, JabberIqResultAuth); + JabberSend(proto, "%s%sttlen.pl", iqId, p /*info->username*/, str); + mir_free(p); + } + mir_free(str); +} + +static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info) +{ + char *sid, *s; + + if (node->name == NULL || strcmp(node->name, "s")) + return; + + if ((sid=JabberXmlGetAttrValue(node, "i")) != NULL) { + if (info->streamId) mir_free(info->streamId); + info->streamId = mir_strdup(sid); + } + if ((s=JabberXmlGetAttrValue(node, "s")) != NULL && !strcmp(s, "1")) { + int i; + char *k1, *k2, *k3; + unsigned char aes_key[32]; + char aes_key_str[140], aes_iv_str[40]; + mpi k1_mpi, k2_mpi, aes_mpi; + size_t slen; + + k1=JabberXmlGetAttrValue(node, "k1"); + k2=JabberXmlGetAttrValue(node, "k2"); + k3=JabberXmlGetAttrValue(node, "k3"); + + memset(&info->aes_in_context, 0, sizeof (aes_context)); + memset(&info->aes_out_context, 0, sizeof (aes_context)); + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_string(&aes_mpi, 16, k3); + mpi_write_binary(&aes_mpi, info->aes_in_iv, 16); + for (i = 0; i < 16; i++) { + info->aes_out_iv[i] = rand(); + aes_key[i] = rand(); + } + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_binary(&aes_mpi, info->aes_out_iv, 16); + slen = 40; + mpi_write_string(&aes_mpi, 16, aes_iv_str, &slen); + aes_setkey_dec(&info->aes_in_context, aes_key, 128); + aes_setkey_enc(&info->aes_out_context, aes_key, 128); + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_binary(&aes_mpi, aes_key, 16); + memset(&k1_mpi, 0, sizeof (mpi)); + mpi_read_string( &k1_mpi, 16, k1 ); + memset(&k2_mpi, 0, sizeof (mpi)); + mpi_read_string( &k2_mpi, 16, k2 ); + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_binary(&aes_mpi, (unsigned char *)aes_key, 16); + mpi_exp_mod( &aes_mpi, &aes_mpi, &k1_mpi, &k2_mpi, NULL ); + slen = 140; + mpi_write_string(&aes_mpi, 16, aes_key_str, &slen); + JabberSend(info->proto, "", aes_key_str, aes_iv_str); + } else { + TlenSendAuth(info->proto); + } +} + +static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info) +{ + Netlib_CloseHandle(info->proto); + if (node->name && !strcmp(node->name, "stream:error") && node->text) + MessageBoxA(NULL, Translate(node->text), Translate("Jabber Connection Error"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND); +} + +static void JabberProcessProtocol(XmlNode *node, ThreadData *info) +{ + if (!strcmp(node->name, "message")) + JabberProcessMessage(node, info); + else if (!strcmp(node->name, "presence")) + TlenProcessPresence(node, info->proto); + else if (!strcmp(node->name, "iq")) + JabberProcessIq(node, info); + else if (!strcmp(node->name, "f")) + TlenProcessF(node, info); + else if (!strcmp(node->name, "w")) + TlenProcessW(node, info); + else if (!strcmp(node->name, "m")) + TlenProcessM(node, info); + else if (!strcmp(node->name, "n")) + TlenProcessN(node, info); + else if (!strcmp(node->name, "p")) + TlenProcessP(node, info); + else if (!strcmp(node->name, "v")) + TlenProcessV(node, info); + else if (!strcmp(node->name, "avatar")) + TlenProcessAvatar(node, info); + else if (!strcmp(node->name, "cipher")) + TlenProcessCipher(node, info); + else + JabberLog(info->proto, "Invalid top-level tag (only

and allowed)"); + +} + +static void TlenProcessCipher(XmlNode *node, ThreadData *info) +{ + char *type; + type=JabberXmlGetAttrValue(node, "type"); + info->useAES = TRUE; + JabberSend(info->proto, ""); + TlenSendAuth(info->proto); +} + +static void TlenProcessIqGetVersion(TlenProtocol *proto, XmlNode* node) +{ + OSVERSIONINFO osvi = { 0 }; + char mversion[256]; + char* from, *version, *mver; + char* os = NULL; + JABBER_LIST_ITEM *item; + + if (proto->m_iStatus == ID_STATUS_INVISIBLE) return; + if (!proto->tlenOptions.enableVersion) return; + if (( from=JabberXmlGetAttrValue( node, "from" )) == NULL ) return; + if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) ==NULL) return; + version = JabberTextEncode( TLEN_VERSION_STRING ); + osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + if ( GetVersionEx( &osvi )) { + switch ( osvi.dwPlatformId ) { + case VER_PLATFORM_WIN32_NT: + if ( osvi.dwMajorVersion == 5 ) { + if ( osvi.dwMinorVersion == 2 ) os = JabberTextEncode( Translate( "Windows Server 2003" )); + else if ( osvi.dwMinorVersion == 1 ) os = JabberTextEncode( Translate( "Windows XP" )); + else if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 2000" )); + } + else if ( osvi.dwMajorVersion <= 4 ) { + os = JabberTextEncode( Translate( "Windows NT" )); + } + break; + case VER_PLATFORM_WIN32_WINDOWS: + if ( osvi.dwMajorVersion == 4 ) { + if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 95" )); + if ( osvi.dwMinorVersion == 10 ) os = JabberTextEncode( Translate( "Windows 98" )); + if ( osvi.dwMinorVersion == 90 ) os = JabberTextEncode( Translate( "Windows ME" )); + } + break; + } } + + if ( os == NULL ) os = JabberTextEncode( Translate( "Windows" )); + + strcpy(mversion, "Miranda NG "); + CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof( mversion ) - 11, ( LPARAM )mversion + 11 ); + strcat(mversion, " (Tlen v."); + strcat(mversion, TLEN_VERSION_STRING); + strcat(mversion, ")"); + mver = JabberTextEncode( mversion ); + JabberSend( proto, "%s%s%s", from, mver?mver:"", version?version:"", os?os:"" ); + if (!item->versionRequested) { + item->versionRequested = TRUE; + JabberSend(proto, "", from); + } + + if ( mver ) mir_free( mver ); + if ( version ) mir_free( version ); + if ( os ) mir_free( os ); +} + +// Support for Tlen avatars - avatar token used to access web interface +static void TlenProcessAvatar(XmlNode* node, ThreadData *info) +{ + XmlNode *tokenNode, *aNode; + tokenNode = JabberXmlGetChild(node, "token"); + aNode = JabberXmlGetChild(node, "a"); + if (tokenNode != NULL) { + char *token = tokenNode->text; + strcpy(info->avatarToken, token); + } + if (aNode != NULL) { + if (TlenProcessAvatarNode(info->proto, node, NULL)) { + } + } +} + +static void JabberProcessMessage(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + PROTORECVEVENT recv; + XmlNode *bodyNode, *subjectNode, *xNode, *n; + char *from, *type, *nick, *p, *localMessage, *idStr; + DWORD msgTime; + BOOL delivered, composing; + int i; + JABBER_LIST_ITEM *item; + BOOL isChatRoomJid; + + if (!node->name || strcmp(node->name, "message")) return; + + if ((type=JabberXmlGetAttrValue(node, "type")) != NULL && !strcmp(type, "error")) { + } + else { + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + char *fromJid = JabberLoginFromJID(from); + if (info->proto->tlenOptions.ignoreAdvertisements && strstr(from, "b73@tlen.pl") == from) { + return; + } + // If message is from a stranger (not in roster), item is NULL + item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fromJid); + isChatRoomJid = JabberListExist(info->proto, LIST_CHATROOM, from); + + if (isChatRoomJid && type != NULL && !strcmp(type, "groupchat")) { + //JabberGroupchatProcessMessage(node, userdata); + } else if (type != NULL && !strcmp(type, "pic")) { + TlenProcessPic(node, info->proto); + } else if (type != NULL && !strcmp(type, "iq")) { + XmlNode *iqNode; + // Jabber-compatible iq + if ((iqNode=JabberXmlGetChild(node, "iq")) != NULL) { + JabberXmlAddAttr(iqNode, "from", from); + JabberProcessIq(iqNode, info); + } + } else { + if ((bodyNode=JabberXmlGetChild(node, "body")) != NULL) { + if (bodyNode->text != NULL) { + if ((subjectNode=JabberXmlGetChild(node, "subject")) != NULL && subjectNode->text != NULL && subjectNode->text[0] != '\0') { + size_t size = strlen(subjectNode->text)+strlen(bodyNode->text)+5; + p = (char *)mir_alloc(size); + mir_snprintf(p, size, "%s\r\n%s", subjectNode->text, bodyNode->text); + localMessage = JabberTextDecode(p); + mir_free(p); + } else { + localMessage = JabberTextDecode(bodyNode->text); + } + + msgTime = 0; + delivered = composing = FALSE; + i = 1; + while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { + if ((p=JabberXmlGetAttrValue(xNode, "xmlns")) != NULL) { + if (!strcmp(p, "jabber:x:delay") && msgTime==0) { + if ((p=JabberXmlGetAttrValue(xNode, "stamp")) != NULL) { + msgTime = JabberIsoToUnixTime(p); + } + } + else if (!strcmp(p, "jabber:x:event")) { + // Check whether any event is requested + if (!delivered && (n=JabberXmlGetChild(xNode, "delivered")) != NULL) { + delivered = TRUE; + idStr = JabberXmlGetAttrValue(node, "id"); + JabberSend(info->proto, "%s", from, (idStr != NULL)?idStr:""); + } + if (item != NULL && JabberXmlGetChild(xNode, "composing") != NULL) { + composing = TRUE; + if (item->messageEventIdStr) + mir_free(item->messageEventIdStr); + idStr = JabberXmlGetAttrValue(node, "id"); + item->messageEventIdStr = (idStr == NULL)?NULL:mir_strdup(idStr); + } + } + } + i++; + } + + if (item != NULL) { + item->wantComposingEvent = composing; + if (item->isTyping) { + item->isTyping = FALSE; + if ((hContact=JabberHContactFromJID(info->proto, fromJid)) != NULL) + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); + } + } + + if ((hContact=JabberHContactFromJID(info->proto, fromJid)) == NULL) { + // Create a temporary contact + if (isChatRoomJid) { + if ((p=strchr(from, '/')) != NULL && p[1]!='\0') + p++; + else + p = from; + nick = JabberTextEncode(p); + hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); + } + else { + nick = JabberLocalNickFromJID(from); + hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); + } + mir_free(nick); + } + + if (msgTime == 0) { + msgTime = time(NULL); + } else { + HANDLE hDbEvent = db_event_last(hContact); + if (hDbEvent != NULL) { + DBEVENTINFO dbei = { sizeof(dbei) }; + db_event_get( hDbEvent, &dbei); + if (msgTime < dbei.timestamp) { + msgTime = dbei.timestamp + 1; + } + } + if (msgTime > (DWORD)time(NULL)) { + msgTime = time(NULL); + } + } + recv.flags = 0; + recv.timestamp = (DWORD) msgTime; + recv.szMessage = localMessage; + recv.lParam = 0; + ProtoChainRecvMsg(hContact, &recv); + mir_free(localMessage); + } + } + } + mir_free(fromJid); + } + } +} + +static void JabberProcessIq(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + XmlNode *queryNode = NULL; + char *type, *jid, *nick; + char *xmlns = NULL; + char *idStr, *str; + int id; + int i; + JABBER_IQ_PFUNC pfunc; + + if (!node->name || strcmp(node->name, "iq")) return; + type=JabberXmlGetAttrValue(node, "type"); +// if ((type=JabberXmlGetAttrValue(node, "type")) == NULL) return; + + id = -1; + if ((idStr=JabberXmlGetAttrValue(node, "id")) != NULL) { + if (!strncmp(idStr, JABBER_IQID, strlen(JABBER_IQID))) + id = atoi(idStr+strlen(JABBER_IQID)); + } + + queryNode = JabberXmlGetChild(node, "query"); + if (queryNode != NULL) { + xmlns = JabberXmlGetAttrValue(queryNode, "xmlns"); + } + + + ///////////////////////////////////////////////////////////////////////// + // MATCH BY ID + ///////////////////////////////////////////////////////////////////////// + if ((pfunc=JabberIqFetchFunc(info->proto, id)) != NULL) { + JabberLog(info->proto, "Handling iq request for id=%d", id); + pfunc(info->proto, node); + ///////////////////////////////////////////////////////////////////////// + // MORE GENERAL ROUTINES, WHEN ID DOES NOT MATCH + ///////////////////////////////////////////////////////////////////////// + // new p2p connections + } else if (xmlns != NULL && !strcmp(xmlns, "p2p")) { + if (info->proto->tlenOptions.useNewP2P) { + TlenProcessP2P(node, info); + } + } + // RECVED: proto, " Got roster push, query has %d children", queryNode->numChild); + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if ((str=JabberXmlGetAttrValue(itemNode, "subscription")) != NULL) { + // we will not add new account when subscription=remove + if (!strcmp(str, "to") || !strcmp(str, "both") || !strcmp(str, "from") || !strcmp(str, "none")) { + if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { + nick = JabberTextDecode(name); + } else { + nick = JabberLocalNickFromJID(jid); + } + if (nick != NULL) { + if ((item=JabberListAdd(info->proto, LIST_ROSTER, jid)) != NULL) { + if (item->nick) mir_free(item->nick); + item->nick = nick; + if ((hContact=JabberHContactFromJID(info->proto, jid)) == NULL) { + // Received roster has a new JID. + // Add the jid (with empty resource) to Miranda contact list. + hContact = JabberDBCreateContact(info->proto, jid, nick, FALSE); + } + db_set_s(hContact, "CList", "MyHandle", nick); + if (item->group) mir_free(item->group); + if ((groupNode=JabberXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { + item->group = TlenGroupDecode(groupNode->text); + JabberContactListCreateGroup(item->group); + db_set_s(hContact, "CList", "Group", item->group); + } + else { + item->group = NULL; + db_unset(hContact, "CList", "Group"); + } + if (!strcmp(str, "none") || (!strcmp(str, "from") && strchr(jid, '@') != NULL)) { + if (db_get_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + db_set_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); + } + } + else { + mir_free(nick); + } + } + } + if ((item=JabberListGetItemPtr(info->proto, LIST_ROSTER, jid)) != NULL) { + if (!strcmp(str, "both")) item->subscription = SUB_BOTH; + else if (!strcmp(str, "to")) item->subscription = SUB_TO; + else if (!strcmp(str, "from")) item->subscription = SUB_FROM; + else item->subscription = SUB_NONE; + JabberLog(info->proto, "Roster push for jid=%s, set subscription to %s", jid, str); + // subscription = remove is to remove from roster list + // but we will just set the contact to offline and not actually + // remove, so that history will be retained. + if (!strcmp(str, "remove")) { + if ((hContact=JabberHContactFromJID(info->proto, jid)) != NULL) { + if (db_get_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + db_set_w(hContact, info->proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); + JabberListRemove(info->proto, LIST_ROSTER, jid); + } + } + } + } + } + } + } + } + + } + // RECVED: proto, node); + } + // RECVED: proto, node); + } else if ( !strcmp( xmlns, "jabber:iq:version" )) { + TlenIqResultVersion(info->proto, node); + } else if ( !strcmp( xmlns, "jabber:iq:info" )) { + TlenIqResultInfo(info->proto, node); + } + } else { + char *from; + if (( from=JabberXmlGetAttrValue( node, "from" )) != NULL ) { + if ( !strcmp(from, "tcfg" )) { + TlenIqResultTcfg(info->proto, node); + } + } + } + } + // RECVED: ... + else if (!strcmp(type, "error")) { + JABBER_LIST_ITEM *item; + // Check for multi-user chat errors + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strstr(from, "@c") != NULL || !strcmp(from, "c")) { + TlenMUCRecvError(info->proto, from, node); + return; + } + } + + // Check for file transfer deny by comparing idStr with ft->iqId + i = 0; + while ((i=JabberListFindNext(info->proto, LIST_FILE, i)) >= 0) { + item = JabberListGetItemPtrFromIndex(info->proto,i); + if (item->ft->state==FT_CONNECTING && !strcmp(idStr, item->ft->iqId)) { + item->ft->state = FT_DENIED; + if (item->ft->hFileEvent != NULL) + SetEvent(item->ft->hFileEvent); // Simulate the termination of file server connection + } + i++; + } + } + // RECVED: ... + else if (!strcmp(type, "1")) { // Chat groups list result + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c") == 0) { + TlenIqResultChatGroups(info->proto, node); + } + } + } + else if (!strcmp(type, "2")) { // Chat rooms list result + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c") == 0) { + TlenIqResultChatRooms(info->proto, node); + } + } + } else if (!strcmp(type, "3")) { // room search result - result to iq type 3 query + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c") == 0) { + TlenIqResultRoomSearch(info->proto, node); + } + } + } else if (!strcmp(type, "4")) { // chat room users list + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strstr(from, "@c") != NULL) { + TlenIqResultChatRoomUsers(info->proto, node); + } + } + } else if (!strcmp(type, "5")) { // room name & group & flags info - sent on joining the room + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strstr(from, "@c") != NULL) { + TlenIqResultRoomInfo(info->proto, node); + } + } + } else if (!strcmp(type, "6")) { // new nick registered + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c") == 0) { + TlenIqResultUserNicks(info->proto, node); + } + } + } else if (!strcmp(type, "7")) { // user nicknames list + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c") == 0) { + TlenIqResultUserNicks(info->proto, node); + } + } + } else if (!strcmp(type, "8")) { // user chat rooms list + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c") == 0) { + TlenIqResultUserRooms(info->proto, node); + } + } + } +} + +/* + * Web messages + */ +static void TlenProcessW(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + PROTORECVEVENT recv; + char *f, *e, *s, *body; + char *str, *localMessage; + int strSize; + + if (!node->name || strcmp(node->name, "w")) return; + if ((body=node->text) == NULL) return; + + if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { + + char webContactName[128]; + mir_snprintf(webContactName, SIZEOF(webContactName), Translate("%s Web Messages"), info->proto->m_szModuleName); + if ((hContact=JabberHContactFromJID(info->proto, webContactName)) == NULL) { + hContact = JabberDBCreateContact(info->proto, webContactName, webContactName, TRUE); + } + + s = JabberXmlGetAttrValue(node, "s"); + e = JabberXmlGetAttrValue(node, "e"); + + str = NULL; + strSize = 0; + JabberStringAppend(&str, &strSize, "%s\r\n%s: ", Translate("Web message"), Translate("From")); + + if (f != NULL) + JabberStringAppend(&str, &strSize, "%s", f); + JabberStringAppend(&str, &strSize, "\r\n%s: ", Translate("E-mail")); + if (e != NULL) + JabberStringAppend(&str, &strSize, "%s", e); + JabberStringAppend(&str, &strSize, "\r\n\r\n%s", body); + + localMessage = JabberTextDecode(str); + + recv.flags = 0; + recv.timestamp = (DWORD) time(NULL); + recv.szMessage = localMessage; + recv.lParam = 0; + ProtoChainRecvMsg(hContact, &recv); + + mir_free(localMessage); + mir_free(str); + } +} + +/* + * Typing notification, multi-user conference messages and invitations + */ +static void TlenProcessM(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + PROTORECVEVENT recv; + char *f;//, *from;//username + char *tp;//typing start/stop + char *p, *n, *r, *s, *str, *localMessage; + int i; + XmlNode *xNode, *invNode, *bNode, *subjectNode; + + if (!node->name || strcmp(node->name, "m")) return; + + if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { + char *fLogin = JabberLoginFromJID(f); + if ((hContact=JabberHContactFromJID(info->proto, fLogin)) != NULL) { + if ((tp=JabberXmlGetAttrValue(node, "tp")) != NULL) { + JABBER_LIST_ITEM *item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fLogin); + if (!strcmp(tp, "t")) { //contact is writing + if (item != NULL ) { + item->isTyping = TRUE; + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_INFINITE); + } + } + else if (!strcmp(tp, "u")) {//contact stopped writing + if (item != NULL) { + item->isTyping = FALSE; + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); + } + } + else if (!strcmp(tp, "a")) {//alert was received + int bAlert = TRUE; + if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_ALL) { + bAlert = FALSE; + } else if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_NIR) { + bAlert = IsAuthorized(info->proto, fLogin); + } + if (bAlert) { + if (info->proto->tlenOptions.useNudge) { + NotifyEventHooks(info->proto->hTlenNudge,(WPARAM) hContact,0); + } else { + if (info->proto->tlenOptions.logAlerts) { + TlenLogMessage(info->proto, hContact, 0, Translate("An alert has been received.")); + } + SkinPlaySound("TlenAlertNotify"); + } + } + } + } + } + mir_free(fLogin); + if ((p=strchr(f, '@')) != NULL) { + if ((p=strchr(p, '/')) != NULL && p[1]!='\0') { // message from user + time_t timestamp; + s = JabberXmlGetAttrValue(node, "s"); + if (s != NULL) { + timestamp = TlenTimeToUTC(atol(s)); + if (timestamp > time(NULL)) { + timestamp = time(NULL); + } + } else { + timestamp = time(NULL); + } + tp=JabberXmlGetAttrValue(node, "tp"); + bNode = JabberXmlGetChild(node, "b"); + f = JabberTextDecode(f); + if (bNode != NULL && bNode->text != NULL) { + if (tp != NULL && !strcmp(tp, "p")) { + /* MUC private message */ + str = JabberResourceFromJID(f); + hContact = JabberDBCreateContact(info->proto, f, str, TRUE); + db_set_b(hContact, info->proto->m_szModuleName, "bChat", TRUE); + mir_free(str); + localMessage = JabberTextDecode(bNode->text); + recv.flags = 0; + recv.timestamp = (DWORD) timestamp; + recv.szMessage = localMessage; + recv.lParam = 0; + ProtoChainRecvMsg(hContact, &recv); + mir_free(localMessage); + } else { + /* MUC message */ + TlenMUCRecvMessage(info->proto, f, timestamp, bNode); + } + } + mir_free(f); + } else { // message from chat room (system) + subjectNode = JabberXmlGetChild(node, "subject"); + if (subjectNode != NULL) { + f = JabberTextDecode(f); + localMessage = ""; + if (subjectNode->text != NULL) { + localMessage = subjectNode->text; + } + localMessage = JabberTextDecode(localMessage); + TlenMUCRecvTopic(info->proto, f, localMessage); + mir_free(localMessage); + mir_free(f); + } + } + } + i=1; + while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { + invNode=JabberXmlGetChild(xNode, "inv"); + if (invNode != NULL) { + r = JabberTextDecode(f); + f = JabberXmlGetAttrValue(invNode, "f"); + f = JabberTextDecode(f); + n = JabberXmlGetAttrValue(invNode, "n"); + if (n != NULL && strstr(r, n) != r) { + n = JabberTextDecode(n); + } else { + n = mir_strdup(Translate("Private conference")); + //n = JabberNickFromJID(r); + } + TlenMUCRecvInvitation(info->proto, r, n, f, ""); + mir_free(n); + mir_free(r); + mir_free(f); + break; + } + i++; + } + } +} + +static void TlenMailPopup(TlenProtocol *proto, char *title, char *emailInfo) +{ + if ( !ServiceExists(MS_POPUP_ADDPOPUP)) + return; + if (!db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE)) + return; + + POPUPDATA ppd = { 0 }; + ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIL)); + strcpy(ppd.lpzContactName, title); + strcpy(ppd.lpzText, emailInfo); + ppd.colorBack = db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", 0); + ppd.colorText = db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", 0); + BYTE delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0); + if (delayMode == 1) + ppd.iSeconds = db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4); + else if (delayMode == 2) + ppd.iSeconds = -1; + PUAddPopup(&ppd); +} +/* + * Incoming e-mail notification + */ +static void TlenProcessN(XmlNode *node, ThreadData *info) +{ + char *f, *s; + char *str, *popupTitle, *popupText; + int strSize; + + if (!node->name || strcmp(node->name, "n")) return; + + s = JabberXmlGetAttrValue(node, "s"); + f = JabberXmlGetAttrValue(node, "f"); + if (s != NULL && f != NULL) { + str = NULL; + strSize = 0; + + JabberStringAppend(&str, &strSize, Translate("%s mail"), info->proto->m_szModuleName); + popupTitle = JabberTextDecode(str); + mir_free(str); + + str = NULL; + strSize = 0; + + JabberStringAppend(&str, &strSize, "%s: %s\n", Translate("From"), f); + JabberStringAppend(&str, &strSize, "%s: %s", Translate("Subject"), s); + popupText = JabberTextDecode(str); + TlenMailPopup(info->proto, popupTitle, popupText); + SkinPlaySound("TlenMailNotify"); + + mir_free(popupTitle); + mir_free(popupText); + mir_free(str); + } +} + +/* + * Presence is chat rooms + */ +static void TlenProcessP(XmlNode *node, ThreadData *info) +{ + char jid[512]; + char *f, *id, *tp, *a, *n, *k; + XmlNode *sNode, *xNode, *iNode, *kNode; + int status, flags; + + if (!node->name || strcmp(node->name, "p")) return; + +// presence from users in chat room + flags = 0; + status = ID_STATUS_ONLINE; + f = JabberXmlGetAttrValue(node, "f"); + xNode = JabberXmlGetChild(node, "x"); + if (xNode != NULL) { // x subtag present (message from chat room) - change user rights only + char *temp, *iStr; + iNode = JabberXmlGetChild(xNode, "i"); + if (iNode != NULL) { + iStr = JabberXmlGetAttrValue(iNode, "i"); + temp = (char*)mir_alloc(strlen(f)+strlen(iStr)+2); + strcpy(temp, f); + strcat(temp, "/"); + strcat(temp, iStr); + f = JabberTextDecode(temp); + mir_free(temp); + node = iNode; + status = 0; + } else { + f = JabberTextDecode(f); + } + } else { + f = JabberTextDecode(f); + } + a = JabberXmlGetAttrValue(node, "z"); + if (a != NULL) { + if (atoi(a) &1 ) { + flags |= USER_FLAGS_REGISTERED; + } + } + a = JabberXmlGetAttrValue(node, "a"); + if (a != NULL) { + if (atoi(a) == 2) { + flags |= USER_FLAGS_ADMIN; + } + if (atoi(a) == 1) { + flags |= USER_FLAGS_OWNER; + } + if (atoi(a) == 3) { + //flags |= USER_FLAGS_MEMBER; + } + if (atoi(a) == 5) { + flags |= USER_FLAGS_GLOBALOWNER; + } + } + sNode = JabberXmlGetChild(node, "s"); + if (sNode != NULL) { + if (!strcmp(sNode->text, "unavailable")) { + status = ID_STATUS_OFFLINE; + } + } + kNode = JabberXmlGetChild(node, "kick"); + k = NULL; + if (kNode != NULL) { + k = JabberXmlGetAttrValue(kNode, "r"); + if (k == NULL) { + k = ""; + } + k = JabberTextDecode(k); + } + tp = JabberXmlGetAttrValue(node, "tp"); + if (tp != NULL && !strcmp(tp, "c")) { // new chat room has just been created + id = JabberXmlGetAttrValue(node, "id"); + if (id != NULL) { + n = JabberXmlGetAttrValue(node, "n"); + if (n != NULL) { + n = JabberTextDecode(n); + } else { + n = mir_strdup(Translate("Private conference"));// JabberNickFromJID(f); + } + mir_snprintf(jid, SIZEOF(jid), "%s/%s", f, info->username); +// if (!db_get(NULL, info->proto->m_szModuleName, "LoginName", &dbv)) { + // always real username +// sprintf(jid, "%s/%s", f, dbv.pszVal); + TlenMUCCreateWindow(info->proto, f, n, 0, NULL, id); + TlenMUCRecvPresence(info->proto, jid, ID_STATUS_ONLINE, flags, k); +// db_free(&dbv); +// } + mir_free(n); + } + } else { + TlenMUCRecvPresence(info->proto, f, status, flags, k); // user presence + } + if (k != NULL) { + mir_free(k); + } + mir_free(f); +} +/* + * Voice chat + */ +static void TlenProcessV(XmlNode *node, ThreadData *info) +{ + char jid[128]; + JABBER_LIST_ITEM *item; + char *from, *id, *e, *p; +// if (!node->name || strcmp(node->name, "v")) return; + + if ((from=JabberXmlGetAttrValue(node, "f")) != NULL) { + if (strchr(from, '@') == NULL) { + mir_snprintf(jid, sizeof(jid), "%s@%s", from, info->server); + } else { + mir_snprintf(jid, sizeof(jid), "%s", from); + } + if ((e=JabberXmlGetAttrValue(node, "e")) != NULL) { + if (!strcmp(e, "1")) { + if ((id=JabberXmlGetAttrValue(node, "i")) != NULL) { + SkinPlaySound("TlenVoiceNotify"); + TlenVoiceAccept(info->proto, id, from); + } + } else if (!strcmp(e, "3")) { + // FILE_RECV : e='3' : invalid transfer error + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if (item->ft != NULL) { + HANDLE hEvent = item->ft->hFileEvent; + item->ft->hFileEvent = NULL; + item->ft->state = FT_ERROR; + if (item->ft->s != NULL) { + Netlib_CloseHandle(item->ft->s); + item->ft->s = NULL; + if (hEvent != NULL) { + SetEvent(hEvent); + } + } else { + TlenP2PFreeFileTransfer(item->ft); + } + } else { + JabberListRemove(info->proto, LIST_VOICE, p); + } + } + } + } else if (!strcmp(e, "4")) { + // FILE_SEND : e='4' : File sending request was denied by the remote client + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if (!strcmp(item->ft->jid, jid)) { + TlenVoiceCancelAll(info->proto); + //JabberListRemove(info->proto, LIST_VOICE, p); + } + } + } + } else if (!strcmp(e, "5")) { + // FILE_SEND : e='5' : Voice request was accepted + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + JabberLog(info->proto, "should start voice 1 ? %s ?? %s", jid, item->ft->jid); + if (!strcmp(item->ft->jid, jid)) { + JabberLog(info->proto, "starting voice 1"); + TlenVoiceStart(item->ft, 1); + } + } + } + } else if (!strcmp(e, "6")) { + // FILE_RECV : e='6' : IP and port information to connect to get file + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { + item->ft->hostName = mir_strdup(p); + if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { + item->ft->wPort = atoi(p); + TlenVoiceStart(item->ft, 0); + //JabberForkThread((void (__cdecl *)(void*))TlenVoiceReceiveThread, 0, item->ft); + } + } + } + } + } + else if (!strcmp(e, "7")) { + // FILE_RECV : e='7' : IP and port information to connect to send file + // in case the conection to the given server was not successful + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { + if (item->ft->hostName != NULL) mir_free(item->ft->hostName); + item->ft->hostName = mir_strdup(p); + if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { + item->ft->wPort = atoi(p); + item->ft->state = FT_SWITCH; + SetEvent(item->ft->hFileEvent); + } + } + } + } + } + else if (!strcmp(e, "8")) { + // FILE_RECV : e='8' : transfer error + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + item->ft->state = FT_ERROR; + SetEvent(item->ft->hFileEvent); + } + } + } + + } + } +} + +static void __cdecl JabberKeepAliveThread(void *ptr) +{ + NETLIBSELECT nls = {0}; + + TlenProtocol *proto = (TlenProtocol *)ptr; + nls.cbSize = sizeof(NETLIBSELECT); + nls.dwTimeout = 60000; // 60000 millisecond (1 minute) + nls.hExceptConns[0] = proto->threadData->s; + for (;;) { + if (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls) != 0) + break; + if (proto->tlenOptions.sendKeepAlive) + JabberSend(proto, " \t "); + } + JabberLog(proto, "Exiting KeepAliveThread"); +} + diff --git a/protocols/Tlen/src/tlen_userinfo.cpp b/protocols/Tlen/src/tlen_userinfo.cpp index 8361bbee92..12e591dc97 100644 --- a/protocols/Tlen/src/tlen_userinfo.cpp +++ b/protocols/Tlen/src/tlen_userinfo.cpp @@ -21,13 +21,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" +#include "tlen.h" #include #include #include #include #include -#include "jabber_list.h" +#include "tlen_list.h" #include "resource.h" #include "tlen_avatar.h" diff --git a/protocols/Tlen/src/tlen_util.cpp b/protocols/Tlen/src/tlen_util.cpp new file mode 100644 index 0000000000..ea054d882d --- /dev/null +++ b/protocols/Tlen/src/tlen_util.cpp @@ -0,0 +1,500 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include "tlen_list.h" +#include +#include + +void JabberSerialInit(TlenProtocol *proto) +{ + InitializeCriticalSection(&proto->csSerial); + proto->serial = 0; +} + +void JabberSerialUninit(TlenProtocol *proto) +{ + DeleteCriticalSection(&proto->csSerial); +} + + +unsigned int JabberSerialNext(TlenProtocol *proto) +{ + unsigned int ret; + + EnterCriticalSection(&proto->csSerial); + ret = proto->serial; + proto->serial++; + LeaveCriticalSection(&proto->csSerial); + return ret; +} + + +void JabberLog(TlenProtocol *proto, const char *fmt, ...) +{ +#ifdef ENABLE_LOGGING + char *str; + va_list vararg; + int strsize; + char *text; + char *p, *q; + int extra; + + va_start(vararg, fmt); + str = (char *) mir_alloc(strsize=2048); + while (mir_vsnprintf(str, strsize, fmt, vararg) == -1) + str = (char *) mir_realloc(str, strsize+=2048); + va_end(vararg); + + extra = 0; + for (p=str; *p != '\0'; p++) + if (*p == '\n' || *p == '\r') + extra++; + size_t size = strlen("TLEN") + 2 + strlen(str) + 2 + extra; + text = (char *) mir_alloc(size); + mir_snprintf(text, size, "[%s]", "TLEN"); + for (p=str,q=text+strlen(text); *p != '\0'; p++,q++) { + if (*p == '\r') { + *q = '\\'; + *(q+1) = 'r'; + q++; + } + else if (*p == '\n') { + *q = '\\'; + *(q+1) = 'n'; + q++; + } + else + *q = *p; + } + *q = '\n'; + *(q+1) = '\0'; + if (proto->hNetlibUser != NULL) { + CallService(MS_NETLIB_LOG, (WPARAM) proto->hNetlibUser, (LPARAM) text); + } + //OutputDebugString(text); + mir_free(text); + mir_free(str); +#endif +} + +// Caution: DO NOT use JabberSend() to send binary (non-string) data + +int JabberSend(TlenProtocol *proto, const char *fmt, ...) +{ + char *str; + int size; + va_list vararg; + int result = 0; + + EnterCriticalSection(&proto->csSend); + + va_start(vararg,fmt); + size = 512; + str = (char *) mir_alloc(size); + while (mir_vsnprintf(str, size, fmt, vararg) == -1) { + size += 512; + str = (char *) mir_realloc(str, size); + } + va_end(vararg); + + JabberLog(proto, "SEND:%s", str); + size = (int)strlen(str); + if (proto->threadData != NULL) { + if (proto->threadData->useAES) { + result = JabberWsSendAES(proto, str, size, &proto->threadData->aes_out_context, proto->threadData->aes_out_iv); + } else { + result = JabberWsSend(proto, proto->threadData->s, str, size); + } + } + LeaveCriticalSection(&proto->csSend); + + mir_free(str); + return result; +} + +char *JabberResourceFromJID(const char *jid2) +{ + char *p; + char *nick; + char* jid = mir_strdup(jid2); + + p=strchr(jid, '/'); + if (p != NULL && p[1] != '\0') { + p++; + if ((nick=(char *) mir_alloc(1+strlen(jid)-(p-jid))) != NULL) { + strncpy(nick, p, strlen(jid)-(p-jid)); + nick[strlen(jid)-(p-jid)] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + mir_free(jid); + return nick; +} + +char *JabberNickFromJID(const char *jid2) +{ + char *p; + char *nick; + char* jid = mir_strdup(jid2); + + if ((p=strchr(jid, '@')) == NULL) + p = strchr(jid, '/'); + if (p != NULL) { + if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { + strncpy(nick, jid, p-jid); + nick[p-jid] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + mir_free(jid); + return nick; +} + +char *JabberLoginFromJID(const char *jid2) +{ + char *p; + char *nick; + char* jid = mir_strdup(jid2); + + p = strchr(jid, '/'); + if (p != NULL) { + if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { + strncpy(nick, jid, p-jid); + nick[p-jid] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + mir_free(jid); + return nick; +} + +char *JabberLocalNickFromJID(const char *jid) +{ + char *p; + char *localNick; + + p = JabberNickFromJID(jid); + localNick = JabberTextDecode(p); + mir_free(p); + return localNick; +} + +char *JabberSha1(char *str) +{ + mir_sha1_ctx sha; + DWORD digest[5]; + char* result; + + if ( str == NULL ) + return NULL; + + mir_sha1_init( &sha ); + mir_sha1_append( &sha, (BYTE* )str, (int)strlen( str )); + mir_sha1_finish( &sha, (BYTE* )digest ); + if ((result=(char *)mir_alloc(41)) == NULL) + return NULL; + sprintf(result, "%08x%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4])); //!!!!!!!!!!! + return result; +} + +char *TlenSha1(char *str, int len) +{ + mir_sha1_ctx sha; + BYTE digest[20]; + char* result; + int i; + + if ( str == NULL ) + return NULL; + + mir_sha1_init( &sha ); + mir_sha1_append( &sha, (BYTE* )str, len); + mir_sha1_finish( &sha, digest ); + if (( result=( char* )mir_alloc( 20 )) == NULL ) + return NULL; + for (i=0; i<20; i++) + result[i]=digest[4*(i>>2)+(3-(i&0x3))]; + return result; +} + +char *TlenPasswordHash(const char *str) +{ + int magic1 = 0x50305735, magic2 = 0x12345671, sum = 7; + char *p, *res; + + if (str == NULL) return NULL; + for (p=(char *)str; *p != '\0'; p++) { + if (*p != ' ' && *p != '\t') { + magic1 ^= (((magic1 & 0x3f) + sum) * ((char) *p)) + (magic1 << 8); + magic2 += (magic2 << 8) ^ magic1; + sum += ((char) *p); + } + } + magic1 &= 0x7fffffff; + magic2 &= 0x7fffffff; + res = (char *) mir_alloc(17); + sprintf(res, "%08x%08x", magic1, magic2); //!!!!!!!!!!! + return res; +} + +char *TlenUrlEncode(const char *str) +{ + char *p, *q, *res; + unsigned char c; + + if (str == NULL) return NULL; + res = (char *) mir_alloc(3*strlen(str) + 1); + for (p=(char *)str,q=res; *p != '\0'; p++,q++) { + if (*p == ' ') { + *q = '+'; + } + else if (*p < 0x20 || *p >= 0x7f || strchr("%&+:'<>\"", *p) != NULL) { + // Convert first from CP1252 to ISO8859-2 + switch ((unsigned char) *p) { + case 0xa5: c = (unsigned char) 0xa1; break; + case 0x8c: c = (unsigned char) 0xa6; break; + case 0x8f: c = (unsigned char) 0xac; break; + case 0xb9: c = (unsigned char) 0xb1; break; + case 0x9c: c = (unsigned char) 0xb6; break; + case 0x9f: c = (unsigned char) 0xbc; break; + default: c = (unsigned char) *p; break; + } + sprintf(q, "%%%02X", c); //!!!!!!!!!!! + q += 2; + } + else { + *q = *p; + } + } + *q = '\0'; + return res; +} + +void TlenUrlDecode(char *str) +{ + char *p, *q; + unsigned int code; + + if (str == NULL) return; + for (p=q=str; *p != '\0'; p++,q++) { + if (*p == '+') { + *q = ' '; + } + else if (*p == '%' && *(p+1) != '\0' && isxdigit(*(p+1)) && *(p+2) != '\0' && isxdigit(*(p+2))) { + sscanf(p+1, "%2x", &code); + *q = (char) code; + // Convert from ISO8859-2 to CP1252 + switch ((unsigned char) *q) { + case 0xa1: *q = (char) 0xa5; break; + case 0xa6: *q = (char) 0x8c; break; + case 0xac: *q = (char) 0x8f; break; + case 0xb1: *q = (char) 0xb9; break; + case 0xb6: *q = (char) 0x9c; break; + case 0xbc: *q = (char) 0x9f; break; + } + p += 2; + } + else { + *q = *p; + } + } + *q = '\0'; +} + +char * TlenGroupDecode(const char *str) +{ + char *p, *q; + if (str == NULL) return NULL; + p = q = JabberTextDecode(str); + for (; *p != '\0'; p++) { + if (*p == '/') { + *p = '\\'; + } + } + return q; +} + +char * TlenGroupEncode(const char *str) +{ + char *p, *q; + if (str == NULL) return NULL; + p = q = mir_strdup(str); + for (; *p != '\0'; p++) { + if (*p == '\\') { + *p = '/'; + } + } + p = JabberTextEncode(q); + mir_free(q); + return p; +} + +char *JabberTextEncode(const char *str) +{ + char *s1; + + if (str == NULL) return NULL; + if ((s1=TlenUrlEncode(str)) == NULL) + return NULL; + return s1; +} + +char *JabberTextDecode(const char *str) +{ + char *s1; + + if (str == NULL) return NULL; + s1 = mir_strdup(str); + TlenUrlDecode(s1); + return s1; +} + +/* + * Apply Polish Daylight Saving Time rules to get "DST-unbiased" timestamp + */ + +time_t TlenTimeToUTC(time_t time) { + struct tm *timestamp; + timestamp = gmtime(&time); + if ( (timestamp->tm_mon > 2 && timestamp->tm_mon < 9) || + (timestamp->tm_mon == 2 && timestamp->tm_mday - timestamp->tm_wday >= 25) || + (timestamp->tm_mon == 9 && timestamp->tm_mday - timestamp->tm_wday < 25)) { + //time -= 3600; + } else { + //time += 3600; + } + return time; +} + +time_t JabberIsoToUnixTime(char *stamp) +{ + struct tm timestamp; + char date[9]; + char *p; + int i, y; + time_t t; + + if (stamp == NULL) return (time_t) 0; + + p = stamp; + + // Get the date part + for (i=0; *p != '\0' && i<8 && isdigit(*p); p++,i++) + date[i] = *p; + + // Parse year + if (i == 6) { + // 2-digit year (1970-2069) + y = (date[0]-'0')*10 + (date[1]-'0'); + if (y < 70) y += 100; + } + else if (i == 8) { + // 4-digit year + y = (date[0]-'0')*1000 + (date[1]-'0')*100 + (date[2]-'0')*10 + date[3]-'0'; + y -= 1900; + } + else + return (time_t) 0; + timestamp.tm_year = y; + // Parse month + timestamp.tm_mon = (date[i-4]-'0')*10 + date[i-3]-'0' - 1; + // Parse date + timestamp.tm_mday = (date[i-2]-'0')*10 + date[i-1]-'0'; + + // Skip any date/time delimiter + for (; *p != '\0' && !isdigit(*p); p++); + + // Parse time + if (sscanf(p, "%d:%d:%d", &(timestamp.tm_hour), &(timestamp.tm_min), &(timestamp.tm_sec)) != 3) + return (time_t) 0; + + timestamp.tm_isdst = 0; // DST is already present in _timezone below + _tzset(); + t = mktime(×tamp); + t -= _timezone; + t = TlenTimeToUTC(t); + + if (t >= 0) + return t; + else + return (time_t) 0; +} + +void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) +{ + va_list vararg; + char *p; + int size, len; + + if (str == NULL) return; + + if (*str == NULL || *sizeAlloced <= 0) { + *sizeAlloced = size = 2048; + *str = (char *) mir_alloc(size); + len = 0; + } + else { + len = (int)strlen(*str); + size = *sizeAlloced - (int)strlen(*str); + } + + p = *str + len; + va_start(vararg, fmt); + while (mir_vsnprintf(p, size, fmt, vararg) == -1) { + size += 2048; + (*sizeAlloced) += 2048; + *str = (char *) mir_realloc(*str, *sizeAlloced); + p = *str + len; + } + va_end(vararg); +} + +BOOL IsAuthorized(TlenProtocol *proto, const char *jid) +{ + JABBER_LIST_ITEM *item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); + if (item != NULL) { + return item->subscription == SUB_BOTH || item->subscription == SUB_FROM; + } + return FALSE; +} + + +void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message) +{ + int size = (int)strlen(message) + 2; + char *localMessage = (char *)mir_alloc(size); + strcpy(localMessage, message); + localMessage[size - 1] = '\0'; + JabberDBAddEvent(proto, hContact, EVENTTYPE_MESSAGE, flags, (PBYTE)message, (DWORD)size); + mir_free(localMessage); +} diff --git a/protocols/Tlen/src/tlen_voice.cpp b/protocols/Tlen/src/tlen_voice.cpp index 2c81755c6d..4e9db3aa77 100644 --- a/protocols/Tlen/src/tlen_voice.cpp +++ b/protocols/Tlen/src/tlen_voice.cpp @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "jabber.h" +#include "tlen.h" #include #include #include @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include //#include #include "resource.h" -#include "jabber_list.h" +#include "tlen_list.h" #include "tlen_voice.h" #include "tlen_p2p_old.h" #include "tlen_file.h" @@ -697,7 +697,7 @@ int TlenVoiceCancelAll(TlenProtocol *proto) return 0; } -int TlenProtocol::VoiceContactMenuHandleVoice(WPARAM wParam, LPARAM lParam) +INT_PTR TlenProtocol::VoiceContactMenuHandleVoice(WPARAM wParam, LPARAM lParam) { HANDLE hContact; DBVARIANT dbv; diff --git a/protocols/Tlen/src/tlen_voice.h b/protocols/Tlen/src/tlen_voice.h index cbd71aa1f1..b1f2a5e2a8 100644 --- a/protocols/Tlen/src/tlen_voice.h +++ b/protocols/Tlen/src/tlen_voice.h @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include -#include "jabber.h" +#include "tlen.h" extern "C" { #include "codec/gsm.h" } diff --git a/protocols/Tlen/src/tlen_ws.cpp b/protocols/Tlen/src/tlen_ws.cpp new file mode 100644 index 0000000000..f1931d5650 --- /dev/null +++ b/protocols/Tlen/src/tlen_ws.cpp @@ -0,0 +1,160 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" + +BOOL JabberWsInit(TlenProtocol *proto) +{ + NETLIBUSER nlu = {0}; + NETLIBUSERSETTINGS nlus = {0}; + TCHAR name[128]; + + + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_TCHAR; // | NUF_HTTPGATEWAY; + mir_sntprintf(name, SIZEOF(name), TranslateT("%s connection"), proto->m_tszUserName); + nlu.ptszDescriptiveName = name; + nlu.szSettingsModule = proto->m_szModuleName; + proto->hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); + + nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_NOOPTIONS | NUF_TCHAR; + mir_sntprintf(name, SIZEOF(name), TranslateT("%s SOCKS connection"), proto->m_tszUserName); + nlu.ptszDescriptiveName = name; + proto->hFileNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); + nlus.cbSize = sizeof(nlus); + nlus.useProxy = 0; + CallService(MS_NETLIB_SETUSERSETTINGS, (WPARAM) proto->hFileNetlibUser, (LPARAM) &nlus); + + return (proto->hNetlibUser != NULL)?TRUE:FALSE; +} + +void JabberWsUninit(TlenProtocol *proto) +{ + if (proto->hNetlibUser != NULL) Netlib_CloseHandle(proto->hNetlibUser); + if (proto->hFileNetlibUser != NULL) Netlib_CloseHandle(proto->hFileNetlibUser); + proto->hNetlibUser = NULL; + proto->hFileNetlibUser = NULL; +} + +JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port) +{ + NETLIBOPENCONNECTION nloc = {0}; + + nloc.cbSize = sizeof(NETLIBOPENCONNECTION); //NETLIBOPENCONNECTION_V1_SIZE; + nloc.szHost = host; + nloc.wPort = port; + nloc.flags = 0; + nloc.timeout = 6; + return (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) proto->hNetlibUser, (LPARAM) &nloc); +} + + +int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen) +{ + int len; + if ((len=Netlib_Send(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT)) == SOCKET_ERROR || len != datalen) { + JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); + return FALSE; + } + return TRUE; +} + +int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen) +{ + int ret; + ret = Netlib_Recv(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT); + if (ret == SOCKET_ERROR) { + JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); + return 0; + } + if (ret == 0) { + JabberLog(proto, "Connection closed gracefully"); + return 0; + } + return ret; +} + + +int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv) +{ + int len, sendlen; + unsigned char aes_input[16]; + unsigned char aes_output[256]; + if (proto->threadData == NULL) { + return FALSE; + } + while (datalen > 0) { + len = 0; + while (datalen > 0 && len < 256) { + int pad = datalen < 16 ? 16 - datalen : 0; + memcpy(aes_input, data, datalen < 16 ? datalen : 16); + memset(aes_input + 16 - pad, ' ', pad); + aes_crypt_cbc(aes_ctx, AES_ENCRYPT, 16, aes_iv, aes_input, aes_output + len); + datalen -= 16; + data += 16; + len += 16; + } + if (len > 0) { + JabberLog(proto, "Sending %d bytes", len); + if ((sendlen=Netlib_Send(proto->threadData->s, (char *)aes_output, len, MSG_NODUMP)) == SOCKET_ERROR || len != sendlen) { + JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); + return FALSE; + } + } + } + return TRUE; +} + +int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv) +{ + int ret, len = 0, maxlen = datalen; + unsigned char aes_input[16]; + unsigned char *aes_output = (unsigned char *)data; + if (proto->threadData == NULL) { + return 0; + } + for (maxlen = maxlen & ~0xF; maxlen != 0; maxlen = maxlen & 0xF) { + ret = Netlib_Recv(proto->threadData->s, data, maxlen, MSG_NODUMP); + if (ret == SOCKET_ERROR) { + JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); + return 0; + } + if (ret == 0) { + JabberLog(proto, "Connection closed gracefully"); + return 0; + } + data += ret; + len += ret; + maxlen -= ret; + } + + ret = len; + while (len > 15) { + memcpy(aes_input, aes_output, 16); + aes_crypt_cbc(aes_ctx, AES_DECRYPT, 16, aes_iv, aes_input, aes_output); + aes_output += 16; + len -= 16; + } + return ret; +} + diff --git a/protocols/Tlen/src/tlen_xml.cpp b/protocols/Tlen/src/tlen_xml.cpp new file mode 100644 index 0000000000..2364bfcadd --- /dev/null +++ b/protocols/Tlen/src/tlen_xml.cpp @@ -0,0 +1,568 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "tlen.h" +#include + +static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr); +static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child); + +void JabberXmlInitState(XmlState *xmlState) +{ + if (xmlState == NULL) return; + xmlState->root.name = NULL; + xmlState->root.depth = 0; + xmlState->root.numAttr = 0; + xmlState->root.maxNumAttr = 0; + xmlState->root.attr = NULL; + xmlState->root.numChild = 0; + xmlState->root.maxNumChild = 0; + xmlState->root.child = NULL; + xmlState->root.text = NULL; + xmlState->root.state = NODE_OPEN; + xmlState->callback1_open = NULL; + xmlState->callback1_close = NULL; + xmlState->callback2_open = NULL; + xmlState->callback2_close = NULL; + xmlState->userdata1_open = NULL; + xmlState->userdata1_close = NULL; + xmlState->userdata2_open = NULL; + xmlState->userdata2_close = NULL; +} + +void JabberXmlDestroyState(XmlState *xmlState) +{ + int i; + XmlNode *node; + + if (xmlState == NULL) return; + // Note: cannot use JabberXmlFreeNode() to free xmlState->root + // because it will do mir_free(xmlState->root) which is not freeable. + node = &(xmlState->root); + // Free all children first + for (i=0; inumChild; i++) + JabberXmlFreeNode(node->child[i]); + if (node->child) mir_free(node->child); + // Free all attributes + for (i=0; inumAttr; i++) { + if (node->attr[i]->name) mir_free(node->attr[i]->name); + if (node->attr[i]->value) mir_free(node->attr[i]->value); + mir_free(node->attr[i]); + } + if (node->attr) mir_free(node->attr); + // Free string field + if (node->text) mir_free(node->text); + if (node->name) mir_free(node->name); +} + +BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata) +{ + if (depth == 1 && type == ELEM_OPEN) { + xmlState->callback1_open = callback; + xmlState->userdata1_open = userdata; + } + else if (depth == 1 && type == ELEM_CLOSE) { + xmlState->callback1_close = callback; + xmlState->userdata1_close = userdata; + } + else if (depth == 2 && type == ELEM_OPEN) { + xmlState->callback2_open = callback; + xmlState->userdata2_open = userdata; + } + else if (depth == 2 && type == ELEM_CLOSE) { + xmlState->callback2_close = callback; + xmlState->userdata2_close = userdata; + } + else + return FALSE; + + return TRUE; +} + +#define TAG_MAX_LEN 50 +#define ATTR_MAX_LEN 1024 +int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen) +{ + char *p, *q, *r, *eob; + char *str; + int num; + char tag[TAG_MAX_LEN]; + char attr[ATTR_MAX_LEN]; + XmlElemType elemType = ELEM_OPEN; + + eob = buffer + datalen; + num = 0; + // Skip leading whitespaces + for (p=buffer; p TAG_MAX_LEN) { +// JabberLog("TAG_MAX_LEN too small, ignore current tag"); + } + else { + if (*(p+1) == '/') { // closing tag + strncpy(tag, p+2, r-(p+2)); + tag[r-(p+2)] = '\0'; + elemType = ELEM_CLOSE; + } + else { + if (*(r-1) == '/') { // single open/close tag + strncpy(tag, p+1, r-(p+1)-1); + tag[r-(p+1)-1] = '\0'; + elemType = ELEM_OPENCLOSE; + } + else { + strncpy(tag, p+1, r-(p+1)); + tag[r-(p+1)] = '\0'; + elemType = ELEM_OPEN; + } + } + for (;r ATTR_MAX_LEN) { +// JabberLog("ATTR_MAX_LEN too small, ignore current tag"); + } + else { + strncpy(attr, r, q-r); + if ((q-r)>0 && attr[q-r-1] == '/') { + attr[q-r-1] = '\0'; + elemType = ELEM_OPENCLOSE; + } + else + attr[q-r] = '\0'; + JabberXmlProcessElem(xmlState, elemType, tag, attr); + } + } + num += (q-p+1); + p = q + 1; + if (elemType == ELEM_CLOSE || elemType == ELEM_OPENCLOSE) { + // Skip whitespaces after end tags + for (; pnumAttr >= node->maxNumAttr) { + node->maxNumAttr = node->numAttr + 20; + node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *)); + } + a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + node->numAttr++; + + // Skip possible whitespaces between key and '=' + for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); + + if (*p == '\0') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + break; + } + + if (*p != '=') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + continue; + } + + // Found '=' + p++; + + // Skip possible whitespaces between '=' and value + for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); + + if (*p == '\0') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + break; + } + + // Fetch value + if (*p == '\'' || *p == '"') { + p++; + vstart = p; + for (;*p != '\0' && *p != *(vstart-1); p++); + vlen = p-vstart; + if (*p != '\0') p++; + } + else { + vstart = p; + for (;*p != '\0' && *p != ' ' && *p != '\t'; p++); + vlen = p-vstart; + } + + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = (char *) mir_alloc(vlen+1); + strncpy(a->value, vstart, vlen); + a->value[vlen] = '\0'; + } +} + +static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr) +{ + XmlNode *node, *parentNode, *n; + //BOOL activateCallback = FALSE; + char *text, *attr; + + if (elemText == NULL) return FALSE; + + if (elemType == ELEM_OPEN && !strcmp(elemText, "?xml")) { +// JabberLog("XML: skip tag"); + return TRUE; + } + + // Find active node + node = &(xmlState->root); + parentNode = NULL; + while (node->numChild>0 && node->child[node->numChild-1]->state == NODE_OPEN) { + parentNode = node; + node = node->child[node->numChild-1]; + } + + if (node->state != NODE_OPEN) return FALSE; + + text = mir_strdup(elemText); + + if (elemAttr) + attr = mir_strdup(elemAttr); + else + attr = NULL; + + switch (elemType) { + case ELEM_OPEN: + if (node->numChild >= node->maxNumChild) { + node->maxNumChild = node->numChild + 20; + node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); + } + n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + node->numChild++; + n->name = text; + n->depth = node->depth + 1; + n->state = NODE_OPEN; + n->numChild = n->maxNumChild = 0; + n->child = NULL; + n->numAttr = n->maxNumAttr = 0; + n->attr = NULL; + JabberXmlParseAttr(n, attr); + n->text = NULL; + if (n->depth == 1 && xmlState->callback1_open != NULL) + (*(xmlState->callback1_open))(n, xmlState->userdata1_open); + if (n->depth == 2 && xmlState->callback2_open != NULL) + (*xmlState->callback2_open)(n, xmlState->userdata2_open); + break; + case ELEM_OPENCLOSE: + if (node->numChild >= node->maxNumChild) { + node->maxNumChild = node->numChild + 20; + node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); + } + n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + node->numChild++; + n->name = text; + n->depth = node->depth + 1; + n->state = NODE_CLOSE; + n->numChild = n->maxNumAttr = 0; + n->child = NULL; + n->numAttr = n->maxNumAttr = 0; + n->attr = NULL; + JabberXmlParseAttr(n, attr); + n->text = NULL; + if (n->depth == 1 && xmlState->callback1_close != NULL) { + (*(xmlState->callback1_close))(n, xmlState->userdata1_close); + JabberXmlRemoveChild(node, n); + } + if (n->depth == 2 && xmlState->callback2_close != NULL) { + (*xmlState->callback2_close)(n, xmlState->userdata2_close); + JabberXmlRemoveChild(node, n); + } + break; + case ELEM_CLOSE: + if (node->name != NULL && !strcmp(node->name, text)) { + node->state = NODE_CLOSE; + if (node->depth == 1 && xmlState->callback1_close != NULL) { + (*(xmlState->callback1_close))(node, xmlState->userdata1_close); + JabberXmlRemoveChild(parentNode, node); + } + if (node->depth == 2 && xmlState->callback2_close != NULL) { + (*xmlState->callback2_close)(node, xmlState->userdata2_close); + JabberXmlRemoveChild(parentNode, node); + } + mir_free(text); + } + else { +// JabberLog("XML: Closing without opening tag", text); + mir_free(text); + if (attr) mir_free(attr); + return FALSE; + } + break; + case ELEM_TEXT: + node->text = text; + break; + default: + mir_free(text); + if (attr) mir_free(attr); + return FALSE; + } + + if (attr) mir_free(attr); + + return TRUE; +} + +char *JabberXmlGetAttrValue(XmlNode *node, char *key) +{ + int i; + + if (node == NULL || node->numAttr <= 0 || key == NULL || strlen(key) <= 0) + return NULL; + for (i=0; inumAttr; i++) { + if (node->attr[i]->name && !strcmp(key, node->attr[i]->name)) + return node->attr[i]->value; + } + return NULL; +} + +XmlNode *JabberXmlGetChild(XmlNode *node, char *tag) +{ + return JabberXmlGetNthChild(node, tag, 1); +} + +XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth) +{ + int i, num; + + if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || nth < 1) + return NULL; + num = 1; + for (i=0; inumChild; i++) { + if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { + if (num == nth) { + return node->child[i]; + } + num++; + } + } + return NULL; +} + +XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue) +{ + int i; + char *str; + + if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || attrKey == NULL || strlen(attrKey) <= 0 || attrValue == NULL || strlen(attrValue) <= 0) + return NULL; + for (i=0; inumChild; i++) { + if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { + if ((str=JabberXmlGetAttrValue(node->child[i], attrKey)) != NULL) + if (!strcmp(str, attrValue)) + return node->child[i]; + } + } + return NULL; +} + +static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child) +{ + int i; + + if (node == NULL || child == NULL || node->numChild <= 0) return; + for (i=0; inumChild; i++) { + if (node->child[i] == child) + break; + } + if (i < node->numChild) { + for (++i; inumChild; i++) + node->child[i-1] = node->child[i]; + node->numChild--; + JabberXmlFreeNode(child); + } +} + +void JabberXmlFreeNode(XmlNode *node) +{ + int i; + + if (node == NULL) return; + // Free all children first + for (i=0; inumChild; i++) + JabberXmlFreeNode(node->child[i]); + if (node->child) mir_free(node->child); + // Free all attributes + for (i=0; inumAttr; i++) { + if (node->attr[i]->name) mir_free(node->attr[i]->name); + if (node->attr[i]->value) mir_free(node->attr[i]->value); + mir_free(node->attr[i]); + } + if (node->attr) mir_free(node->attr); + // Free string field + if (node->text) mir_free(node->text); + if (node->name) mir_free(node->name); + // Free the node itself + mir_free(node); +} + +XmlNode *JabberXmlCopyNode(XmlNode *node) +{ + XmlNode *n; + int i; + + if (node == NULL) return NULL; + n = (XmlNode *) mir_alloc(sizeof(XmlNode)); + // Copy attributes + if (node->numAttr > 0) { + n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *)); + for (i=0; inumAttr; i++) { + n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name); + else n->attr[i]->name = NULL; + if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value); + else n->attr[i]->value = NULL; + } + } + else + n->attr = NULL; + // Recursively copy children + if (node->numChild > 0) { + n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *)); + for (i=0; inumChild; i++) + n->child[i] = JabberXmlCopyNode(node->child[i]); + } + else + n->child = NULL; + // Copy other fields + n->numAttr = node->numAttr; + n->maxNumAttr = node->numAttr; + n->numChild = node->numChild; + n->maxNumChild = node->numChild; + n->depth = node->depth; + n->state = node->state; + n->name = (node->name)?mir_strdup(node->name):NULL; + n->text = (node->text)?mir_strdup(node->text):NULL; + + return n; +} + +XmlNode *JabberXmlCreateNode(char *name) +{ + XmlNode *n; + + if (name == NULL) + return NULL; + + n = (XmlNode *) mir_alloc(sizeof(XmlNode)); + memset(n, 0, sizeof(XmlNode)); + n->name = mir_strdup(name); + return n; +} + +void JabberXmlAddAttr(XmlNode *n, char *name, char *value) +{ + int i; + + if (n == NULL || name == NULL || value == NULL) + return; + + i = n->numAttr; + (n->numAttr)++; + n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr); + n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + n->attr[i]->name = mir_strdup(name); + n->attr[i]->value = mir_strdup(value); +} + +XmlNode *JabberXmlAddChild(XmlNode *n, char *name) +{ + int i; + + if (n == NULL || name == NULL) + return NULL; + + i = n->numChild; + n->numChild++; + n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild); + n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + memset(n->child[i], 0, sizeof(XmlNode)); + n->child[i]->name = mir_strdup(name); + return n->child[i]; +} + +void JabberXmlAddText(XmlNode *n, char *text) +{ + if (n != NULL && text != NULL) { + if (n->text) mir_free(n->text); + n->text = mir_strdup(text); + } +} + diff --git a/protocols/Tlen/src/tlen_xml.h b/protocols/Tlen/src/tlen_xml.h new file mode 100644 index 0000000000..165a8fadc5 --- /dev/null +++ b/protocols/Tlen/src/tlen_xml.h @@ -0,0 +1,79 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _JABBER_XML_H_ +#define _JABBER_XML_H_ + +typedef enum { ELEM_OPEN, ELEM_CLOSE, ELEM_OPENCLOSE, ELEM_TEXT } XmlElemType; +typedef enum { NODE_OPEN, NODE_CLOSE } XmlNodeType; + +typedef struct tagXmlAttr { + char *name; + char *value; +} XmlAttr; + +typedef struct tagXmlNode { + int depth; // depth of the current node (1=root) + char *name; // tag name of the current node + int numAttr; // number of attributes + int maxNumAttr; // internal use (num of slots currently allocated to attr) + XmlAttr **attr; // attribute list + int numChild; // number of direct child nodes + int maxNumChild; // internal use (num of slots currently allocated to child) + struct tagXmlNode **child; // child node list + char *text; + XmlNodeType state; // internal use by parser +} XmlNode; + + +typedef struct tagXmlState { + XmlNode root; // root is the document (depth = 0); + // callback for depth=n element on opening/closing + void (*callback1_open)(XmlNode *,void *); + void (*callback1_close)(XmlNode *,void *); + void (*callback2_open)(XmlNode *,void *); + void (*callback2_close)(XmlNode *,void *); + void *userdata1_open; + void *userdata1_close; + void *userdata2_open; + void *userdata2_close; +} XmlState; + +void JabberXmlInitState(XmlState *xmlState); +void JabberXmlDestroyState(XmlState *xmlState); +BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata); +int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen); +char *JabberXmlGetAttrValue(XmlNode *node, char *key); +XmlNode *JabberXmlGetChild(XmlNode *node, char *tag); +XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth); +XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue); +void JabberXmlFreeNode(XmlNode *node); +XmlNode *JabberXmlCopyNode(XmlNode *node); + +XmlNode *JabberXmlCreateNode(char *name); +void JabberXmlAddAttr(XmlNode *n, char *name, char *value); +XmlNode *JabberXmlAddChild(XmlNode *n, char *name); +void JabberXmlAddText(XmlNode *n, char *text); + +#endif + diff --git a/protocols/Tlen/tlen_10.vcxproj b/protocols/Tlen/tlen_10.vcxproj index e515d6b7da..fa38451b98 100644 --- a/protocols/Tlen/tlen_10.vcxproj +++ b/protocols/Tlen/tlen_10.vcxproj @@ -75,28 +75,19 @@ true - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/jabber.tlb - - - Full OnlyExplicitInline Size true ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true false true - jabber.h + tlen.h AssemblyAndSourceCode @@ -128,27 +119,19 @@ - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/jabber.tlb - - - Full OnlyExplicitInline Size true ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true false true - jabber.h + tlen.h AssemblyAndSourceCode @@ -181,19 +164,10 @@ - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/jabber.tlb - - - Disabled ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false false EnableFastChecks @@ -202,7 +176,7 @@ Precise - jabber.h + tlen.h @@ -238,18 +212,10 @@ - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/jabber.tlb - - - Disabled ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - _DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false false EnableFastChecks @@ -258,7 +224,7 @@ Precise - jabber.h + tlen.h @@ -301,16 +267,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -334,10 +300,10 @@ - - - - + + + + diff --git a/protocols/Tlen/tlen_10.vcxproj.filters b/protocols/Tlen/tlen_10.vcxproj.filters index 2893437d57..1f0de881e5 100644 --- a/protocols/Tlen/tlen_10.vcxproj.filters +++ b/protocols/Tlen/tlen_10.vcxproj.filters @@ -28,34 +28,34 @@ Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files @@ -108,13 +108,13 @@ Header Files - + Header Files - + Header Files - + Header Files @@ -144,7 +144,7 @@ Header Files - + Header Files diff --git a/protocols/Tlen/tlen_11.vcxproj b/protocols/Tlen/tlen_11.vcxproj index b184f4da20..5bb46928bc 100644 --- a/protocols/Tlen/tlen_11.vcxproj +++ b/protocols/Tlen/tlen_11.vcxproj @@ -78,28 +78,19 @@ true - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/jabber.tlb - - - Full OnlyExplicitInline Size true ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true false true - jabber.h + tlen.h AssemblyAndSourceCode @@ -130,27 +121,19 @@ - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/jabber.tlb - - - Full OnlyExplicitInline Size true ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true false true - jabber.h + tlen.h AssemblyAndSourceCode @@ -182,19 +165,10 @@ - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/jabber.tlb - - - Disabled ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false false EnableFastChecks @@ -203,7 +177,7 @@ Precise - jabber.h + tlen.h @@ -239,18 +213,10 @@ - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/jabber.tlb - - - Disabled ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) - _DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false false EnableFastChecks @@ -259,7 +225,7 @@ Precise - jabber.h + tlen.h @@ -302,16 +268,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -335,10 +301,10 @@ - - - - + + + + diff --git a/protocols/Tlen/tlen_11.vcxproj.filters b/protocols/Tlen/tlen_11.vcxproj.filters index 2893437d57..1f0de881e5 100644 --- a/protocols/Tlen/tlen_11.vcxproj.filters +++ b/protocols/Tlen/tlen_11.vcxproj.filters @@ -28,34 +28,34 @@ Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files @@ -108,13 +108,13 @@ Header Files - + Header Files - + Header Files - + Header Files @@ -144,7 +144,7 @@ Header Files - + Header Files -- cgit v1.2.3