summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2006-11-08 14:16:31 (UTC)
committer Michael Krelin <hacker@klever.net>2006-11-08 14:16:31 (UTC)
commit4148b7ad68f2b5bf83d637bdc5ebbb9f0d2aa869 (patch) (unidiff)
tree1816e76710d722b77ac99f8ca8719f0208b31088
parentf3915982902595f324ef27dd67589f5e950a046b (diff)
downloaddudki-4148b7ad68f2b5bf83d637bdc5ebbb9f0d2aa869.zip
dudki-4148b7ad68f2b5bf83d637bdc5ebbb9f0d2aa869.tar.gz
dudki-4148b7ad68f2b5bf83d637bdc5ebbb9f0d2aa869.tar.bz2
fixed a bug for setting up unspecified group,
bumped version and years, added NEWS item
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--COPYING2
-rw-r--r--NEWS.xml3
-rw-r--r--configure.ac2
-rw-r--r--src/process.cc14
4 files changed, 13 insertions, 8 deletions
diff --git a/COPYING b/COPYING
index 873f196..8ceaf0a 100644
--- a/COPYING
+++ b/COPYING
@@ -1,19 +1,19 @@
1Copyright (c) 2004 Klever Group (http://www.klever.net/) 1Copyright (c) 2004-2006 Klever Group (http://www.klever.net/)
2 2
3Permission is hereby granted, free of charge, to any person obtaining a copy of 3Permission is hereby granted, free of charge, to any person obtaining a copy of
4this software and associated documentation files (the "Software"), to deal in 4this software and associated documentation files (the "Software"), to deal in
5the Software without restriction, including without limitation the rights to 5the Software without restriction, including without limitation the rights to
6use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 6use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7of the Software, and to permit persons to whom the Software is furnished to do 7of the Software, and to permit persons to whom the Software is furnished to do
8so, subject to the following conditions: 8so, subject to the following conditions:
9 9
10The above copyright notice and this permission notice shall be included in all 10The above copyright notice and this permission notice shall be included in all
11copies or substantial portions of the Software. 11copies or substantial portions of the Software.
12 12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19SOFTWARE. 19SOFTWARE.
diff --git a/NEWS.xml b/NEWS.xml
index f9be239..2041a58 100644
--- a/NEWS.xml
+++ b/NEWS.xml
@@ -1,19 +1,22 @@
1<?xml version="1.0" encoding="us-ascii"?> 1<?xml version="1.0" encoding="us-ascii"?>
2<news> 2<news>
3 <version version="0.2.2" date="November 8th, 2006">
4 <ni>Do not try to set unspecified group</ni>
5 </version>
3 <version version="0.2.1" date="August 1st, 2004"> 6 <version version="0.2.1" date="August 1st, 2004">
4 <ni>do not act -e when doing -r</ni> 7 <ni>do not act -e when doing -r</ni>
5 <ni>proper handling of <kbd>ProcessName</kbd> on <kbd>FreeBSD</kbd></ni> 8 <ni>proper handling of <kbd>ProcessName</kbd> on <kbd>FreeBSD</kbd></ni>
6 </version> 9 </version>
7 <version version="0.2" date="July 24th, 2004"> 10 <version version="0.2" date="July 24th, 2004">
8 <ni>now dudki sends arbitrary signals to the processes being monitored from the command line</ni> 11 <ni>now dudki sends arbitrary signals to the processes being monitored from the command line</ni>
9 <ni>detection of running processes which do not keep pidfiles, using process name</ni> 12 <ni>detection of running processes which do not keep pidfiles, using process name</ni>
10 </version> 13 </version>
11 <version version="0.1" date="July 21st, 2004"> 14 <version version="0.1" date="July 21st, 2004">
12 <ni><kbd>initgroups()</kbd> called before executing <kbd>RestartCommand</kbd></ni> 15 <ni><kbd>initgroups()</kbd> called before executing <kbd>RestartCommand</kbd></ni>
13 <ni>more civilized way of restarting on <kbd>SIGHUP</kbd></ni> 16 <ni>more civilized way of restarting on <kbd>SIGHUP</kbd></ni>
14 <ni>minor changes to build process</ni> 17 <ni>minor changes to build process</ni>
15 </version> 18 </version>
16 <version version="0.0" date="July 11th, 2004"> 19 <version version="0.0" date="July 11th, 2004">
17 <ni>Initial release</ni> 20 <ni>Initial release</ni>
18 </version> 21 </version>
19</news> 22</news>
diff --git a/configure.ac b/configure.ac
index eed8e97..a0e01e4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,40 +1,40 @@
1AC_INIT([dudki], [0.2.1], [dudki-bugs@klever.net]) 1AC_INIT([dudki], [0.2.2], [dudki-bugs@klever.net])
2AC_CONFIG_SRCDIR([src/dudki.cc]) 2AC_CONFIG_SRCDIR([src/dudki.cc])
3AC_CONFIG_HEADER([config.h]) 3AC_CONFIG_HEADER([config.h])
4AM_INIT_AUTOMAKE([dist-bzip2]) 4AM_INIT_AUTOMAKE([dist-bzip2])
5 5
6AC_PROG_CXX 6AC_PROG_CXX
7AC_PROG_CC 7AC_PROG_CC
8 8
9AC_HEADER_SYS_WAIT 9AC_HEADER_SYS_WAIT
10AC_CHECK_HEADERS([syslog.h unistd.h getopt.h]) 10AC_CHECK_HEADERS([syslog.h unistd.h getopt.h])
11 11
12AC_HEADER_STDBOOL 12AC_HEADER_STDBOOL
13AC_C_CONST 13AC_C_CONST
14AC_TYPE_UID_T 14AC_TYPE_UID_T
15AC_TYPE_PID_T 15AC_TYPE_PID_T
16 16
17AC_FUNC_FORK 17AC_FUNC_FORK
18AC_HEADER_STDC 18AC_HEADER_STDC
19AC_TYPE_SIGNAL 19AC_TYPE_SIGNAL
20AC_CHECK_FUNCS([dup2 memmove strtol]) 20AC_CHECK_FUNCS([dup2 memmove strtol])
21AC_CHECK_FUNC([getopt_long],[ 21AC_CHECK_FUNC([getopt_long],[
22 AC_DEFINE([HAVE_GETOPT_LONG],[1],[Define to make use of getopt_long]) 22 AC_DEFINE([HAVE_GETOPT_LONG],[1],[Define to make use of getopt_long])
23 AC_SUBST([HAVE_GETOPT_LONG],1) 23 AC_SUBST([HAVE_GETOPT_LONG],1)
24],[ 24],[
25 AC_SUBST([HAVE_GETOPT_LONG],0) 25 AC_SUBST([HAVE_GETOPT_LONG],0)
26]) 26])
27 27
28AC_PATH_PROG([XSLTPROC],[xsltproc],[true]) 28AC_PATH_PROG([XSLTPROC],[xsltproc],[true])
29 29
30PKG_CHECK_MODULES([DOTCONF],[dotconf],,[ 30PKG_CHECK_MODULES([DOTCONF],[dotconf],,[
31 AC_MSG_ERROR([no dotconf library found]) 31 AC_MSG_ERROR([no dotconf library found])
32]) 32])
33 33
34AC_CONFIG_FILES([ 34AC_CONFIG_FILES([
35 Makefile 35 Makefile
36 src/Makefile 36 src/Makefile
37 man/Makefile 37 man/Makefile
38 man/dudki.8 man/dudki.conf.5 38 man/dudki.8 man/dudki.conf.5
39]) 39])
40AC_OUTPUT 40AC_OUTPUT
diff --git a/src/process.cc b/src/process.cc
index 96c874f..6d3b2a2 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -34,134 +34,136 @@ void process::check(const string& id,configuration& config) {
34 try { 34 try {
35 check(); 35 check();
36 patience = 0; 36 patience = 0;
37 }catch(exception& e) { 37 }catch(exception& e) {
38 if(patience>60) { // TODO: configurable 38 if(patience>60) { // TODO: configurable
39 patience = 0; 39 patience = 0;
40 }else{ 40 }else{
41 if(patience<10) { // TODO: configurable 41 if(patience<10) { // TODO: configurable
42 syslog(LOG_NOTICE,"The process '%s' is down, trying to launch.",id.c_str()); 42 syslog(LOG_NOTICE,"The process '%s' is down, trying to launch.",id.c_str());
43 do_notify(id,"Starting up", 43 do_notify(id,"Starting up",
44 "The named process seems to be down. Dudki will try\n" 44 "The named process seems to be down. Dudki will try\n"
45 "to revive it by running the specified command.\n", 45 "to revive it by running the specified command.\n",
46 config); 46 config);
47 try { 47 try {
48 launch(id,config); 48 launch(id,config);
49 }catch(exception& e) { 49 }catch(exception& e) {
50 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what()); 50 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what());
51 } 51 }
52 }else if(patience==10){ // TODO: configurable like the above 52 }else if(patience==10){ // TODO: configurable like the above
53 syslog(LOG_NOTICE,"Giving up on process '%s' for a while",id.c_str()); 53 syslog(LOG_NOTICE,"Giving up on process '%s' for a while",id.c_str());
54 do_notify(id,"Giving up", 54 do_notify(id,"Giving up",
55 "After a number of attempts to relaunch the named process\n" 55 "After a number of attempts to relaunch the named process\n"
56 "It still seems to be down. Dudki is giving up attempts\n" 56 "It still seems to be down. Dudki is giving up attempts\n"
57 "to revive the process for a while.\n", 57 "to revive the process for a while.\n",
58 config); 58 config);
59 } 59 }
60 patience++; 60 patience++;
61 } 61 }
62 } 62 }
63} 63}
64 64
65void process::launch(const string& id,configuration& config) { 65void process::launch(const string& id,configuration& config) {
66 uid_t uid = (uid_t)-1; 66 uid_t uid = (uid_t)-1;
67 gid_t gid = (gid_t)-1; 67 gid_t gid = (gid_t)-1;
68 if(!user.empty()) { 68 if(!user.empty()) {
69 struct passwd *ptmp = getpwnam(user.c_str()); 69 struct passwd *ptmp = getpwnam(user.c_str());
70 if(ptmp) { 70 if(ptmp) {
71 uid = ptmp->pw_uid; 71 uid = ptmp->pw_uid;
72 gid = ptmp->pw_gid; 72 gid = ptmp->pw_gid;
73 }else{ 73 }else{
74 errno=0; 74 errno=0;
75 uid = strtol(user.c_str(),NULL,0); 75 uid = strtol(user.c_str(),NULL,0);
76 if(errno) 76 if(errno)
77 throw runtime_error("Failed to resolve User value to uid"); 77 throw runtime_error("Failed to resolve User value to uid");
78 } 78 }
79 } 79 }
80 if(!group.empty()) { 80 if(!group.empty()) {
81 struct group *gtmp = getgrnam(group.c_str()); 81 struct group *gtmp = getgrnam(group.c_str());
82 if(gtmp) { 82 if(gtmp) {
83 gid = gtmp->gr_gid; 83 gid = gtmp->gr_gid;
84 }else{ 84 }else{
85 errno = 0; 85 errno = 0;
86 gid = strtol(group.c_str(),NULL,0); 86 gid = strtol(group.c_str(),NULL,0);
87 if(errno) 87 if(errno)
88 throw runtime_error("Failed to reslove Group value to gid"); 88 throw runtime_error("Failed to reslove Group value to gid");
89 } 89 }
90 } 90 }
91 pid_t p = fork(); 91 pid_t p = fork();
92 if(p<0) 92 if(p<0)
93 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to fork()"); 93 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to fork()");
94 if(!p) { 94 if(!p) {
95 // child 95 // child
96 try { 96 try {
97 setsid(); 97 setsid();
98 if(user.empty()) { 98 if(!group.empty()) {
99 if((getgid()!=gid) && setgid(gid)) 99 if(user.empty()) {
100 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setgid()"); 100 if((getgid()!=gid) && setgid(gid))
101 }else{ 101 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setgid()");
102 if(initgroups(user.c_str(),gid)) 102 }else{
103 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to initgroups()"); 103 if(initgroups(user.c_str(),gid))
104 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to initgroups()");
105 }
104 } 106 }
105 if(!chroot.empty()) { 107 if(!chroot.empty()) {
106 if(::chroot(chroot.c_str())) 108 if(::chroot(chroot.c_str()))
107 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to chroot()"); 109 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to chroot()");
108 } 110 }
109 if(!user.empty()) { 111 if(!user.empty()) {
110 if((getuid()!=uid) && setuid(uid)) 112 if((getuid()!=uid) && setuid(uid))
111 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setuid()"); 113 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setuid()");
112 } 114 }
113 char *argv[] = { "/bin/sh", "-c", (char*)restart_cmd.c_str(), NULL }; 115 char *argv[] = { "/bin/sh", "-c", (char*)restart_cmd.c_str(), NULL };
114 close(0); close(1); close(2); 116 close(0); close(1); close(2);
115 execv("/bin/sh",argv); 117 execv("/bin/sh",argv);
116 }catch(exception& e) { 118 }catch(exception& e) {
117 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what()); 119 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what());
118 } 120 }
119 _exit(-1); 121 _exit(-1);
120 } 122 }
121 // parent 123 // parent
122 int rv; 124 int rv;
123 if(waitpid(p,&rv,0)<0) 125 if(waitpid(p,&rv,0)<0)
124 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to waitpid()"); 126 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to waitpid()");
125} 127}
126 128
127void process::do_notify(const string& id,const string& event,const string& description,configuration& config) { 129void process::do_notify(const string& id,const string& event,const string& description,configuration& config) {
128 string the_notify; 130 string the_notify;
129 if(!notify.empty()) 131 if(!notify.empty())
130 the_notify=notify; 132 the_notify=notify;
131 else if(!config.notify.empty()) 133 else if(!config.notify.empty())
132 the_notify=config.notify; 134 the_notify=config.notify;
133 else 135 else
134 return; 136 return;
135 try { 137 try {
136 string::size_type colon = the_notify.find(':'); 138 string::size_type colon = the_notify.find(':');
137 if(colon==string::npos) 139 if(colon==string::npos)
138 throw runtime_error("invalid notify action specification"); 140 throw runtime_error("invalid notify action specification");
139 string nschema = the_notify.substr(0,colon); 141 string nschema = the_notify.substr(0,colon);
140 string ntarget = the_notify.substr(colon+1); 142 string ntarget = the_notify.substr(colon+1);
141 if(nschema=="mailto") { 143 if(nschema=="mailto") {
142 notify_mailto(ntarget,id,event,description,config); 144 notify_mailto(ntarget,id,event,description,config);
143 }else 145 }else
144 throw runtime_error("unrecognized notification schema"); 146 throw runtime_error("unrecognized notification schema");
145 }catch(exception& e) { 147 }catch(exception& e) {
146 syslog(LOG_ERR,"Notification error: %s",e.what()); 148 syslog(LOG_ERR,"Notification error: %s",e.what());
147 } 149 }
148} 150}
149 151
150void process::notify_mailto(const string& email,const string& id,const string& event,const string& description,configuration& config) { 152void process::notify_mailto(const string& email,const string& id,const string& event,const string& description,configuration& config) {
151 int files[2]; 153 int files[2];
152 if(pipe(files)) 154 if(pipe(files))
153 throw runtime_error("Failed to pipe()"); 155 throw runtime_error("Failed to pipe()");
154 pid_t pid = vfork(); 156 pid_t pid = vfork();
155 if(pid==-1) { 157 if(pid==-1) {
156 close(files[0]); 158 close(files[0]);
157 close(files[1]); 159 close(files[1]);
158 throw runtime_error("Failed to vfork()"); 160 throw runtime_error("Failed to vfork()");
159 } 161 }
160 if(!pid) { 162 if(!pid) {
161 // child 163 // child
162 if(dup2(files[0],0)!=0) 164 if(dup2(files[0],0)!=0)
163 _exit(-1); 165 _exit(-1);
164 close(1); 166 close(1);
165 close(files[0]); 167 close(files[0]);
166 close(files[1]); 168 close(files[1]);
167 execl("/usr/sbin/sendmail","usr/sbin/sendmail","-i",email.c_str(),NULL); 169 execl("/usr/sbin/sendmail","usr/sbin/sendmail","-i",email.c_str(),NULL);