diff options
Diffstat (limited to 'protocols/IcqOscarJ/src/cookies.cpp')
-rw-r--r-- | protocols/IcqOscarJ/src/cookies.cpp | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/protocols/IcqOscarJ/src/cookies.cpp b/protocols/IcqOscarJ/src/cookies.cpp new file mode 100644 index 0000000000..87ffb4bc07 --- /dev/null +++ b/protocols/IcqOscarJ/src/cookies.cpp @@ -0,0 +1,301 @@ +// ---------------------------------------------------------------------------80
+// ICQ plugin for Miranda Instant Messenger
+// ________________________________________
+//
+// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
+// Copyright © 2001-2002 Jon Keating, Richard Hughes
+// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
+// Copyright © 2004-2010 Joe Kucera
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// -----------------------------------------------------------------------------
+// DESCRIPTION:
+//
+// Handles packet & message cookies
+//
+// -----------------------------------------------------------------------------
+#include "icqoscar.h"
+
+
+#define INVALID_COOKIE_INDEX -1
+
+void CIcqProto::RemoveExpiredCookies()
+{
+ time_t tNow = time(NULL);
+
+ for (int i = cookies.getCount()-1; i >= 0; i--)
+ {
+ icq_cookie_info *cookie = cookies[i];
+
+ if ((cookie->dwTime + COOKIE_TIMEOUT) < tNow)
+ {
+ cookies.remove(i);
+ SAFE_FREE((void**)&cookie);
+ }
+ }
+}
+
+
+// Generate and allocate cookie
+DWORD CIcqProto::AllocateCookie(BYTE bType, WORD wIdent, HANDLE hContact, void *pvExtra)
+{
+ icq_lock l(cookieMutex);
+
+ DWORD dwThisSeq = wCookieSeq++;
+ dwThisSeq &= 0x7FFF;
+ dwThisSeq |= wIdent<<0x10;
+
+ icq_cookie_info* p = (icq_cookie_info*)SAFE_MALLOC(sizeof(icq_cookie_info));
+ if (p)
+ {
+ p->bType = bType;
+ p->dwCookie = dwThisSeq;
+ p->hContact = hContact;
+ p->pvExtra = pvExtra;
+ p->dwTime = time(NULL);
+ cookies.insert(p);
+ }
+ return dwThisSeq;
+}
+
+
+DWORD CIcqProto::GenerateCookie(WORD wIdent)
+{
+ icq_lock l(cookieMutex);
+
+ DWORD dwThisSeq = wCookieSeq++;
+ dwThisSeq &= 0x7FFF;
+ dwThisSeq |= wIdent<<0x10;
+
+ return dwThisSeq;
+}
+
+
+int CIcqProto::GetCookieType(DWORD dwCookie)
+{
+ icq_lock l(cookieMutex);
+
+ int i = cookies.getIndex(( icq_cookie_info* )&dwCookie );
+ if ( i != INVALID_COOKIE_INDEX )
+ i = cookies[i]->bType;
+
+ return i;
+}
+
+
+int CIcqProto::FindCookie(DWORD dwCookie, HANDLE *phContact, void **ppvExtra)
+{
+ icq_lock l(cookieMutex);
+
+ int i = cookies.getIndex(( icq_cookie_info* )&dwCookie );
+ if (i != INVALID_COOKIE_INDEX)
+ {
+ if (phContact)
+ *phContact = cookies[i]->hContact;
+ if (ppvExtra)
+ *ppvExtra = cookies[i]->pvExtra;
+
+ // Cookie found
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int CIcqProto::FindCookieByData(void *pvExtra, DWORD *pdwCookie, HANDLE *phContact)
+{
+ icq_lock l(cookieMutex);
+
+ for (int i = 0; i < cookies.getCount(); i++)
+ {
+ if (pvExtra == cookies[i]->pvExtra)
+ {
+ if (phContact)
+ *phContact = cookies[i]->hContact;
+ if (pdwCookie)
+ *pdwCookie = cookies[i]->dwCookie;
+
+ // Cookie found
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+int CIcqProto::FindCookieByType(BYTE bType, DWORD *pdwCookie, HANDLE *phContact, void** ppvExtra)
+{
+ icq_lock l(cookieMutex);
+
+ for (int i = 0; i < cookies.getCount(); i++)
+ {
+ if (bType == cookies[i]->bType)
+ {
+ if (pdwCookie)
+ *pdwCookie = cookies[i]->dwCookie;
+ if (phContact)
+ *phContact = cookies[i]->hContact;
+ if (ppvExtra)
+ *ppvExtra = cookies[i]->pvExtra;
+
+ // Cookie found
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+int CIcqProto::FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCookie, HANDLE *phContact, cookie_message_data **ppvExtra)
+{
+ icq_lock l(cookieMutex);
+
+ for (int i = 0; i < cookies.getCount(); i++)
+ {
+ if (cookies[i]->bType == CKT_MESSAGE || cookies[i]->bType == CKT_FILE || cookies[i]->bType == CKT_REVERSEDIRECT)
+ { // message cookie found
+ cookie_message_data *pCookie = (cookie_message_data*)cookies[i]->pvExtra;
+
+ if (pCookie->dwMsgID1 == dwMsgID1 && pCookie->dwMsgID2 == dwMsgID2)
+ {
+ if (phContact)
+ *phContact = cookies[i]->hContact;
+ if (pdwCookie)
+ *pdwCookie = cookies[i]->dwCookie;
+ if (ppvExtra)
+ *ppvExtra = pCookie;
+
+ // Cookie found
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+void CIcqProto::FreeCookie(DWORD dwCookie)
+{
+ icq_lock l(cookieMutex);
+
+ int i = cookies.getIndex((icq_cookie_info*)&dwCookie);
+ if (i != INVALID_COOKIE_INDEX)
+ { // Cookie found, remove from list
+ icq_cookie_info *cookie = cookies[i];
+
+ cookies.remove(i);
+ SAFE_FREE((void**)&cookie);
+ }
+
+ RemoveExpiredCookies();
+}
+
+
+void CIcqProto::FreeCookieByData(BYTE bType, void *pvExtra)
+{
+ icq_lock l(cookieMutex);
+
+ for (int i = 0; i < cookies.getCount(); i++)
+ {
+ icq_cookie_info *cookie = cookies[i];
+
+ if (bType == cookie->bType && pvExtra == cookie->pvExtra)
+ { // Cookie found, remove from list
+ cookies.remove(i);
+ SAFE_FREE((void**)&cookie);
+ break;
+ }
+ }
+
+ RemoveExpiredCookies();
+}
+
+
+void CIcqProto::ReleaseCookie(DWORD dwCookie)
+{
+ icq_lock l(cookieMutex);
+
+ int i = cookies.getIndex(( icq_cookie_info* )&dwCookie );
+ if (i != INVALID_COOKIE_INDEX)
+ { // Cookie found, remove from list
+ icq_cookie_info *cookie = cookies[i];
+
+ cookies.remove(i);
+ SAFE_FREE((void**)&cookie->pvExtra);
+ SAFE_FREE((void**)&cookie);
+ }
+ RemoveExpiredCookies();
+}
+
+
+void CIcqProto::InitMessageCookie(cookie_message_data *pCookie)
+{
+ DWORD dwMsgID1;
+ DWORD dwMsgID2;
+
+ do
+ { // ensure that message ids are unique
+ dwMsgID1 = time(NULL);
+ dwMsgID2 = RandRange(0, 0x0FFFF);
+ } while (FindMessageCookie(dwMsgID1, dwMsgID2, NULL, NULL, NULL));
+
+ if (pCookie)
+ {
+ pCookie->dwMsgID1 = dwMsgID1;
+ pCookie->dwMsgID2 = dwMsgID2;
+ }
+}
+
+
+cookie_message_data* CIcqProto::CreateMessageCookie(WORD bMsgType, BYTE bAckType)
+{
+ cookie_message_data *pCookie = (cookie_message_data*)SAFE_MALLOC(sizeof(cookie_message_data));
+ if (pCookie)
+ {
+ pCookie->bMessageType = bMsgType;
+ pCookie->nAckType = bAckType;
+
+ InitMessageCookie(pCookie);
+ }
+ return pCookie;
+}
+
+
+cookie_message_data* CIcqProto::CreateMessageCookieData(BYTE bMsgType, HANDLE hContact, DWORD dwUin, int bUseSrvRelay)
+{
+ BYTE bAckType;
+ WORD wStatus = getContactStatus(hContact);
+
+ if (!getSettingByte(hContact, "SlowSend", getSettingByte(NULL, "SlowSend", DEFAULT_SLOWSEND)) ||
+ (!dwUin && wStatus == ID_STATUS_OFFLINE))
+ bAckType = ACKTYPE_NONE;
+ else if (bUseSrvRelay)
+ bAckType = ACKTYPE_CLIENT;
+ else
+ bAckType = ACKTYPE_SERVER;
+
+ cookie_message_data* pCookieData = CreateMessageCookie(bMsgType, bAckType);
+
+ // set flag for offline messages - to allow proper error handling
+ if (wStatus == ID_STATUS_OFFLINE || wStatus == ID_STATUS_INVISIBLE)
+ pCookieData->isOffline = TRUE;
+
+ return pCookieData;
+}
|