Icinga-core 1.4.0
next gen monitoring
contrib/daemonchk.c
Go to the documentation of this file.
00001 #include "config.h"
00002 #include "common.h"
00003 #include "locations.h"
00004 #include "cgiutils.h"
00005 #include "getcgi.h"
00006 #ifdef HAVE_GETOPT_H
00007 #include <getopt.h>
00008 #endif
00009 #include <stdarg.h>
00010 
00011 #define CHARLEN 256
00012 #define max(a,b) ((a)>(b))?(a):(b)
00013 
00014 static int process_cgivars(void);
00015 
00016 static char *strscpy(char *dest, const char *src);
00017 static char *ssprintf(char *str, const char *fmt, ...);
00018 static void terminate (int result, const char *fmt, ...);
00019 static void get_expire_time_string(time_t *raw_time,char *buffer,int buffer_length);
00020 
00021 int main (int argc, char **argv){
00022         FILE *fp;
00023         char *status_file=NULL;
00024         char *lock_file=NULL;
00025         char *proc_file=NULL;
00026         char input_buffer[CHARLEN];
00027         int c, age, pid, testpid, found;
00028         int wt=-1;
00029         int ct=-1;
00030         struct stat statbuf;
00031         time_t current_time;
00032 
00033 #ifdef DEFAULT_STATUS_FILE
00034         status_file=strscpy(status_file,DEFAULT_STATUS_FILE);
00035 #else
00036         status_file=strscpy(status_file,"/usr/local/icinga/var/status.dat");
00037 #endif
00038 
00039 #ifdef DEFAULT_LOCK_FILE
00040         lock_file=strscpy(lock_file,DEFAULT_LOCK_FILE);
00041 #else
00042         lock_file=strscpy(lock_file,"/usr/local/icinga/var/icinga.lock");
00043 #endif
00044 
00045         if(getenv("REQUEST_METHOD")){
00046                 process_cgivars();
00047         } else { /* get arguments */
00048 
00049                 while ((c=getopt(argc,argv,"+c:w:s:l:"))!=EOF){
00050                         switch (c){
00051                         case 'c':
00052                                 ct = atoi(optarg);
00053                                 break;
00054                         case 'w':
00055                                 wt = atoi(optarg);
00056                                 break;
00057                         case 's':
00058                                 status_file=optarg;
00059                                 break;
00060                         case 'l':
00061                                 lock_file=optarg;
00062                                 break;
00063                         }
00064                 }
00065         }
00066 
00067         /* find status file, get lastmod time */
00068         if(stat(status_file,&statbuf)==-1){
00069                 printf("ICINGA CRITICAL - could not find status log: %s\n",status_file);
00070                 exit(STATE_CRITICAL);
00071         }
00072 
00073         time(&current_time);
00074         age=(int)(current_time-statbuf.st_mtime);
00075 
00076         /* find lock file.  get pid if it exists */
00077         if(stat(lock_file, &statbuf)==-1){
00078                 printf("ICINGA CRITICAL - could not find lock file: %s\n",lock_file);
00079                 exit(STATE_CRITICAL);
00080         }
00081 
00082         fp=fopen(lock_file,"r");
00083         fscanf(fp,"%d",&pid);
00084         fclose(fp);
00085         proc_file=ssprintf(proc_file,"/proc/%d",pid);
00086 
00087         if (stat("/proc",&statbuf)==0) {
00088                 if (stat(proc_file,&statbuf)==-1) {
00089                         printf("ICINGA CRITICAL - could not find proc file: %s\n",proc_file);
00090                         exit(STATE_CRITICAL);
00091                 }
00092         } else if (snprintf(proc_file,CHARLEN-1,"/bin/ps -o pid -p %d",pid) && (fp=popen(proc_file,"r"))!=NULL) {
00093                 fgets(input_buffer,CHARLEN-1,fp);
00094                 fgets(input_buffer,CHARLEN-1,fp);
00095                 if (sscanf(input_buffer,"%d",&testpid)==1) {
00096                         if (testpid!=pid) {
00097                                 printf("ICINGA CRITICAL - could not find process(1): %d\n",pid);
00098                                 exit(STATE_CRITICAL);
00099                         }
00100                 }
00101         } else if (snprintf(proc_file,CHARLEN-1,"/bin/ps -eo pid") && (fp=popen(proc_file,"r"))!=NULL) {
00102                 found=FALSE;
00103                 fgets(input_buffer,CHARLEN-1,fp);
00104                 while(fgets(input_buffer,CHARLEN-1,fp)) {
00105                         if (sscanf(input_buffer,"%d",&testpid)==1)
00106                                 if (testpid==pid) found=TRUE;
00107                 }
00108                 if (!found) {
00109                         printf("ICINGA CRITICAL - could not find process(2): %d\n",pid);
00110                         exit(STATE_CRITICAL);
00111                 }
00112         } else if (snprintf(proc_file,CHARLEN-1,"/bin/ps -Ao pid") && (fp=popen(proc_file,"r"))!=NULL) {
00113                 found=FALSE;
00114                 fgets(input_buffer,CHARLEN-1,fp);
00115                 while(fgets(input_buffer,CHARLEN-1,fp)) {
00116                         if (sscanf(input_buffer,"%d",&testpid)==1)
00117                                 if (testpid==pid) found=TRUE;
00118                 }
00119                 if (!found) {
00120                         printf("ICINGA CRITICAL - could not find process(2): %d\n",pid);
00121                         exit(STATE_CRITICAL);
00122                 }
00123         }
00124 
00125         if(ct>0&&ct<age){
00126                 printf("ICINGA CRITICAL - status written %d seconds ago\n",age);
00127                 exit(STATE_CRITICAL);
00128         } else if(wt>0&&wt<age){
00129                 printf("ICINGA WARNING - status written %d seconds ago\n",age);
00130                 exit(STATE_WARNING);
00131         } else {
00132                 printf("ICINGA OK - status written %d seconds ago\n",age);
00133                 exit(STATE_OK);
00134         }
00135 }
00136 
00137 static int process_cgivars(void){
00138         char **variables;
00139         int error=FALSE;
00140         int x;
00141 
00142         variables=getcgivars();
00143 
00144         for(x=0;variables[x]!=NULL;x++){
00145 
00146                 /* do some basic length checking on the variable identifier to prevent buffer overflows */
00147                 if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){
00148                         x++;
00149                         continue;
00150                 }
00151         }
00152         return error;
00153 }
00154 
00155 /* get date/time string used in META tags for page expiration */
00156 static void get_expire_time_string(time_t *raw_time,char *buffer,int buffer_length){
00157         time_t t;
00158         struct tm *tm_ptr;
00159         int day;
00160         int hour;
00161         int minute;
00162         int second;
00163         int year;
00164         char *weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
00165         char *months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"};
00166 
00167         if(raw_time==NULL)
00168                 time(&t);
00169         else
00170                 t=*raw_time;
00171 
00172         tm_ptr=gmtime(&t);
00173 
00174         hour=tm_ptr->tm_hour;
00175         minute=tm_ptr->tm_min;
00176         second=tm_ptr->tm_sec;
00177         day=tm_ptr->tm_mday;
00178         year=tm_ptr->tm_year+1900;
00179 
00180         snprintf(buffer,buffer_length,"%s, %d %s %d %02d:%02d:%02d GMT",weekdays[tm_ptr->tm_wday],day,months[tm_ptr->tm_mon],year,hour,minute,second);
00181         buffer[buffer_length-1]='\x0';
00182 
00183         return;
00184 }
00185 
00186 static char *strscpy(char *dest, const char *src){
00187         int len;
00188 
00189         if(src!=NULL)
00190                 len=strlen(src)+1;
00191         else
00192                 return dest;
00193 
00194         if (dest==NULL || strlen(dest)<len)
00195                 dest=realloc(dest,len);
00196         if (dest==NULL)
00197                 terminate(STATE_UNKNOWN,"failed realloc in strscpy\n");
00198 
00199         strncpy(dest,src,len);
00200 
00201         return dest;
00202 }
00203 
00204 static char *ssprintf(char *str, const char *fmt, ...){
00205         va_list ap;
00206         int nchars;
00207         int size;
00208 
00209         if (str==NULL)
00210                 str=malloc(CHARLEN);
00211         if (str==NULL)
00212                 terminate(STATE_UNKNOWN,"malloc failed in ssprintf");
00213 
00214         size=max(strlen(str),CHARLEN);
00215 
00216         va_start(ap,fmt);
00217 
00218         while (1) {
00219 
00220                 nchars = vsnprintf(str,size,fmt,ap);
00221 
00222                 if (nchars > -1)
00223                         if (nchars < size) {
00224                                 va_end(ap);
00225                                 return str;
00226                         } else {
00227                                 size = nchars + 1;
00228                         }
00229 
00230                 else
00231                         size *= 2;
00232 
00233                 str = realloc(str,nchars+1);
00234 
00235                 if (str==NULL)
00236                         terminate(STATE_UNKNOWN,"realloc failed in ssprintf");
00237         }
00238 
00239 }
00240 
00241 static void terminate (int result, const char *fmt, ...){
00242         va_list ap;
00243         va_start(ap,fmt);
00244         vprintf(fmt,ap);
00245         va_end(ap);
00246         exit(result);
00247 }
 All Data Structures Files Functions Variables Typedefs Defines