00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <signal.h>
00024 #include <errno.h>
00025 #include <stdlib.h>
00026
00027 #ifdef HAVE_STRING_H
00028 #include <string.h>
00029 #endif
00030
00031 #ifdef HAVE_STRINGS_H
00032 #include <strings.h>
00033 #endif
00034
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038
00039 #ifdef HAVE_SYS_WAIT_H
00040 #include <sys/wait.h>
00041 #endif
00042
00043 #ifdef HAVE_SYS_TYPES_H
00044 #include <sys/types.h>
00045 #endif
00046
00047 #ifdef HAVE_SYS_STAT_H
00048 #include <sys/stat.h>
00049 #endif
00050
00051 #include "alert.h"
00052 #include "monitor.h"
00053 #include "engine.h"
00054
00055
00056 static void do_free();
00057 static Command_T copy_command(Command_T);
00058 static Mail_T create_exec_alert_list(Process_T, Command_T);
00059
00060
00074
00075
00076
00084 void spawn(Process_T P, Command_T C) {
00085
00086 pid_t pid;
00087 sigset_t mask, save;
00088
00089
00090
00091
00092 sigemptyset(&mask);
00093 sigaddset(&mask, SIGCHLD);
00094 pthread_sigmask(SIG_BLOCK, &mask, &save);
00095
00096 if ((pid= fork ()) < 0) {
00097
00098 log("Cannot fork of a new process\n");
00099 exit (1);
00100
00101 } else if ( pid == 0 ) {
00102
00103 if ( (pid= fork()) < 0 ) {
00104
00105 log("Cannot fork of a new process\n");
00106 exit (1);
00107
00108 }
00109
00110 else if ( pid > 0 ) {
00111
00112 _exit(0);
00113
00114 } else {
00115
00116 Command_T c= copy_command(C);
00117 Mail_T alert_list= create_exec_alert_list(P, C);
00118
00119
00120
00121
00122
00123 sigemptyset(&mask);
00124 pthread_sigmask(SIG_SETMASK, &mask, NULL);
00125
00126
00127 signal(SIGTERM, SIG_DFL);
00128 signal(SIGUSR1, SIG_DFL);
00129 signal(SIGPIPE, SIG_DFL);
00130
00131
00132 do_free();
00133
00134
00135
00136
00137
00138 umask(Run.umask);
00139
00140
00141
00142
00143 (void) execv(c->arg[0], c->arg);
00144 sendmail(alert_list);
00145 log("Could not execute %s\n", c->arg[0]);
00146 gc_mail_list(&alert_list);
00147 _exit (1);
00148
00149 }
00150 }
00151
00152
00153 if ( waitpid(pid, NULL, 0) != pid ) {
00154
00155 log("Waitpid error\n");
00156
00157 }
00158
00159
00160
00161
00162 pthread_sigmask(SIG_SETMASK, &save, NULL);
00163
00164
00165
00166
00167
00168 return ;
00169
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179 static void do_free() {
00180
00181 gc();
00182 destroy_hosts_allow();
00183 free(Run.controlfile);
00184 free(Run.pidfile);
00185 free(Run.logfile);
00186 free(Run.localhostname);
00187 free(Run.Env.user);
00188 free(Run.Env.home);
00189 free(Run.Env.cwd);
00190 free(Run.Auth.uname);
00191 free(Run.Auth.passwd);
00192 free(Run.MailFormat.from);
00193 free(Run.MailFormat.subject);
00194 free(Run.MailFormat.message);
00195 free(Run.bind_addr);
00196
00197
00198 }
00199
00200
00201
00202
00203
00204 static Command_T copy_command(Command_T C) {
00205
00206 int i;
00207 Command_T P= NEW(P);
00208
00209 for(i= 0; C->arg[i]; i++)
00210 P->arg[i]= xstrdup(C->arg[i]);
00211 P->arg[i]= NULL;
00212
00213 return P;
00214
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 static Mail_T create_exec_alert_list(Process_T p, Command_T c) {
00224
00225 Mail_T l= NULL;
00226 Mail_T h= p->maillist;
00227
00228 for(; h; h= h->next)
00229 if(h->alert_on_restart) {
00230
00231 Mail_T n= NEW(n);
00232 char *message= xmalloc(STRLEN);
00233
00234 n->to= xstrdup(h->to);
00235 n->from= xstrdup("monit@localhost");
00236 n->subject= xstrdup("monit alert -- exec error");
00237 snprintf(message, STRLEN,
00238 "NOTE, THIS EMAIL TAKES PRECEDENCE OVER SUBSEQUENT RESTART ALERTS\n\n"
00239 "Could not execute program '%s' for process %s\n\n"
00240 "Your faithful employee,\nmonit",
00241 c->arg[0]?c->arg[0]:"null", p->name);
00242 n->message= message;
00243 n->next= l;
00244 l= n;
00245
00246 }
00247
00248 return l;
00249
00250 }