LCOV - code coverage report
Current view: top level - cmail-smtpd - smtpd.c (source / functions) Hit Total Coverage
Test: smtpd.info Lines: 32 68 47.1 %
Date: 2015-11-25 19:06:20 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #include "smtpd.h"
       2             : 
       3           0 : int usage(char* filename){
       4           0 :         printf("%s - Part of the cmail internet mail processing suite\n", VERSION);
       5           0 :         printf("Accept incoming mail\n");
       6           0 :         printf("Usage: %s <conffile> [options]\n", filename);
       7           0 :         printf("Recognized options:\n");
       8           0 :         printf("\tnodrop\t\tDo not drop privileges\n");
       9           0 :         printf("\tnodetach\tDo not detach from console\n");
      10           0 :         return EXIT_FAILURE;
      11             : }
      12             : 
      13           1 : int main(int argc, char** argv){
      14           1 :         FILE* pid_file = NULL;
      15           1 :         ARGUMENTS args = {
      16             :                 .config_file = NULL,
      17             :                 .drop_privileges = true,
      18             :                 .detach = true
      19             :         };
      20             : 
      21           1 :         CONFIGURATION config = {
      22             :                 .database = {
      23             :                         .conn = NULL,
      24             :                         .query_authdata = NULL,
      25             :                         .query_address = NULL,
      26             :                         .query_outbound_router = NULL,
      27             :                         .mail_storage = {
      28             :                                 .mailbox_master = NULL,
      29             :                                 .outbox_master = NULL,
      30             :                                 .users = NULL
      31             :                         }
      32             :                 },
      33             :                 .listeners = {
      34             :                         .count = 0,
      35             :                         .conns = NULL
      36             :                 },
      37             :                 .privileges = {
      38             :                         .uid=0,
      39             :                         .gid=0
      40             :                 },
      41             :                 .log = {
      42             :                         .stream = stderr,
      43             :                         .verbosity = 0,
      44             :                         .log_secondary = false,
      45             :                         .print_timestamp = true
      46             :                 },
      47             :                 .pid_file = NULL
      48             :         };
      49             : 
      50             :         //parse arguments
      51           1 :         if(!arguments_parse(&args, argc - 1, argv + 1)){
      52           0 :                 arguments_free(&args);
      53           0 :                 exit(usage(argv[0]));
      54             :         }
      55             : 
      56             :         #ifndef CMAIL_NO_TLS
      57           1 :         if(gnutls_global_init()){
      58           0 :                 arguments_free(&args);
      59           0 :                 fprintf(stderr, "Failed to initialize GnuTLS\n");
      60           0 :                 exit(EXIT_FAILURE);
      61             :         }
      62             :         #endif
      63             : 
      64             :         //read config file
      65           1 :         if(config_parse(config.log, &config, args.config_file) < 0){
      66           0 :                 arguments_free(&args);
      67           0 :                 config_free(&config);
      68           0 :                 TLSSUPPORT(gnutls_global_deinit());
      69           0 :                 exit(usage(argv[0]));
      70             :         }
      71             : 
      72           1 :         logprintf(config.log, LOG_INFO, "This is %s, starting up\n", VERSION);
      73             : 
      74           1 :         if(signal_init(config.log) < 0){
      75           0 :                 arguments_free(&args);
      76           0 :                 config_free(&config);
      77           0 :                 TLSSUPPORT(gnutls_global_deinit());
      78           0 :                 exit(EXIT_FAILURE);
      79             :         }
      80             : 
      81             :         //attach aux databases
      82           1 :         if(database_initialize(config.log, &(config.database)) < 0){
      83           0 :                 arguments_free(&args);
      84           0 :                 config_free(&config);
      85           0 :                 TLSSUPPORT(gnutls_global_deinit());
      86           0 :                 exit(EXIT_FAILURE);
      87             :         }
      88             : 
      89             :         //if needed, open pid file handle before dropping privileges
      90           1 :         if(config.pid_file){
      91           1 :                 pid_file = fopen(config.pid_file, "w");
      92           1 :                 if(!pid_file){
      93           0 :                         logprintf(config.log, LOG_ERROR, "Failed to open pidfile for writing\n");
      94             :                 }
      95             :         }
      96             : 
      97             :         //drop privileges
      98           1 :         if(getuid() == 0 && args.drop_privileges){
      99           0 :                 if(privileges_drop(config.log, config.privileges) < 0){
     100           0 :                         arguments_free(&args);
     101           0 :                         config_free(&config);
     102           0 :                         exit(EXIT_FAILURE);
     103             :                 }
     104             :         }
     105             :         else{
     106           1 :                 logprintf(config.log, LOG_INFO, "Not dropping privileges%s\n", (args.drop_privileges ? " (Because you are not root)":""));
     107             :         }
     108             : 
     109             :         //detach from console (or dont)
     110           1 :         if(args.detach && config.log.stream != stderr){
     111           1 :                 logprintf(config.log, LOG_INFO, "Detaching from parent process\n");
     112             : 
     113             :                 //flush the stream so we do not get everything twice
     114           1 :                 fflush(config.log.stream);
     115             : 
     116             :                 //stop secondary log output
     117           1 :                 config.log.log_secondary = false;
     118             : 
     119           1 :                 switch(daemonize(config.log, pid_file)){
     120             :                         case 0:
     121           1 :                                 break;
     122             :                         case 1:
     123           1 :                                 logprintf(config.log, LOG_INFO, "Parent process going down\n");
     124           1 :                                 arguments_free(&args);
     125           1 :                                 config_free(&config);
     126           1 :                                 exit(EXIT_SUCCESS);
     127             :                                 break;
     128             :                         case -1:
     129           0 :                                 arguments_free(&args);
     130           0 :                                 config_free(&config);
     131           0 :                                 exit(EXIT_FAILURE);
     132             :                 }
     133           1 :         }
     134             :         else{
     135           0 :                 logprintf(config.log, LOG_INFO, "Not detaching from console%s\n", (args.detach ? " (Because the log output stream is stderr)":""));
     136           0 :                 if(pid_file){
     137           0 :                         fclose(pid_file);
     138             :                 }
     139             :         }
     140             : 
     141             : 
     142             :         //enter main processing loop
     143           1 :         core_loop(config.log, config.listeners, &(config.database));
     144             : 
     145             :         //clean up allocated resources
     146           1 :         logprintf(config.log, LOG_INFO, "Cleaning up resources\n");
     147           1 :         arguments_free(&args);
     148           1 :         config_free(&config);
     149           1 :         TLSSUPPORT(gnutls_global_deinit());
     150             : 
     151           1 :         return EXIT_SUCCESS;
     152             : }

Generated by: LCOV version 1.11