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 <stdlib.h>
00024 #include <stdarg.h>
00025
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029
00030 #include "monitor.h"
00031 #include "net.h"
00032 #include "alert.h"
00033
00034 #define DO_TIMEOUT 0
00035 #define DO_RESTART 1
00036 #define DO_CHECKSUM 2
00037 #define DO_RESOURCE 3
00038 #define DO_STOP 4
00039 #define DO_FAILED 5
00040 #define DO_TIMESTAMP 6
00041
00042
00043
00044 static int count(char *, char *);
00045 static void copy_mail(Mail_T, Mail_T);
00046 static void replace(char **, char *, char *);
00047 static void smtp_alert(Process_T, int, char *, va_list);
00048 static void substitute(Mail_T*, char *name, char *event);
00049
00050
00051 static char desc[][STRLEN]= {"timed out", "restarted", "checksum error",
00052 "matches resource limitation", "stopped",
00053 "failed", "timestamp error"};
00054
00055 static char desclog[][STRLEN]= {"Timeout", "Restart", "Checksum error",
00056 "Resource limit matched", "Stop",
00057 "Failed", "Timestamp error"};
00058
00059
00075
00076
00077
00084 void smtp_alert_timeout(Process_T p, char *m, ...) {
00085
00086 va_list ap;
00087
00088 ASSERT(p);
00089
00090 va_start(ap, m);
00091 smtp_alert(p, DO_TIMEOUT, m, ap);
00092 va_end(ap);
00093
00094
00095 }
00096
00097
00104 void smtp_alert_checksum(Process_T p, char *m, ...) {
00105
00106 va_list ap;
00107
00108 ASSERT(p);
00109
00110 va_start(ap, m);
00111 smtp_alert(p, DO_CHECKSUM, m, ap);
00112 va_end(ap);
00113
00114 }
00115
00116
00122 void smtp_alert_restart(Process_T p, char *m, ...) {
00123
00124 va_list ap;
00125
00126 ASSERT(p);
00127
00128 va_start(ap, m);
00129 smtp_alert(p, DO_RESTART, m, ap);
00130 va_end(ap);
00131
00132 }
00133
00134
00140 void smtp_alert_resource(Process_T p, char *m, ...) {
00141
00142 va_list ap;
00143
00144 ASSERT(p);
00145
00146 va_start(ap, m);
00147 smtp_alert(p, DO_RESOURCE, m, ap);
00148 va_end(ap);
00149
00150 }
00151
00152
00158 void smtp_alert_stop(Process_T p, char *m, ...) {
00159
00160 va_list ap;
00161
00162 ASSERT(p);
00163
00164 va_start(ap, m);
00165 smtp_alert(p, DO_STOP, m, ap);
00166 va_end(ap);
00167
00168 }
00169
00170
00176 void smtp_alert_failed(Process_T p, char *m, ...) {
00177
00178 va_list ap;
00179
00180 ASSERT(p);
00181
00182 va_start(ap, m);
00183 smtp_alert(p, DO_FAILED, m, ap);
00184 va_end(ap);
00185
00186 }
00187
00188
00194 void smtp_alert_timestamp(Process_T p, char *m, ...) {
00195
00196 va_list ap;
00197
00198 ASSERT(p);
00199
00200 va_start(ap, m);
00201 smtp_alert(p, DO_TIMESTAMP, m, ap);
00202 va_end(ap);
00203
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213 static void smtp_alert(Process_T p, int event, char *optmsg, va_list ap) {
00214
00215 ASSERT(p);
00216
00217 if(p->maillist) {
00218
00219 Mail_T m;
00220 sigset_t ns, os;
00221 Mail_T list= NULL;
00222
00223
00224 sigemptyset(&ns);
00225 sigaddset(&ns, SIGUSR1);
00226 pthread_sigmask(SIG_BLOCK, &ns, &os);
00227
00228
00229
00230
00231
00232 for(m= p->maillist; m; m= m->next) {
00233
00234 int notify[]= { m->alert_on_timeout,
00235 m->alert_on_restart,
00236 m->alert_on_checksum,
00237 m->alert_on_resource,
00238 m->alert_on_stop,
00239 m->alert_on_restart,
00240 m->alert_on_timestamp};
00241
00242 if ( notify[event] ) {
00243
00244 Mail_T tmp= NEW(tmp);
00245
00246 copy_mail(tmp, m);
00247
00248 if(optmsg)
00249 tmp->opt_message= format(optmsg, ap);
00250
00251 substitute(&tmp, p->name, desc[event]);
00252
00253 tmp->next= list;
00254 list= tmp;
00255
00256 if ( Run.debug )
00257 log("%s notification is sent to %s\n", desclog[event], m->to);
00258
00259 }
00260
00261 }
00262
00263 if(list) {
00264
00265 sendmail(list);
00266 gc_mail_list(&list);
00267
00268 }
00269
00270
00271 pthread_sigmask(SIG_SETMASK, &os, NULL);
00272
00273 }
00274
00275 }
00276
00277
00278 static void substitute(Mail_T *m, char *name, char *event) {
00279
00280 char *now= get_ctime();
00281 char *host= get_localhostname();
00282
00283 ASSERT(m && name && event);
00284
00285 replace(&(*m)->from, "$HOST", host);
00286 replace(&(*m)->subject, "$DATE", now);
00287 replace(&(*m)->message, "$DATE", now);
00288 replace(&(*m)->subject, "$HOST", host);
00289 replace(&(*m)->message, "$HOST", host);
00290 replace(&(*m)->subject, "$PROGRAM", name);
00291 replace(&(*m)->message, "$PROGRAM", name);
00292 replace(&(*m)->subject, "$EVENT", event);
00293 replace(&(*m)->message, "$EVENT", event);
00294
00295 free(now);
00296 free(host);
00297
00298 }
00299
00300
00301 static void replace(char **src, char *old, char *new) {
00302
00303 int i;
00304 int d;
00305
00306 ASSERT(src && old && new);
00307
00308 i= count(*src, old);
00309 d= strlen(new)-strlen(old);
00310
00311 if(i==0)
00312 return;
00313 if(d>0)
00314 d*= i;
00315 else
00316 d= 0;
00317
00318 {
00319 char *p, *q;
00320 int l= strlen(old);
00321 char buf[strlen(*src)+d+1];
00322
00323 q= *src;
00324 *buf= '\0';
00325
00326 while((p= strstr(q, old))) {
00327
00328 *p= '\0';
00329 strcat(buf, q);
00330 strcat(buf, new);
00331 p+= l;
00332 q= p;
00333
00334 }
00335
00336 strcat(buf, q);
00337 free(*src);
00338 *src= xstrdup(buf);
00339
00340 }
00341
00342 }
00343
00344
00345 static int count(char *src, char *needle) {
00346
00347 int i= 0;
00348 char *p= src;
00349
00350 ASSERT(src && needle);
00351
00352 while((p= strstr(p, needle))) { i++; p++; }
00353
00354 return i;
00355
00356 }
00357
00358
00359 static void copy_mail(Mail_T n, Mail_T o) {
00360
00361 ASSERT(n && o);
00362
00363 n->to= xstrdup(o->to);
00364 n->from=
00365 o->from?
00366 xstrdup(o->from):
00367 Run.MailFormat.from?
00368 xstrdup(Run.MailFormat.from):
00369 xstrdup(ALERT_FROM);
00370 n->subject=
00371 o->subject?
00372 xstrdup(o->subject):
00373 Run.MailFormat.subject?
00374 xstrdup(Run.MailFormat.subject):
00375 xstrdup(ALERT_SUBJECT);
00376 n->message=
00377 o->message?
00378 xstrdup(o->message):
00379 Run.MailFormat.message?
00380 xstrdup(Run.MailFormat.message):
00381 xstrdup(ALERT_MESSAGE);
00382 n->opt_message= NULL;
00383
00384 }
00385