status.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2003 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 
00025 #ifdef HAVE_SYS_TYPES_H
00026 #include <sys/types.h>
00027 #endif
00028 
00029 #include <sys/socket.h>
00030 
00031 #ifdef HAVE_STRING_H
00032 #include <string.h>
00033 #endif
00034 
00035 #ifdef HAVE_STRINGS_H
00036 #include <strings.h>
00037 #endif
00038 
00039 #ifdef HAVE_UNISTD_H
00040 #include <unistd.h>
00041 #endif
00042 
00043 #include "net.h"
00044 #include "monitor.h"
00045 #include "monit_process.h"
00046 #include "ssl.h"
00047 
00048 
00049 /* Private Prototypes */
00050 static void local_status(Process_T);
00051 static int remote_status(Process_T, ssl_connection *);
00052 
00064 /* ------------------------------------------------------------------ Public */
00065 
00066 
00070 void status() {
00071 
00072   Process_T p;
00073   char *uptime= get_process_uptime(Run.pidfile);
00074   int remote= TRUE;
00075   ssl_connection * ssl= NULL;
00076 
00077   if(Run.httpdssl) {
00078 
00079     ssl = new_ssl_connection(Run.httpsslpem, SSL_VERSION_AUTO);
00080 
00081   }
00082 
00083   fprintf(stdout, "monit daemon uptime: %s\n", uptime);
00084   free(uptime);
00085   
00086   for(p= processlist; p; p= p->next) {
00087 
00088       if(remote) {
00089 
00090     remote = remote_status(p, ssl);
00091 
00092       } else {
00093 
00094     local_status(p);
00095 
00096       }
00097     
00098   }
00099 
00100   if(Run.httpdssl) {
00101 
00102     delete_ssl_socket(ssl);
00103 
00104   }
00105   
00106 }
00107 
00112 void status_group(char *G) {
00113 
00114   Process_T p;
00115   int remote= TRUE;
00116   ssl_connection * ssl= NULL;
00117 
00118   ASSERT(G);
00119   
00120   if(Run.httpdssl) {
00121 
00122     ssl = new_ssl_connection(Run.httpsslclientpem, SSL_VERSION_AUTO);
00123 
00124   }
00125 
00126   for(p= processlist; p; p= p->next) {
00127 
00128     if(is(p->group, G)) {
00129 
00130       if(remote) {
00131 
00132     remote = remote_status(p, ssl);
00133 
00134       } else {
00135 
00136     local_status(p);
00137 
00138       }
00139 
00140     }
00141    
00142   }
00143 
00144   if(Run.httpdssl) {
00145 
00146     delete_ssl_socket(ssl);
00147 
00148   }
00149 }
00150 
00151 /* ----------------------------------------------------------------- Private */
00152 
00153 
00158 static void local_status(Process_T p) {
00159   
00160   pid_t  pid= -1;
00161 
00162   ASSERT(p);
00163   
00164   if((pid= is_process_running(p))) {
00165 
00166     char *uptime= get_process_uptime(p->pidfile);
00167 
00168     fprintf(stdout, "Process '%s' is running with pid [%d] Uptime: %s "
00169             "Monitoring status: %s\n",
00170             p->name, (int)pid, uptime, statusnames[p->do_validate]);
00171     
00172     free(uptime);
00173  
00174   } else {
00175     
00176     fprintf(stdout, "Process '%s' is not running\n",  p->name);
00177     
00178   }
00179   
00180 }
00181 
00182 
00188 static int remote_status(Process_T p, ssl_connection * ssl) {
00189 
00190   ASSERT(p);
00191   
00192   if(exist_daemon()) {
00193     
00194     /* If a monit daemon exist we request status information from the server */
00195     
00196     int s= create_socket(Run.bind_addr?Run.bind_addr:"localhost",
00197              Run.httpdport, SOCK_STREAM);
00198     if(s<0) {
00199 
00200       fprintf(stdout,
00201           "Cannot connect to monit server to get"
00202           " extended process data.\n");
00203       local_status(p);
00204 
00205       return FALSE;
00206             
00207     } else {
00208 
00209       int n;
00210       char req[2*STRLEN];
00211       char *auth= get_basic_authentication_header();
00212       char buf[STRLEN];
00213 
00214       snprintf(req, 2*STRLEN,
00215            "GET /%s?action=status HTTP/1.0\r\n%s\r\n", p->name, auth);
00216       
00217       free(auth);
00218 
00219       if(ssl != NULL) {
00220 
00221     if(!embed_ssl_socket(ssl, s)) {
00222 
00223       fprintf(stdout, "Failed to establish SSL communication to monit"
00224           " server\n");
00225       local_status(p);
00226       
00227       return FALSE;
00228     }
00229 
00230     send_ssl_socket(ssl, req, sizeof(req));
00231     if(0>(n= recv_ssl_socket(ssl, buf, STRLEN))) {
00232       
00233       local_status(p);
00234       close_ssl_socket(ssl);
00235       close_socket(s);
00236       
00237       return TRUE;
00238     
00239     }
00240 
00241     close_ssl_socket(ssl);
00242     close_socket(s);
00243 
00244       } else {
00245 
00246     sock_send(s, req, sizeof(req), 0);
00247       
00248     if(0>(n= sock_recv(s, buf, STRLEN, 0))) {
00249       
00250       local_status(p);
00251       close_socket(s);
00252       
00253       return TRUE;
00254     
00255     }
00256     
00257     close_socket(s);
00258       }
00259       
00260 
00261       /* If everything has gone well the returned string starts with
00262      "Process " */
00263 
00264       buf[n]= 0;
00265       if(starts_with(buf, "Process ")) {
00266 
00267     fprintf(stdout, "%s", buf);
00268     
00269       } else {
00270 
00271     fprintf(stdout, "The monit server did not return a process record.\n");
00272     local_status(p);
00273     
00274     return TRUE;
00275 
00276       }
00277 
00278       return TRUE;
00279     }
00280     
00281   } else {
00282     
00283     /* No monit daemon exist, just print local status information */
00284     
00285     fprintf(stdout, "Cannot connect to the monit server to get extended "
00286         "process data.\n");
00287     local_status(p);
00288     
00289     return FALSE;
00290   }
00291 
00292 }