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 : }
|