/* Jabber Protocol Plugin for Miranda NG Copyright (c) 2002-04 Santithorn Bunchua Copyright (c) 2005-12 George Hazan Copyright (c) 2007 Maxim Mluhov Copyright (C) 2012-19 Miranda NG team XEP-0146 support for Miranda IM 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_RC_H_ #define _JABBER_RC_H_ class CJabberAdhocSession; #define JABBER_ADHOC_HANDLER_STATUS_EXECUTING 1 #define JABBER_ADHOC_HANDLER_STATUS_COMPLETED 2 #define JABBER_ADHOC_HANDLER_STATUS_CANCEL 3 #define JABBER_ADHOC_HANDLER_STATUS_REMOVE_SESSION 4 typedef int (CJabberProto::*JABBER_ADHOC_HANDLER)(const TiXmlElement *iqNode, CJabberIqInfo *pInfo, CJabberAdhocSession *pSession); // 5 minutes to fill out form :) #define JABBER_ADHOC_SESSION_EXPIRE_TIME 300000 class CJabberAdhocSession { protected: CMStringA m_szSessionId; CJabberAdhocSession* m_pNext; DWORD m_dwStartTime; void* m_pUserData; BOOL m_bAutofreeUserData; DWORD m_dwStage; public: CJabberProto *ppro; CJabberAdhocSession(CJabberProto* global); ~CJabberAdhocSession() { if (m_bAutofreeUserData && m_pUserData) mir_free(m_pUserData); if (m_pNext) delete m_pNext; } CJabberAdhocSession* GetNext() { return m_pNext; } CJabberAdhocSession* SetNext(CJabberAdhocSession *pNext) { CJabberAdhocSession *pRetVal = m_pNext; m_pNext = pNext; return pRetVal; } DWORD GetSessionStartTime() { return m_dwStartTime; } const char* GetSessionId() { return m_szSessionId; } BOOL SetUserData(void* pUserData, BOOL bAutofree = FALSE) { if (m_bAutofreeUserData && m_pUserData) mir_free(m_pUserData); m_pUserData = pUserData; m_bAutofreeUserData = bAutofree; return TRUE; } DWORD SetStage(DWORD dwStage) { DWORD dwRetVal = m_dwStage; m_dwStage = dwStage; return dwRetVal; } DWORD GetStage() { return m_dwStage; } }; class CJabberAdhocNode; class CJabberAdhocNode { protected: char *m_szJid; char *m_szNode; char *m_szName; CJabberAdhocNode* m_pNext; JABBER_ADHOC_HANDLER m_pHandler; CJabberProto *m_pProto; public: CJabberAdhocNode(CJabberProto* pProto, const char *szJid, const char *szNode, const char *szName, JABBER_ADHOC_HANDLER pHandler) { memset(this, 0, sizeof(CJabberAdhocNode)); replaceStr(m_szJid, szJid); replaceStr(m_szNode, szNode); replaceStr(m_szName, szName); m_pHandler = pHandler; m_pProto = pProto; } ~CJabberAdhocNode() { mir_free(m_szJid); mir_free(m_szNode); mir_free(m_szName); if (m_pNext) delete m_pNext; } CJabberAdhocNode* GetNext() const { return m_pNext; } CJabberAdhocNode* SetNext(CJabberAdhocNode *pNext) { CJabberAdhocNode *pRetVal = m_pNext; m_pNext = pNext; return pRetVal; } char* GetJid() const { return m_szJid; } char* GetNode() const { return m_szNode; } char* GetName() const { return m_szName; } BOOL CallHandler(const TiXmlElement *iqNode, CJabberIqInfo *pInfo, CJabberAdhocSession *pSession) { if (m_pHandler == nullptr) return FALSE; return (m_pProto->*m_pHandler)(iqNode, pInfo, pSession); } }; class CJabberAdhocManager { protected: CJabberProto *m_pProto; CJabberAdhocNode* m_pNodes; CJabberAdhocSession* m_pSessions; mir_cs m_cs; CJabberAdhocSession* FindSession(const char *szSession) { CJabberAdhocSession *pSession = m_pSessions; while (pSession) { if (!mir_strcmp(pSession->GetSessionId(), szSession)) return pSession; pSession = pSession->GetNext(); } return nullptr; } CJabberAdhocSession* AddNewSession() { CJabberAdhocSession *pSession = new CJabberAdhocSession(m_pProto); if (!pSession) return nullptr; pSession->SetNext(m_pSessions); m_pSessions = pSession; return pSession; } CJabberAdhocNode* FindNode(const char *szNode) { CJabberAdhocNode* pNode = m_pNodes; while (pNode) { if (!mir_strcmp(pNode->GetNode(), szNode)) return pNode; pNode = pNode->GetNext(); } return nullptr; } BOOL RemoveSession(CJabberAdhocSession *pSession) { if (!m_pSessions) return FALSE; if (pSession == m_pSessions) { m_pSessions = m_pSessions->GetNext(); pSession->SetNext(nullptr); delete pSession; return TRUE; } CJabberAdhocSession* pTmp = m_pSessions; while (pTmp->GetNext()) { if (pTmp->GetNext() == pSession) { pTmp->SetNext(pSession->GetNext()); pSession->SetNext(nullptr); delete pSession; return TRUE; } pTmp = pTmp->GetNext(); } return FALSE; } BOOL _ExpireSession(DWORD dwExpireTime) { if (!m_pSessions) return FALSE; CJabberAdhocSession *pSession = m_pSessions; if (pSession->GetSessionStartTime() < dwExpireTime) { m_pSessions = pSession->GetNext(); pSession->SetNext(nullptr); delete pSession; return TRUE; } while (pSession->GetNext()) { if (pSession->GetNext()->GetSessionStartTime() < dwExpireTime) { CJabberAdhocSession* pRetVal = pSession->GetNext(); pSession->SetNext(pSession->GetNext()->GetNext()); pRetVal->SetNext(nullptr); delete pRetVal; return TRUE; } pSession = pSession->GetNext(); } return FALSE; } public: CJabberAdhocManager(CJabberProto* pProto) { m_pProto = pProto; m_pNodes = nullptr; m_pSessions = nullptr; } ~CJabberAdhocManager() { delete m_pNodes; delete m_pSessions; } BOOL FillDefaultNodes(); BOOL AddNode(const char *szJid, const char *szNode, const char *szName, JABBER_ADHOC_HANDLER pHandler) { CJabberAdhocNode* pNode = new CJabberAdhocNode(m_pProto, szJid, szNode, szName, pHandler); if (!pNode) return FALSE; mir_cslock lck(m_cs); if (!m_pNodes) m_pNodes = pNode; else { CJabberAdhocNode* pTmp = m_pNodes; while (pTmp->GetNext()) pTmp = pTmp->GetNext(); pTmp->SetNext(pNode); } return TRUE; } CJabberAdhocNode* GetFirstNode() { return m_pNodes; } BOOL HandleItemsRequest(const TiXmlElement *iqNode, CJabberIqInfo *pInfo, const char *szNode); BOOL HandleInfoRequest(const TiXmlElement *iqNode, CJabberIqInfo *pInfo, const char *szNode); BOOL HandleCommandRequest(const TiXmlElement *iqNode, CJabberIqInfo *pInfo, const char *szNode); BOOL ExpireSessions() { mir_cslock lck(m_cs); DWORD dwExpireTime = GetTickCount() - JABBER_ADHOC_SESSION_EXPIRE_TIME; while (_ExpireSession(dwExpireTime)) ; return TRUE; } }; #endif //_JABBER_RC_H_