LCOV - code coverage report
Current view: top level - cmail-popd - popd.c (source / functions) Hit Total Coverage
Test: popd.info Lines: 30 59 50.8 %
Date: 2015-11-25 19:05:59 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #include "popd.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("Provide POP3 access to mailboxes\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             :                 .drop_privileges = true,
      17             :                 .daemonize = true,
      18             :                 .config_file = NULL
      19             :         };
      20             : 
      21           1 :         CONFIGURATION config = {
      22             :                 .listeners = {
      23             :                         .count = 0,
      24             :                         .conns = NULL
      25             :                 },
      26             :                 .database = {
      27             :                         .conn = NULL,
      28             :                         .query_authdata = NULL,
      29             :                         .query_userdatabase = NULL,
      30             :                         .update_lock = NULL,
      31             :                         .list_master = NULL,
      32             :                         .fetch_master = NULL,
      33             :                         .mark_deletion = NULL,
      34             :                         .unmark_deletions = NULL,
      35             :                         .delete_master = NULL
      36             :                 },
      37             :                 .log = {
      38             :                         .stream = stderr,
      39             :                         .verbosity = 0,
      40             :                         .log_secondary = false,
      41             :                         .print_timestamp = true
      42             :                 },
      43             :                 .privileges = {
      44             :                         .uid = 0,
      45             :                         .gid= 0
      46             :                 },
      47             :                 .pid_file = NULL
      48             :         };
      49             : 
      50           1 :         if(argc < 2){
      51           0 :                 return usage(argv[0]);
      52             :         }
      53             : 
      54             :         //parse arguments
      55           1 :         if(!args_parse(&args, argc - 1, argv + 1)){
      56           0 :                 return usage(argv[0]);
      57             :         }
      58             : 
      59             :         #ifndef CMAIL_NO_TLS
      60           1 :         if(gnutls_global_init()){
      61           0 :                 fprintf(stderr, "Failed to initialize GnuTLS\n");
      62           0 :                 exit(EXIT_FAILURE);
      63             :         }
      64             :         #endif
      65             : 
      66             :         //read config file
      67           1 :         if(config_parse(config.log, &config, args.config_file) < 0){
      68           0 :                 config_free(&config);
      69           0 :                 TLSSUPPORT(gnutls_global_deinit());
      70           0 :                 return EXIT_FAILURE;
      71             :         }
      72             : 
      73             :         //initialize database
      74           1 :         if(database_initialize(config.log, &(config.database)) < 0){
      75           0 :                 config_free(&config);
      76           0 :                 TLSSUPPORT(gnutls_global_deinit());
      77           0 :                 return EXIT_FAILURE;
      78             :         }
      79             : 
      80             :         //set up signal masks //TODO error check this
      81           1 :         signal_init(config.log);
      82             : 
      83             :         //if needed, open pid file handle before dropping privileges
      84           1 :         if(config.pid_file){
      85           1 :                 pid_file = fopen(config.pid_file, "w");
      86           1 :                 if(!pid_file){
      87           0 :                         logprintf(config.log, LOG_ERROR, "Failed to open pidfile for writing\n");
      88             :                 }
      89             :         }
      90             : 
      91             :         //drop privileges
      92           1 :         if(getuid() == 0 && args.drop_privileges){
      93           0 :                 if(privileges_drop(config.log, config.privileges) < 0){
      94           0 :                         config_free(&config);
      95           0 :                         TLSSUPPORT(gnutls_global_deinit());
      96           0 :                         exit(EXIT_FAILURE);
      97             :                 }
      98             :         }
      99             :         else{
     100           1 :                 logprintf(config.log, LOG_INFO, "Not dropping privileges%s\n", (args.drop_privileges ? " (Because you are not root)":""));
     101             :         }
     102             : 
     103             :         //detach from console
     104           1 :         if(args.daemonize && config.log.stream != stderr){
     105           1 :                 logprintf(config.log, LOG_INFO, "Detaching from parent process\n");
     106             : 
     107             :                 //flush the stream so we do not get everything twice
     108           1 :                 fflush(config.log.stream);
     109             : 
     110             :                 //stop secondary log output
     111           1 :                 config.log.log_secondary = false;
     112             : 
     113           1 :                 switch(daemonize(config.log, pid_file)){
     114             :                         case 0:
     115           1 :                                 break;
     116             :                         case 1:
     117           1 :                                 logprintf(config.log, LOG_INFO, "Parent process going down\n");
     118           1 :                                 config_free(&config);
     119           1 :                                 TLSSUPPORT(gnutls_global_deinit());
     120           1 :                                 exit(EXIT_SUCCESS);
     121             :                                 break;
     122             :                         case -1:
     123           0 :                                 config_free(&config);
     124           0 :                                 TLSSUPPORT(gnutls_global_deinit());
     125           0 :                                 exit(EXIT_FAILURE);
     126             :                 }
     127           1 :         }
     128             :         else{
     129           0 :                 logprintf(config.log, LOG_INFO, "Not detaching from console%s\n", (args.daemonize ? " (Because the log output stream is stderr)":""));
     130           0 :                 if(pid_file){
     131           0 :                         fclose(pid_file);
     132             :                 }
     133             :         }
     134             : 
     135             :         //run core loop
     136           1 :         core_loop(config.log, config.listeners, &(config.database));
     137             : 
     138             :         //cleanup
     139           1 :         config_free(&config);
     140           1 :         TLSSUPPORT(gnutls_global_deinit());
     141             : 
     142           1 :         return 0;
     143             : }

Generated by: LCOV version 1.11