comparison src/masqmail.c @ 281:ea5f86e0a81c

modes are now enforced exclusive Other MTAs (exim, postfix) are more relaxing, but as combinations of exclusive modes are senseless we behave more obvious if we fail early. This makes understanding the behavior easier too.
author markus schnalke <meillo@marmaro.de>
date Tue, 07 Dec 2010 14:04:56 -0300
parents c35c59a36a2a
children ba53e648906f
comparison
equal deleted inserted replaced
280:72e377210d5e 281:ea5f86e0a81c
35 #include "masqmail.h" 35 #include "masqmail.h"
36 36
37 /* mutually exclusive modes. Note that there is no 'queue daemon' mode. 37 /* mutually exclusive modes. Note that there is no 'queue daemon' mode.
38 It, as well as the distinction beween the two (non exclusive) daemon 38 It, as well as the distinction beween the two (non exclusive) daemon
39 (queue and listen) modes, is handled by flags.*/ 39 (queue and listen) modes, is handled by flags.*/
40 typedef enum _mta_mode { 40 enum mta_mode {
41 MODE_ACCEPT = 0, /* accept message on stdin (fallback mode) */ 41 MODE_NONE = 0, /* to check if a mode was set */
42 MODE_ACCEPT, /* accept message on stdin (fallback mode) */
42 MODE_DAEMON, /* run as daemon */ 43 MODE_DAEMON, /* run as daemon */
43 MODE_RUNQUEUE, /* single queue run, online or offline */ 44 MODE_RUNQUEUE, /* single queue run, online or offline */
44 MODE_SMTP, /* accept SMTP on stdin */ 45 MODE_SMTP, /* accept SMTP on stdin */
45 MODE_LIST, /* list queue */ 46 MODE_LIST, /* list queue */
46 MODE_MCMD, /* do queue manipulation */ 47 MODE_MCMD, /* do queue manipulation */
47 MODE_VERSION, /* show version */ 48 MODE_VERSION, /* show version */
48 MODE_BI, /* fake ;-) */ 49 MODE_BI, /* fake ;-) */
49 } mta_mode; 50 };
51 enum mta_mode mta_mode = MODE_NONE;
50 52
51 char *pidfile = NULL; 53 char *pidfile = NULL;
52 volatile int sigterm_in_progress = 0; 54 volatile int sigterm_in_progress = 0;
53 55
54 static void 56 static void
412 #endif 414 #endif
413 415
414 printf("%s %s%s%s%s\n", PACKAGE, VERSION, with_resolver, with_auth, with_ident); 416 printf("%s %s%s%s%s\n", PACKAGE, VERSION, with_resolver, with_auth, with_ident);
415 } 417 }
416 418
419 void
420 set_mode(enum mta_mode mode)
421 {
422 if (mta_mode && mta_mode!=mode) {
423 fprintf(stderr, "operation mode was already specified (%d vs. %d)\n", mta_mode, mode);
424 exit(1);
425 }
426
427 mta_mode = mode;
428 return;
429 }
430
417 int 431 int
418 main(int argc, char *argv[]) 432 main(int argc, char *argv[])
419 { 433 {
420 gchar *progname; 434 gchar *progname;
421 char* opt; 435 char* opt;
422 gint arg; 436 gint arg;
423 437
424 mta_mode mta_mode = MODE_ACCEPT;
425 gboolean do_listen = FALSE; 438 gboolean do_listen = FALSE;
426 gboolean do_runq = FALSE; 439 gboolean do_runq = FALSE;
427 gboolean do_runq_online = FALSE; 440 gboolean do_runq_online = FALSE;
428 gboolean do_queue = FALSE; 441 gboolean do_queue = FALSE;
429 gint queue_interval = 0; 442 gint queue_interval = 0;
468 /* everything after `--' are address arguments */ 481 /* everything after `--' are address arguments */
469 arg++; 482 arg++;
470 break; 483 break;
471 484
472 } else if (strcmp(opt, "bm") == 0) { 485 } else if (strcmp(opt, "bm") == 0) {
473 mta_mode = MODE_ACCEPT; 486 set_mode(MODE_ACCEPT);
474 487
475 } else if (strcmp(opt, "bd") == 0) { 488 } else if (strcmp(opt, "bd") == 0) {
489 set_mode(MODE_DAEMON);
476 do_listen = TRUE; 490 do_listen = TRUE;
477 mta_mode = MODE_DAEMON;
478 491
479 } else if (strcmp(opt, "bi") == 0) { 492 } else if (strcmp(opt, "bi") == 0) {
480 /* ignored */ 493 set_mode(MODE_BI);
481 mta_mode = MODE_BI;
482 494
483 } else if (strcmp(opt, "bs") == 0) { 495 } else if (strcmp(opt, "bs") == 0) {
484 mta_mode = MODE_SMTP; 496 set_mode(MODE_SMTP);
485 497
486 } else if (strcmp(opt, "bp") == 0) { 498 } else if (strcmp(opt, "bp") == 0) {
487 mta_mode = MODE_LIST; 499 set_mode(MODE_LIST);
488 500
489 } else if (strcmp(opt, "bV") == 0) { 501 } else if (strcmp(opt, "bV") == 0) {
490 mta_mode = MODE_VERSION; 502 set_mode(MODE_VERSION);
491 503
492 } else if (strncmp(opt, "B", 1) == 0) { 504 } else if (strncmp(opt, "B", 1) == 0) {
493 /* we ignore this and throw the argument away */ 505 /* we ignore this and throw the argument away */
494 get_optarg(argv, &arg, opt+1); 506 get_optarg(argv, &arg, opt+1);
495 507
533 545
534 } else if (strcmp(opt, "m") == 0) { 546 } else if (strcmp(opt, "m") == 0) {
535 /* ignore -m (me too) switch (see man page) */ 547 /* ignore -m (me too) switch (see man page) */
536 548
537 } else if (strcmp(opt, "Mrm") == 0) { 549 } else if (strcmp(opt, "Mrm") == 0) {
538 mta_mode = MODE_MCMD; 550 set_mode(MODE_MCMD);
539 M_cmd = "rm"; 551 M_cmd = "rm";
540 552
541 } else if (strcmp(opt, "odq") == 0) { 553 } else if (strcmp(opt, "odq") == 0) {
542 do_queue = TRUE; 554 do_queue = TRUE;
543 555
547 } else if (strncmp(opt, "o", 1) == 0) { 559 } else if (strncmp(opt, "o", 1) == 0) {
548 /* ignore all other -oXXX options */ 560 /* ignore all other -oXXX options */
549 561
550 } else if (strncmp(opt, "qo", 2) == 0) { 562 } else if (strncmp(opt, "qo", 2) == 0) {
551 /* must be before the `q' check */ 563 /* must be before the `q' check */
552 mta_mode = MODE_RUNQUEUE; 564 set_mode(MODE_RUNQUEUE);
553 do_runq = FALSE; 565 do_runq = FALSE;
554 do_runq_online = TRUE; 566 do_runq_online = TRUE;
555 /* can be NULL, then we use online detection method */ 567 /* can be NULL, then we use online detection method */
556 route_name = get_optarg(argv, &arg, opt+2); 568 route_name = get_optarg(argv, &arg, opt+2);
557 569
558 } else if (strncmp(opt, "q", 1) == 0) { 570 } else if (strncmp(opt, "q", 1) == 0) {
559 /* must be after the `qo' check */ 571 /* must be after the `qo' check */
560 gchar *optarg; 572 gchar *optarg;
561 573
562 do_runq = TRUE;
563 mta_mode = MODE_RUNQUEUE;
564 optarg = get_optarg(argv, &arg, opt+1); 574 optarg = get_optarg(argv, &arg, opt+1);
565 if (optarg) { 575 if (optarg) {
566 /* not just one single queue run but regular runs */ 576 /* not just one single queue run but regular runs */
567 mta_mode = MODE_DAEMON; 577 set_mode(MODE_DAEMON);
568 queue_interval = time_interval(optarg); 578 queue_interval = time_interval(optarg);
579 } else {
580 set_mode(MODE_RUNQUEUE);
581 do_runq = TRUE;
569 } 582 }
570 583
571 } else if (strcmp(opt, "t") == 0) { 584 } else if (strcmp(opt, "t") == 0) {
572 opt_t = TRUE; 585 opt_t = TRUE;
573 586
578 fprintf(stderr, "unrecognized option `-%s'\n", opt); 591 fprintf(stderr, "unrecognized option `-%s'\n", opt);
579 exit(1); 592 exit(1);
580 } 593 }
581 } 594 }
582 595
583 if (mta_mode==MODE_ACCEPT && arg==argc && !opt_t) { 596 if (!mta_mode && arg==argc && !opt_t) {
584 /* 597 /*
585 In this case no rcpts can be found, thus no mail 598 In this case no rcpts can be found, thus no mail
586 can be sent, thus masqmail will always fail. We 599 can be sent, thus masqmail will always fail. We
587 rather do something better instead. This covers 600 rather do something better instead. This covers
588 also the case of calling masqmail without args. 601 also the case of calling masqmail without args.
589 */ 602 */
590 mta_mode = MODE_VERSION; 603 mode_version();
604 exit(0);
591 } 605 }
592 606
593 if (mta_mode == MODE_VERSION) { 607 if (mta_mode == MODE_VERSION) {
594 mode_version(); 608 mode_version();
595 exit(0); 609 exit(0);
610 }
611
612 if (!mta_mode) {
613 mta_mode = MODE_ACCEPT;
596 } 614 }
597 615
598 /* initialize random generator */ 616 /* initialize random generator */
599 srand(time(NULL)); 617 srand(time(NULL));
600 /* ignore SIGPIPE signal */ 618 /* ignore SIGPIPE signal */