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