1 #include "config.h"
2 #include "common.h"
3 #include "locations.h"
4 #include "cgiutils.h"
5 #include "getcgi.h"
6 #ifdef HAVE_GETOPT_H
7 #include <getopt.h>
8 #endif
9 #include <stdarg.h>
10
11 #define CHARLEN 256
12 #define max(a,b) ((a)>(b))?(a):(b)
13
14 static void document_header(void);
15 //static void document_footer(void);
16 static int process_cgivars(void);
17
18 static char *strscpy(char *dest, const char *src);
19 static char *ssprintf(char *str, const char *fmt, ...);
20 static void terminate(int result, const char *fmt, ...);
21 static void get_expire_time_string(time_t *raw_time, char *buffer, int buffer_length);
22
main(int argc,char ** argv)23 int main(int argc, char **argv) {
24 FILE *fp;
25 char *status_file = NULL;
26 char *lock_file = NULL;
27 char *proc_file = NULL;
28 char input_buffer[CHARLEN];
29 int c, age, pid, testpid, found;
30 int wt = -1;
31 int ct = -1;
32 struct stat statbuf;
33 time_t current_time;
34
35 #ifdef DEFAULT_STATUS_FILE
36 status_file = strscpy(status_file, DEFAULT_STATUS_FILE);
37 #else
38 status_file = strscpy(status_file, "/var/log/nagios/status.log");
39 #endif
40
41 #ifdef DEFAULT_LOCK_FILE
42 lock_file = strscpy(lock_file, DEFAULT_LOCK_FILE);
43 #else
44 lock_file = strscpy(lock_file, "/tmp/nagios.lock");
45 #endif
46
47 if(getenv("REQUEST_METHOD")) {
48 process_cgivars();
49 document_header();
50 }
51 else { /* get arguments */
52 while((c = getopt(argc, argv, "+c:w:s:l:")) != EOF) {
53 switch(c) {
54 case 'c':
55 ct = atoi(optarg);
56 break;
57 case 'w':
58 wt = atoi(optarg);
59 break;
60 case 's':
61 status_file = optarg;
62 break;
63 case 'l':
64 lock_file = optarg;
65 break;
66 }
67 }
68 }
69
70 /* find status file, get lastmod time */
71 if(stat(status_file, &statbuf) == -1) {
72 printf("NAGIOS CRITICAL - could not find status log: %s\n", status_file);
73 exit(STATE_CRITICAL);
74 }
75 time(¤t_time);
76 age = (int)(current_time - statbuf.st_mtime);
77
78 /* find lock file. get pid if it exists */
79 if(stat(lock_file, &statbuf) == -1) {
80 printf("NAGIOS CRITICAL - could not find lock file: %s\n", lock_file);
81 exit(STATE_CRITICAL);
82 }
83 fp = fopen(lock_file, "r");
84 fscanf(fp, "%d", &pid);
85 fclose(fp);
86 proc_file = ssprintf(proc_file, "/proc/%d", pid);
87
88 if(stat("/proc", &statbuf) == 0) {
89 if(stat(proc_file, &statbuf) == -1) {
90 printf("NAGIOS CRITICAL - could not find proc file: %s\n", proc_file);
91 exit(STATE_CRITICAL);
92 }
93 }
94 else if(snprintf(proc_file, CHARLEN - 1, "/bin/ps -o pid -p %d", pid) &&
95 (fp = popen(proc_file, "r")) != NULL) {
96 fgets(input_buffer, CHARLEN - 1, fp);
97 fgets(input_buffer, CHARLEN - 1, fp);
98 if(sscanf(input_buffer, "%d", &testpid) == 1) {
99 if(testpid != pid) {
100 printf("NAGIOS CRITICAL - could not find process(1): %d\n", pid);
101 exit(STATE_CRITICAL);
102 }
103 }
104 }
105 else if(snprintf(proc_file, CHARLEN - 1, "/bin/ps -eo pid") &&
106 (fp = popen(proc_file, "r")) != NULL) {
107 found = FALSE;
108 fgets(input_buffer, CHARLEN - 1, fp);
109 while(fgets(input_buffer, CHARLEN - 1, fp)) {
110 if(sscanf(input_buffer, "%d", &testpid) == 1)
111 if(testpid == pid) found = TRUE;
112 }
113 if(!found) {
114 printf("NAGIOS CRITICAL - could not find process(2): %d\n", pid);
115 exit(STATE_CRITICAL);
116 }
117 }
118 else if(snprintf(proc_file, CHARLEN - 1, "/bin/ps -Ao pid") &&
119 (fp = popen(proc_file, "r")) != NULL) {
120 found = FALSE;
121 fgets(input_buffer, CHARLEN - 1, fp);
122 while(fgets(input_buffer, CHARLEN - 1, fp)) {
123 if(sscanf(input_buffer, "%d", &testpid) == 1)
124 if(testpid == pid) found = TRUE;
125 }
126 if(!found) {
127 printf("NAGIOS CRITICAL - could not find process(2): %d\n", pid);
128 exit(STATE_CRITICAL);
129 }
130 }
131
132 if(ct > 0 && ct < age) {
133 printf("NAGIOS CRITICAL - status written %d seconds ago\n", age);
134 exit(STATE_CRITICAL);
135 }
136 else if(wt > 0 && wt < age) {
137 printf("NAGIOS WARNING - status written %d seconds ago\n", age);
138 exit(STATE_WARNING);
139 }
140 else {
141 printf("NAGIOS ok - status written %d seconds ago\n", age);
142 exit(STATE_OK);
143 }
144
145 }
146
document_header(void)147 static void document_header(void) {
148 char date_time[48];
149 time_t current_time;
150
151 printf("Cache-Control: no-store\nPragma: no-cache\n");
152
153 time(¤t_time);
154 get_expire_time_string(¤t_time, date_time, (int)sizeof(date_time));
155 printf("Last-Modified: %s\n", date_time);
156 printf("Expires: %s\n", date_time);
157
158 printf("Content-type: text/html\n\n");
159
160 printf("<html>\n<head>\n<title>Nagios Daemon Status</title>\n</head>\n");
161 printf("<body onunload=\"if (window.wnd && wnd.close) wnd.close(); return true;\">\n");
162
163 return;
164 }
165
process_cgivars(void)166 static int process_cgivars(void) {
167 char **variables;
168 int error = FALSE;
169 int x;
170
171 variables = getcgivars();
172
173 for(x = 0; variables[x] != NULL; x++) {
174
175 /* do some basic length checking on the variable identifier to prevent buffer overflows */
176 if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
177 continue;
178 }
179 }
180 return error;
181 }
182
183 /* get date/time string used in META tags for page expiration */
get_expire_time_string(time_t * raw_time,char * buffer,int buffer_length)184 static void get_expire_time_string(time_t *raw_time, char *buffer, int buffer_length) {
185 time_t t;
186 struct tm *tm_ptr;
187 int day;
188 int hour;
189 int minute;
190 int second;
191 int year;
192 char *weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
193 char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
194
195 if(raw_time == NULL)
196 time(&t);
197 else
198 t = *raw_time;
199
200 tm_ptr = gmtime(&t);
201
202 hour = tm_ptr->tm_hour;
203 minute = tm_ptr->tm_min;
204 second = tm_ptr->tm_sec;
205 day = tm_ptr->tm_mday;
206 year = tm_ptr->tm_year + 1900;
207
208 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);
209 buffer[buffer_length - 1] = '\x0';
210
211 return;
212 }
213
strscpy(char * dest,const char * src)214 static char *strscpy(char *dest, const char *src) {
215 int len;
216
217 if(src != NULL)
218 len = strlen(src) + 1;
219 else
220 return dest;
221
222 if(dest == NULL || strlen(dest) < len)
223 dest = realloc(dest, len);
224 if(dest == NULL)
225 terminate(STATE_UNKNOWN, "failed realloc in strscpy\n");
226
227 strncpy(dest, src, len);
228
229 return dest;
230 }
231
ssprintf(char * str,const char * fmt,...)232 static char *ssprintf(char *str, const char *fmt, ...) {
233 va_list ap;
234 int nchars;
235 int size;
236
237 if(str == NULL)
238 str = malloc(CHARLEN);
239 if(str == NULL)
240 terminate(STATE_UNKNOWN, "malloc failed in ssprintf");
241
242 size = max(strlen(str), CHARLEN);
243
244 va_start(ap, fmt);
245
246 while(1) {
247
248 nchars = vsnprintf(str, size, fmt, ap);
249
250 if(nchars > -1)
251 if(nchars < size) {
252 va_end(ap);
253 return str;
254 }
255 else {
256 size = nchars + 1;
257 }
258
259 else
260 size *= 2;
261
262 str = realloc(str, nchars + 1);
263
264 if(str == NULL)
265 terminate(STATE_UNKNOWN, "realloc failed in ssprintf");
266 }
267
268 }
269
terminate(int result,const char * fmt,...)270 static void terminate(int result, const char *fmt, ...) {
271 va_list ap;
272 va_start(ap, fmt);
273 vprintf(fmt, ap);
274 va_end(ap);
275 exit(result);
276 }
277