Mercurial > masqmail
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 */ |