diff options
Diffstat (limited to 'protocols/MSN/src/msn_msgqueue.cpp')
-rw-r--r-- | protocols/MSN/src/msn_msgqueue.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/protocols/MSN/src/msn_msgqueue.cpp b/protocols/MSN/src/msn_msgqueue.cpp new file mode 100644 index 0000000000..eeafdfea2f --- /dev/null +++ b/protocols/MSN/src/msn_msgqueue.cpp @@ -0,0 +1,204 @@ +/*
+Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
+Copyright (c) 2006-2012 Boris Krasnovskiy.
+Copyright (c) 2003-2005 George Hazan.
+Copyright (c) 2002-2003 Richard Hughes (original version).
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "msn_global.h"
+#include "msn_proto.h"
+
+//a few little functions to manage queuing send message requests until the
+//connection is established
+
+void CMsnProto::MsgQueue_Init(void)
+{
+ msgQueueSeq = 1;
+ InitializeCriticalSection(&csMsgQueue);
+}
+
+void CMsnProto::MsgQueue_Uninit(void)
+{
+ MsgQueue_Clear();
+ DeleteCriticalSection(&csMsgQueue);
+}
+
+int CMsnProto::MsgQueue_Add(const char* wlid, int msgType, const char* msg, int msgSize, filetransfer* ft, int flags, STRLIST *cnt)
+{
+ EnterCriticalSection(&csMsgQueue);
+
+ MsgQueueEntry* E = new MsgQueueEntry;
+ msgQueueList.insert(E);
+
+ int seq = msgQueueSeq++;
+
+ E->wlid = mir_strdup(wlid);
+ E->msgSize = msgSize;
+ E->msgType = msgType;
+ if (msgSize <= 0)
+ E->message = mir_strdup(msg);
+ else
+ memcpy(E->message = (char*)mir_alloc(msgSize), msg, msgSize);
+ E->ft = ft;
+ E->cont = cnt;
+ E->seq = seq;
+ E->flags = flags;
+ E->allocatedToThread = 0;
+ E->ts = time(NULL);
+
+ LeaveCriticalSection(&csMsgQueue);
+ return seq;
+}
+
+// shall we create another session?
+const char* CMsnProto::MsgQueue_CheckContact(const char* wlid, time_t tsc)
+{
+ EnterCriticalSection(&csMsgQueue);
+
+ time_t ts = time(NULL);
+ const char* ret = NULL;
+ for (int i=0; i < msgQueueList.getCount(); i++)
+ {
+ if (_stricmp(msgQueueList[i].wlid, wlid) == 0 && (tsc == 0 || (ts - msgQueueList[i].ts) < tsc))
+ {
+ ret = wlid;
+ break;
+ }
+ }
+
+ LeaveCriticalSection(&csMsgQueue);
+ return ret;
+}
+
+//for threads to determine who they should connect to
+const char* CMsnProto::MsgQueue_GetNextRecipient(void)
+{
+ EnterCriticalSection(&csMsgQueue);
+
+ const char* ret = NULL;
+ for (int i=0; i < msgQueueList.getCount(); i++)
+ {
+ MsgQueueEntry& E = msgQueueList[i];
+ if (!E.allocatedToThread)
+ {
+ E.allocatedToThread = 1;
+ ret = E.wlid;
+
+ while(++i < msgQueueList.getCount())
+ if (_stricmp(msgQueueList[i].wlid, ret) == 0)
+ msgQueueList[i].allocatedToThread = 1;
+
+ break;
+ }
+ }
+
+ LeaveCriticalSection(&csMsgQueue);
+ return ret;
+}
+
+//deletes from list. Must mir_free() return value
+bool CMsnProto::MsgQueue_GetNext(const char* wlid, MsgQueueEntry& retVal)
+{
+ int i;
+
+ EnterCriticalSection(&csMsgQueue);
+ for(i=0; i < msgQueueList.getCount(); i++)
+ if (_stricmp(msgQueueList[i].wlid, wlid) == 0)
+ break;
+
+ bool res = i != msgQueueList.getCount();
+ if (res)
+ {
+ retVal = msgQueueList[i];
+ msgQueueList.remove(i);
+ }
+ LeaveCriticalSection(&csMsgQueue);
+ return res;
+}
+
+int CMsnProto::MsgQueue_NumMsg(const char* wlid)
+{
+ int res = 0;
+ EnterCriticalSection(&csMsgQueue);
+
+ for(int i=0; i < msgQueueList.getCount(); i++)
+ res += (_stricmp(msgQueueList[i].wlid, wlid) == 0);
+
+ LeaveCriticalSection(&csMsgQueue);
+ return res;
+}
+
+void CMsnProto::MsgQueue_Clear(const char* wlid, bool msg)
+{
+ int i;
+
+ EnterCriticalSection(&csMsgQueue);
+ if (wlid == NULL)
+ {
+
+ for(i=0; i < msgQueueList.getCount(); i++)
+ {
+ const MsgQueueEntry& E = msgQueueList[i];
+ if (E.msgSize == 0)
+ {
+ HANDLE hContact = MSN_HContactFromEmail(E.wlid);
+ SendBroadcast(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED,
+ (HANDLE)E.seq, (LPARAM)MSN_Translate("Message delivery failed"));
+ }
+ mir_free(E.message);
+ mir_free(E.wlid);
+ if (E.cont) delete E.cont;
+ }
+ msgQueueList.destroy();
+
+ msgQueueSeq = 1;
+ }
+ else
+ {
+ for(i=0; i < msgQueueList.getCount(); i++)
+ {
+ time_t ts = time(NULL);
+ const MsgQueueEntry& E = msgQueueList[i];
+ if (_stricmp(msgQueueList[i].wlid, wlid) == 0 && (!msg || E.msgSize == 0))
+ {
+ bool msgfnd = E.msgSize == 0 && E.ts < ts;
+ int seq = E.seq;
+
+ mir_free(E.message);
+ mir_free(E.wlid);
+ if (E.cont) delete E.cont;
+ msgQueueList.remove(i);
+
+ if (msgfnd)
+ {
+ LeaveCriticalSection(&csMsgQueue);
+ HANDLE hContact = MSN_HContactFromEmail(wlid);
+ SendBroadcast(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)seq,
+ (LPARAM)MSN_Translate("Message delivery failed"));
+ i = 0;
+ EnterCriticalSection(&csMsgQueue);
+ }
+ }
+ }
+ }
+ LeaveCriticalSection(&csMsgQueue);
+}
+
+void __cdecl CMsnProto::MsgQueue_AllClearThread(void* arg)
+{
+ MsgQueue_Clear((char*)arg);
+ mir_free(arg);
+}
|