summaryrefslogtreecommitdiff
path: root/contact.c
diff options
context:
space:
mode:
Diffstat (limited to 'contact.c')
-rw-r--r--contact.c1636
1 files changed, 818 insertions, 818 deletions
diff --git a/contact.c b/contact.c
index 6891b9c..97102c1 100644
--- a/contact.c
+++ b/contact.c
@@ -1,818 +1,818 @@
-/*
-
-"Spam Filter"-Plugin for Miranda IM
-
-Copyright 2003-2006 Heiko Herkenrath
-
-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 ("SpamFilter-License.txt"); if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-
-// -- Includes
-#include "common.h"
-
-
-// -----------------------------------------
-
-
-WORD IncreasePreSpammerCount(SPAMCHECKDATA* pscd)
-{
- WCHAR* pszUnique;
- char* pszUniqueUtf8;
- WORD sentSpam;
-
- // Get UTF-8 encoded unique str
- pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
- if (!pszUnique) return FALSE;
- pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
- mir_free(pszUnique);
- if (!pszUniqueUtf8) return FALSE;
-
- // Inc count
- sentSpam = (WORD)DBGetContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, 0);
- sentSpam++;
- DBWriteContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, sentSpam);
-
- mir_free(pszUniqueUtf8);
-
- // Update "Auto-Ignore" button if options are opened
- if (IsWindow(hwndSpamFilterOpt))
- PostMessage(hwndSpamFilterOpt, SFM_CHECK_AUTOIGNORE, 0, 0);
-
- return sentSpam;
-}
-
-WORD GetPreSpammerCount(SPAMCHECKDATA* pscd)
-{
- WCHAR* pszUnique;
- char* pszUniqueUtf8;
- WORD sentSpam;
-
- // Get UTF-8 encoded unique str
- pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
- if (!pszUnique) return 0;
- pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
- mir_free(pszUnique);
- if (!pszUniqueUtf8) return 0;
-
- sentSpam = (WORD)DBGetContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, 0);
- mir_free(pszUniqueUtf8);
- return sentSpam;
-}
-
-BOOL RemovePreSpammerCount(SPAMCHECKDATA* pscd)
-{
- WCHAR* pszUnique;
- char* pszUniqueUtf8;
- BOOL bReturn;
-
- // Get UTF-8 encoded unique str
- pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
- if (!pszUnique) return FALSE;
- pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
- mir_free(pszUnique);
- if (!pszUniqueUtf8) return FALSE;
-
- bReturn = (DBDeleteContactSetting(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8) == 0);
-
- // Update "Auto-Ignore" button if options are opened
- if (IsWindow(hwndSpamFilterOpt))
- PostMessage(hwndSpamFilterOpt, SFM_CHECK_AUTOIGNORE, 0, 0);
-
- mir_free(pszUniqueUtf8);
- return bReturn;
-}
-
-
-int MarkAllContactEventsUnRead(HANDLE hContact)
-{
- int iReturn;
- HANDLE* hDbEvents = NULL;
- HANDLE* hDbEventsBuf;
- int iEventCount;
- HANDLE hDbEvent;
- int i;
- DBEVENTINFO dbei;
-
- iReturn = 0;
-
- // Loop through all events in the contact chain
- iEventCount = 0;
- for (hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0); hDbEvent; hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0))
- {
- // Store all events in memory
- hDbEventsBuf = (HANDLE*)mir_realloc(hDbEvents, (iEventCount+1)*sizeof(HANDLE));
- if (!hDbEventsBuf) break;
- hDbEvents = hDbEventsBuf;
- hDbEvents[iEventCount] = hDbEvent;
- iEventCount++;
- BOX2("cnt:%i, hndl:%i", iEventCount, hDbEvent);
- }
-
- // Add all old events back to the contact
- for (i=0; i<iEventCount; i++)
- {
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvents[i], 0);
- if (dbei.cbBlob <= 0) continue;
- dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
- if (!dbei.pBlob) continue;
-
- if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvents[i], (LPARAM)&dbei) == 0)
- {
- switch (dbei.eventType)
- {
- case EVENTTYPE_AUTHREQUEST:
- case EVENTTYPE_ADDED:
- case EVENTTYPE_CONTACTS:
- case EVENTTYPE_MESSAGE:
- case EVENTTYPE_URL:
- case EVENTTYPE_FILE:
- {
- if (!(dbei.flags&DBEF_SENT))
- dbei.flags ^= DBEF_READ;
-
- CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvents[i]);
-
- // Re-add event
- BOX2("handle evnts: %i hdl:%i", i, hDbEvents[i]);
- if (CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvents[i]) == 0)
- if ((HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei) != NULL)
- iReturn++;
- break;
- }
- }
- }
-
- mir_free(dbei.pBlob);
- }
-
- // Authorization requests are stored under the main contact
- // Loop through all events in the main chain
- iEventCount = 0;
- for (hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)NULL, 0); hDbEvent; hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0))
- {
- // Store all events in memory
- hDbEventsBuf = (HANDLE*)mir_realloc(hDbEvents, (iEventCount+1)*sizeof(HANDLE));
- if (!hDbEventsBuf) break;
- hDbEvents = hDbEventsBuf;
- hDbEvents[iEventCount] = hDbEvent;
- iEventCount++;
- }
-
- // Add all old events back to the contact
- for (i=0; i<iEventCount; i++)
- {
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvents[i], 0);
- if (dbei.cbBlob <= 0) continue;
- dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
- if (!dbei.pBlob) continue;
-
- if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvents[i], (LPARAM)&dbei) == 0)
- {
- if ((dbei.eventType == EVENTTYPE_AUTHREQUEST) || (dbei.eventType == EVENTTYPE_ADDED))
- {
- // DB event corrupt check
- if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)))
- {
- if (*((PHANDLE)(dbei.pBlob+sizeof(DWORD))) == hContact)
- {
- if (!(dbei.flags&DBEF_SENT))
- dbei.flags ^= DBEF_READ;
-
- CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvents[i]);
-
- // Re-add event
- if (CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvents[i]) == 0) // if successful
- if ((HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei) != NULL)
- iReturn++;
- }
- }
- }
- }
-
- mir_free(dbei.pBlob);
- }
-
- if (hDbEvents) mir_free(hDbEvents);
- return iReturn;
-}
-
-BOOL SendContactAutomatedMessage(HANDLE hContact, WCHAR* pszMessage, BOOL bAddToHistory)
-{
- BOOL bReturn;
- WCHAR* sendBuffer;
- int bufSize;
- char* pszProto;
- int iSendRes;
-
- if (!hContact || !pszMessage || (pszMessage[0] == _T('\0'))) return FALSE;
- pszProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
- if (!pszProto) return FALSE;
-
- // Limit the message to max possible length
- {
- int iMaxLen = CallProtoService(pszProto, PS_GETCAPS, (WPARAM)PFLAG_MAXLENOFMESSAGE, (LPARAM)hContact);
- if (iMaxLen != CALLSERVICE_NOTFOUND)
- if ((int)lstrlen(pszMessage) > iMaxLen)
- pszMessage[iMaxLen] = _T('\0');
- }
-
- // Construct message text
- #if defined(UNICODE)
- {
- char* buf;
- mir_utf8decode((char*)pszMessage,&sendBuffer);
- if (!sendBuffer) return FALSE;
- bufSize = lstrlenW(sendBuffer)+1;
- bufSize *= sizeof(WCHAR)+1;
- buf = (char*)mir_realloc(sendBuffer, bufSize);
- if (!buf) {
- mir_free(sendBuffer);
- return FALSE;
- }
- }
- #else
- sendBuffer = pszMessage;
- bufSize = lstrlen(pszMessage)+1;
- #endif
-
- // Send the message
- #if defined(UNICODE)
- if (pszProto) {
- char szService[MAXMODULELABELLENGTH+10];
- mir_snprintf(szService, ARRAYSIZE(szService), "%s%sW", pszProto, PSS_MESSAGE);
- bReturn = ServiceExists(szService);
- } else {
- bReturn = FALSE;
- }
- iSendRes = CallContactService(hContact, bReturn?PSS_MESSAGE"W":PSS_MESSAGE, (WPARAM)PREF_UNICODE, (LPARAM)sendBuffer);
- #else
- iSendRes = CallContactService(hContact, PSS_MESSAGE, (WPARAM)0, (LPARAM)sendBuffer);
- #endif
- bReturn = ((iSendRes != CALLSERVICE_NOTFOUND) && (iSendRes != 0));
-
- // Add the message to history
- if (bReturn && bAddToHistory)
- {
- DBEVENTINFO dbei;
-
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.timestamp = time(NULL);
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.flags = DBEF_SENT;
- dbei.szModule = pszProto;
- dbei.cbBlob = bufSize; // Blob without terminating zero, but adding it though to avoid problems
- dbei.pBlob = (PBYTE)sendBuffer;
-
- CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
- }
-
- #if defined(UNICODE)
- mir_free(sendBuffer);
- #endif
-
- return bReturn;
-}
-
-
-BOOL CreateContactListGroup(WCHAR* pszGroupName)
-{
- int i;
- char str[MAX_INT_LENGTH+1];
- WCHAR name[256];
- DBVARIANT dbv;
-
- if (!pszGroupName) return FALSE;
-
- for (i=0; ;i++)
- {
- mir_snprintf(str, ARRAYSIZE(str), "%i", i);
- if (DBGetContactSettingTString(NULL, "CListGroups", str, &dbv) != 0)
- break;
- if (dbv.ptszVal[0] && !StrCmpI(dbv.ptszVal+1, pszGroupName)) {
- DBFreeVariant(&dbv);
- return FALSE;
- }
- DBFreeVariant(&dbv);
- }
-
- name[0] = 1|GROUPF_EXPANDED;
- mir_sntprintf(&name[1], ARRAYSIZE(name)-1, _T("%s"), pszGroupName);
- DBWriteContactSettingTString(NULL, "CListGroups", str, name);
- CallService(MS_CLUI_GROUPADDED, (WPARAM)i+1, 0);
- return TRUE;
-}
-
-
-BOOL RemoveContactListGroup(WCHAR* pszGroupName)
-{
- int i;
- char str[MAX_INT_LENGTH+1];
- DBVARIANT dbv;
-
- if (!pszGroupName) return FALSE;
- for (i=0; ;i++)
- {
- mir_snprintf(str, ARRAYSIZE(str), "%i", i);
- if (DBGetContactSettingTString(NULL, "CListGroups", str, &dbv) != 0)
- return FALSE;
- if (dbv.ptszVal[0] && !StrCmpI(dbv.ptszVal+1, pszGroupName)) {
- DBFreeVariant(&dbv);
- break;
- }
- DBFreeVariant(&dbv);
- }
-
- // Bring up confirm window
- return (CallService(MS_CLIST_GROUPDELETE, (WPARAM)i+1, 0) == 0);
-}
-
-
-BOOL RemoveContactFromIgnoreList(HANDLE hContact)
-{
- // Un-Ignore all events for the contact
- BOOL bReturn = (CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, IGNOREEVENT_ALL) == 0);
-
- // Remove group association
- DBDeleteContactSetting(hContact, "CList", "Group");
-
- // Restore NotOnList state
- if (!DBGetContactSettingByte(hContact, DB_MODULE_NAME, "WasOnList", 0))
- DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
- DBDeleteContactSetting(hContact, DB_MODULE_NAME, "WasOnList");
-
- // Unhide the contact
- DBDeleteContactSetting(hContact, "CList", "Hidden");
-
- // Re-Accept typing notifications
- DBWriteContactSettingByte(hContact, "SRMM", "SupportTyping", 1);
-
- // Restore not to appear as offline to the contact (back to normal mode)
- CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)0, 0);
-
- // Rename contact (to default name)
- DBDeleteContactSetting(hContact, "CList", "MyHandle");
- // Tell clist to refresh it's cache
- CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, 0);
-
- // NotifySpammerStateChanged will be called automatically on settings change
- DBWriteContactSettingByte(hContact, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)FALSE);
-
- return bReturn;
-}
-
-
-BOOL AddContactToIgnoreList(HANDLE hContact, BOOL bKeepHistory, BOOL bDenyAuthRequests, BOOL bNoLog)
-{
- BOOL bReturn;
- DBVARIANT dbv;
-
- // NotifySpammerStateChanged will be called automatically on settings change
- DBWriteContactSettingByte(hContact, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)TRUE);
-
- // Ignore all events for the contact
- bReturn = (CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, IGNOREEVENT_ALL) == 0);
-
- if (DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
- {
- // Hide the contact
- // (Hide it before removing NotOnList setting, so that no YouWereAdded notification is sent)
- if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_HIDEFROMCLIST, (BYTE)DEFAULT_SETTING_HIDEFROMCLIST))
- DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
- else
- DBDeleteContactSetting(hContact, "CList", "Hidden");
-
- // Add permanently to list (after hide!!!)
- DBDeleteContactSetting(hContact, "CList", "NotOnList");
-
- // Remove association to a contactlist group (change to spammers)
- if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUP, (BYTE)DEFAULT_SETTING_MOVETOGROUP) &&
- DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, &dbv) == 0)
- {
- CreateContactListGroup(dbv.ptszVal);
- DBWriteContactSettingTString(hContact, "CList", "Group", dbv.ptszVal);
- DBFreeVariant(&dbv);
- } else {
- DBDeleteContactSetting(hContact, "CList", "Group");
- }
- } else {
- DBWriteContactSettingByte(hContact, DB_MODULE_NAME, "WasOnList", 1);
- }
-
- // Do not send typing notifications
- DBWriteContactSettingByte(hContact, "SRMM", "SupportTyping", 0);
-
- // Appear as offline to the contact
- CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)ID_STATUS_OFFLINE, 0);
-
- // Rename contact
- {
- CONTACTINFO ci;
-
- ZeroMemory(&ci, sizeof(ci));
- ci.cbSize = sizeof(ci);
- ci.hContact = hContact;
- #if defined(UNICODE)
- ci.dwFlag = CNF_UNIQUEID|CNF_UNICODE;
- #else
- ci.dwFlag = CNF_UNIQUEID;
- #endif
-
- if (CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci) == 0)
- {
- WCHAR* pszUniqueID = NULL;
-
- if (ci.type == CNFT_ASCIIZ) {
- pszUniqueID = ci.pszVal; // mir_alloc used by MS_CONTACT_GETCONTACTINFO
- } else if (ci.type == CNFT_DWORD) {
- pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
- if (pszUniqueID)
- mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.dVal);
- } else if (ci.type == CNFT_WORD) {
- pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
- if (pszUniqueID)
- mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.wVal);
- } else if (ci.type == CNFT_BYTE) {
- pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
- if (pszUniqueID)
- mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.bVal);
- }
-
- if (pszUniqueID) {
- DBWriteContactSettingTString(hContact, "CList", "MyHandle", pszUniqueID);
- mir_free(pszUniqueID);
- }
- }
-/*
- pszSuffix = TranslateT(" (Spammer)");
- if (pszUniqueID && pszSuffix)
- {
- TCHAR* pszNewName = (TCHAR*)mir_alloc((lstrlen(pszUniqueID)+lstrlen(pszSuffix)+1)*sizeof(TCHAR));
-
- if (pszNewName)
- {
- mir_sntprintf(pszNewName, lstrlen(pszUniqueID)+lstrlen(pszSuffix)+1, _T("%s%s"), pszUniqueID, pszSuffix);
-
- DBWriteContactSettingTString(hContact, "CList", "MyHandle", pszNewName);
-
- // Tell CList to refresh it's cache
- CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, 0);
-
- mir_free(pszNewName);
- }
- }
-*/
- }
-
- // Remove History (or mark read to get rid of pending "new message" notifications)
- {
- HANDLE hDbEvent, hDbEventBuf;
-
- STRINGLIST* pslRecognition = NULL;
- DBEVENTINFO dbei;
- PBYTE pLogText;
- WCHAR* pszUserName;
- BOOL bDoWriteLog;
-
- bDoWriteLog = !bNoLog && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, DEFAULT_SETTING_LOGGING);
- if (bDoWriteLog)
- {
- pslRecognition = SLNewList();
- SLAddItem(pslRecognition, TranslateT("Contact set as spammer"));
- }
-
- // ** History of the contact **
- // hDbEvent gets buffered to allow deleting while enumerating (handle is offset)
- hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
- hDbEvent = hDbEventBuf;
-
- while (hDbEvent)
- {
- hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
-
- // Now handle hDbEvent
- {
- if (bDoWriteLog || bDenyAuthRequests)
- {
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
- if (dbei.cbBlob <= 0)
- {
- dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob+sizeof(WCHAR)); // adding terminating zeros (security)
- if (!dbei.pBlob)
- {
- // Ensure terminating zero
- ZeroMemory(dbei.pBlob+dbei.cbBlob, sizeof(WCHAR));
-
- if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0) // if successful
- {
- if (!(dbei.flags&DBEF_SENT) && !(dbei.flags&DBEF_READ))
- {
- switch (dbei.eventType)
- {
- case EVENTTYPE_MESSAGE:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
- {
- #if defined(UNICODE)
- // Checking if Unicode text available
- if (dbei.cbBlob > lstrlenA((char*)dbei.pBlob))
- pLogText = dbei.pBlob+(lstrlenA((char*)dbei.pBlob)+1)*sizeof(char);
- else
- pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)dbei.pBlob);
- #else
- pLogText = dbei.pBlob;
- #endif
-
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
- WriteToLogFile(dbei.szModule, SFMT_MESSAGE, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
-
- #if defined(UNICODE)
- if (pLogText)
- if (dbei.cbBlob <= lstrlenA((char*)dbei.pBlob))
- mir_free(pLogText);
- #endif
- }
- }
- break;
- }
-
- case EVENTTYPE_URL:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_URL))
- {
- // DB event corrupt check
- if (dbei.cbBlob >= 2*sizeof(char))
- {
- pLogText = dbei.pBlob+(lstrlenA((char*)dbei.pBlob)+1)*sizeof(char);
-
- #if defined(UNICODE)
- pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
- #endif
-
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_URL, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
-
- #if defined(UNICODE)
- if (pLogText) mir_free(pLogText);
- #endif
- }
- }
- }
- break;
- }
-
- case EVENTTYPE_FILE:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_FILE))
- {
- // DB event corrupt check
- if (dbei.cbBlob >= (sizeof(DWORD)+3*sizeof(char)))
- {
- pLogText = dbei.pBlob+sizeof(DWORD); // hTransfer, filename(s)
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // description
-
- #if defined(UNICODE)
- pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
- #endif
-
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_FILE, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
-
- #if defined(UNICODE)
- if (pLogText) mir_free(pLogText);
- #endif
- }
- }
- }
- break;
- }
-
- case EVENTTYPE_CONTACTS:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_CONTACTS))
- {
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_CONTACTS, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
- }
- }
- break;
- }
-
- case EVENTTYPE_AUTHREQUEST:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
- {
- // DB event corrupt check
- if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)+5*sizeof(char)))
- {
- pLogText = dbei.pBlob+sizeof(DWORD)+sizeof(HANDLE); // uin, hcontact, nick
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // first
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // last
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // email
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // reason
-
- #if defined(UNICODE)
- pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
- #endif
-
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_AUTHREQUEST, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
-
- #if defined(UNICODE)
- if (pLogText) mir_free(pLogText);
- #endif
- }
- }
- }
-
- // Deny authorisation
- if (bDenyAuthRequests)
- CallProtoService(dbei.szModule, PS_AUTHDENY, (WPARAM)hDbEvent, (LPARAM)NULL); // without reason
-
- break;
- }
-
- case EVENTTYPE_ADDED:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
- {
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_ADDED, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
- }
- }
- break;
- }
-
- } // switch
- }
-
- mir_free(dbei.pBlob);
- }
- }
- }
- }
-
- CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvent);
-
- if (bKeepHistory)
- CallService(MS_DB_EVENT_MARKREAD, (WPARAM)hContact, (LPARAM)hDbEvent);
- else
- CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvent);
- }
-
- hDbEvent = hDbEventBuf;
- }
-
- return TRUE;
-
- // ** Main contact **
- // Authorization Requests and Added Notifications are stored under the main contact
- // hDbEvent gets buffered to allow deleting while enumerating (handle is offset)
- hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
- hDbEvent = hDbEventBuf;
-
- while (hDbEvent)
- {
- hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
-
- // Now handle hDbEvent
- {
- ZeroMemory(&dbei,sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
- if (dbei.cbBlob < 0)
- {
- dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob+sizeof(WCHAR));
- if (dbei.pBlob)
- {
- // Ensure terminating zero
- ZeroMemory(dbei.pBlob+dbei.cbBlob, sizeof(WCHAR));
-
- if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0)
- {
- if ((dbei.eventType == EVENTTYPE_AUTHREQUEST) || (dbei.eventType == EVENTTYPE_ADDED))
- {
- // DB event corrupt check
- if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)))
- {
- if (*((PHANDLE)(dbei.pBlob+sizeof(DWORD))) == hContact)
- {
- if (bDoWriteLog || bDenyAuthRequests)
- {
- if (!(dbei.flags&DBEF_SENT) && !(dbei.flags&DBEF_READ))
- {
- switch (dbei.eventType)
- {
- case EVENTTYPE_AUTHREQUEST:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_AUTHREQUEST))
- {
- // DB event corrupt check
- if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)+5*sizeof(char)))
- {
- pLogText = dbei.pBlob+sizeof(DWORD)+sizeof(HANDLE); // uin, hcontact, nick
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // first
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // last
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // email
- pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // reason
-
- #if defined(UNICODE)
- pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
- #endif
-
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_AUTHREQUEST, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
-
- #if defined(UNICODE)
- if (pLogText) mir_free(pLogText);
- #endif
- }
- }
- }
-
- // Deny authorisation
- if (bDenyAuthRequests)
- CallProtoService(dbei.szModule, PS_AUTHDENY, (WPARAM)hDbEvent, (LPARAM)NULL); // without reason
-
- break;
- }
-
- case EVENTTYPE_ADDED:
- {
- if (bDoWriteLog)
- {
- if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_ADDED))
- {
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- WriteToLogFile(dbei.szModule, SFMT_ADDED, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
- }
- }
- break;
- }
- } // switch
- }
- }
-
- CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvent);
-
- if (bKeepHistory)
- CallService(MS_DB_EVENT_MARKREAD, (WPARAM)hContact, (LPARAM)hDbEvent);
- else
- CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvent); }
- }
- }
-
- }
-
- mir_free(dbei.pBlob);
- }
- }
-
- }
-
- hDbEvent = hDbEventBuf;
- }
- }
-
- return bReturn;
-}
+/*
+
+"Spam Filter"-Plugin for Miranda IM
+
+Copyright 2003-2006 Heiko Herkenrath
+
+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 ("SpamFilter-License.txt"); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+// -- Includes
+#include "common.h"
+
+
+// -----------------------------------------
+
+
+WORD IncreasePreSpammerCount(SPAMCHECKDATA* pscd)
+{
+ WCHAR* pszUnique;
+ char* pszUniqueUtf8;
+ WORD sentSpam;
+
+ // Get UTF-8 encoded unique str
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (!pszUnique) return FALSE;
+ pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
+ mir_free(pszUnique);
+ if (!pszUniqueUtf8) return FALSE;
+
+ // Inc count
+ sentSpam = (WORD)DBGetContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, 0);
+ sentSpam++;
+ DBWriteContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, sentSpam);
+
+ mir_free(pszUniqueUtf8);
+
+ // Update "Auto-Ignore" button if options are opened
+ if (IsWindow(hwndSpamFilterOpt))
+ PostMessage(hwndSpamFilterOpt, SFM_CHECK_AUTOIGNORE, 0, 0);
+
+ return sentSpam;
+}
+
+WORD GetPreSpammerCount(SPAMCHECKDATA* pscd)
+{
+ WCHAR* pszUnique;
+ char* pszUniqueUtf8;
+ WORD sentSpam;
+
+ // Get UTF-8 encoded unique str
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (!pszUnique) return 0;
+ pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
+ mir_free(pszUnique);
+ if (!pszUniqueUtf8) return 0;
+
+ sentSpam = (WORD)DBGetContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, 0);
+ mir_free(pszUniqueUtf8);
+ return sentSpam;
+}
+
+BOOL RemovePreSpammerCount(SPAMCHECKDATA* pscd)
+{
+ WCHAR* pszUnique;
+ char* pszUniqueUtf8;
+ BOOL bReturn;
+
+ // Get UTF-8 encoded unique str
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (!pszUnique) return FALSE;
+ pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
+ mir_free(pszUnique);
+ if (!pszUniqueUtf8) return FALSE;
+
+ bReturn = (DBDeleteContactSetting(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8) == 0);
+
+ // Update "Auto-Ignore" button if options are opened
+ if (IsWindow(hwndSpamFilterOpt))
+ PostMessage(hwndSpamFilterOpt, SFM_CHECK_AUTOIGNORE, 0, 0);
+
+ mir_free(pszUniqueUtf8);
+ return bReturn;
+}
+
+
+int MarkAllContactEventsUnRead(HANDLE hContact)
+{
+ int iReturn;
+ HANDLE* hDbEvents = NULL;
+ HANDLE* hDbEventsBuf;
+ int iEventCount;
+ HANDLE hDbEvent;
+ int i;
+ DBEVENTINFO dbei;
+
+ iReturn = 0;
+
+ // Loop through all events in the contact chain
+ iEventCount = 0;
+ for (hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0); hDbEvent; hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0))
+ {
+ // Store all events in memory
+ hDbEventsBuf = (HANDLE*)mir_realloc(hDbEvents, (iEventCount+1)*sizeof(HANDLE));
+ if (!hDbEventsBuf) break;
+ hDbEvents = hDbEventsBuf;
+ hDbEvents[iEventCount] = hDbEvent;
+ iEventCount++;
+ BOX2("cnt:%i, hndl:%i", iEventCount, hDbEvent);
+ }
+
+ // Add all old events back to the contact
+ for (i=0; i<iEventCount; i++)
+ {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvents[i], 0);
+ if (dbei.cbBlob <= 0) continue;
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
+ if (!dbei.pBlob) continue;
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvents[i], (LPARAM)&dbei) == 0)
+ {
+ switch (dbei.eventType)
+ {
+ case EVENTTYPE_AUTHREQUEST:
+ case EVENTTYPE_ADDED:
+ case EVENTTYPE_CONTACTS:
+ case EVENTTYPE_MESSAGE:
+ case EVENTTYPE_URL:
+ case EVENTTYPE_FILE:
+ {
+ if (!(dbei.flags&DBEF_SENT))
+ dbei.flags ^= DBEF_READ;
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvents[i]);
+
+ // Re-add event
+ BOX2("handle evnts: %i hdl:%i", i, hDbEvents[i]);
+ if (CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvents[i]) == 0)
+ if ((HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei) != NULL)
+ iReturn++;
+ break;
+ }
+ }
+ }
+
+ mir_free(dbei.pBlob);
+ }
+
+ // Authorization requests are stored under the main contact
+ // Loop through all events in the main chain
+ iEventCount = 0;
+ for (hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)NULL, 0); hDbEvent; hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0))
+ {
+ // Store all events in memory
+ hDbEventsBuf = (HANDLE*)mir_realloc(hDbEvents, (iEventCount+1)*sizeof(HANDLE));
+ if (!hDbEventsBuf) break;
+ hDbEvents = hDbEventsBuf;
+ hDbEvents[iEventCount] = hDbEvent;
+ iEventCount++;
+ }
+
+ // Add all old events back to the contact
+ for (i=0; i<iEventCount; i++)
+ {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvents[i], 0);
+ if (dbei.cbBlob <= 0) continue;
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
+ if (!dbei.pBlob) continue;
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvents[i], (LPARAM)&dbei) == 0)
+ {
+ if ((dbei.eventType == EVENTTYPE_AUTHREQUEST) || (dbei.eventType == EVENTTYPE_ADDED))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)))
+ {
+ if (*((PHANDLE)(dbei.pBlob+sizeof(DWORD))) == hContact)
+ {
+ if (!(dbei.flags&DBEF_SENT))
+ dbei.flags ^= DBEF_READ;
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvents[i]);
+
+ // Re-add event
+ if (CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvents[i]) == 0) // if successful
+ if ((HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei) != NULL)
+ iReturn++;
+ }
+ }
+ }
+ }
+
+ mir_free(dbei.pBlob);
+ }
+
+ if (hDbEvents) mir_free(hDbEvents);
+ return iReturn;
+}
+
+BOOL SendContactAutomatedMessage(HANDLE hContact, WCHAR* pszMessage, BOOL bAddToHistory)
+{
+ BOOL bReturn;
+ WCHAR* sendBuffer;
+ int bufSize;
+ char* pszProto;
+ int iSendRes;
+
+ if (!hContact || !pszMessage || (pszMessage[0] == _T('\0'))) return FALSE;
+ pszProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (!pszProto) return FALSE;
+
+ // Limit the message to max possible length
+ {
+ int iMaxLen = CallProtoService(pszProto, PS_GETCAPS, (WPARAM)PFLAG_MAXLENOFMESSAGE, (LPARAM)hContact);
+ if (iMaxLen != CALLSERVICE_NOTFOUND)
+ if ((int)lstrlen(pszMessage) > iMaxLen)
+ pszMessage[iMaxLen] = _T('\0');
+ }
+
+ // Construct message text
+ #if defined(UNICODE)
+ {
+ char* buf;
+ mir_utf8decode((char*)pszMessage,&sendBuffer);
+ if (!sendBuffer) return FALSE;
+ bufSize = lstrlenW(sendBuffer)+1;
+ bufSize *= sizeof(WCHAR)+1;
+ buf = (char*)mir_realloc(sendBuffer, bufSize);
+ if (!buf) {
+ mir_free(sendBuffer);
+ return FALSE;
+ }
+ }
+ #else
+ sendBuffer = pszMessage;
+ bufSize = lstrlen(pszMessage)+1;
+ #endif
+
+ // Send the message
+ #if defined(UNICODE)
+ if (pszProto) {
+ char szService[MAXMODULELABELLENGTH+10];
+ mir_snprintf(szService, ARRAYSIZE(szService), "%s%sW", pszProto, PSS_MESSAGE);
+ bReturn = ServiceExists(szService);
+ } else {
+ bReturn = FALSE;
+ }
+ iSendRes = CallContactService(hContact, bReturn?PSS_MESSAGE"W":PSS_MESSAGE, (WPARAM)PREF_UNICODE, (LPARAM)sendBuffer);
+ #else
+ iSendRes = CallContactService(hContact, PSS_MESSAGE, (WPARAM)0, (LPARAM)sendBuffer);
+ #endif
+ bReturn = ((iSendRes != CALLSERVICE_NOTFOUND) && (iSendRes != 0));
+
+ // Add the message to history
+ if (bReturn && bAddToHistory)
+ {
+ DBEVENTINFO dbei;
+
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.timestamp = time(NULL);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT;
+ dbei.szModule = pszProto;
+ dbei.cbBlob = bufSize; // Blob without terminating zero, but adding it though to avoid problems
+ dbei.pBlob = (PBYTE)sendBuffer;
+
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+ }
+
+ #if defined(UNICODE)
+ mir_free(sendBuffer);
+ #endif
+
+ return bReturn;
+}
+
+
+BOOL CreateContactListGroup(WCHAR* pszGroupName)
+{
+ int i;
+ char str[MAX_INT_LENGTH+1];
+ WCHAR name[256];
+ DBVARIANT dbv;
+
+ if (!pszGroupName) return FALSE;
+
+ for (i=0; ;i++)
+ {
+ mir_snprintf(str, ARRAYSIZE(str), "%i", i);
+ if (DBGetContactSettingTString(NULL, "CListGroups", str, &dbv) != 0)
+ break;
+ if (dbv.ptszVal[0] && !StrCmpI(dbv.ptszVal+1, pszGroupName)) {
+ DBFreeVariant(&dbv);
+ return FALSE;
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ name[0] = 1|GROUPF_EXPANDED;
+ mir_sntprintf(&name[1], ARRAYSIZE(name)-1, _T("%s"), pszGroupName);
+ DBWriteContactSettingTString(NULL, "CListGroups", str, name);
+ CallService(MS_CLUI_GROUPADDED, (WPARAM)i+1, 0);
+ return TRUE;
+}
+
+
+BOOL RemoveContactListGroup(WCHAR* pszGroupName)
+{
+ int i;
+ char str[MAX_INT_LENGTH+1];
+ DBVARIANT dbv;
+
+ if (!pszGroupName) return FALSE;
+ for (i=0; ;i++)
+ {
+ mir_snprintf(str, ARRAYSIZE(str), "%i", i);
+ if (DBGetContactSettingTString(NULL, "CListGroups", str, &dbv) != 0)
+ return FALSE;
+ if (dbv.ptszVal[0] && !StrCmpI(dbv.ptszVal+1, pszGroupName)) {
+ DBFreeVariant(&dbv);
+ break;
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ // Bring up confirm window
+ return (CallService(MS_CLIST_GROUPDELETE, (WPARAM)i+1, 0) == 0);
+}
+
+
+BOOL RemoveContactFromIgnoreList(HANDLE hContact)
+{
+ // Un-Ignore all events for the contact
+ BOOL bReturn = (CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, IGNOREEVENT_ALL) == 0);
+
+ // Remove group association
+ DBDeleteContactSetting(hContact, "CList", "Group");
+
+ // Restore NotOnList state
+ if (!DBGetContactSettingByte(hContact, DB_MODULE_NAME, "WasOnList", 0))
+ DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
+ DBDeleteContactSetting(hContact, DB_MODULE_NAME, "WasOnList");
+
+ // Unhide the contact
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+
+ // Re-Accept typing notifications
+ DBWriteContactSettingByte(hContact, "SRMM", "SupportTyping", 1);
+
+ // Restore not to appear as offline to the contact (back to normal mode)
+ CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)0, 0);
+
+ // Rename contact (to default name)
+ DBDeleteContactSetting(hContact, "CList", "MyHandle");
+ // Tell clist to refresh it's cache
+ CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, 0);
+
+ // NotifySpammerStateChanged will be called automatically on settings change
+ DBWriteContactSettingByte(hContact, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)FALSE);
+
+ return bReturn;
+}
+
+
+BOOL AddContactToIgnoreList(HANDLE hContact, BOOL bKeepHistory, BOOL bDenyAuthRequests, BOOL bNoLog)
+{
+ BOOL bReturn;
+ DBVARIANT dbv;
+
+ // NotifySpammerStateChanged will be called automatically on settings change
+ DBWriteContactSettingByte(hContact, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)TRUE);
+
+ // Ignore all events for the contact
+ bReturn = (CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, IGNOREEVENT_ALL) == 0);
+
+ if (DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ {
+ // Hide the contact
+ // (Hide it before removing NotOnList setting, so that no YouWereAdded notification is sent)
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_HIDEFROMCLIST, (BYTE)DEFAULT_SETTING_HIDEFROMCLIST))
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
+ else
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+
+ // Add permanently to list (after hide!!!)
+ DBDeleteContactSetting(hContact, "CList", "NotOnList");
+
+ // Remove association to a contactlist group (change to spammers)
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUP, (BYTE)DEFAULT_SETTING_MOVETOGROUP) &&
+ DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, &dbv) == 0)
+ {
+ CreateContactListGroup(dbv.ptszVal);
+ DBWriteContactSettingTString(hContact, "CList", "Group", dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ } else {
+ DBDeleteContactSetting(hContact, "CList", "Group");
+ }
+ } else {
+ DBWriteContactSettingByte(hContact, DB_MODULE_NAME, "WasOnList", 1);
+ }
+
+ // Do not send typing notifications
+ DBWriteContactSettingByte(hContact, "SRMM", "SupportTyping", 0);
+
+ // Appear as offline to the contact
+ CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)ID_STATUS_OFFLINE, 0);
+
+ // Rename contact
+ {
+ CONTACTINFO ci;
+
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+ #if defined(UNICODE)
+ ci.dwFlag = CNF_UNIQUEID|CNF_UNICODE;
+ #else
+ ci.dwFlag = CNF_UNIQUEID;
+ #endif
+
+ if (CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci) == 0)
+ {
+ WCHAR* pszUniqueID = NULL;
+
+ if (ci.type == CNFT_ASCIIZ) {
+ pszUniqueID = ci.pszVal; // mir_alloc used by MS_CONTACT_GETCONTACTINFO
+ } else if (ci.type == CNFT_DWORD) {
+ pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
+ if (pszUniqueID)
+ mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.dVal);
+ } else if (ci.type == CNFT_WORD) {
+ pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
+ if (pszUniqueID)
+ mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.wVal);
+ } else if (ci.type == CNFT_BYTE) {
+ pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
+ if (pszUniqueID)
+ mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.bVal);
+ }
+
+ if (pszUniqueID) {
+ DBWriteContactSettingTString(hContact, "CList", "MyHandle", pszUniqueID);
+ mir_free(pszUniqueID);
+ }
+ }
+/*
+ pszSuffix = TranslateT(" (Spammer)");
+ if (pszUniqueID && pszSuffix)
+ {
+ TCHAR* pszNewName = (TCHAR*)mir_alloc((lstrlen(pszUniqueID)+lstrlen(pszSuffix)+1)*sizeof(TCHAR));
+
+ if (pszNewName)
+ {
+ mir_sntprintf(pszNewName, lstrlen(pszUniqueID)+lstrlen(pszSuffix)+1, _T("%s%s"), pszUniqueID, pszSuffix);
+
+ DBWriteContactSettingTString(hContact, "CList", "MyHandle", pszNewName);
+
+ // Tell CList to refresh it's cache
+ CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, 0);
+
+ mir_free(pszNewName);
+ }
+ }
+*/
+ }
+
+ // Remove History (or mark read to get rid of pending "new message" notifications)
+ {
+ HANDLE hDbEvent, hDbEventBuf;
+
+ STRINGLIST* pslRecognition = NULL;
+ DBEVENTINFO dbei;
+ PBYTE pLogText;
+ WCHAR* pszUserName;
+ BOOL bDoWriteLog;
+
+ bDoWriteLog = !bNoLog && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, DEFAULT_SETTING_LOGGING);
+ if (bDoWriteLog)
+ {
+ pslRecognition = SLNewList();
+ SLAddItem(pslRecognition, TranslateT("Contact set as spammer"));
+ }
+
+ // ** History of the contact **
+ // hDbEvent gets buffered to allow deleting while enumerating (handle is offset)
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ hDbEvent = hDbEventBuf;
+
+ while (hDbEvent)
+ {
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+
+ // Now handle hDbEvent
+ {
+ if (bDoWriteLog || bDenyAuthRequests)
+ {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ if (dbei.cbBlob <= 0)
+ {
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob+sizeof(WCHAR)); // adding terminating zeros (security)
+ if (!dbei.pBlob)
+ {
+ // Ensure terminating zero
+ ZeroMemory(dbei.pBlob+dbei.cbBlob, sizeof(WCHAR));
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0) // if successful
+ {
+ if (!(dbei.flags&DBEF_SENT) && !(dbei.flags&DBEF_READ))
+ {
+ switch (dbei.eventType)
+ {
+ case EVENTTYPE_MESSAGE:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
+ {
+ #if defined(UNICODE)
+ // Checking if Unicode text available
+ if (dbei.cbBlob > lstrlenA((char*)dbei.pBlob))
+ pLogText = dbei.pBlob+(lstrlenA((char*)dbei.pBlob)+1)*sizeof(char);
+ else
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)dbei.pBlob);
+ #else
+ pLogText = dbei.pBlob;
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+ WriteToLogFile(dbei.szModule, SFMT_MESSAGE, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText)
+ if (dbei.cbBlob <= lstrlenA((char*)dbei.pBlob))
+ mir_free(pLogText);
+ #endif
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_URL:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_URL))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= 2*sizeof(char))
+ {
+ pLogText = dbei.pBlob+(lstrlenA((char*)dbei.pBlob)+1)*sizeof(char);
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_URL, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_FILE:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_FILE))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+3*sizeof(char)))
+ {
+ pLogText = dbei.pBlob+sizeof(DWORD); // hTransfer, filename(s)
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // description
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_FILE, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_CONTACTS:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_CONTACTS))
+ {
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_CONTACTS, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_AUTHREQUEST:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)+5*sizeof(char)))
+ {
+ pLogText = dbei.pBlob+sizeof(DWORD)+sizeof(HANDLE); // uin, hcontact, nick
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // first
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // last
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // email
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // reason
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_AUTHREQUEST, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+
+ // Deny authorisation
+ if (bDenyAuthRequests)
+ CallProtoService(dbei.szModule, PS_AUTHDENY, (WPARAM)hDbEvent, (LPARAM)NULL); // without reason
+
+ break;
+ }
+
+ case EVENTTYPE_ADDED:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
+ {
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_ADDED, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+ }
+ }
+ break;
+ }
+
+ } // switch
+ }
+
+ mir_free(dbei.pBlob);
+ }
+ }
+ }
+ }
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvent);
+
+ if (bKeepHistory)
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM)hContact, (LPARAM)hDbEvent);
+ else
+ CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvent);
+ }
+
+ hDbEvent = hDbEventBuf;
+ }
+
+ return TRUE;
+
+ // ** Main contact **
+ // Authorization Requests and Added Notifications are stored under the main contact
+ // hDbEvent gets buffered to allow deleting while enumerating (handle is offset)
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ hDbEvent = hDbEventBuf;
+
+ while (hDbEvent)
+ {
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+
+ // Now handle hDbEvent
+ {
+ ZeroMemory(&dbei,sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ if (dbei.cbBlob < 0)
+ {
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob+sizeof(WCHAR));
+ if (dbei.pBlob)
+ {
+ // Ensure terminating zero
+ ZeroMemory(dbei.pBlob+dbei.cbBlob, sizeof(WCHAR));
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0)
+ {
+ if ((dbei.eventType == EVENTTYPE_AUTHREQUEST) || (dbei.eventType == EVENTTYPE_ADDED))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)))
+ {
+ if (*((PHANDLE)(dbei.pBlob+sizeof(DWORD))) == hContact)
+ {
+ if (bDoWriteLog || bDenyAuthRequests)
+ {
+ if (!(dbei.flags&DBEF_SENT) && !(dbei.flags&DBEF_READ))
+ {
+ switch (dbei.eventType)
+ {
+ case EVENTTYPE_AUTHREQUEST:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_AUTHREQUEST))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)+5*sizeof(char)))
+ {
+ pLogText = dbei.pBlob+sizeof(DWORD)+sizeof(HANDLE); // uin, hcontact, nick
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // first
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // last
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // email
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // reason
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_AUTHREQUEST, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+
+ // Deny authorisation
+ if (bDenyAuthRequests)
+ CallProtoService(dbei.szModule, PS_AUTHDENY, (WPARAM)hDbEvent, (LPARAM)NULL); // without reason
+
+ break;
+ }
+
+ case EVENTTYPE_ADDED:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_ADDED))
+ {
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_ADDED, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+ }
+ }
+ break;
+ }
+ } // switch
+ }
+ }
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvent);
+
+ if (bKeepHistory)
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM)hContact, (LPARAM)hDbEvent);
+ else
+ CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvent); }
+ }
+ }
+
+ }
+
+ mir_free(dbei.pBlob);
+ }
+ }
+
+ }
+
+ hDbEvent = hDbEventBuf;
+ }
+ }
+
+ return bReturn;
+}