diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-05 13:27:02 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-05 13:27:02 +0000 |
commit | 3a56ba391bf176c11cc5bde6f860759a3ce4477c (patch) | |
tree | e6e82e3d87e43303e1e01fb2b206a812f3683af6 /plugins/BasicHistory/Scheduler.cpp | |
parent | cde14766d167f10dbad62c66acc0c7cc9d62f518 (diff) |
BasicHistory: folder structure change
git-svn-id: http://svn.miranda-ng.org/main/trunk@773 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/BasicHistory/Scheduler.cpp')
-rw-r--r-- | plugins/BasicHistory/Scheduler.cpp | 1576 |
1 files changed, 0 insertions, 1576 deletions
diff --git a/plugins/BasicHistory/Scheduler.cpp b/plugins/BasicHistory/Scheduler.cpp deleted file mode 100644 index 3b2ba18ab9..0000000000 --- a/plugins/BasicHistory/Scheduler.cpp +++ /dev/null @@ -1,1576 +0,0 @@ -/*
-Basic History plugin
-Copyright (C) 2011-2012 Krzysztof Kral
-
-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 version 2
-of the License.
-
-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 "StdAfx.h"
-#include "Options.h"
-#include "ExportManager.h"
-#include "HistoryWindow.h"
-#include "zip\zip.h"
-#include "zip\unzip.h"
-#include "zip\iowin32.h"
-
-// Sorry for plain C implementation
-#define MODULE "BasicHistory"
-extern HANDLE g_hMainThread;
-bool bPopupsEnabled;
-bool DoTask(TaskOptions& to);
-bool IsValidTask(TaskOptions& to, std::list<TaskOptions>* top = NULL, std::wstring* err = NULL, std::wstring* errDescr = NULL);
-std::wstring GetFileName(const std::wstring &baseName, std::wstring contactName, std::map<std::wstring, bool>& existingContacts, bool replaceContact);
-std::wstring GetDirectoryName(const std::wstring &path);
-std::wstring GetName(const std::wstring &path);
-bool DeleteDirectory(LPCTSTR lpszDir, bool noRecycleBin = true);
-void ListDirectory(const std::wstring &basePath, const std::wstring &path, std::list<std::wstring>& files);
-std::wstring ReplaceStr(const std::wstring& str, wchar_t oldCh, wchar_t newCh);
-time_t GetNextExportTime(TaskOptions& to);
-void SchedulerThreadFunc(void*);
-volatile bool finishThread = false;
-bool initTask = false;
-HANDLE thread = NULL;
-HANDLE threadEvent;
-time_t nextExportTime;
-void StartThread(bool init);
-void StopThread();
-bool GetNextExportTime(bool init, time_t now);
-bool ExecuteCurrentTask(time_t now);
-void GetZipFileTime(const TCHAR *file, uLong *dt);
-std::wstring ReplaceExt(const std::wstring& file, const TCHAR* ext);
-bool ZipFiles(const std::wstring& dir, std::wstring zipFilePath, const std::string& password);
-bool UnzipFiles(const std::wstring& dir, std::wstring& zipFilePath, const std::string& password);
-bool FtpFiles(const std::wstring& dir, const std::wstring& filePath, const std::wstring& ftpName);
-bool FtpGetFiles(const std::wstring& dir, const std::list<std::wstring>& files, const std::wstring& ftpName);
-void CreatePath(const TCHAR *szDir);
-void DoError(const TaskOptions& to, const std::wstring error);
-
-void OptionsSchedulerChanged()
-{
- StartThread(false);
-}
-
-void InitScheduler()
-{
- bPopupsEnabled = ServiceExists(MS_POPUP_ADDPOPUPT) || ServiceExists(MS_POPUP_ADDPOPUPCLASS);
- if (ServiceExists(MS_POPUP_REGISTERCLASS))
- {
- //hPopupIcon = LoadIconEx(I_CHKUPD);
- POPUPCLASS test = {0};
- test.cbSize = sizeof(POPUPCLASS);
- test.flags = PCF_TCHAR;
- test.hIcon = LoadSkinnedIcon(SKINICON_OTHER_HISTORY);
- test.iSeconds = 10;
- test.ptszDescription = TranslateT("History task");
- test.pszName = MODULE;
- CallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&test);
- }
-
- StartThread(true);
-}
-
-void DeinitScheduler()
-{
- StopThread();
-}
-
-int DoLastTask(WPARAM, LPARAM)
-{
- for(std::vector<TaskOptions>::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it)
- {
- if(it->trigerType == TaskOptions::AtEnd && it->active)
- {
- DoTask(*it);
- }
- }
-
- return 0;
-}
-
-bool IsValidTask(TaskOptions& to, std::list<TaskOptions>* top, std::wstring* err, std::wstring* errDescr)
-{
- if(to.taskName.empty())
- {
- if(err != NULL)
- *err = TranslateT("Name");
- return false;
- }
- if(top != NULL)
- {
- for(std::list<TaskOptions>::iterator it = top->begin(); it != top->end(); ++it)
- {
- if(it->taskName == to.taskName)
- {
- if(err != NULL)
- *err = TranslateT("Name");
- return false;
- }
- }
- }
- if(!to.isSystem && to.contacts.size() == 0)
- {
- if(err != NULL)
- *err = TranslateT("Contacts");
- if(errDescr != NULL)
- *errDescr = TranslateT("At least one contact should be selected.");
- return false;
- }
-
- bool isImportTask = to.type == TaskOptions::Import || to.type == TaskOptions::ImportAndMarge;
- if(!isImportTask)
- {
- if(to.filterId > 1)
- {
- int filter = 0;
-
- for(int i = 0; i < (int)Options::instance->customFilters.size(); ++i)
- {
- if(to.filterName == Options::instance->customFilters[i].name)
- {
- filter = i + 2;
- break;
- }
- }
-
- if(filter < 2)
- {
- if(err != NULL)
- *err = TranslateT("Filter");
- return false;
- }
-
- to.filterId = filter;
- }
- else if(to.filterId < 0)
- {
- if(err != NULL)
- *err = TranslateT("Filter");
- return false;
- }
- }
-
- if(to.type == TaskOptions::Delete)
- {
- return true;
- }
-
- if(!Options::FTPAvail() && to.useFtp)
- {
- if(err != NULL)
- *err = TranslateT("Upload to FTP");
- return false;
- }
- if(to.filePath.empty())
- {
- if(err != NULL)
- *err = TranslateT("Path to output file");
- return false;
- }
- if(to.useFtp && to.ftpName.empty())
- {
- if(err != NULL)
- *err = TranslateT("Session name");
- if(errDescr != NULL)
- *errDescr = TranslateT("To create session open WinSCP, click New Session, enter data and save with specific name. Remember if FTP server using password you should save it in WinSCP.");
- return false;
- }
- if(to.useFtp && (to.filePath.find(_T('\\')) < to.filePath.length() || to.filePath.find(_T(':')) < to.filePath.length() || to.filePath[0] != L'/'))
- {
- if(err != NULL)
- *err = TranslateT("Path to file");
- if(errDescr != NULL)
- *errDescr = TranslateT("FTP path must contains '/' instead '\\' and starts from '/'.");
- return false;
- }
- if(isImportTask && to.filePath.find(_T("<date>")) < to.filePath.length())
- {
- if(err != NULL)
- *err = TranslateT("Path to file");
- if(errDescr != NULL)
- *errDescr = TranslateT("FTP path cannot contain <date> in import task.");
- return false;
- }
- if(!isImportTask && (to.exportType < IExport::RichHtml || to.exportType > IExport::Dat))
- {
- if(err != NULL)
- *err = TranslateT("Export to");
- return false;
- }
- if(isImportTask && (to.importType < IImport::Binary || to.importType > IImport::Dat))
- {
- if(err != NULL)
- *err = TranslateT("Import from");
- return false;
- }
- if((to.trigerType == TaskOptions::Daily || to.trigerType == TaskOptions::Weekly || to.trigerType == TaskOptions::Monthly) && (to.dayTime < 0 || to.dayTime >= 24 * 60))
- {
- if(err != NULL)
- *err = TranslateT("Time");
- return false;
- }
- if(to.trigerType == TaskOptions::Weekly && (to.dayOfWeek < 0 || to.dayOfWeek >= 7))
- {
- if(err != NULL)
- *err = TranslateT("Day of week");
- return false;
- }
- if(to.trigerType == TaskOptions::Monthly && (to.dayOfMonth <= 0 || to.dayOfMonth >= 32))
- {
- if(err != NULL)
- *err = TranslateT("Day");
- return false;
- }
- if((to.trigerType == TaskOptions::DeltaMin || to.trigerType == TaskOptions::DeltaHour) && (to.deltaTime < 0 || to.deltaTime >= 10000))
- {
- if(err != NULL)
- *err = TranslateT("Delta time");
- return false;
- }
-
- return true;
-}
-
-static void CALLBACK DoRebuildEventsInMainAPCFunc(ULONG_PTR dwParam)
-{
- HANDLE* contacts = (HANDLE*) dwParam;
- size_t size = (size_t)contacts[0];
- for(size_t i = 1; i <= size; ++i)
- {
- HistoryWindow::RebuildEvents(contacts[i]);
- }
-
- delete[] contacts;
-}
-
-bool DoTask(TaskOptions& to)
-{
- std::wstring err;
- std::wstring errDescr;
- if(!IsValidTask(to, NULL, &err, &errDescr))
- {
- TCHAR msg[256];
- if(err.empty())
- _tcscpy_s(msg, TranslateT("Some value is invalid"));
- else if(errDescr.empty())
- {
- _stprintf_s(msg, TranslateT("Invalid '%s' value."), err.c_str());
- }
- else
- {
- _stprintf_s(msg, TranslateT("Invalid '%s' value.\n%s"), err.c_str(), errDescr.c_str());
- }
- DoError(to, msg);
- return true;
- }
-
- DWORD now = time(NULL);
- long long int t = to.eventDeltaTime * 60;
- if(to.eventUnit > TaskOptions::Minute)
- t *= 60LL;
- if(to.eventUnit > TaskOptions::Hour)
- t *= 24LL;
- if(t > 2147483647LL)
- {
- DoError(to, TranslateT("Unknown error"));
- return true;
- }
-
- bool error = false;
- std::wstring errorStr;
- std::list<ExportManager*> managers;
- if(to.type == TaskOptions::Delete)
- {
- if(to.isSystem)
- {
- ExportManager *exp = new ExportManager(NULL, NULL, to.filterId);
- exp->SetDeleteWithoutExportEvents(t, now);
- managers.push_back(exp);
- }
-
- for(size_t i = 0; i < to.contacts.size(); ++i)
- {
- ExportManager *exp = new ExportManager(NULL, to.contacts[i], to.filterId);
- exp->SetDeleteWithoutExportEvents(t, now);
- managers.push_back(exp);
- }
- }
- else if(to.type == TaskOptions::Import || to.type == TaskOptions::ImportAndMarge)
- {
- std::map<std::wstring, bool> existingContacts1;
- ExportManager mExp = ExportManager(NULL, NULL, 1);
- std::wstring filePath = to.filePath;
- std::wstring dir;
- std::list<std::wstring> files;
- std::vector<HANDLE> contacts;
- if(to.useFtp || to.compress)
- {
- std::map<std::wstring, bool> existingContacts;
- TCHAR temp[MAX_PATH];
- temp[0] = 0;
- GetTempPath(MAX_PATH, temp);
- dir = temp;
- dir += GetName(filePath);
- dir = GetFileName(dir, L"", existingContacts, true);
- dir = ReplaceExt(dir, L"");
- size_t pos = dir.find_last_of(_T('.'));
- if(pos < dir.length())
- {
- dir = dir.substr(0, pos);
- }
-
- DeleteDirectory(dir.c_str());
- CreateDirectory(dir.c_str(), NULL);
- }
-
- const TCHAR* ext = ExportManager::GetExt(to.importType);
- if(to.isSystem)
- {
- std::wstring n = GetFileName(filePath, mExp.GetContactName(), existingContacts1, true);
- n = ReplaceExt(n, ext);
- files.push_back(n);
- contacts.push_back(NULL);
- }
-
- for(size_t i = 0; i < to.contacts.size(); ++i)
- {
- mExp.hContact = to.contacts[i];
- std::wstring n = GetFileName(filePath, mExp.GetContactName(), existingContacts1, true);
- n = ReplaceExt(n, ext);
- files.push_back(n);
- contacts.push_back(to.contacts[i]);
- }
-
- if(to.useFtp)
- {
- if(to.compress)
- {
- std::map<std::wstring, bool> existingContacts;
- std::wstring n = GetFileName(filePath, L"", existingContacts, true);
- n = ReplaceExt(n, L"zip");
- files.clear();
- files.push_back(n);
- filePath = dir + L"\\" + GetName(filePath);
- }
-
- error = FtpGetFiles(dir, files, to.ftpName);
- if(error)
- {
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- errorStr += TranslateT("Cannot get FTP file(s).");
- }
- }
-
- if(!error && to.compress)
- {
- error = UnzipFiles(dir, filePath, to.zipPassword);
- if(error)
- {
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- errorStr += TranslateT("Cannot unzip file(s).");
- }
-
- if(to.useFtp)
- DeleteFile(filePath.c_str());
- }
-
- if(!error && (to.useFtp || to.compress))
- {
- files.clear();
- std::list<std::wstring> files1;
- ListDirectory(dir, L"\\", files1);
- for(std::list<std::wstring>::iterator it = files1.begin(); it != files1.end(); ++it)
- {
- files.push_back(dir + *it);
- }
- }
-
- if(!error)
- {
- std::list<HANDLE> contactList;
- for(std::list<std::wstring>::iterator it = files.begin(); it != files.end(); ++it)
- {
- mExp.SetAutoImport(*it);
- int ret = mExp.Import(to.importType, contacts);
- if(ret == -3)
- {
- if(contacts.size() == 1)
- {
- ret = 0;
- }
- else
- {
- std::map<std::wstring, bool> existingContacts;
- std::wstring name = GetName(*it);
- for(ret = 0; ret < (int)contacts.size(); ++ret)
- {
- mExp.hContact = contacts[ret];
- std::wstring n = GetFileName(to.filePath, mExp.GetContactName(), existingContacts, true);
- n = ReplaceExt(n, ext);
- n = GetName(n);
- if(n == name)
- break;
- }
-
- if(ret >= (int)contacts.size())
- ret = -1;
- }
- }
-
- if(ret >= 0)
- {
- mExp.hContact = contacts[ret];
- if(to.type == TaskOptions::Import)
- {
- EventList::AddImporter(mExp.hContact, to.importType, *it);
- contactList.push_back(mExp.hContact);
- }
- else
- {
- std::vector<IImport::ExternalMessage> messages;
- if(mExp.Import(to.importType, messages, NULL))
- {
- mExp.MargeMessages(messages);
- contactList.push_back(mExp.hContact);
- }
- }
- }
- else if(ret != -1)
- {
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- TCHAR msg[1024];
-
- _stprintf_s(msg, TranslateT("Incorrect file format: %s."), GetName(*it).c_str());
- errorStr += msg;
- }
- else
- {
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- TCHAR msg[1024];
-
- _stprintf_s(msg, TranslateT("Unknown contact in file: %s."), GetName(*it).c_str());
- errorStr += msg;
- }
- }
-
- if(contactList.size() > 0)
- {
- HANDLE* contacts = new HANDLE[contactList.size() + 1];
- contacts[0] = (HANDLE)contactList.size();
- int i = 1;
- for(std::list<HANDLE>::iterator it = contactList.begin(); it != contactList.end(); ++it)
- {
- contacts[i++] = *it;
- }
-
- QueueUserAPC(DoRebuildEventsInMainAPCFunc, g_hMainThread, (ULONG_PTR) contacts);
- }
- }
-
- if(to.useFtp || to.compress)
- {
- DeleteDirectory(dir.c_str());
- }
- }
- else
- {
- std::map<std::wstring, bool> existingContacts;
- std::wstring filePath = to.filePath;
- std::wstring dir;
- if(!to.useFtp && !to.compress)
- {
- dir = GetDirectoryName(filePath);
- if(!dir.empty())
- {
- CreateDirectory(dir.c_str(), NULL);
- }
- }
- else
- {
- filePath = GetName(filePath);
- TCHAR temp[MAX_PATH];
- temp[0] = 0;
- GetTempPath(MAX_PATH, temp);
- dir = temp;
- dir += filePath;
- dir = GetFileName(dir, L"", existingContacts, true);
- dir = ReplaceExt(dir, L"");
- size_t pos = dir.find_last_of(_T('.'));
- if(pos < dir.length())
- {
- dir = dir.substr(0, pos);
- }
-
- DeleteDirectory(dir.c_str());
- CreateDirectory(dir.c_str(), NULL);
- filePath = dir + L"\\" + filePath;
- }
- if(to.isSystem)
- {
- ExportManager *exp = new ExportManager(NULL, NULL, to.filterId);
- exp->SetAutoExport(GetFileName(filePath, exp->GetContactName(), existingContacts, true), t, now);
- exp->useImportedMessages = to.exportImported;
- if(!exp->Export(to.exportType))
- {
- error = true;
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- TCHAR msg[1024];
-
- _stprintf_s(msg, TranslateT("Cannot export history for contact: %s."), exp->GetContactName().c_str());
- errorStr += msg;
- }
-
- if(to.type == TaskOptions::Export)
- {
- delete exp;
- }
- else
- {
- managers.push_back(exp);
- }
- }
-
- if(!error)
- {
- for(size_t i = 0; i < to.contacts.size(); ++i)
- {
- ExportManager *exp = new ExportManager(NULL, to.contacts[i], to.filterId);
- exp->SetAutoExport(GetFileName(filePath, exp->GetContactName(), existingContacts, true), t, now);
- exp->useImportedMessages = to.exportImported;
- if(!exp->Export(to.exportType))
- {
- error = true;
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- TCHAR msg[1024];
-
- _stprintf_s(msg, TranslateT("Cannot export history for contact: %s."), exp->GetContactName().c_str());
- errorStr += msg;
- break;
- }
-
- if(to.type == TaskOptions::Export)
- {
- delete exp;
- }
- else
- {
- managers.push_back(exp);
- }
- }
- }
-
- if(error)
- {
- if(to.compress && !to.useFtp)
- {
- DeleteDirectory(dir.c_str());
- }
- }
- else if(to.compress)
- {
- std::wstring zipFilePath = to.filePath;
- std::wstring zipDir = dir;
- if(!to.useFtp)
- {
- zipDir = GetDirectoryName(zipFilePath);
- if(!zipDir.empty())
- {
- CreateDirectory(zipDir.c_str(), NULL);
- }
- }
- else
- {
- zipFilePath = GetName(zipFilePath);
- TCHAR temp[MAX_PATH];
- temp[0] = 0;
- GetTempPath(MAX_PATH, temp);
- zipDir = temp;
- zipDir += L"zip<date>";
- zipDir = GetFileName(zipDir, L"", existingContacts, true);
- DeleteDirectory(zipDir.c_str());
- CreateDirectory(zipDir.c_str(), NULL);
- zipFilePath = zipDir + L"\\" + zipFilePath;
- }
- error = ZipFiles(dir + L"\\", zipFilePath, to.zipPassword);
- dir = zipDir;
- if(error)
- {
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- errorStr += TranslateT("Cannot compress file(s).");
- }
- }
-
- if(to.useFtp)
- {
- if(!error)
- {
- error = FtpFiles(dir, to.filePath, to.ftpName);
- if(error)
- {
- if(!errorStr.empty())
- {
- errorStr += L"\n";
- }
-
- errorStr += TranslateT("Cannot send FTP file(s).");
- }
- }
-
- DeleteDirectory(dir.c_str());
- }
- }
-
- if(to.type == TaskOptions::Delete || to.type == TaskOptions::ExportAndDelete)
- {
- for(std::list<ExportManager*>::iterator it = managers.begin(); it != managers.end(); ++it)
- {
- if(!error)
- {
- (*it)->DeleteExportedEvents();
- }
-
- delete *it;
- }
- }
-
- if(error)
- {
- DoError(to, errorStr.empty() ? TranslateT("Unknown error") : errorStr);
- }
-
- return error;
-}
-
-std::wstring GetFileName(const std::wstring &baseName, std::wstring contactName, std::map<std::wstring, bool>& existingContacts, bool replaceContact)
-{
- std::wstring str = baseName;
- size_t pos = baseName.find(_T("<contact>"));
- if(replaceContact && pos < baseName.length())
- {
- str = baseName.substr(0, pos);
- std::wstring baseName1 = contactName;
- if(!baseName1.empty())
- {
- std::wstring name = baseName1;
- int i = 0;
- TCHAR buf[32];
- std::map<std::wstring, bool>::iterator it = existingContacts.find(name);
- while(it != existingContacts.end())
- {
- _itot_s(++i, buf, 10);
- name = baseName1 + buf;
- it = existingContacts.find(name);
- }
-
- str += name;
- existingContacts[name] = true;
- }
- str += baseName.substr(pos + 9);
- }
-
- pos = str.find(_T("<date>"));
- if(pos < str.length())
- {
- TCHAR time[256];
- SYSTEMTIME st;
- GetLocalTime(&st);
- _stprintf_s(time, _T("%d-%02d-%02d %02d%02d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute);
- std::wstring str1 = str.substr(0, pos);
- str1 += time;
- str1 += str.substr(pos + 6);
- str = str1;
- }
-
- return str;
-}
-
-std::wstring GetDirectoryName(const std::wstring &path)
-{
- size_t find = path.find_last_of(L"\\/");
- if(find < path.length())
- {
- return path.substr(0, find);
- }
-
- return L"";
-}
-
-void ListDirectory(const std::wstring &basePath, const std::wstring &path, std::list<std::wstring>& files)
-{
- WIN32_FIND_DATA findFileData;
- HANDLE hFind = FindFirstFile((basePath + path + _T("*")).c_str(), &findFileData);
- if (hFind == INVALID_HANDLE_VALUE)
- return;
- do
- {
- if(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- std::wstring name = findFileData.cFileName;
- if(name != L"." && name != L"..")
- ListDirectory(basePath, path + findFileData.cFileName + _T("\\"), files);
- }
- else
- {
- files.push_back(path + findFileData.cFileName);
- }
- }
- while(FindNextFile(hFind, &findFileData));
- FindClose(hFind);
-}
-
-std::wstring ReplaceStr(const std::wstring& str, wchar_t oldCh, wchar_t newCh)
-{
- std::wstring ret;
- size_t start = 0;
- size_t find;
- while((find = str.find_first_of(oldCh, start)) < str.length())
- {
- ret += str.substr(start, find - start);
- ret += newCh;
- start = find + 1;
- }
-
- ret += str.substr(start, str.length() - start);
- return ret;
-}
-
-time_t GetNextExportTime(TaskOptions& to)
-{
- switch(to.trigerType)
- {
- case TaskOptions::Daily:
- {
- tm t;
- localtime_s(&t, &to.lastExport);
- t.tm_hour = to.dayTime/60;
- t.tm_min = to.dayTime%60;
- t.tm_sec = 0;
- time_t newTime = mktime(&t);
- if(newTime <= to.lastExport)
- {
- newTime += 60 * 60 * 24;
- }
-
- return newTime;
- }
- case TaskOptions::Weekly:
- {
- tm t;
- localtime_s(&t, &to.lastExport);
- t.tm_hour = to.dayTime/60;
- t.tm_min = to.dayTime%60;
- t.tm_sec = 0;
- int dow = (to.dayOfWeek + 1) % 7;
- time_t newTime = mktime(&t);
- while(dow != t.tm_wday)
- {
- newTime += 60 * 60 * 24;
- localtime_s(&t, &newTime);
- newTime = mktime(&t);
- }
-
- if(newTime <= to.lastExport)
- {
- newTime += 7 * 60 * 60 * 24;
- }
-
- return newTime;
- }
- case TaskOptions::Monthly:
- {
- tm t;
- localtime_s(&t, &to.lastExport);
- t.tm_hour = to.dayTime/60;
- t.tm_min = to.dayTime%60;
- t.tm_sec = 0;
- time_t newTime = mktime(&t);
- int lastM = t.tm_mon;
- int lastD;
- while(to.dayOfMonth != t.tm_mday || newTime <= to.lastExport)
- {
- lastD = t.tm_mday;
- newTime += 60 * 60 * 24;
- localtime_s(&t, &newTime);
- newTime = mktime(&t);
- if(to.dayOfMonth > 28 && t.tm_mon != lastM && (newTime - 60 * 60 * 24) > to.lastExport)
- {
- lastM = t.tm_mon;
- if(to.dayOfMonth > lastD)
- {
- newTime -= 60 * 60 * 24;
- break;
- }
- }
- }
-
- return newTime;
- }
- case TaskOptions::DeltaMin:
- return to.lastExport + to.deltaTime * 60;
- case TaskOptions::DeltaHour:
- return to.lastExport + to.deltaTime * 60 * 60;
- default:
- return to.lastExport;
- }
-}
-
-void SchedulerThreadFunc(void*)
-{
- if(initTask)
- {
- WaitForSingleObject(threadEvent, 5 * 1000);
- initTask = false;
- }
-
- while(!finishThread)
- {
- DWORD timeWait;
- time_t now = time(NULL);
- while(nextExportTime <= now)
- {
- if(!ExecuteCurrentTask(now))
- return;
- }
-
- time_t dif = nextExportTime - now;
- timeWait = (dif > 60 * 60 * 24) ? (60 * 60 * 1000) : (60 * 1000);
-
- WaitForSingleObject(threadEvent, timeWait);
- }
-}
-
-void StartThread(bool init)
-{
- StopThread();
-
- initTask = false;
- bool isExport = GetNextExportTime(init, time(NULL));
- if(isExport)
- {
- finishThread = false;
- threadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- thread = mir_forkthread(SchedulerThreadFunc, NULL);
- }
-}
-
-void StopThread()
-{
- if(thread != NULL)
- {
- finishThread = true;
- SetEvent(threadEvent);
- WaitForSingleObject(thread, INFINITE);
- //CloseHandle(thread);
- CloseHandle(threadEvent);
- thread = NULL;
- threadEvent = NULL;
- }
-}
-
-bool GetNextExportTime(bool init, time_t now)
-{
- EnterCriticalSection(&Options::instance->criticalSection);
- bool isExport = false;
- for(std::vector<TaskOptions>::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it)
- {
- if(it->forceExecute)
- {
- nextExportTime = now;
- isExport = true;
- initTask = init;
- break;
- }
- else if(it->active && it->trigerType != TaskOptions::AtStart && it->trigerType != TaskOptions::AtEnd)
- {
- time_t t = GetNextExportTime(*it);
- if(isExport)
- {
- if(t < nextExportTime)
- nextExportTime = t;
- }
- else
- {
- nextExportTime = t;
- isExport = true;
- initTask = init;
- }
- }
- else if(it->active && it->trigerType == TaskOptions::AtStart && init)
- {
- it->forceExecute = true;
- it->showMBAfterExecute = false;
- nextExportTime = now;
- isExport = true;
- initTask = true;
- }
- }
-
- LeaveCriticalSection(&Options::instance->criticalSection);
- return isExport;
-}
-
-static void CALLBACK DoTaskFinishInMainAPCFunc(ULONG_PTR dwParam)
-{
- TCHAR *item = (TCHAR*) dwParam;
- MessageBox(NULL, item, TranslateT("Task finished"), MB_OK | MB_ICONINFORMATION);
- delete[] item;
-}
-
-bool ExecuteCurrentTask(time_t now)
-{
- EnterCriticalSection(&Options::instance->criticalSection);
- TaskOptions to;
- bool isExport = false;
- for(std::vector<TaskOptions>::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it)
- {
- if(it->forceExecute)
- {
- it->lastExport = time(NULL);
- Options::instance->SaveTaskTime(*it);
- to = *it;
- isExport = true;
- break;
- }
- else if(it->active && it->trigerType != TaskOptions::AtStart && it->trigerType != TaskOptions::AtEnd)
- {
- time_t t = GetNextExportTime(*it);
- if(t <= now)
- {
- it->lastExport = time(NULL);
- Options::instance->SaveTaskTime(*it);
- to = *it;
- isExport = true;
- break;
- }
- }
- }
-
- LeaveCriticalSection(&Options::instance->criticalSection);
-
- if(isExport)
- {
- bool error = DoTask(to);
- if(to.forceExecute)
- {
- EnterCriticalSection(&Options::instance->criticalSection);
- for(std::vector<TaskOptions>::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it)
- {
- if(it->taskName == to.taskName)
- {
- it->forceExecute = false;
- it->showMBAfterExecute = false;
- break;
- }
- }
-
- LeaveCriticalSection(&Options::instance->criticalSection);
-
- if(to.showMBAfterExecute)
- {
- size_t size = to.taskName.size() + 1024;
- TCHAR* name = new TCHAR[size];
- if(error)
- {
- _stprintf_s(name, size, TranslateT("Task '%s' execution failed"), to.taskName.c_str());
- }
- else
- {
- _stprintf_s(name, size, TranslateT("Task '%s' finished successfully"), to.taskName.c_str());
- }
-
- QueueUserAPC(DoTaskFinishInMainAPCFunc, g_hMainThread, (ULONG_PTR) name);
- }
- }
- }
-
- return GetNextExportTime(false, now);
-}
-
-void GetZipFileTime(const TCHAR *file, uLong *dt)
-{
- FILETIME ftLocal;
- HANDLE hFind;
- WIN32_FIND_DATA ff32;
-
- hFind = FindFirstFile(file, &ff32);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
- FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
- FindClose(hFind);
- }
-}
-
-/* calculate the CRC32 of a file,
- because to encrypt a file, we need known the CRC32 of the file before */
-bool GetFileCrc(const TCHAR* filenameinzip, unsigned char* buf, unsigned long size_buf, unsigned long* result_crc)
-{
- unsigned long calculate_crc = 0;
- bool error = true;
- HANDLE hFile = CreateFile(filenameinzip, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if(hFile != INVALID_HANDLE_VALUE)
- {
- DWORD readed;
- do
- {
- if(!ReadFile(hFile, buf, 1024, &readed, NULL))
- {
- error = false;
- break;
- }
-
- if (readed > 0)
- {
- calculate_crc = crc32(calculate_crc, buf, readed);
- }
- }
- while (readed > 0);
- CloseHandle(hFile);
- }
- else
- {
- error = false;
- }
-
- *result_crc=calculate_crc;
- return error;
-}
-
-bool ZipFiles(const std::wstring& dir, std::wstring zipFilePath, const std::string& password)
-{
- std::list<std::wstring> files;
- std::map<std::wstring, bool> existingContacts;
- ListDirectory(dir, L"", files);
- bool error = false;
- if(files.size() > 0)
- {
- zlib_filefunc_def pzlib_filefunc_def;
- fill_win32_filefunc(&pzlib_filefunc_def);
- zipFilePath = GetFileName(zipFilePath, L"", existingContacts, true);
- zipFilePath = ReplaceExt(zipFilePath, L"zip");
- zipFile zf = zipOpen2((LPCSTR)(LPTSTR)zipFilePath.c_str(), APPEND_STATUS_CREATE, NULL, &pzlib_filefunc_def);
- if (zf != NULL)
- {
- unsigned char buf[1024];
- char bufF[MAX_PATH + 20];
- while(files.size() > 0)
- {
- std::wstring zipDir = *files.begin();
- std::wstring localDir = dir + L"\\" + zipDir;
- zip_fileinfo zi = {0};
- GetZipFileTime(localDir.c_str(), &zi.dosDate);
- if(zipDir.size() > MAX_PATH + 19)
- {
- error = true;
- break;
- }
-
- BOOL badChar;
- WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, zipDir.c_str(), -1, bufF, MAX_PATH + 20, NULL, &badChar);
- int flag = 0;
- if(badChar)
- {
- flag = 0x800; // UTF
- WideCharToMultiByte(CP_UTF8, 0, zipDir.c_str(), -1, bufF, MAX_PATH + 20, NULL, NULL);
- }
-
- unsigned long calculate_crc = 0;
- const char* passwordCh = NULL;
- if(password.size() > 0)
- {
- if(!GetFileCrc(localDir.c_str(), buf, 1024, &calculate_crc))
- {
- error = true;
- break;
- }
-
- passwordCh = password.c_str();
- }
-
- int err = zipOpenNewFileInZip4_64 (zf, bufF, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, passwordCh, calculate_crc, 0, flag, 0);
- if (err == ZIP_OK)
- {
- HANDLE hFile = CreateFile(localDir.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if(hFile != INVALID_HANDLE_VALUE)
- {
- DWORD readed;
- do
- {
- err = ZIP_OK;
- if(!ReadFile(hFile, buf, 1024, &readed, NULL))
- {
- error = true;
- break;
- }
-
- if (readed > 0)
- {
- err = zipWriteInFileInZip(zf, buf, readed);
- }
- }
- while ((err == ZIP_OK) && (readed > 0));
- CloseHandle(hFile);
- }
-
- if(zipCloseFileInZip(zf) != ZIP_OK)
- {
- error = true;
- break;
- }
- }
- else
- {
- error = true;
- break;
- }
-
- files.pop_front();
- }
-
- zipClose(zf, NULL);
- }
- else
- {
- error = true;
- }
- }
-
- DeleteDirectory(dir.c_str());
- return error;
-}
-
-bool UnzipFiles(const std::wstring& dir, std::wstring& zipFilePath, const std::string& password)
-{
- std::list<std::wstring> files;
- bool error = false;
- zlib_filefunc_def pzlib_filefunc_def;
- fill_win32_filefunc(&pzlib_filefunc_def);
- std::wstring fileNameInZip;
- std::map<std::wstring, bool> existingContacts;
- zipFilePath = GetFileName(zipFilePath, L"", existingContacts, true);
- zipFilePath = ReplaceExt(zipFilePath, L"zip");
- unzFile zf = unzOpen2((LPCSTR)(LPTSTR)zipFilePath.c_str(), &pzlib_filefunc_def);
- if (zf != NULL)
- {
- char buf[8192];
- char bufF[MAX_PATH + 20];
- unz_file_info file_info;
- do
- {
- int err = unzGetCurrentFileInfo(zf, &file_info, bufF, MAX_PATH + 20, buf, 8192, NULL, 0);
- if (err == UNZ_OK)
- {
- UINT cp = CP_OEMCP;
- if(file_info.flag & 0x800)// UTF
- {
- cp = CP_UTF8;
- }
-
- // Get Unicode file name for InfoZip style archives, otherwise assume PKZip/WinZip style
- if (file_info.size_file_extra)
- {
- char *p = buf;
- unsigned long size = min(file_info.size_file_extra, 8192);
- while (size > 0)
- {
- unsigned short id = *(unsigned short*)p;
- unsigned len = *(unsigned short*)(p + 2);
-
- if (size < (len + 4)) break;
-
- if (id == 0x7075 && len > 5 && (len - 5) < MAX_PATH + 20 && *(p + 4) == 1)
- {
- memcpy(bufF, p + 9, len - 5);
- bufF[len - 5] = 0;
- cp = CP_UTF8;
- break;
- }
- size -= len + 4;
- p += len + 4;
- }
- }
-
- int sizeC = (int)strlen(bufF);
- int sizeW = MultiByteToWideChar(cp, 0, bufF, sizeC, NULL, 0);
- fileNameInZip.resize(sizeW);
- MultiByteToWideChar(cp, 0, bufF, sizeC, (wchar_t*)fileNameInZip.c_str(), sizeW);
- fileNameInZip = dir + L"\\" + fileNameInZip;
- for (size_t i = 0; i < fileNameInZip.length(); ++i)
- {
- if (fileNameInZip[i] == L'/')
- fileNameInZip[i] = L'\\';
- }
-
- if (file_info.external_fa & FILE_ATTRIBUTE_DIRECTORY)
- CreatePath(fileNameInZip.c_str());
- else
- {
- const char* passwordCh = NULL;
- if(password.size() > 0)
- {
- passwordCh = password.c_str();
- }
-
- err = unzOpenCurrentFilePassword(zf, passwordCh);
- if (err == UNZ_OK)
- {
- CreatePath(GetDirectoryName(fileNameInZip).c_str());
- HANDLE hFile = CreateFile(fileNameInZip.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
- if(hFile != INVALID_HANDLE_VALUE)
- {
- DWORD writed;
- for (;;)
- {
- err = unzReadCurrentFile(zf, buf, 8192);
- if (err <= 0) break;
-
- if (!WriteFile(hFile, buf, err, &writed, FALSE))
- {
- err = -1;
- break;
- }
- }
-
- CloseHandle(hFile);
- if(err < 0)
- {
- error = true;
- break;
- }
- }
- else
- {
- unzCloseCurrentFile(zf);
- error = true;
- break;
- }
-
- if(unzCloseCurrentFile(zf) != ZIP_OK)
- {
- error = true;
- break;
- }
- }
- else
- {
- error = true;
- break;
- }
- }
- }
- else
- {
- error = true;
- break;
- }
- }
- while (unzGoToNextFile(zf) == UNZ_OK);
-
- unzClose(zf);
- }
- else
- {
- error = true;
- }
-
- return error;
-}
-
-bool FtpFiles(const std::wstring& dir, const std::wstring& filePath, const std::wstring& ftpName)
-{
- std::list<std::wstring> files;
- std::map<std::wstring, bool> existingContacts;
- ListDirectory(dir, L"\\", files);
- if(files.size() > 0)
- {
- std::wofstream stream ((dir + _T("\\script.sc")).c_str());
- if(stream.is_open())
- {
- std::wstring ftpDir = GetDirectoryName(filePath);
- ftpDir = GetFileName(ftpDir, L"", existingContacts, false);
- stream << "option batch continue\noption confirm off\nopen \""
- << ftpName << "\"\noption transfer binary\n";
- std::wstring lastCD;
- size_t filSize = files.size();
- while(files.size() > 0)
- {
- std::wstring localDir = *files.begin();
- std::wstring currentCD = ftpDir + GetDirectoryName(ReplaceStr(localDir, L'\\', L'/'));
- if(currentCD != lastCD)
- {
- if(!currentCD.empty() && currentCD != L"/")
- stream << "mkdir \"" << currentCD << "\"\n";
- stream << "cd \"" << currentCD << "\"\n";
- lastCD = currentCD;
- }
-
- std::wstring name = GetName(localDir);
- stream << "call MDTM " << name << "\n";
- stream << "put \"." << localDir << "\"\n";
- stream << "call MDTM " << name << "\n";
- files.pop_front();
- }
-
- stream.close();
- std::wstring &log = Options::instance->ftpLogPath;
- CreateDirectory(GetDirectoryName(log).c_str(), NULL);
- DeleteFile(log.c_str());
- TCHAR cmdLine[MAX_PATH];
- _stprintf_s(cmdLine, _T("\"%s\" /nointeractiveinput /log=\"%s\" /script=script.sc"), Options::instance->ftpExePath.c_str(), log.c_str());
- STARTUPINFO startupInfo = {0};
- PROCESS_INFORMATION processInfo;
- startupInfo.cb = sizeof(STARTUPINFO);
- if(CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startupInfo, &processInfo))
- {
- WaitForSingleObject(processInfo.hProcess, INFINITE);
- CloseHandle(processInfo.hThread);
- CloseHandle(processInfo.hProcess);
- if(log.empty())
- {
- return false;
- }
-
- std::wifstream logStream (log.c_str());
- if(logStream.is_open())
- {
- bool isInMDTM = false;
- std::list<std::wstring> dates;
- while(!logStream.eof())
- {
- std::wstring lineStr;
- std::getline(logStream, lineStr);
- if(lineStr.length() > 1)
- {
- if(lineStr[0] == L'>')
- {
- if(isInMDTM)
- {
- if(lineStr.find(L"Script:") < lineStr.length())
- {
- dates.push_back(L"");
- isInMDTM = false;
- }
- }
-
- if(lineStr.find(L"Script: call MDTM") < lineStr.length())
- {
- isInMDTM = true;
- }
- }
- else if(isInMDTM && lineStr[0] == L'<')
- {
- size_t ss = lineStr.find(L"Script: 213 ");
- if(ss < lineStr.length())
- {
- ss += 12;
- if(ss < lineStr.length())
- {
- lineStr = lineStr.substr(ss);
- if(lineStr.size() == 14)
- {
- dates.push_back(lineStr);
- isInMDTM = false;
- }
- }
- }
- }
- }
- }
-
- if(dates.size() > 0 && dates.size() == filSize * 2)
- {
- for(std::list<std::wstring>::const_iterator it = dates.begin(); it != dates.end(); ++it)
- {
- std::wstring date1 = *it++;
- if(it->empty() || date1 == *it)
- return true;
-
- }
-
- return false;
- }
- }
- }
- }
- }
-
- return true;
-}
-
-bool FtpGetFiles(const std::wstring& dir, const std::list<std::wstring>& files, const std::wstring& ftpName)
-{
- std::map<std::wstring, bool> existingContacts;
- std::wstring script = dir + _T("\\script.sc");
- std::wofstream stream (script.c_str());
- if(stream.is_open())
- {
- stream << "option batch continue\noption confirm off\nopen \""
- << ftpName << "\"\noption transfer binary\n";
- std::wstring lastCD;
- std::list<std::wstring> localFiles;
- for(std::list<std::wstring>::const_iterator it = files.begin(); it != files.end(); ++it)
- {
- std::wstring fileName = GetName(*it);
- localFiles.push_back(dir + L"\\" + fileName);
- std::wstring currentCD = GetDirectoryName(*it);
- if(currentCD != lastCD)
- {
- stream << "cd \"" << currentCD << "\"\n";
- lastCD = currentCD;
- }
-
- stream << "get \"" << fileName << "\"\n";
- }
-
- stream.close();
- std::wstring &log = Options::instance->ftpLogPath;
- CreateDirectory(GetDirectoryName(log).c_str(), NULL);
- DeleteFile(log.c_str());
- TCHAR cmdLine[MAX_PATH];
- _stprintf_s(cmdLine, _T("\"%s\" /nointeractiveinput /log=\"%s\" /script=script.sc"), Options::instance->ftpExePath.c_str(), log.c_str());
- STARTUPINFO startupInfo = {0};
- PROCESS_INFORMATION processInfo;
- startupInfo.cb = sizeof(STARTUPINFO);
- if(CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startupInfo, &processInfo))
- {
- WaitForSingleObject(processInfo.hProcess, INFINITE);
- CloseHandle(processInfo.hThread);
- CloseHandle(processInfo.hProcess);
- }
-
- DeleteFile(script.c_str());
- for(std::list<std::wstring>::const_iterator it = localFiles.begin(); it != localFiles.end(); ++it)
- {
- DWORD atr = GetFileAttributes(it->c_str());
- if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY)
- {
- return true;
- }
- }
-
- return false;
- }
-
- return true;
-}
-
-void CreatePath(const TCHAR *szDir)
-{
- if (!szDir) return;
-
- DWORD dwAttributes;
- TCHAR *pszLastBackslash, szTestDir[ MAX_PATH ];
-
- lstrcpyn( szTestDir, szDir, SIZEOF( szTestDir ));
- if (( dwAttributes = GetFileAttributes( szTestDir )) != INVALID_FILE_ATTRIBUTES && ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ))
- return;
-
- pszLastBackslash = _tcsrchr( szTestDir, '\\' );
- if ( pszLastBackslash == NULL )
- return;
-
- *pszLastBackslash = '\0';
- CreatePath( szTestDir );
- *pszLastBackslash = '\\';
-
- CreateDirectory( szTestDir, NULL );
-}
-
-INT_PTR ExecuteTaskService(WPARAM wParam, LPARAM lParam)
-{
- EnterCriticalSection(&Options::instance->criticalSection);
- int taskNr = (int)wParam;
- if(taskNr < 0 || taskNr >= (int)Options::instance->taskOptions.size())
- {
- LeaveCriticalSection(&Options::instance->criticalSection);
- return FALSE;
- }
-
- Options::instance->taskOptions[taskNr].forceExecute = true;
- Options::instance->taskOptions[taskNr].showMBAfterExecute = true;
- LeaveCriticalSection(&Options::instance->criticalSection);
- StartThread(false);
- return TRUE;
-}
-
-void DoError(const TaskOptions& to, const std::wstring _error)
-{
- TCHAR msg[256];
- _stprintf_s(msg, TranslateT("Task '%s' execution failed:"), to.taskName.c_str());
- if(Options::instance->schedulerHistoryAlerts)
- {
- std::wstring error = msg;
- error += L"\n";
- error += _error;
- DBEVENTINFO dbei = {0};
- dbei.cbSize = sizeof(DBEVENTINFO);
- dbei.szModule = MODULE;
- dbei.flags = DBEF_UTF | DBEF_READ;
- dbei.timestamp = time(NULL);
- // For now I do not convert event data from string to blob, and event type must be message to handle it properly
- dbei.eventType = EVENTTYPE_MESSAGE;
- int len = (int)error.length() + 1;
- dbei.cbBlob = WideCharToMultiByte(CP_UTF8, 0, error.c_str(), len, NULL, 0, NULL, NULL);
- char* buf = new char[dbei.cbBlob];
- dbei.cbBlob = WideCharToMultiByte(CP_UTF8, 0, error.c_str(), len, buf, dbei.cbBlob, NULL, NULL);
- dbei.pBlob = (PBYTE)buf;
- CallService(MS_DB_EVENT_ADD, NULL, (LPARAM) & dbei);
- }
-
-
- if(Options::instance->schedulerAlerts)
- {
- if(CallService(MS_SYSTEM_TERMINATED, 0, 0)) return;
- if(ServiceExists(MS_POPUP_ADDPOPUPCLASS))
- {
- ShowClassPopupT(MODULE, msg, (wchar_t*)_error.c_str());
- }
- else if (ServiceExists( MS_POPUP_ADDPOPUPT ))
- {
- POPUPDATAT ppd = {0};
- ppd.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_HISTORY);
- _tcscpy_s(ppd.lptzContactName, msg);
- _tcscpy_s(ppd.lptzText, _error.c_str());
- CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0);
- }
- }
-}
|