00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <errno.h>
00025 #include <signal.h>
00026
00027 #ifdef HAVE_GETOPT_H
00028 #include <getopt.h>
00029 #endif
00030
00031 #ifdef HAVE_STRING_H
00032 #include <string.h>
00033 #endif
00034
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038
00039 #ifdef HAVE_SYS_TYPES_H
00040 #include <sys/types.h>
00041 #endif
00042
00043 #ifdef HAVE_SYS_STAT_H
00044 #include <sys/stat.h>
00045 #endif
00046
00047
00048 #include "monitor.h"
00049 #include "net.h"
00050 #include "monit_process.h"
00051
00067
00068 static void do_init();
00069 static void do_reinit();
00070 static void do_action(char **);
00071 static RETSIGTYPE do_destroy(int);
00072 static void do_default();
00073 static RETSIGTYPE do_wakeup(int);
00074 static int do_wakeupcall();
00075 static void do_wait();
00076 static void handle_options(int, char **);
00077 static void help();
00078 static void version();
00079 static void stop_http();
00080 static void start_http();
00081
00082
00086 int main(int argc, char **argv) {
00087
00088 prog= stripfilename(argv[0]);
00089 init_env();
00090 handle_options(argc, argv);
00091
00092 do_init();
00093 do_action(argv);
00094 do_destroy(SIGSTOP);
00095
00096 exit(0);
00097
00098 }
00099
00100
00101
00102
00103
00109 static void do_init() {
00110
00111 int status;
00112
00113
00114
00115
00116
00117
00118 signal(SIGTERM, do_destroy);
00119
00120
00121
00122
00123
00124
00125 signal(SIGUSR1, do_wakeup);
00126
00127
00128
00129
00130 signal(SIGPIPE, SIG_IGN);
00131
00132
00133
00134
00135
00136
00137 status= pthread_mutex_init(&Run.mutex, NULL);
00138 if ( status != 0 ) {
00139
00140 error("%s: Cannot initialize mutex -- %s\n", prog, strerror(status));
00141 exit(1);
00142
00143 }
00144
00145
00146 if ( ! Run.controlfile ) {
00147
00148 Run.controlfile= find_rcfile();
00149
00150 }
00151
00152
00153 Run.doprocess= init_process_info();
00154
00155
00156
00157
00158
00159 if ( ! parse(Run.controlfile) ) {
00160
00161 exit(1);
00162
00163 }
00164
00165
00166 if ( ! log_init() ) {
00167
00168 exit(1);
00169
00170 }
00171
00172
00173 if ( ! processlist ) {
00174
00175 error("%s: No programs have been specified\n", prog);
00176 exit(0);
00177
00178 }
00179
00180
00181 init_files();
00182
00183
00184 if ( Run.debug && have_tty ) {
00185
00186 printrunlist();
00187 printprocesslist();
00188
00189 }
00190
00191 }
00192
00193
00199 static void do_reinit() {
00200
00201 log("Reinitializing %s - Control file '%s' was changed\n",
00202 prog, Run.controlfile);
00203
00204
00205 gc();
00206
00207 if ( ! parse(Run.controlfile) ) {
00208
00209 log("%s daemon died\n", prog);
00210 exit(1);
00211
00212 }
00213
00214
00215 log_close();
00216
00217
00218 if ( ! log_init() ) {
00219
00220 exit(1);
00221
00222 }
00223
00224
00225 if ( ! processlist ) {
00226
00227 error("%s: No programs have been specified\n", prog);
00228 exit(0);
00229
00230 }
00231
00232
00233 re_init_files();
00234
00235 }
00236
00237
00241 static void do_action(char **args) {
00242
00243 char *action= args[optind];
00244 char *P= args[++optind];
00245
00246 if( ! action ) {
00247
00248 do_default();
00249
00250 }
00251 else if( is(action, "start") ) {
00252
00253 if ( P ) dstart_process(P); else
00254 if ( mygroup ) start_group(mygroup); else start();
00255
00256 }
00257 else if( is(action, "stop") ) {
00258
00259 if ( P ) dstop_process(P); else
00260 if ( mygroup ) stop_group(mygroup); else stop();
00261
00262 }
00263 else if( is(action, "restart") ) {
00264
00265 if ( P ) {
00266
00267 if ( ! exist_process(P) ) {
00268
00269 error("%s: Cannot restart program '%s' -- not found in %s\n",
00270 prog, P, Run.controlfile);
00271
00272 return;
00273
00274 }
00275
00276 dstop_process(P);
00277
00278 } else
00279 if ( mygroup ) stop_group(mygroup); else stop();
00280
00281 do_wait();
00282
00283 if ( P ) dstart_process(P); else
00284 if ( mygroup ) start_group(mygroup); else start();
00285
00286 }
00287 else if( is(action, "status") ) {
00288
00289 if ( mygroup ) status_group(mygroup); else status();
00290
00291 }
00292 else if( is(action, "quit") ) {
00293
00294 log("Stopping monit daemon\n", prog);
00295 kill_daemon();
00296
00297 }
00298 else if( is(action, "validate") ) {
00299
00300 validate();
00301
00302 }
00303 else {
00304
00305 error("%s: invalid argument -- %s (-h will show valid arguments)\n",
00306 prog, action);
00307 exit(1);
00308
00309 }
00310
00311 }
00312
00313
00317 static RETSIGTYPE do_wakeup(int sig) {
00318
00319 signal(SIGUSR1, SIG_IGN);
00320 log("Awakened by User defined signal 1\n");
00321 signal(SIGUSR1, do_wakeup);
00322
00323 }
00324
00325
00330 static int do_wakeupcall() {
00331
00332 pid_t pid;
00333
00334 if ( (pid= exist_daemon()) > 0 ) {
00335
00336 kill(pid, SIGUSR1);
00337 error("%s daemon at %d awakened\n", prog, pid);
00338
00339 return TRUE;
00340
00341 }
00342
00343 return FALSE;
00344
00345 }
00346
00347
00351 static RETSIGTYPE do_destroy(int sig) {
00352
00353 switch ( sig ) {
00354
00355 case SIGTERM:
00356
00357 stop_http();
00358
00359 if ( Run.isdaemon ) {
00360
00361 log("%s daemon with pid [%d] killed\n", prog, (int)getpid());
00362
00363 }
00364
00365 finalize_files();
00366
00367
00368 default:
00369
00370 gc();
00371 log_close();
00372 exit(0);
00373
00374 }
00375
00376 }
00377
00378
00384 static void do_default() {
00385
00386 if ( Run.isdaemon ) {
00387
00388 if ( do_wakeupcall() ) {
00389
00390 exit(0);
00391
00392 }
00393
00394 log("Starting %s daemon\n", prog);
00395 if(!Run.debug) printf("Starting %s daemon\n", prog);
00396
00397 if ( can_http() ) {
00398
00399 printf("Starting httpd at port [%d]\n", Run.httpdport);
00400
00401 }
00402
00403 have_tty= FALSE;
00404
00405 if (Run.Init != TRUE)
00406 daemonize();
00407
00408 if ( !create_pidfile(Run.pidfile) ) {
00409
00410 log("%s daemon died\n", prog);
00411 exit(1);
00412
00413 }
00414
00415 if ( can_http() ) {
00416
00417 start_http();
00418
00419 }
00420
00421 for (;;) {
00422
00423 if (Run.validate != TRUE)
00424 {
00425 validate();
00426 } else {
00427 Run.validate= FALSE;
00428 }
00429
00430 sleep(Run.polltime);
00431
00432 if ( is_rcfile_changed() ) {
00433
00434 int port= Run.httpdport;
00435
00436 do_reinit();
00437
00438 if ( ! can_http() ) {
00439
00440 stop_http();
00441
00442 } else if ( port != Run.httpdport ) {
00443
00444 stop_http();
00445 start_http();
00446
00447 } else if ( ! check_httpd() ) {
00448
00449 start_http();
00450
00451 }
00452
00453 }
00454
00455 }
00456
00457 }
00458 else {
00459
00460 validate();
00461
00462 }
00463
00464 }
00465
00466
00471 static void handle_options(int argc, char **argv) {
00472
00473 char opt;
00474 opterr= 0;
00475
00476 mygroup=0;
00477
00478 while((opt= getopt(argc,argv,"c:l:d:g:iIvVh")) != -1) {
00479
00480 switch(opt) {
00481
00482 case 'i':
00483 Run.validate= TRUE;
00484 break;
00485
00486 case 'I':
00487 Run.Init= TRUE;
00488 break;
00489
00490 case 'c':
00491 Run.controlfile= xstrdup(optarg);
00492 break;
00493
00494 case 'l':
00495 Run.logfile= xstrdup(optarg);
00496 if ( is(Run.logfile, "syslog") )
00497 Run.use_syslog= TRUE;
00498 Run.dolog= TRUE;
00499 break;
00500
00501 case 'g':
00502 mygroup= xstrdup(optarg);
00503 break;
00504
00505 case 'd':
00506 Run.isdaemon= TRUE;
00507 sscanf(optarg, "%d", &Run.polltime);
00508 if (Run.polltime<1) {
00509 error("%s: option -%c requires a natural number\n", prog, opt);
00510 exit(1);
00511 }
00512 break;
00513
00514 case 'v':
00515 Run.debug= TRUE;
00516 break;
00517
00518 case 'V':
00519 version();
00520 exit(0);
00521 break;
00522
00523 case 'h':
00524 help();
00525 exit(0);
00526 break;
00527
00528 case '?':
00529 switch ( optopt ) {
00530
00531 case 'c':
00532 case 'g':
00533 case 'l':
00534 case 'd':
00535 error("%s: option -- %c requires an argument\n", prog, optopt);
00536 break;
00537 default:
00538 error("%s: invalid option -- %c (-h will show valid options)\n",
00539 prog, optopt);
00540
00541 }
00542
00543 exit(1);
00544
00545 }
00546
00547 }
00548
00549 }
00550
00551
00555 static void help() {
00556
00557 printf("Usage: %s [options] {arguments}\n", prog);
00558 printf("Options are as follows:\n");
00559 printf(" -c file, Use this control file\n");
00560 printf(" -l logfile, Print log information to this file\n");
00561 printf(" -d n, run as a daemon once per n seconds\n");
00562 printf(" -i, Validate mode, startup in validate mode\n");
00563 printf(" -I, Init mode, run from init\n");
00564 printf(" -v Verbose mode, work noisy (diagnostic output)\n");
00565 printf(" -V Print version number and patchlevel\n");
00566 printf(" -g Set group name for start, stop, restart and status\n");
00567 printf(" -h Print this text\n");
00568 printf("Optional action arguments for non-daemon mode are as follows:\n");
00569 printf(" start - Start all programs listed in the control file\n");
00570 printf(" start name - Only start the named program in the control file\n");
00571 printf(" stop - Stop all programs listed in the control file\n");
00572 printf(" stop name - Only stop the named program in the control file\n");
00573 printf(" restart - Stop and start all programs\n");
00574 printf(" restart name - Only restart the named program in the control file\n");
00575 printf(" status - Print status information for each program\n");
00576 printf(" quit - Kill monit daemon process\n");
00577 printf(" validate - Check all programs and start if not running.\n");
00578
00579 }
00580
00581
00585 static void version() {
00586
00587 printf("This is monit version %s\n", VERSION);
00588 printf("Copyright (C) 2000-2002 by Contributors to the monit codebase\n");
00589
00590 }
00591
00592
00596 static void do_wait() {
00597
00598 int i;
00599
00600 if ( have_tty ) {
00601
00602 fprintf(stdout, "Please wait for restart: ");
00603
00604 for (i= 0; i<10; i++) {
00605
00606 fprintf(stdout, "."); fflush(stdout);
00607 sleep(1);
00608
00609 }
00610
00611 fprintf(stdout, "\n");
00612
00613 } else {
00614
00615 sleep(10);
00616
00617 }
00618
00619 }
00620
00621
00625 static void stop_http() {
00626
00627 monit_http(STOP_HTTP);
00628
00629 }
00630
00631
00635 static void start_http() {
00636
00637 monit_http(START_HTTP);
00638
00639 }