diff --git a/win32/clamav-for-windows/clamav-for-windows/interface.c b/win32/clamav-for-windows/clamav-for-windows/interface.c index 5b7409ab7..5d78f4264 100644 --- a/win32/clamav-for-windows/clamav-for-windows/interface.c +++ b/win32/clamav-for-windows/clamav-for-windows/interface.c @@ -253,9 +253,9 @@ static int sigload_callback(const char *type, const char *name, void *context) { return 0; } - +const char* cli_ctime(const time_t *timep, char *buf, const size_t bufsize); /* Must be called with engine_mutex locked ! */ -static void touch_last_update(void) { +static void touch_last_update(unsigned signo) { char touchme[PATH_MAX]; HANDLE h; @@ -263,7 +263,27 @@ static void touch_last_update(void) { touchme[sizeof(touchme)-1] = '\0'; if((h = CreateFile(touchme, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) { DWORD d; - snprintf(touchme, sizeof(touchme), "w00t!"); + int err; + unsigned ver = (unsigned)cl_engine_get_num(engine, CL_ENGINE_DB_VERSION, &err); + if (ver) { + char timestr[32]; + const char *tstr; + time_t t; + t = cl_engine_get_num(engine, CL_ENGINE_DB_TIME, NULL); + tstr = cli_ctime(&t, timestr, sizeof(timestr)); + /* cut trailing \n */ + timestr[strlen(tstr)-1] = '\0'; + snprintf(touchme, sizeof(touchme), "daily %u/%u sigs\n" + "Database version: %u/%s\n" + "Known viruses: %u\n" + "Reloaded at: %d\n", + ver, signo, ver, tstr, signo, (unsigned)time(NULL)); + } else { + snprintf(touchme, sizeof(touchme), "no daily/%u sigs\n" + "Known viruses: %u\n" + "Reloaded at: %d\n", + signo, signo, (unsigned)time(NULL)); + } touchme[sizeof(touchme)-1] = '\0'; if(WriteFile(h, touchme, strlen(touchme), &d, NULL)) { /* SetEndOfFile(h); */ @@ -301,7 +321,7 @@ static int load_db(void) { if (!mpool_getstats(engine, &used, &total)) logg("load_db: memory %.3f MB / %.3f MB\n", used/(1024*1024.0), total/(1024*1024.0)); - touch_last_update(); + touch_last_update(signo); WIN(); } diff --git a/win32/clamav-for-windows/sigui/SigUI/Makefile.mingw b/win32/clamav-for-windows/sigui/SigUI/Makefile.mingw index f2e0b3f00..9e5a8444a 100644 --- a/win32/clamav-for-windows/sigui/SigUI/Makefile.mingw +++ b/win32/clamav-for-windows/sigui/SigUI/Makefile.mingw @@ -31,7 +31,7 @@ PCH_H = wx_pch.h WINDRES=`$(WX)/wx-config --rescomp` CXXFLAGS = `$(WX)/wx-config --cxxflags` $(COMMON_CPPFLAGS) $(COMMON_CXXFLAGS) CPPFLAGS = `$(WX)/wx-config --cppflags` $(COMMON_CPPFLAGS) -LDFLAGS = `$(WX)/wx-config --libs core,base` $(COMMON_LDFLAGS) +LDFLAGS = `$(WX)/wx-config --libs core,base,adv` $(COMMON_LDFLAGS) RCFLAGS = `$(WX)/wx-config --cppflags` OBJ = $(addprefix $(OBJDIR)/,$(subst .rc,.o,$(subst .cpp,.o,$(SRC)))) diff --git a/win32/clamav-for-windows/sigui/SigUI/SigUIApp.h b/win32/clamav-for-windows/sigui/SigUI/SigUIApp.h index 6c3ebe07e..c05b13889 100644 --- a/win32/clamav-for-windows/sigui/SigUI/SigUIApp.h +++ b/win32/clamav-for-windows/sigui/SigUI/SigUIApp.h @@ -30,6 +30,7 @@ class SigUIApp : public wxApp virtual int OnRun(); virtual void OnInitCmdLine(wxCmdLineParser& parser); virtual bool OnCmdLineParsed(wxCmdLineParser& parser); + virtual void OnEventLoopEnter(wxEventLoopBase *loop); static bool validate_dbname(const wxString &name); private: bool install_mode; diff --git a/win32/clamav-for-windows/sigui/SigUI/SigUIMain.cpp b/win32/clamav-for-windows/sigui/SigUI/SigUIMain.cpp index 3ec003874..75adc3abe 100644 --- a/win32/clamav-for-windows/sigui/SigUI/SigUIMain.cpp +++ b/win32/clamav-for-windows/sigui/SigUI/SigUIMain.cpp @@ -24,6 +24,7 @@ #pragma hdrstop #endif //__BORLANDC__ +#include "../../../../libclamav/version.h" #include "SigUIMain.h" #include "installdb.h" #include @@ -37,34 +38,6 @@ #include #include -//helper functions -enum wxbuildinfoformat { - short_f, long_f }; - -wxString wxbuildinfo(wxbuildinfoformat format) -{ - wxString wxbuild(wxVERSION_STRING); - - if (format == long_f ) - { -#if defined(__WXMSW__) - wxbuild << _T("-Windows"); -#elif defined(__WXMAC__) - wxbuild << _T("-Mac"); -#elif defined(__UNIX__) - wxbuild << _T("-Linux"); -#endif - -#if wxUSE_UNICODE - wxbuild << _T("-Unicode build"); -#else - wxbuild << _T("-ANSI build"); -#endif // wxUSE_UNICODE - } - - return wxbuild; -} - #if wxUSE_DRAG_AND_DROP class DropFiles : public wxFileDropTarget { @@ -123,6 +96,8 @@ class HostnameValidator : public wxTextValidator SigUIFrame::~SigUIFrame() { + delete watcher; + delete icon; delete editor; } @@ -164,6 +139,7 @@ void SigUIFrame::OnClose(wxCloseEvent& event) } } +// icon->RemoveIcon(); Destroy(); } @@ -174,8 +150,6 @@ void SigUIFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void SigUIFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { - wxString msg = wxbuildinfo(long_f); - wxMessageBox(msg, _("Welcome to...")); } void SigUIFrame::m_proxyOnCheckBox( wxCommandEvent& event ) @@ -367,6 +341,21 @@ void SigUIFrame::m_custom_removeOnButtonClick( wxCommandEvent& WXUNUSED(event) ) m_custom_remove->Disable(); } +static wxString GetExecPath() +{ + wxFileName exec(wxStandardPaths::Get().GetExecutablePath()); + return exec.GetPathWithSep(); +} + +static wxFileSystemWatcher *watcher; +void SigUIApp::OnEventLoopEnter(wxEventLoopBase *WXUNUSED(loop)) +{ + watcher = new wxFileSystemWatcher(); + watcher->SetOwner(GetTopWindow()); + watcher->Add(GetExecPath(), wxFSW_EVENT_CREATE | wxFSW_EVENT_MODIFY | + wxFSW_EVENT_WARNING | wxFSW_EVENT_ERROR); +} + void SigUIFrame::m_save_settingsOnButtonClick( wxCommandEvent& WXUNUSED(event) ) { if (!Validate() || !TransferDataFromWindow()) { @@ -377,28 +366,27 @@ void SigUIFrame::m_save_settingsOnButtonClick( wxCommandEvent& WXUNUSED(event) ) wxLogMessage(_("Settings saved")); } -static wxString GetExecPath() -{ - wxFileName exec(wxStandardPaths::Get().GetExecutablePath()); - return exec.GetPathWithSep(); -} - static wxString GetConfigFile() { return GetExecPath() + "freshclam.conf"; } - SigUIFrame::SigUIFrame(wxFrame *frame) : GUIFrame(frame), val_bytecode(true) { #ifdef _WIN32 - SetIcon(wxIcon(wxT("clam"))); + SetIcon(wxIcon(wxT("aaaa"))); #endif + icon = new wxTaskBarIcon(); + icon->Connect(wxEVT_TASKBAR_BALLOON_TIMEOUT, wxTaskBarIconEventHandler(SigUIFrame::OnBalloon), NULL, this); + icon->Connect(wxEVT_TASKBAR_BALLOON_CLICK, wxTaskBarIconEventHandler(SigUIFrame::OnBalloon), NULL, this); + + this->Connect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(SigUIFrame::OnChange)); + this->Connect(wxEVT_END_PROCESS, wxProcessEventHandler(SigUIFrame::OnTerminateInstall)); this->SetStatusBar(statusBar); - statusBar->SetStatusText(wxbuildinfo(short_f), 1); + statusBar->SetStatusText(REPO_VERSION, 1); // m_sig_files->SetDropTarget(new DropFiles(m_sig_files)); // m_urls->SetDropTarget(new DropURLs(m_urls)); @@ -450,6 +438,66 @@ SigUIFrame::SigUIFrame(wxFrame *frame) //prevent window from being resizing below minimum this->GetSizer()->SetSizeHints(this); + show_db(true); +} + +void SigUIFrame::OnBalloon(wxTaskBarIconEvent& WXUNUSED(event)) +{ + if (icon->IsIconInstalled()) + icon->RemoveIcon(); +} + +void SigUIFrame::OnChange(wxFileSystemWatcherEvent &event) +{ + if (event.IsError()) { + wxLogVerbose("fswatcher error: %s", event.GetErrorDescription()); + return; + } + wxLogVerbose("event on %s", event.GetPath().GetFullPath()); + switch (event.GetChangeType()) { + default: + break; + case wxFSW_EVENT_CREATE: + case wxFSW_EVENT_MODIFY: + wxFileName filename = event.GetPath(); + if (filename.GetName() != "lastupd") + return; + show_db(false); + break; + } +} + +void SigUIFrame::show_db(bool first) +{ + wxLogNull logNo; + char msg[512]; + wxFileName filename(GetExecPath() + "lastupd"); + if (!filename.IsFileReadable()) + return; + wxFile file(filename.GetFullPath()); + if (!file.IsOpened()) + return; + memset(&msg, 0, sizeof(msg)); + if (file.Read(msg, sizeof(msg) - 1) <= 0) + return; + + wxString line = wxString(msg).BeforeFirst('\n'); + wxString text = statusBar->GetStatusText(0); + statusBar->SetStatusText(line, 0); + if (first || lastmsg == msg) + return; + lastmsg = msg; + //only show when changed, and not the first time + if (icon->IsIconInstalled()) + icon->RemoveIcon();//remove old balloon + icon->SetIcon(GetIcon()); + line = wxString(msg).AfterFirst('\n'); +#ifdef _WIN32 + icon->ShowBalloon("ClamAV database reloaded", + line, wxICON_INFORMATION); +#endif + wxFileName filename0(GetExecPath() + "forcerld"); + wxLogVerbose("Reload delta: %s", filename.GetModificationTime().Subtract( filename0.GetModificationTime() ).Format()); } void SigUIFrame::tabsOnNotebookPageChanged( wxNotebookEvent& event ) @@ -493,6 +541,22 @@ class MyProcess : public wxProcess MyProcessOutput *m_parent; }; +void SigUIFrame::reload() +{ + wxFileName filename(GetExecPath() + "forcerld"); + if (!filename.FileExists()) { + wxFile file; + if (!file.Create(filename.GetFullPath(), true)) { + wxLogMessage(_("Cannot signal reload")); + return; + } + } else { + filename.Touch(); + } + + wxLogMessage(_("Database reload queued")); +} + void SigUIFrame::m_run_freshclamOnButtonClick( wxCommandEvent& WXUNUSED(event) ) { MyProcessOutput *output = new MyProcessOutput(this); @@ -521,9 +585,7 @@ void SigUIFrame::m_run_freshclamOnButtonClick( wxCommandEvent& WXUNUSED(event) ) output->SetProcess(process); output->ShowModal(); - - wxLogMessage(_("The database will be reloaded in the next hour.\n" - "Press 'Update Now' in the main UI if you want them reloaded now")); + reload(); } MyProcessOutput::MyProcessOutput(wxWindow *parent) @@ -712,9 +774,8 @@ void SigUIFrame::OnTerminateInstall(wxProcessEvent &event) wxWakeUpIdle(); if (event.GetExitCode() == 0) { m_sig_candidates->Clear(); - wxLogMessage(_("Successfully installed new virus signatures\n" - "The signatures will be reloaded in the next hour." - "If you want to reload them now, press 'Update Now' on the main UI")); + wxLogMessage(_("Successfully installed new virus signatures\n")); + reload(); } else { bool had_errors = false; wxInputStream *err = m_siginst_process->GetErrorStream(); diff --git a/win32/clamav-for-windows/sigui/SigUI/SigUIMain.h b/win32/clamav-for-windows/sigui/SigUI/SigUIMain.h index 63609a7b6..281ffe588 100644 --- a/win32/clamav-for-windows/sigui/SigUI/SigUIMain.h +++ b/win32/clamav-for-windows/sigui/SigUI/SigUIMain.h @@ -41,6 +41,9 @@ class SigUIFrame: public GUIFrame wxString val_mirror; bool val_bytecode; wxProcess *m_siginst_process; + wxFileSystemWatcher *watcher; + wxTaskBarIcon *icon; + wxString lastmsg; virtual void OnClose(wxCloseEvent& event); virtual void OnQuit(wxCommandEvent& event); @@ -60,7 +63,11 @@ class SigUIFrame: public GUIFrame virtual void GUIFrameOnIdle( wxIdleEvent& event ); void tabsOnNotebookPageChanged( wxNotebookEvent& event ); void OnTerminateInstall(wxProcessEvent &event); + void OnChange(wxFileSystemWatcherEvent &event); void GetFreshclamDBnames(StringSet *set); + void OnBalloon(wxTaskBarIconEvent& event); + void reload(void); + void show_db(bool first); }; class MyProcessOutput : public ProcessOutput diff --git a/win32/clamav-for-windows/sigui/SigUI/installdb.cpp b/win32/clamav-for-windows/sigui/SigUI/installdb.cpp index 98eaceaee..2844be52b 100644 --- a/win32/clamav-for-windows/sigui/SigUI/installdb.cpp +++ b/win32/clamav-for-windows/sigui/SigUI/installdb.cpp @@ -1,5 +1,5 @@ /*************************************************************** - * Purpose: Test and install ClamAV databases + * Purpose: Test and install ClamAV databases * * Copyright (C) 2010 Sourcefire, Inc. * @@ -30,6 +30,7 @@ #include "../../../../libclamav/clamav.h" #include "installdb.h" +#include static wxString GetExecPath() { diff --git a/win32/clamav-for-windows/sigui/SigUI/sigui_vc10.vcxproj b/win32/clamav-for-windows/sigui/SigUI/sigui_vc10.vcxproj index ec16bfb81..c2fa0d614 100644 --- a/win32/clamav-for-windows/sigui/SigUI/sigui_vc10.vcxproj +++ b/win32/clamav-for-windows/sigui/SigUI/sigui_vc10.vcxproj @@ -94,10 +94,8 @@ true true $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb Level4 true - ProgramDatabase NotUsing wx_pch.h @@ -113,7 +111,6 @@ true $(SolutionDir)$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true - vc_mswud\minimal.pdb Windows MachineX86 RequireAdministrator @@ -139,10 +136,8 @@ true true $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb Level4 true - ProgramDatabase NotUsing wx_pch.h @@ -158,7 +153,6 @@ true $(SolutionDir)$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true - vc_mswud\minimal.pdb Windows RequireAdministrator @@ -181,10 +175,8 @@ MultiThreadedDLL false $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb Level4 true - ProgramDatabase true Size true @@ -206,7 +198,6 @@ true $(SolutionDir)$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true - vc_mswu\minimal.pdb Windows MachineX86 true @@ -233,10 +224,8 @@ MultiThreadedDLL false $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb Level4 true - ProgramDatabase true Size true @@ -257,7 +246,6 @@ true $(SolutionDir)$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true - vc_mswu\minimal.pdb Windows true true diff --git a/win32/clamav-for-windows/sigui/SigUI/wx_pch.h b/win32/clamav-for-windows/sigui/SigUI/wx_pch.h index f7394fba1..24fce3737 100644 --- a/win32/clamav-for-windows/sigui/SigUI/wx_pch.h +++ b/win32/clamav-for-windows/sigui/SigUI/wx_pch.h @@ -57,6 +57,8 @@ #include #include #include +#include +#include #ifdef WX_PRECOMP #include "SigUIApp.h" diff --git a/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/build/wx291_msw_vc10/wx_vc10_core.vcxproj b/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/build/wx291_msw_vc10/wx_vc10_core.vcxproj index 369c9ba46..1062b62ba 100644 --- a/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/build/wx291_msw_vc10/wx_vc10_core.vcxproj +++ b/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/build/wx291_msw_vc10/wx_vc10_core.vcxproj @@ -247,6 +247,8 @@ + + @@ -1406,4 +1408,4 @@ - \ No newline at end of file + diff --git a/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/include/wx/msw/setup.h b/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/include/wx/msw/setup.h index 55b75ab25..b4175adee 100644 --- a/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/include/wx/msw/setup.h +++ b/win32/clamav-for-windows/sigui/wxWidgets-2.9.1/include/wx/msw/setup.h @@ -68,7 +68,7 @@ #define wxUSE_CMDLINE_PARSER 1 -#define wxUSE_THREADS 0 +#define wxUSE_THREADS 1 #define wxUSE_STREAMS 1 @@ -114,7 +114,7 @@ #define wxUSE_STOPWATCH 0 -#define wxUSE_FSWATCHER 0 +#define wxUSE_FSWATCHER 1 #define wxUSE_CONFIG 1 @@ -272,7 +272,7 @@ #define wxUSE_TOOLBOOK 0 -#define wxUSE_TASKBARICON 0 +#define wxUSE_TASKBARICON 1 #define wxUSE_GRID 0 @@ -506,7 +506,7 @@ #define wxUSE_OWNER_DRAWN 1 -#define wxUSE_TASKBARICON_BALLOONS 0 +#define wxUSE_TASKBARICON_BALLOONS 1 #define wxUSE_UXTHEME 1