From 7fd9fe181150f166a098eaf4e006f878c28cb770 Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Mon, 15 Feb 2010 05:51:01 +0300 Subject: sort --- logfile.c | 478 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 logfile.c (limited to 'logfile.c') diff --git a/logfile.c b/logfile.c new file mode 100644 index 0000000..7712119 --- /dev/null +++ b/logfile.c @@ -0,0 +1,478 @@ +/* + +"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" + + +// ----------------------------------------- + + +BOOL WriteToLogFile(const char* pszMsgTypeSection, const char* pszMsgTypeName, const WCHAR* pszUserName, const WCHAR* pszMsgContent, STRINGLIST* pslRecognition, DWORD dwResult) +{ + BOOL bReturn; + + HANDLE hFile; + DWORD dwWritten; // For Windows 95/98/ME compatibility for WriteFile (parameter needed) + + STRINGLIST* pslVariablesFromTo; + WCHAR szLogFile[MAX_PATH]; + + int iBuf; + WCHAR* pszBuf; + + // Get file to log to + { + DBVARIANT dbv; + if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_LOGFILE, &dbv) == 0) + { + mir_sntprintf(szLogFile, ARRAYSIZE(szLogFile), _T("%s"), dbv.pszVal); + DBFreeVariant(&dbv); + PMakePathUsable(szLogFile); + } else { + szLogFile[0] = _T('\0'); + } + } + + // Make sure the directory exists: SILENT! + PPreparePathForWrite(NULL, szLogFile, FALSE, TRUE); + + // Open file + hFile = CreateFile(szLogFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + bReturn = (hFile != INVALID_HANDLE_VALUE); + if (!bReturn) + { + WCHAR* pszLastError = GetLastErrorDescription(GetLastError()); + + ShowInfoMessage(NIIF_ERROR, TranslateT("Spam Filter Error"), TranslateT("The log file \"%s\"\r\ncan not be written.\r\n\r\nProblem:\r\n%s\r\nPlease check the settings."), lstrlen(szLogFile)+lstrlen(pszLastError), (lstrlen(PathFindFileName(szLogFile))>0)?PathFindFileName(szLogFile):szLogFile, pszLastError?pszLastError:_T("")); + if (pszLastError) mir_free(pszLastError); + + return FALSE; + } + + // Variables list (From-To) + pslVariablesFromTo = SLNewList(); + + // %log_time% + iBuf = GetTimeFormat(GetThreadLocale(), 0, NULL, NULL, NULL, 0); // or: LOCALE_USER_DEFAULT + pszBuf = (WCHAR*)mir_alloc((iBuf+1)*sizeof(WCHAR)); + GetTimeFormat(GetThreadLocale(), 0, NULL, NULL, pszBuf, iBuf); // or: LOCALE_USER_DEFAULT + SLAddItemPair(pslVariablesFromTo, _T("%log_time%"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // %log_date% + iBuf = GetDateFormat(GetThreadLocale(), DATE_SHORTDATE, NULL, NULL, NULL, 0); // or: LOCALE_USER_DEFAULT + pszBuf = (WCHAR*)mir_alloc((iBuf+1)*sizeof(WCHAR)); + GetDateFormat(GetThreadLocale(), DATE_SHORTDATE, NULL, NULL, pszBuf, iBuf); // or: LOCALE_USER_DEFAULT + SLAddItemPair(pslVariablesFromTo, _T("%log_date%"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // %log_user% + SLAddItemPair(pslVariablesFromTo, _T("%log_user%"), pszUserName); + + // %log_type% + EnterCriticalSection(&csMsgTypes); // thread safety + iBuf = GetMsgTypeID(pszMsgTypeSection, pszMsgTypeName); + pszBuf = (iBuf >= 0) ? pamtdMsgTypes[iBuf].ptszDescription : NULL; + SLAddItemPair(pslVariablesFromTo, _T("%log_type%"), pszBuf); + LeaveCriticalSection(&csMsgTypes); // thread safety + + // %log_recognition% + pszBuf = SLConvertToString(pslRecognition, TranslateT(", "), FALSE, FALSE, NULL); + SLAddItemPair(pslVariablesFromTo, _T("%log_recognition%"), pszBuf); + if (pszBuf) SLFreeReturn(pszBuf); + + // %log_result% + if (dwResult&SFF_MARKREAD) + pszBuf = TranslateT("Message marked read"); + else if (dwResult&SFF_IGNORE) + pszBuf = TranslateT("Message deleted"); + else + pszBuf = TranslateT("User ignored"); + SLAddItemPair(pslVariablesFromTo, _T("%log_result%"), pszBuf); + + // %log_message% + SLAddItemPair(pslVariablesFromTo, _T("%log_message%"), pszMsgContent); + + // ##### XML format ##### + if (PathMatchSpec(szLogFile, _T("*.xml"))) + { + HANDLE hXSLFile; + WCHAR szXSLFile[MAX_PATH]; + + STRINGLIST* pslSpecialCharsFromTo; + char* pszUtf8; + WCHAR* pszBuf2; + + // Create XSL file name + mir_sntprintf(szXSLFile, ARRAYSIZE(szXSLFile), _T("%s"), szLogFile); + PathRenameExtension(szXSLFile, _T(".xsl")); + + // Construct XML special char replace filter + pslSpecialCharsFromTo = SLNewList(); + SLAddItemPair(pslSpecialCharsFromTo, _T("&"), _T("&")); + SLAddItemPair(pslSpecialCharsFromTo, _T("<"), _T("<")); + SLAddItemPair(pslSpecialCharsFromTo, _T(">"), _T(">")); + SLAddItemPair(pslSpecialCharsFromTo, _T("'"), _T("'")); + SLAddItemPair(pslSpecialCharsFromTo, _T("\""), _T(""")); + SLAddItemPair(pslSpecialCharsFromTo, _T(" "), _T("  "));// Only one single space is allowed (multiple must be replaced) + + // Replace special chars in replacement variables + for (iBuf=SL_MIN_POS; iBuf<=SLGetMaxPos(pslVariablesFromTo); iBuf+=2) + { + pszBuf = ReplaceSubStringWithStringMultiple(SLGetItem(pslVariablesFromTo, iBuf), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLChangeItem(pslVariablesFromTo, iBuf, pszBuf, FALSE); + if (pszBuf) mir_free(pszBuf); + } + + // Write XSL stylesheet for XML (XSL-File) + hXSLFile = CreateFile(szXSLFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + if (hXSLFile != INVALID_HANDLE_VALUE) // If file does not already exist + { + STRINGLIST* pslXSLFromTo = SLNewList(); + + // Translate file contents + // ", " + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT(", "), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T(", "), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // "Received Spam" + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("Received Spam"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("Received Spam"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // "Logged since" + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("Logged since"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("Logged since"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // "Date/Time:" + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("Date/Time:"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("Date/Time:"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // "User:" + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("User:"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("User:"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // Type: + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("Type:"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("Type:"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // "Recognition:" + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("Recognition:"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("Recognition:"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + // "Result:" + pszBuf = ReplaceSubStringWithStringMultiple(TranslateT("Result:"), pslSpecialCharsFromTo, TRUE, FALSE, NULL); + SLAddItemPair(pslXSLFromTo, _T("Result:"), pszBuf); + if (pszBuf) mir_free(pszBuf); + + mir_utf8decode(LockResource(LoadResource(hInstance, FindResource(hInstance, MAKEINTRESOURCE(IDR_XSLLAYOUTFILETEMPLATE), _T("TEXT")))),&pszBuf2); + if (pszBuf2) + { + pszBuf = ReplaceSubStringWithStringMultiple(pszBuf2, pslXSLFromTo, TRUE, FALSE, NULL); + mir_free(pszBuf2); + if (pszBuf) + { + pszUtf8 = mir_utf8encodeW(pszBuf); + mir_free(pszBuf); + if (pszUtf8) + { + WriteFile(hXSLFile, (PBYTE)pszUtf8, lstrlenA(pszUtf8)*sizeof(char), &dwWritten, NULL); + //SetEndOfFile(hXSLFile); + mir_free(pszUtf8); + } + } + } + + SLFreeList(pslXSLFromTo); + CloseHandle(hXSLFile); + } + + // Write XML header/footer (XML-File) + if (GetFileSize(hFile, NULL) == 0) // If file is empty + { + // Replace spacial variables in header + // %log_xslfile% + SLAddItemPair(pslVariablesFromTo, _T("%log_xslfile%"), PathFindFileName(szXSLFile)); + + mir_utf8decode(LockResource(LoadResource(hInstance, FindResource(hInstance, MAKEINTRESOURCE(IDR_XMLFILETEMPLATE), _T("TEXT")))),&pszBuf2); + if (pszBuf2) + { + pszBuf = ReplaceSubStringWithStringMultiple(pszBuf2, pslVariablesFromTo, TRUE, FALSE, NULL); + mir_free(pszBuf2); + if (pszBuf) + { + pszUtf8 = mir_utf8encodeW(pszBuf); + mir_free(pszBuf); + if (pszUtf8) + { + WriteFile(hFile, (PBYTE)pszUtf8, lstrlenA(pszUtf8)*sizeof(char), &dwWritten, NULL); + //SetEndOfFile(hFile); + mir_free(pszUtf8); + } + } + } + } + + // Inject new XML item (XML-File) + mir_utf8decode(LockResource(LoadResource(hInstance, FindResource(hInstance, MAKEINTRESOURCE(IDR_XMLITEMTEMPLATE), _T("TEXT")))),&pszBuf2); + if (pszBuf2) + { + pszBuf = ReplaceSubStringWithStringMultiple(pszBuf2, pslVariablesFromTo, TRUE, FALSE, NULL); + mir_free(pszBuf2); + if (pszBuf) + { + pszUtf8 = mir_utf8encodeW(pszBuf); + mir_free(pszBuf); + if (pszUtf8) + { + SetFilePointer(hFile, -12, NULL, FILE_END); + bReturn = WriteFile(hFile, (PBYTE)pszUtf8, lstrlenA(pszUtf8)*sizeof(char), &dwWritten, NULL); + //SetEndOfFile(hFile); + mir_free(pszUtf8); + } + } + } + + SLFreeList(pslSpecialCharsFromTo); + + + // ##### Character Separated Values (CSV) format ##### + } else if (PathMatchSpec(szLogFile, _T("*.csv"))) { + + BOOL bIsUnicodeFile; + + // Replace special chars in replacement variables + for (iBuf=SL_MIN_POS; iBuf<=SLGetMaxPos(pslVariablesFromTo); iBuf+=2) + { + pszBuf = ReplaceSubStringWithString(SLGetItem(pslVariablesFromTo, iBuf), _T("\""), _T("\"\""), TRUE, FALSE, NULL); + SLChangeItem(pslVariablesFromTo, iBuf, pszBuf, FALSE); + if (pszBuf) mir_free(pszBuf); + } + + // Unicode and CSV header (Byte-order Mark) + if (GetFileSize(hFile, NULL) == 0) // If file is empty + { + #if defined(UNICODE) + // Write Unicode BOM UTF-16LE (Notepad) + // FF FE = UTF-16, little-endian + // -> indicating Unicode text file + if (IsWinVer2000Plus()) { // Notepad doesn't support Unicode on Win9x/ME -> no viewer available + WCHAR chBOM = 0xFFFE; + bIsUnicodeFile = WriteFile(hFile, (PBYTE)&chBOM, sizeof(WCHAR), &dwWritten, NULL); + } else { + bIsUnicodeFile = FALSE; + } + #else + bIsUnicodeFile = FALSE; + #endif + + pszBuf = TranslateT("\"Date\";\"Time\";\"User\";\"Type\";\"Recognition\";\"Result\";\"Message\"\r\n"); + if (pszBuf) + { + #if defined(UNICODE) + + if (!bIsUnicodeFile) + { + WCHAR* pszAnsi; + mir_utf8decode((char*)pszBuf,&pszAnsi); + if (pszAnsi) + { + bReturn = WriteFile(hFile, (PBYTE)pszAnsi, lstrlenW(pszAnsi)*sizeof(char), &dwWritten, NULL); + mir_free(pszAnsi); + } + + } else { + bReturn = WriteFile(hFile, (PBYTE)pszBuf, lstrlenW(pszBuf)*sizeof(WCHAR), &dwWritten, NULL); + } + + #else + + if (bIsUnicodeFile) + { + WCHAR* pszUnicode = mir_utf8encodeW(pszBuf); + if (pszUnicode) + { + bReturn = WriteFile(hFile, (PBYTE)pszUnicode, lstrlenW(pszUnicode)*sizeof(WCHAR), &dwWritten, NULL); + mir_free(pszUnicode); + } + + } else { + bReturn = WriteFile(hFile, (PBYTE)pszBuf, lstrlenA(pszBuf)*sizeof(char), &dwWritten, NULL); + } + + #endif + } + + } else { + + WCHAR chBOM; + + // Read BOM header (Is file UTF-16LE?) + if (ReadFile(hFile, (PBYTE)&chBOM, sizeof(WCHAR), &dwWritten, NULL)) + bIsUnicodeFile = (chBOM == 0xFFFE); + else + bIsUnicodeFile = FALSE; + } + + pszBuf = TranslateT("\"%log_date%\";\"%log_time%\";\"%log_user%\";\"%log_type%\";\"%log_recognition%\";\"%log_result%\";\"%log_message%\"\r\n"); + pszBuf = ReplaceSubStringWithStringMultiple(pszBuf, pslVariablesFromTo, TRUE, FALSE, NULL); + if (pszBuf) + { + SetFilePointer(hFile, 0, NULL, FILE_END); + + // Append Unicode/ANSI CSV item + #if defined(UNICODE) + + if (!bIsUnicodeFile) + { + WCHAR* pszAnsi; + mir_utf8decode((char*)pszBuf,&pszAnsi); + if (pszAnsi) + { + bReturn = WriteFile(hFile, (PBYTE)pszAnsi, lstrlenW(pszAnsi)*sizeof(char), &dwWritten, NULL); + mir_free(pszAnsi); + } + + } else { + bReturn = WriteFile(hFile, (PBYTE)pszBuf, lstrlen(pszBuf)*sizeof(WCHAR), &dwWritten, NULL); + } + + #else + + if (bIsUnicodeFile) + { + WCHAR* pszUnicode = mir_utf8encodeW(pszBuf); + if (pszUnicode) + { + bReturn = WriteFile(hFile, (PBYTE)pszUnicode, lstrlenW(pszUnicode)*sizeof(WCHAR), &dwWritten, NULL); + mir_free(pszUnicode); + } + + } else { + bReturn = WriteFile(hFile, (PBYTE)pszBuf, lstrlen(pszBuf)*sizeof(WCHAR), &dwWritten, NULL); + } + + #endif + + //SetEndOfFile(hFile); + mir_free(pszBuf); + } + + + // ##### Plain-Text format (TXT/LOG) ##### + } else { + + BOOL bIsUnicodeFile; + + // Unicode header (Byte-order Mark) + if (GetFileSize(hFile, NULL) == 0) // If file is empty + { + #if defined(UNICODE) + // Write Unicode BOM UTF-16LE (Notepad) + // FF FE = UTF-16, little-endian + // -> indicating Unicode text file + if (IsWinVer2000Plus()) {// Notepad doesn't support Unicode on Win9x/ME -> no viewer available + WCHAR chBOM = 0xFFFE; + bIsUnicodeFile = WriteFile(hFile, (PBYTE)&chBOM, sizeof(WCHAR), &dwWritten, NULL); + } else { + bIsUnicodeFile = FALSE; + } + #else + bIsUnicodeFile = FALSE; + #endif + + } else { + + WCHAR chBOM; + bIsUnicodeFile = FALSE; + + // Read BOM header (Is file UTF-16LE?) + if (ReadFile(hFile, (PBYTE)&chBOM, sizeof(WCHAR), &dwWritten, NULL)) { + bIsUnicodeFile = (chBOM == 0xFFFE); + } else { + bIsUnicodeFile = FALSE; + } + } + + pszBuf = TranslateT("[%log_date% %log_time%, User: %log_user%, Type: %log_type%]\r\nRecognition: %log_recognition%\t\r\nResult: %log_result%\r\n%log_message%\r\n\r\n"); + pszBuf = ReplaceSubStringWithStringMultiple(pszBuf, pslVariablesFromTo, TRUE, FALSE, NULL); + if (pszBuf) + { + SetFilePointer(hFile, 0, NULL, FILE_END); + + // Append Unicode/ANSI log item + #if defined(UNICODE) + + if (!bIsUnicodeFile) + { + WCHAR* pszAnsi; + mir_utf8decode((char*)pszBuf,&pszAnsi); + if (pszAnsi) + { + bReturn = WriteFile(hFile, (PBYTE)pszAnsi, lstrlenW(pszAnsi)*sizeof(char), &dwWritten, NULL); + mir_free(pszAnsi); + } + + } else { + bReturn = WriteFile(hFile, (PBYTE)pszBuf, lstrlen(pszBuf)*sizeof(WCHAR), &dwWritten, NULL); + } + + #else + + if (bIsUnicodeFile) + { + WCHAR* pszUnicode = mir_utf8encodeW(pszBuf); + if (pszUnicode) + { + bReturn = WriteFile(hFile, (PBYTE)pszUnicode, lstrlenW(pszUnicode)*sizeof(WCHAR), &dwWritten, NULL); + mir_free(pszUnicode); + } + + } else { + bReturn = WriteFile(hFile, (PBYTE)pszBuf, lstrlen(pszBuf)*sizeof(TCHAR), &dwWritten, NULL); + } + + #endif + + //SetEndOfFile(hFile); + mir_free(pszBuf); + } + + + } // ##### format end ##### + + CloseHandle(hFile); + SLFreeList(pslVariablesFromTo); + + // Enable "show log" button if log was created while window open + if (IsWindow(hwndSpamFilterOpt)) + PostMessage(hwndSpamFilterOpt, SFM_VALIDATE_LOGFILENAME, 0, 0); + + return bReturn; +} \ No newline at end of file -- cgit v1.2.3