forked from xbmc/xbmc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shutdownHookCheck.h
144 lines (109 loc) · 4.04 KB
/
shutdownHookCheck.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// shutdownHookCheck.h
//
// @AUTHOR: Sven Burkard <dev@sven-burkard.de>
// @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 <cstdlib> // system / getenv
//#include <iostream> // cout
#include <dirent.h> // dir...
#include <string.h> // strcmp
#include <sys/stat.h> // stat
// xbmc includes
#include "dialogs/GUIDialogKaiToast.h"
using namespace std;
////////////////////////////////////////////////////////
char* getHomeDirectory()
{
////////////////////////////////////////////////////////
char *h=getenv("HOME");
return h;
}
////////////////////////////////////////////////////////
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()
{
////////////////////////////////////////////////////////
DIR* dir;
dirent* pdir;
int shutdownStopped = 0;
string dirHooks;
/*
//////////////////////////////////////////////////
create a path-variable of the hook scripts dir
//////////////////////////////////////////////////
*/
char* homeDirectory = getHomeDirectory();
if(homeDirectory != NULL)
{
dirHooks = homeDirectory;
}
else
{
dirHooks = "/home/xbmc";
CLog::Log(LOGERROR,"[shutdownHookCheck] homeDirectory var is undef => using default homeDirectory!!!");
}
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, "failed to open hooks directory, shutdown anyway");
CLog::Log(LOGWARNING,"[shutdownHookCheck] dirHooks (%s) failed to open hooks directory, 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;
}