diff --git a/xbmc/ApplicationMessenger.cpp b/xbmc/ApplicationMessenger.cpp index f66591e25b2e8..77c854248e19b 100644 --- a/xbmc/ApplicationMessenger.cpp +++ b/xbmc/ApplicationMessenger.cpp @@ -226,6 +226,9 @@ void CApplicationMessenger::ProcessMessages() void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) { + + CshutdownHookCheck CshutdownHookCheck; + switch (pMsg->dwMessage) { case TMSG_SHUTDOWN: @@ -233,35 +236,35 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) switch (CSettings::Get().GetInt("powermanagement.shutdownstate")) { case POWERSTATE_SHUTDOWN: - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { Powerdown(); break; } case POWERSTATE_SUSPEND: - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { Suspend(); break; } case POWERSTATE_HIBERNATE: - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { Hibernate(); break; } case POWERSTATE_QUIT: - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { Quit(); break; } case POWERSTATE_MINIMIZE: - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { Minimize(); break; @@ -276,7 +279,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) case TMSG_POWERDOWN: { - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { g_application.Stop(EXITCODE_POWERDOWN); g_powerManager.Powerdown(); @@ -286,7 +289,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) case TMSG_QUIT: { - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { g_application.Stop(EXITCODE_QUIT); } @@ -295,7 +298,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) case TMSG_HIBERNATE: { - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { g_PVRManager.SetWakeupCommand(); g_powerManager.Hibernate(); @@ -305,7 +308,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) case TMSG_SUSPEND: { - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { g_PVRManager.SetWakeupCommand(); g_powerManager.Suspend(); @@ -316,7 +319,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) case TMSG_RESTART: case TMSG_RESET: { - if(shutdownHookCheck()) + if(CshutdownHookCheck.shutdownHookCheck()) { g_application.Stop(EXITCODE_REBOOT); g_powerManager.Reboot(); diff --git a/xbmc/Makefile.in b/xbmc/Makefile.in index 76ec9bf5acdc0..b124c215a4ffb 100644 --- a/xbmc/Makefile.in +++ b/xbmc/Makefile.in @@ -22,6 +22,7 @@ SRCS=Application.cpp \ PlayListPlayer.cpp \ PartyModeManager.cpp \ SectionLoader.cpp \ + shutdownHookCheck.cpp \ SystemGlobals.cpp \ Temperature.cpp \ TextureCache.cpp \ diff --git a/xbmc/shutdownHookCheck.cpp b/xbmc/shutdownHookCheck.cpp new file mode 100644 index 0000000000000..15dc4599e8bb5 --- /dev/null +++ b/xbmc/shutdownHookCheck.cpp @@ -0,0 +1,133 @@ +// shutdownHookCheck.cpp +// +// @AUTHOR: Sven Burkard +// @DESC..: checks for user defined xbmc-shutdown-hooks in a predefined hook directory. +// @DESC..: if one of the hook scripts returns an exit code not 0, +// @DESC..: the xbmc shutdown will be stopped and the user will be informed via xbmc-notifications +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// system includes +#include // system / getenv +//#include // cout +#include // dir... +#include // strcmp +#include // stat + +// xbmc includes +#include "utils/log.h" +#include "dialogs/GUIDialogKaiToast.h" +#include "filesystem/SpecialProtocol.h" +#include "shutdownHookCheck.h" + + +using namespace std; + + +//////////////////////////////////////////////////////// +bool fileIsExecutable(const string file) +{ +//////////////////////////////////////////////////////// + + struct stat st; + + if(stat(file.c_str(), &st) < 0) + { + return false; + } + else if((st.st_mode & S_IEXEC) != 0) + { + return true; + } + + return false; +} + + +//////////////////////////////////////////////////////// +bool CshutdownHookCheck::shutdownHookCheck() +{ +//////////////////////////////////////////////////////// + + DIR* dir; + dirent* pdir; + int shutdownStopped = 0; + string dirHome; + string dirHooks; + +/* +////////////////////////////////////////////////// + create a path-variable of the hook scripts dir +////////////////////////////////////////////////// +*/ + dirHome = CSpecialProtocol::TranslatePath("special://home/").c_str(); + + CLog::Log(LOGDEBUG,"[shutdownHookCheck] dirHome:>>%s<<", dirHome.c_str()); + + + dirHooks += dirHome; + dirHooks += "../xbmcShutdownHooks/hooks-enabled/"; + + CLog::Log(LOGDEBUG,"[shutdownHookCheck] dirHooks:>>%s<<", dirHooks.c_str()); +/* +////////////////////////////////////////////////// +*/ + + dir = opendir(dirHooks.c_str()); + + if(!dir) + { + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, "shutdown-hook: " + dirHooks, "hooks directory couldn't be opened, shutdown anyway"); + CLog::Log(LOGWARNING,"[shutdownHookCheck] hooks directory (dirHooks: %s) couldn't be opened, shutdown anyway", dirHooks.c_str()); + return true; // return true because: a missing shutdown hook dir should't be a reason to abort exit/shutdown + } + + while((pdir = readdir(dir)) != NULL) + { + + CLog::Log(LOGDEBUG,"[shutdownHookCheck] shutdownStopped:>>%i<<", shutdownStopped); + + if(!strcmp(pdir->d_name, ".")) continue; + if(!strcmp(pdir->d_name, "..")) continue; + if(!strcmp(pdir->d_name, ".gitignore")) continue; + if(!strcmp(pdir->d_name, "README")) continue; + if(shutdownStopped == 1) continue; + + + string scriptName = pdir->d_name; + string combinedCmd = dirHooks+scriptName; + + CLog::Log(LOGDEBUG,"[shutdownHookCheck] scriptName:>>%s<<", scriptName.c_str()); + + if(!fileIsExecutable(combinedCmd)) + { + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, "shutdown-hook-check: ", scriptName + ": can NOT be executed"); + CLog::Log(LOGERROR,"[shutdownHookCheck] %s : can NOT be executed", scriptName.c_str()); + return false; + } + + + int exitCode = system(combinedCmd.c_str()); + + if(exitCode == 0) + { + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "shutdown-hook-check: ", scriptName + ": ok"); + CLog::Log(LOGINFO,"[shutdownHookCheck] %s: ok", scriptName.c_str()); + } + else + { + shutdownStopped = 1; + CLog::Log(LOGDEBUG,"[shutdownHookCheck] setting shutdownStopped to 1 !!!"); + + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "shutdown-hook-check: ", "shutdown stopped by " + scriptName); + CLog::Log(LOGINFO,"[shutdownHookCheck] shutdown stopped by %s", scriptName.c_str()); + + closedir(dir); + return false; + } + + } + closedir(dir); + + + return true; +} diff --git a/xbmc/shutdownHookCheck.h b/xbmc/shutdownHookCheck.h index c70f69778427d..2598a9151d8d8 100644 --- a/xbmc/shutdownHookCheck.h +++ b/xbmc/shutdownHookCheck.h @@ -6,126 +6,10 @@ // @DESC..: the xbmc shutdown will be stopped and the user will be informed via xbmc-notifications ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// system includes -#include // system / getenv -//#include // cout -#include // dir... -#include // strcmp -#include // stat -// xbmc includes -#include "dialogs/GUIDialogKaiToast.h" -#include "filesystem/SpecialProtocol.h" - - -using namespace std; - - -//////////////////////////////////////////////////////// -bool fileIsExecutable(const string file) -{ -//////////////////////////////////////////////////////// - - struct stat st; - - if(stat(file.c_str(), &st) < 0) - { - return false; - } - else if((st.st_mode & S_IEXEC) != 0) - { - return true; - } - - return false; -} - - -//////////////////////////////////////////////////////// -bool shutdownHookCheck() +class CshutdownHookCheck { -//////////////////////////////////////////////////////// - - DIR* dir; - dirent* pdir; - int shutdownStopped = 0; - string dirHome; - string dirHooks; - -/* -////////////////////////////////////////////////// - create a path-variable of the hook scripts dir -////////////////////////////////////////////////// -*/ - dirHome = CSpecialProtocol::TranslatePath("special://home/").c_str(); - - CLog::Log(LOGDEBUG,"[shutdownHookCheck] dirHome:>>%s<<", dirHome.c_str()); - - - dirHooks += dirHome; - dirHooks += "../xbmcShutdownHooks/hooks-enabled/"; - - CLog::Log(LOGDEBUG,"[shutdownHookCheck] dirHooks:>>%s<<", dirHooks.c_str()); -/* -////////////////////////////////////////////////// -*/ - - dir = opendir(dirHooks.c_str()); - - if(!dir) - { - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, "shutdown-hook: " + dirHooks, "hooks directory couldn't be opened, shutdown anyway"); - CLog::Log(LOGWARNING,"[shutdownHookCheck] hooks directory (dirHooks: %s) couldn't be opened, shutdown anyway", dirHooks.c_str()); - return true; // return true because: a missing shutdown hook dir should't be a reason to abort exit/shutdown - } - - while((pdir = readdir(dir)) != NULL) - { - - CLog::Log(LOGDEBUG,"[shutdownHookCheck] shutdownStopped:>>%i<<", shutdownStopped); - - if(!strcmp(pdir->d_name, ".")) continue; - if(!strcmp(pdir->d_name, "..")) continue; - if(!strcmp(pdir->d_name, ".gitignore")) continue; - if(!strcmp(pdir->d_name, "README")) continue; - if(shutdownStopped == 1) continue; - - - string scriptName = pdir->d_name; - string combinedCmd = dirHooks+scriptName; - - CLog::Log(LOGDEBUG,"[shutdownHookCheck] scriptName:>>%s<<", scriptName.c_str()); - - if(!fileIsExecutable(combinedCmd)) - { - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, "shutdown-hook-check: ", scriptName + ": can NOT be executed"); - CLog::Log(LOGERROR,"[shutdownHookCheck] %s : can NOT be executed", scriptName.c_str()); - return false; - } - - - int exitCode = system(combinedCmd.c_str()); - - if(exitCode == 0) - { - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "shutdown-hook-check: ", scriptName + ": ok"); - CLog::Log(LOGINFO,"[shutdownHookCheck] %s: ok", scriptName.c_str()); - } - else - { - shutdownStopped = 1; - CLog::Log(LOGDEBUG,"[shutdownHookCheck] setting shutdownStopped to 1 !!!"); - - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "shutdown-hook-check: ", "shutdown stopped by " + scriptName); - CLog::Log(LOGINFO,"[shutdownHookCheck] shutdown stopped by %s", scriptName.c_str()); - - closedir(dir); - return false; - } - - } - closedir(dir); - + public: + bool shutdownHookCheck(); +}; - return true; -}