alert.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2002 by Contributors to the monit codebase. 
00003  * All Rights Reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 
00040 
00041 /* Private Prototypes */
00042 static int count(char *, char *);
00043 static void copy_mail(Mail_T, Mail_T);
00044 static void replace(char **, char *, char *);
00045 static void smtp_alert(Process_T, int, char *, va_list);
00046 static void substitute(Mail_T*, char *name, char *event);
00047 
00048 /* Private Variables */
00049 static char desc[][STRLEN]= {"timed out", "restarted", "checksum error", 
00050                  "matches resource limitation", "stopped"};
00051 
00052 static char desclog[][STRLEN]= {"Timeout", "Restart", "Checksum error", 
00053                 "Resource limit matched", "Stop"};
00054 
00055 
00071 /* ------------------------------------------------------------------ Public */
00072 
00073 
00080 void smtp_alert_timeout(Process_T p, char *m, ...) {
00081 
00082   va_list ap;
00083   
00084   va_start(ap, m);
00085   smtp_alert(p, DO_TIMEOUT, m, ap);
00086   va_end(ap);
00087   
00088   
00089 }
00090 
00091 
00098 void smtp_alert_checksum(Process_T p, char *m, ...) {
00099 
00100   va_list ap;
00101   
00102   va_start(ap, m);
00103   smtp_alert(p, DO_CHECKSUM, m, ap);
00104   va_end(ap);
00105   
00106 }
00107 
00108 
00114 void smtp_alert_restart(Process_T p, char *m, ...) {
00115 
00116   va_list ap;
00117   
00118   va_start(ap, m);
00119   smtp_alert(p, DO_RESTART, m, ap);
00120   va_end(ap);
00121   
00122 }
00123 
00124 
00130 void smtp_alert_resource(Process_T p, char *m, ...) {
00131 
00132   va_list ap;
00133   
00134   va_start(ap, m);
00135   smtp_alert(p, DO_RESOURCE, m, ap);
00136   va_end(ap);
00137   
00138 }
00139 
00140 
00146 void smtp_alert_stop(Process_T p, char *m, ...) {
00147 
00148   va_list ap;
00149   
00150   va_start(ap, m);
00151   smtp_alert(p, DO_STOP, m, ap);
00152   va_end(ap);
00153   
00154 }
00155 
00156 
00157 /* ----------------------------------------------------------------- Private */
00158 
00159 
00160 /*
00161  * Send a smtp notification 
00162  */
00163 static void smtp_alert(Process_T p, int event, char *optmsg, va_list ap) {
00164 
00165   if(p->maillist) {
00166 
00167     Mail_T m;
00168     sigset_t ns, os;
00169     Mail_T list= NULL;
00170 
00171     /* Set a SIGUSR1 block here */
00172     sigemptyset(&ns);
00173     sigaddset(&ns, SIGUSR1);
00174     pthread_sigmask(SIG_BLOCK, &ns, &os);
00175     
00176     /*
00177      * Build a mail-list with recipients that has registered interest
00178      * for this event.
00179      */
00180     for(m= p->maillist; m; m= m->next) {
00181       
00182       int notify[]= { m->alert_on_timeout,
00183               m->alert_on_restart,
00184               m->alert_on_checksum,
00185               m->alert_on_resource,
00186               m->alert_on_stop};
00187       
00188       if ( notify[event] ) {
00189 
00190     Mail_T tmp= NEW(tmp);
00191     
00192     copy_mail(tmp, m);
00193 
00194     if(optmsg)
00195         tmp->opt_message= format(optmsg, ap);
00196     
00197     substitute(&tmp, p->name, desc[event]);
00198     
00199     tmp->next= list;
00200     list= tmp;
00201     
00202         if ( Run.debug )
00203         log("%s notification is sent to %s\n", desclog[event], m->to);
00204 
00205       }
00206 
00207     }
00208 
00209     if(list) {
00210       
00211       sendmail(list);
00212       gc_mail_list(&list);
00213       
00214     }
00215 
00216     /* Release the SIGUSR1 block */
00217     pthread_sigmask(SIG_SETMASK, &os, NULL);
00218 
00219   }
00220   
00221 }
00222 
00223 
00224 static void substitute(Mail_T *m, char *name, char *event) {
00225 
00226   char *now= get_ctime();
00227   char *host= get_localhostname();
00228 
00229   replace(&(*m)->from, "$HOST", host);
00230   replace(&(*m)->subject, "$DATE", now);
00231   replace(&(*m)->message, "$DATE", now);
00232   replace(&(*m)->subject, "$HOST", host);
00233   replace(&(*m)->message, "$HOST", host);
00234   replace(&(*m)->subject, "$PROGRAM", name);
00235   replace(&(*m)->message, "$PROGRAM", name);
00236   replace(&(*m)->subject, "$EVENT", event);
00237   replace(&(*m)->message, "$EVENT", event);
00238  
00239   free(now);
00240   free(host);
00241 
00242 }
00243 
00244 
00245 static void replace(char **src, char *old, char *new) {
00246 
00247   int i= count(*src, old);
00248   int d= strlen(new)-strlen(old);
00249 
00250   if(i==0)
00251       return;
00252   if(d>0)
00253       d*= i;
00254   else
00255       d= 0;
00256   
00257   {
00258     char *p, *q;
00259     int l= strlen(old);
00260     char buf[strlen(*src)+d+1];
00261 
00262     q= *src;
00263     *buf= '\0';
00264     
00265     while((p= strstr(q, old))) {
00266       
00267       *p= '\0';
00268       strcat(buf, q);
00269       strcat(buf, new);
00270       p+= l;
00271       q= p;
00272       
00273     }
00274     
00275     strcat(buf, q);
00276     free(*src);
00277     *src= xstrdup(buf);
00278 
00279   }
00280   
00281 }
00282 
00283 
00284 static int count(char *src, char *needle) {
00285 
00286   int i= 0;
00287   char *p= src;
00288 
00289   while((p= strstr(p, needle))) { i++;  p++; }
00290 
00291   return i;
00292 
00293 }
00294   
00295 
00296 static void copy_mail(Mail_T n, Mail_T o) {
00297 
00298   n->to= xstrdup(o->to);
00299   n->from=
00300       o->from?
00301       xstrdup(o->from):
00302       Run.MailFormat.from?
00303       xstrdup(Run.MailFormat.from):
00304       xstrdup(ALERT_FROM);
00305   n->subject=
00306       o->subject?
00307       xstrdup(o->subject):
00308       Run.MailFormat.subject?
00309       xstrdup(Run.MailFormat.subject):
00310       xstrdup(ALERT_SUBJECT);
00311   n->message=
00312       o->message?
00313       xstrdup(o->message):
00314       Run.MailFormat.message?
00315       xstrdup(Run.MailFormat.message):
00316       xstrdup(ALERT_MESSAGE);
00317   n->opt_message= NULL;
00318   
00319 }
00320