comparison src/masqmail.c @ 10:26e34ae9a3e3

changed indention and line wrapping to a more consistent style
author meillo@marmaro.de
date Mon, 27 Oct 2008 16:23:10 +0100
parents 08114f7dcc23
children 9fb7ddbaf129
comparison
equal deleted inserted replaced
9:31cc8a89cb74 10:26e34ae9a3e3
35 35
36 /* mutually exclusive modes. Note that there is neither a 'get' mode 36 /* mutually exclusive modes. Note that there is neither a 'get' mode
37 nor a 'queue daemon' mode. These, as well as the distinction beween 37 nor a 'queue daemon' mode. These, as well as the distinction beween
38 the two (non exclusive) daemon (queue and listen) modes are handled 38 the two (non exclusive) daemon (queue and listen) modes are handled
39 by flags.*/ 39 by flags.*/
40 typedef enum _mta_mode 40 typedef enum _mta_mode {
41 { 41 MODE_ACCEPT = 0, /* accept message on stdin */
42 MODE_ACCEPT = 0, /* accept message on stdin */ 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_GET_DAEMON, /* run as get (retrieve) daemon */
45 MODE_GET_DAEMON, /* run as get (retrieve) daemon */ 45 MODE_SMTP, /* accept SMTP on stdin */
46 MODE_SMTP, /* accept SMTP on stdin */ 46 MODE_LIST, /* list queue */
47 MODE_LIST, /* list queue */ 47 MODE_MCMD, /* do queue manipulation */
48 MODE_MCMD, /* do queue manipulation */ 48 MODE_VERSION, /* show version */
49 MODE_VERSION, /* show version */ 49 MODE_BI, /* fake ;-) */
50 MODE_BI, /* fake ;-) */ 50 MODE_NONE /* to prevent default MODE_ACCEPT */
51 MODE_NONE /* to prevent default MODE_ACCEPT */ 51 } mta_mode;
52 }mta_mode;
53 52
54 char *pidfile = NULL; 53 char *pidfile = NULL;
55 volatile int sigterm_in_progress = 0; 54 volatile int sigterm_in_progress = 0;
56 55
57 static 56 static void
58 void sigterm_handler(int sig) 57 sigterm_handler(int sig)
59 { 58 {
60 if(sigterm_in_progress) 59 if (sigterm_in_progress)
61 raise(sig); 60 raise(sig);
62 sigterm_in_progress = 1; 61 sigterm_in_progress = 1;
63 62
64 if(pidfile){ 63 if (pidfile) {
65 uid_t uid; 64 uid_t uid;
66 uid = seteuid(0); 65 uid = seteuid(0);
67 if(unlink(pidfile) != 0) 66 if (unlink(pidfile) != 0)
68 logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", 67 logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", pidfile, strerror(errno));
69 pidfile, strerror(errno)); 68 seteuid(uid); /* we exit anyway after this, just to be sure */
70 seteuid(uid); /* we exit anyway after this, just to be sure */ 69 }
71 } 70
72 71 signal(sig, SIG_DFL);
73 signal(sig, SIG_DFL); 72 raise(sig);
74 raise(sig); 73 }
75 } 74
76 75 #ifdef ENABLE_IDENT /* so far used for that only */
77 #ifdef ENABLE_IDENT /* so far used for that only */ 76 static gboolean
78 static 77 is_in_netlist(gchar * host, GList * netlist)
79 gboolean is_in_netlist(gchar *host, GList *netlist) 78 {
80 { 79 guint hostip = inet_addr(host);
81 guint hostip = inet_addr(host); 80 struct in_addr addr;
82 struct in_addr addr; 81
83 82 addr.s_addr = hostip;
84 addr.s_addr = hostip; 83 if (addr.s_addr != INADDR_NONE) {
85 if(addr.s_addr != INADDR_NONE){ 84 GList *node;
86 GList *node; 85 foreach(netlist, node) {
87 foreach(netlist, node){ 86 struct in_addr *net = (struct in_addr *) (node->data);
88 struct in_addr *net = (struct in_addr *)(node->data); 87 if ((addr.s_addr & net->s_addr) == net->s_addr)
89 if((addr.s_addr & net->s_addr) == net->s_addr) 88 return TRUE;
90 return TRUE; 89 }
91 } 90 }
92 } 91 return FALSE;
93 return FALSE; 92 }
94 } 93 #endif
95 #endif 94
96 95 gchar*
97 gchar *get_optarg(char *argv[], gint argc, gint *argp, gint *pos) 96 get_optarg(char *argv[], gint argc, gint * argp, gint * pos)
98 { 97 {
99 if(argv[*argp][*pos]) 98 if (argv[*argp][*pos])
100 return &(argv[*argp][*pos]); 99 return &(argv[*argp][*pos]);
101 else{ 100 else {
102 if(*argp+1 < argc){ 101 if (*argp + 1 < argc) {
103 if(argv[(*argp)+1][0] != '-'){ 102 if (argv[(*argp) + 1][0] != '-') {
104 (*argp)++; 103 (*argp)++;
105 *pos = 0; 104 *pos = 0;
106 return &(argv[*argp][*pos]); 105 return &(argv[*argp][*pos]);
107 } 106 }
108 } 107 }
109 } 108 }
110 return NULL; 109 return NULL;
111 } 110 }
112 111
113 gchar *get_progname(gchar *arg0) 112 gchar*
114 { 113 get_progname(gchar * arg0)
115 gchar *p = arg0 + strlen(arg0) - 1; 114 {
116 while(p > arg0){ 115 gchar *p = arg0 + strlen(arg0) - 1;
117 if(*p == '/') 116 while (p > arg0) {
118 return p+1; 117 if (*p == '/')
119 p--; 118 return p + 1;
120 } 119 p--;
121 return p; 120 }
122 } 121 return p;
123 122 }
124 gboolean write_pidfile(gchar *name) 123
125 { 124 gboolean
126 FILE *fptr; 125 write_pidfile(gchar * name)
127 126 {
128 if((fptr = fopen(name, "wt"))){ 127 FILE *fptr;
129 fprintf(fptr, "%d\n", getpid()); 128
130 fclose(fptr); 129 if ((fptr = fopen(name, "wt"))) {
131 pidfile = strdup(name); 130 fprintf(fptr, "%d\n", getpid());
132 return TRUE; 131 fclose(fptr);
133 } 132 pidfile = strdup(name);
134 logwrite(LOG_WARNING, "could not write pid file: %s\n", strerror(errno)); 133 return TRUE;
135 return FALSE; 134 }
136 } 135 logwrite(LOG_WARNING, "could not write pid file: %s\n", strerror(errno));
137 136 return FALSE;
138 static 137 }
139 void mode_daemon(gboolean do_listen, gint queue_interval, char *argv[]) 138
140 { 139 static void
141 guint pid; 140 mode_daemon(gboolean do_listen, gint queue_interval, char *argv[])
142 141 {
143 /* daemon */ 142 guint pid;
144 if(!conf.run_as_user){ 143
145 if((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)){ 144 /* daemon */
146 fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER); 145 if (!conf.run_as_user) {
147 exit(EXIT_FAILURE); 146 if ((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)) {
148 } 147 fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER);
149 } 148 exit(EXIT_FAILURE);
150 149 }
151 if((pid = fork()) > 0){ 150 }
152 exit(EXIT_SUCCESS); 151
153 }else if(pid < 0){ 152 if ((pid = fork()) > 0) {
154 logwrite(LOG_ALERT, "could not fork!"); 153 exit(EXIT_SUCCESS);
155 exit(EXIT_FAILURE); 154 } else if (pid < 0) {
156 } 155 logwrite(LOG_ALERT, "could not fork!");
157 156 exit(EXIT_FAILURE);
158 signal(SIGTERM, sigterm_handler); 157 }
159 write_pidfile(PIDFILEDIR"/masqmail.pid"); 158
160 159 signal(SIGTERM, sigterm_handler);
161 conf.do_verbose = FALSE; 160 write_pidfile(PIDFILEDIR "/masqmail.pid");
162 161
163 fclose(stdin); 162 conf.do_verbose = FALSE;
164 fclose(stdout); 163
165 fclose(stderr); 164 fclose(stdin);
166 165 fclose(stdout);
167 listen_port(do_listen ? conf.listen_addresses : NULL, 166 fclose(stderr);
168 queue_interval, argv); 167
168 listen_port(do_listen ? conf.listen_addresses : NULL, queue_interval, argv);
169 } 169 }
170 170
171 #ifdef ENABLE_POP3 171 #ifdef ENABLE_POP3
172 static 172 static void
173 void mode_get_daemon(gint get_interval, char *argv[]) 173 mode_get_daemon(gint get_interval, char *argv[])
174 { 174 {
175 guint pid; 175 guint pid;
176 176
177 /* daemon */ 177 /* daemon */
178 if(!conf.run_as_user){ 178 if (!conf.run_as_user) {
179 if((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)){ 179 if ((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)) {
180 fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER); 180 fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER);
181 exit(EXIT_FAILURE); 181 exit(EXIT_FAILURE);
182 } 182 }
183 } 183 }
184 184
185 if((pid = fork()) > 0){ 185 if ((pid = fork()) > 0) {
186 exit(EXIT_SUCCESS); 186 exit(EXIT_SUCCESS);
187 }else if(pid < 0){ 187 } else if (pid < 0) {
188 logwrite(LOG_ALERT, "could not fork!"); 188 logwrite(LOG_ALERT, "could not fork!");
189 exit(EXIT_FAILURE); 189 exit(EXIT_FAILURE);
190 } 190 }
191 191
192 signal(SIGTERM, sigterm_handler); 192 signal(SIGTERM, sigterm_handler);
193 write_pidfile(PIDFILEDIR"/masqmail-get.pid"); 193 write_pidfile(PIDFILEDIR "/masqmail-get.pid");
194 194
195 conf.do_verbose = FALSE; 195 conf.do_verbose = FALSE;
196 196
197 fclose(stdin); 197 fclose(stdin);
198 fclose(stdout); 198 fclose(stdout);
199 fclose(stderr); 199 fclose(stderr);
200 200
201 get_daemon(get_interval, argv); 201 get_daemon(get_interval, argv);
202 } 202 }
203 #endif 203 #endif
204 204
205 #ifdef ENABLE_SMTP_SERVER 205 #ifdef ENABLE_SMTP_SERVER
206 static void mode_smtp() 206 static void
207 { 207 mode_smtp()
208 /* accept smtp message on stdin */ 208 {
209 /* write responses to stderr. */ 209 /* accept smtp message on stdin */
210 210 /* write responses to stderr. */
211 struct sockaddr_in saddr; 211
212 gchar *peername = NULL; 212 struct sockaddr_in saddr;
213 int dummy = sizeof(saddr); 213 gchar *peername = NULL;
214 int dummy = sizeof(saddr);
214 #ifdef ENABLE_IDENT 215 #ifdef ENABLE_IDENT
215 gchar *ident = NULL; 216 gchar *ident = NULL;
216 #endif 217 #endif
217 218
218 conf.do_verbose = FALSE; 219 conf.do_verbose = FALSE;
219 220
220 if(!conf.run_as_user){ 221 if (!conf.run_as_user) {
221 seteuid(conf.orig_uid); 222 seteuid(conf.orig_uid);
222 setegid(conf.orig_gid); 223 setegid(conf.orig_gid);
223 } 224 }
224 225
225 DEBUG(5) debugf("accepting smtp message on stdin\n"); 226 DEBUG(5) debugf("accepting smtp message on stdin\n");
226 227
227 if(getpeername(0, (struct sockaddr *)(&saddr), &dummy) == 0){ 228 if (getpeername(0, (struct sockaddr *) (&saddr), &dummy) == 0) {
228 peername = g_strdup(inet_ntoa(saddr.sin_addr)); 229 peername = g_strdup(inet_ntoa(saddr.sin_addr));
229 #ifdef ENABLE_IDENT 230 #ifdef ENABLE_IDENT
230 { 231 {
231 gchar *id = NULL; 232 gchar *id = NULL;
232 if((id = (gchar *)ident_id(0, 60))){ 233 if ((id = (gchar *) ident_id(0, 60))) {
233 ident = g_strdup(id); 234 ident = g_strdup(id);
234 } 235 }
235 } 236 }
236 #endif 237 #endif
237 }else if(errno != ENOTSOCK) 238 } else if (errno != ENOTSOCK)
238 exit(EXIT_FAILURE); 239 exit(EXIT_FAILURE);
239 240
240 //smtp_in(stdin, stdout, peername); 241 //smtp_in(stdin, stdout, peername);
241 smtp_in(stdin, stderr, peername, NULL); 242 smtp_in(stdin, stderr, peername, NULL);
242 243
243 #ifdef ENABLE_IDENT 244 #ifdef ENABLE_IDENT
244 if(ident) g_free(ident); 245 if (ident)
245 #endif 246 g_free(ident);
246 } 247 #endif
247 #endif 248 }
248 249 #endif
249 static void mode_accept(address *return_path, gchar *full_sender_name, 250
250 guint accept_flags, char **addresses, int addr_cnt) 251 static void
251 { 252 mode_accept(address * return_path, gchar * full_sender_name, guint accept_flags, char **addresses, int addr_cnt)
252 /* accept message on stdin */ 253 {
253 accept_error err; 254 /* accept message on stdin */
254 message *msg = create_message(); 255 accept_error err;
255 gint i; 256 message *msg = create_message();
256 257 gint i;
257 if(return_path != NULL){ 258
258 if((conf.orig_uid != 0) && 259 if (return_path != NULL) {
259 (conf.orig_uid != conf.mail_uid) && 260 if ((conf.orig_uid != 0)
260 (!is_ingroup(conf.orig_uid, conf.mail_gid))){ 261 && (conf.orig_uid != conf.mail_uid)
261 fprintf(stderr, 262 && (!is_ingroup(conf.orig_uid, conf.mail_gid))) {
262 "must be in root, %s or in group %s for setting return path.\n", 263 fprintf(stderr, "must be in root, %s or in group %s for setting return path.\n", DEF_MAIL_USER, DEF_MAIL_GROUP);
263 DEF_MAIL_USER, DEF_MAIL_GROUP); 264 exit(EXIT_FAILURE);
264 exit(EXIT_FAILURE); 265 }
265 } 266 }
266 } 267
267 268 if (!conf.run_as_user) {
268 if(!conf.run_as_user){ 269 seteuid(conf.orig_uid);
269 seteuid(conf.orig_uid); 270 setegid(conf.orig_gid);
270 setegid(conf.orig_gid); 271 }
271 } 272
272 273 DEBUG(5) debugf("accepting message on stdin\n");
273 DEBUG(5) debugf("accepting message on stdin\n"); 274
274 275 msg->received_prot = PROT_LOCAL;
275 msg->received_prot = PROT_LOCAL; 276 for (i = 0; i < addr_cnt; i++) {
276 for(i = 0; i < addr_cnt; i++){ 277 if (addresses[i][0] != '|')
277 if(addresses[i][0] != '|') 278 msg->rcpt_list = g_list_append(msg->rcpt_list, create_address_qualified(addresses[i], TRUE, conf.host_name));
278 msg->rcpt_list = 279 else {
279 g_list_append(msg->rcpt_list, 280 logwrite(LOG_ALERT, "no pipe allowed as recipient address: %s\n", addresses[i]);
280 create_address_qualified(addresses[i], TRUE, conf.host_name)); 281 exit(EXIT_FAILURE);
281 else{ 282 }
282 logwrite(LOG_ALERT, "no pipe allowed as recipient address: %s\n", addresses[i]); 283 }
283 exit(EXIT_FAILURE); 284
284 } 285 /* -f option */
285 } 286 msg->return_path = return_path;
286 287
287 /* -f option */ 288 /* -F option */
288 msg->return_path = return_path; 289 msg->full_sender_name = full_sender_name;
289 290
290 /* -F option */ 291 if ((err = accept_message(stdin, msg, accept_flags)) == AERR_OK) {
291 msg->full_sender_name = full_sender_name; 292 if (spool_write(msg, TRUE)) {
292 293 pid_t pid;
293 if((err = accept_message(stdin, msg, accept_flags)) == AERR_OK){ 294 logwrite(LOG_NOTICE, "%s <= %s with %s\n", msg->uid, addr_string(msg->return_path), prot_names[PROT_LOCAL]);
294 if(spool_write(msg, TRUE)){ 295
295 pid_t pid; 296 if (!conf.do_queue) {
296 logwrite(LOG_NOTICE, "%s <= %s with %s\n", 297 if ((pid = fork()) == 0) {
297 msg->uid, addr_string(msg->return_path), 298 conf.do_verbose = FALSE;
298 prot_names[PROT_LOCAL]); 299 fclose(stdin);
299 300 fclose(stdout);
300 if(!conf.do_queue){ 301 fclose(stderr);
301 302 if (deliver(msg)) {
302 if((pid = fork()) == 0){ 303 exit(EXIT_SUCCESS);
303 304 } else
304 conf.do_verbose = FALSE; 305 exit(EXIT_FAILURE);
305 306 } else if (pid < 0) {
306 fclose(stdin); 307 logwrite(LOG_ALERT, "could not fork for delivery, id = %s", msg->uid);
307 fclose(stdout); 308 }
308 fclose(stderr); 309 }
309 310 } else {
310 if(deliver(msg)){ 311 fprintf(stderr, "Could not write spool file\n");
311 exit(EXIT_SUCCESS); 312 exit(EXIT_FAILURE);
312 }else 313 }
313 exit(EXIT_FAILURE); 314 } else {
314 }else if(pid < 0){ 315 switch (err) {
315 logwrite(LOG_ALERT, "could not fork for delivery, id = %s", 316 case AERR_EOF:
316 msg->uid); 317 fprintf(stderr, "unexpected EOF.\n");
317 } 318 exit(EXIT_FAILURE);
318 } 319 case AERR_NORCPT:
319 }else{ 320 fprintf(stderr, "no recipients.\n");
320 fprintf(stderr, "Could not write spool file\n"); 321 exit(EXIT_FAILURE);
321 exit(EXIT_FAILURE); 322 default:
322 } 323 /* should never happen: */
323 }else{ 324 fprintf(stderr, "Unknown error (%d)\r\n", err);
324 switch(err){ 325 exit(EXIT_FAILURE);
325 case AERR_EOF: 326 }
326 fprintf(stderr, "unexpected EOF.\n"); 327 exit(EXIT_FAILURE);
327 exit(EXIT_FAILURE); 328 }
328 case AERR_NORCPT:
329 fprintf(stderr, "no recipients.\n");
330 exit(EXIT_FAILURE);
331 default:
332 /* should never happen: */
333 fprintf(stderr, "Unknown error (%d)\r\n", err);
334 exit(EXIT_FAILURE);
335 }
336 exit(EXIT_FAILURE);
337 }
338 } 329 }
339 330
340 int 331 int
341 main(int argc, char *argv[]) 332 main(int argc, char *argv[])
342 { 333 {
343 /* cmd line flags */ 334 /* cmd line flags */
344 gchar *conf_file = CONF_FILE; 335 gchar *conf_file = CONF_FILE;
345 gint arg = 1; 336 gint arg = 1;
346 gboolean do_get = FALSE; 337 gboolean do_get = FALSE;
347 gboolean do_get_online = FALSE; 338 gboolean do_get_online = FALSE;
348 339
349 gboolean do_listen = FALSE; 340 gboolean do_listen = FALSE;
350 gboolean do_runq = FALSE; 341 gboolean do_runq = FALSE;
351 gboolean do_runq_online = FALSE; 342 gboolean do_runq_online = FALSE;
352 343
353 gboolean do_queue = FALSE; 344 gboolean do_queue = FALSE;
354 345
355 gboolean do_verbose = FALSE; 346 gboolean do_verbose = FALSE;
356 gint debug_level = -1; 347 gint debug_level = -1;
357 348
358 mta_mode mta_mode = MODE_ACCEPT; 349 mta_mode mta_mode = MODE_ACCEPT;
359 350
360 gint queue_interval = 0; 351 gint queue_interval = 0;
361 gint get_interval = 0; 352 gint get_interval = 0;
362 gboolean opt_t = FALSE; 353 gboolean opt_t = FALSE;
363 gboolean opt_i = FALSE; 354 gboolean opt_i = FALSE;
364 gboolean opt_odb = FALSE; 355 gboolean opt_odb = FALSE;
365 gboolean opt_oem = FALSE; 356 gboolean opt_oem = FALSE;
366 gboolean exit_failure = FALSE; 357 gboolean exit_failure = FALSE;
367 358
368 gchar *M_cmd = NULL; 359 gchar *M_cmd = NULL;
369 360
370 gint exit_code = EXIT_SUCCESS; 361 gint exit_code = EXIT_SUCCESS;
371 gchar *route_name = NULL; 362 gchar *route_name = NULL;
372 gchar *get_name = NULL; 363 gchar *get_name = NULL;
373 gchar *progname; 364 gchar *progname;
374 gchar *f_address = NULL; 365 gchar *f_address = NULL;
375 gchar *full_sender_name = NULL; 366 gchar *full_sender_name = NULL;
376 address *return_path = NULL; /* may be changed by -f option */ 367 address *return_path = NULL; /* may be changed by -f option */
377 368
378 progname = get_progname(argv[0]); 369 progname = get_progname(argv[0]);
379 370
380 if(strcmp(progname, "mailq") == 0) 371 if (strcmp(progname, "mailq") == 0) {
381 { mta_mode = MODE_LIST; } 372 mta_mode = MODE_LIST;
382 else if(strcmp(progname, "mailrm") == 0) 373 } else if (strcmp(progname, "mailrm") == 0) {
383 { mta_mode = MODE_MCMD; M_cmd = "rm"; } 374 mta_mode = MODE_MCMD;
384 else if(strcmp(progname, "runq") == 0) 375 M_cmd = "rm";
385 { mta_mode = MODE_RUNQUEUE; do_runq = TRUE; } 376 } else if (strcmp(progname, "runq") == 0) {
386 else if(strcmp(progname, "rmail") == 0) 377 mta_mode = MODE_RUNQUEUE;
387 { mta_mode = MODE_ACCEPT; opt_i = TRUE; } 378 do_runq = TRUE;
388 else if(strcmp(progname, "smtpd") == 0 || strcmp(progname, "in.smtpd") == 0) 379 } else if (strcmp(progname, "rmail") == 0) {
389 { mta_mode = MODE_SMTP; } 380 mta_mode = MODE_ACCEPT;
390 381 opt_i = TRUE;
391 /* parse cmd line */ 382 } else if (strcmp(progname, "smtpd") == 0 || strcmp(progname, "in.smtpd") == 0) {
392 while(arg < argc){ 383 mta_mode = MODE_SMTP;
393 gint pos = 0; 384 }
394 if((argv[arg][pos] == '-') && (argv[arg][pos+1] != '-')){ 385
395 pos++; 386 /* parse cmd line */
396 switch(argv[arg][pos++]){ 387 while (arg < argc) {
397 case 'b': 388 gint pos = 0;
398 switch(argv[arg][pos++]){ 389 if ((argv[arg][pos] == '-') && (argv[arg][pos + 1] != '-')) {
399 case 'd': 390 pos++;
400 do_listen = TRUE; 391 switch (argv[arg][pos++]) {
401 mta_mode = MODE_DAEMON; 392 case 'b':
402 break; 393 switch (argv[arg][pos++]) {
403 case 'i': 394 case 'd':
404 /* ignored */ 395 do_listen = TRUE;
405 mta_mode = MODE_BI; 396 mta_mode = MODE_DAEMON;
406 break; 397 break;
407 case 's': 398 case 'i':
408 mta_mode = MODE_SMTP; 399 /* ignored */
409 break; 400 mta_mode = MODE_BI;
410 case 'p': 401 break;
411 mta_mode = MODE_LIST; 402 case 's':
412 break; 403 mta_mode = MODE_SMTP;
413 case 'V': 404 break;
414 mta_mode = MODE_VERSION; 405 case 'p':
415 break; 406 mta_mode = MODE_LIST;
407 break;
408 case 'V':
409 mta_mode = MODE_VERSION;
410 break;
411 default:
412 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
413 exit(EXIT_FAILURE);
414 }
415 break;
416 case 'B':
417 /* we ignore this and throw the argument away */
418 get_optarg(argv, argc, &arg, &pos);
419 break;
420 case 'C':
421 if (!(conf_file = get_optarg(argv, argc, &arg, &pos))) {
422 fprintf(stderr, "-C requires a filename as argument.\n");
423 exit(EXIT_FAILURE);
424 }
425 break;
426 case 'F':
427 {
428 full_sender_name = get_optarg(argv, argc, &arg, &pos);
429 if (!full_sender_name) {
430 fprintf(stderr, "-F requires a name as an argument\n");
431 exit(EXIT_FAILURE);
432 }
433 }
434 break;
435 case 'd':
436 if (getuid() == 0) {
437 char *lvl = get_optarg(argv, argc, &arg, &pos);
438 if (lvl)
439 debug_level = atoi(lvl);
440 else {
441 fprintf(stderr, "-d requires a number as an argument.\n");
442 exit(EXIT_FAILURE);
443 }
444 } else {
445 fprintf(stderr, "only root may set the debug level.\n");
446 exit(EXIT_FAILURE);
447 }
448 break;
449 case 'f':
450 /* set return path */
451 {
452 gchar *address;
453 address = get_optarg(argv, argc, &arg, &pos);
454 if (address) {
455 f_address = g_strdup(address);
456 } else {
457 fprintf(stderr, "-f requires an address as an argument\n");
458 exit(EXIT_FAILURE);
459 }
460 }
461 break;
462 case 'g':
463 do_get = TRUE;
464 if (!mta_mode)
465 mta_mode = MODE_NONE; /* to prevent default MODE_ACCEPT */
466 if (argv[arg][pos] == 'o') {
467 pos++;
468 do_get_online = TRUE;
469 /* can be NULL, then we use online detection method */
470 route_name = get_optarg(argv, argc, &arg, &pos);
471
472 if (route_name != NULL) {
473 if (isdigit(route_name[0])) {
474 get_interval = time_interval(route_name, &pos);
475 route_name = get_optarg(argv, argc, &arg, &pos);
476 mta_mode = MODE_GET_DAEMON;
477 do_get = FALSE;
478 }
479 }
480 } else {
481 if ((optarg = get_optarg(argv, argc, &arg, &pos))) {
482 get_name = get_optarg(argv, argc, &arg, &pos);
483 }
484 }
485 break;
486 case 'i':
487 if (argv[arg][pos] == 0) {
488 opt_i = TRUE;
489 exit_failure = FALSE; /* may override -oem */
490 } else {
491 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
492 exit(EXIT_FAILURE);
493 }
494 break;
495 case 'M':
496 {
497 mta_mode = MODE_MCMD;
498 M_cmd = g_strdup(&(argv[arg][pos]));
499 }
500 break;
501 case 'o':
502 switch (argv[arg][pos++]) {
503 case 'e':
504 if (argv[arg][pos++] == 'm') /* -oem */
505 if (!opt_i)
506 exit_failure = TRUE;
507 opt_oem = TRUE;
508 break;
509 case 'd':
510 if (argv[arg][pos] == 'b') /* -odb */
511 opt_odb = TRUE;
512 else if (argv[arg][pos] == 'q') /* -odq */
513 do_queue = TRUE;
514 break;
515 case 'i':
516 opt_i = TRUE;
517 exit_failure = FALSE; /* may override -oem */
518 break;
519 }
520 break;
521
522 case 'q':
523 {
524 gchar *optarg;
525
526 do_runq = TRUE;
527 mta_mode = MODE_RUNQUEUE;
528 if (argv[arg][pos] == 'o') {
529 pos++;
530 do_runq = FALSE;
531 do_runq_online = TRUE;
532 /* can be NULL, then we use online detection method */
533 route_name = get_optarg(argv, argc, &arg, &pos);
534 } else
535 if ((optarg = get_optarg(argv, argc, &arg, &pos))) {
536 mta_mode = MODE_DAEMON;
537 queue_interval = time_interval(optarg, &pos);
538 }
539 }
540 break;
541 case 't':
542 if (argv[arg][pos] == 0) {
543 opt_t = TRUE;
544 } else {
545 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
546 exit(EXIT_FAILURE);
547 }
548 break;
549 case 'v':
550 do_verbose = TRUE;
551 break;
552 default:
553 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
554 exit(EXIT_FAILURE);
555 }
556 } else {
557 if (argv[arg][pos + 1] == '-') {
558 if (argv[arg][pos + 2] != '\0') {
559 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
560 exit(EXIT_FAILURE);
561 }
562 arg++;
563 }
564 break;
565 }
566 arg++;
567 }
568
569 if (mta_mode == MODE_VERSION) {
570 gchar *with_resolver = "", *with_smtp_server = "", *with_pop3 = "",
571 *with_auth = "", *with_maildir = "", *with_ident = "", *with_mserver = "";
572
573 #ifdef ENABLE_RESOLVER
574 with_resolver = " +resolver";
575 #endif
576 #ifdef ENABLE_SMTP_SERVER
577 with_smtp_server = " +smtp-server";
578 #endif
579 #ifdef ENABLE_POP3
580 with_pop3 = " +pop3";
581 #endif
582 #ifdef ENABLE_AUTH
583 with_auth = " +auth";
584 #endif
585 #ifdef ENABLE_MAILDIR
586 with_maildir = " +maildir";
587 #endif
588 #ifdef ENABLE_IDENT
589 with_ident = " +ident";
590 #endif
591 #ifdef ENABLE_MSERVER
592 with_mserver = " +mserver";
593 #endif
594
595 printf("%s %s%s%s%s%s%s%s%s\n", PACKAGE, VERSION, with_resolver, with_smtp_server,
596 with_pop3, with_auth, with_maildir, with_ident, with_mserver);
597
598 exit(EXIT_SUCCESS);
599 }
600
601 /* initialize random generator */
602 srand(time(NULL));
603 /* ignore SIGPIPE signal */
604 signal(SIGPIPE, SIG_IGN);
605
606 /* close all possibly open file descriptors */
607 {
608 int i, max_fd = sysconf(_SC_OPEN_MAX);
609
610 if (max_fd <= 0)
611 max_fd = 64;
612 for (i = 3; i < max_fd; i++)
613 close(i);
614 }
615
616 init_conf();
617
618 /* if we are not privileged, and the config file was changed we
619 implicetely set the the run_as_user flag and give up all
620 privileges.
621
622 So it is possible for a user to run his own daemon without
623 breaking security.
624 */
625 if (strcmp(conf_file, CONF_FILE) != 0) {
626 if (conf.orig_uid != 0) {
627 conf.run_as_user = TRUE;
628 seteuid(conf.orig_uid);
629 setegid(conf.orig_gid);
630 setuid(conf.orig_uid);
631 setgid(conf.orig_gid);
632 }
633 }
634
635 read_conf(conf_file);
636
637 if (do_queue)
638 conf.do_queue = TRUE;
639 if (do_verbose)
640 conf.do_verbose = TRUE;
641 if (debug_level >= 0) /* if >= 0, it was given by argument */
642 conf.debug_level = debug_level;
643
644 chdir("/");
645
646 if (!conf.run_as_user) {
647 if (setgid(0) != 0) {
648 fprintf(stderr, "could not set gid to 0. Is the setuid bit set? : %s\n", strerror(errno));
649 exit(EXIT_FAILURE);
650 }
651 if (setuid(0) != 0) {
652 fprintf(stderr, "could not gain root privileges. Is the setuid bit set? : %s\n", strerror(errno));
653 exit(EXIT_FAILURE);
654 }
655 }
656
657 if (!logopen()) {
658 fprintf(stderr, "could not open log file\n");
659 exit(EXIT_FAILURE);
660 }
661
662 DEBUG(1) debugf("masqmail %s starting\n", VERSION);
663
664 DEBUG(5) {
665 gchar **str = argv;
666 debugf("args: \n");
667 while (*str) {
668 debugf("%s \n", *str);
669 str++;
670 }
671 }
672 DEBUG(5) debugf("queue_interval = %d\n", queue_interval);
673
674 if (f_address) {
675 return_path = create_address_qualified(f_address, TRUE, conf.host_name);
676 g_free(f_address);
677 if (!return_path) {
678 fprintf(stderr, "invalid RFC821 address: %s\n", f_address);
679 exit(EXIT_FAILURE);
680 }
681 }
682
683 if (do_get) {
684 #ifdef ENABLE_POP3
685 if ((mta_mode == MODE_NONE) || (mta_mode == MODE_RUNQUEUE)) {
686 set_identity(conf.orig_uid, "getting mail");
687 if (do_get_online) {
688 if (route_name != NULL) {
689 conf.online_detect = g_strdup("argument");
690 set_online_name(route_name);
691 }
692 get_online();
693 } else {
694 if (get_name)
695 get_from_name(get_name);
696 else
697 get_all();
698 }
699 } else {
700 logwrite(LOG_ALERT, "get (-g) only allowed alone or together with queue run (-q)\n");
701 }
702 #else
703 fprintf(stderr, "get (pop) support not compiled in\n");
704 #endif
705 }
706
707 switch (mta_mode) {
708 case MODE_DAEMON:
709 mode_daemon(do_listen, queue_interval, argv);
710 break;
711 case MODE_RUNQUEUE:
712 {
713 /* queue runs */
714 set_identity(conf.orig_uid, "queue run");
715
716 if (do_runq)
717 exit_code = queue_run() ? EXIT_SUCCESS : EXIT_FAILURE;
718
719 if (do_runq_online) {
720 if (route_name != NULL) {
721 conf.online_detect = g_strdup("argument");
722 set_online_name(route_name);
723 }
724 exit_code =
725 queue_run_online() ? EXIT_SUCCESS : EXIT_FAILURE;
726 }
727 }
728 break;
729 case MODE_GET_DAEMON:
730 #ifdef ENABLE_POP3
731 if (route_name != NULL) {
732 conf.online_detect = g_strdup("argument");
733 set_online_name(route_name);
734 }
735 mode_get_daemon(get_interval, argv);
736 #endif
737 break;
738
739 case MODE_SMTP:
740 #ifdef ENABLE_SMTP_SERVER
741 mode_smtp();
742 #else
743 fprintf(stderr, "smtp server support not compiled in\n");
744 #endif
745 break;
746
747 case MODE_LIST:
748 queue_list();
749 break;
750
751 case MODE_BI:
752 exit(EXIT_SUCCESS);
753 break; /* well... */
754
755 case MODE_MCMD:
756 if (strcmp(M_cmd, "rm") == 0) {
757 gboolean ok = FALSE;
758
759 set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL);
760
761 if (is_privileged_user(conf.orig_uid)) {
762 for (; arg < argc; arg++) {
763 if (queue_delete(argv[arg]))
764 ok = TRUE;
765 }
766 } else {
767 struct passwd *pw = getpwuid(conf.orig_uid);
768 if (pw) {
769 for (; arg < argc; arg++) {
770 message *msg = msg_spool_read(argv[arg], FALSE);
771 #ifdef ENABLE_IDENT
772 if (((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL))
773 || is_in_netlist(msg->received_host, conf.ident_trusted_nets)) {
774 #else
775 if ((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)) {
776 #endif
777 if (msg->ident) {
778 if (strcmp(pw->pw_name, msg->ident) == 0) {
779 if (queue_delete(argv[arg]))
780 ok = TRUE;
781 } else {
782 fprintf(stderr, "you do not own message id %s\n", argv[arg]);
783 }
784 } else
785 fprintf(stderr, "message %s does not have an ident.\n", argv[arg]);
786 } else {
787 fprintf(stderr, "message %s was not received locally or from a trusted network.\n", argv[arg]);
788 }
789 }
790 } else {
791 fprintf(stderr, "could not find a passwd entry for uid %d: %s\n", conf.orig_uid, strerror(errno));
792 }
793 }
794 exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
795 } else {
796 fprintf(stderr, "unknown command %s\n", M_cmd);
797 exit(EXIT_FAILURE);
798 }
799 break;
800
801 case MODE_ACCEPT:
802 {
803 guint accept_flags = (opt_t ? ACC_DEL_RCPTS | ACC_DEL_BCC | ACC_RCPT_FROM_HEAD : ACC_HEAD_FROM_RCPT)
804 | (opt_i ? ACC_NODOT_TERM : ACC_NODOT_RELAX);
805 mode_accept(return_path, full_sender_name, accept_flags, &(argv[arg]), argc - arg);
806 exit(exit_failure ? EXIT_FAILURE : EXIT_SUCCESS);
807 }
808 break;
809 case MODE_NONE:
810 break;
416 default: 811 default:
417 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); 812 fprintf(stderr, "unknown mode: %d\n", mta_mode);
418 exit(EXIT_FAILURE); 813 break;
419 } 814 }
420 break; 815
421 case 'B': 816 logclose();
422 /* we ignore this and throw the argument away */ 817
423 get_optarg(argv, argc, &arg, &pos); 818 exit(exit_code);
424 break; 819 }
425 case 'C':
426 if(!(conf_file = get_optarg(argv, argc, &arg, &pos))){
427 fprintf(stderr, "-C requires a filename as argument.\n");
428 exit(EXIT_FAILURE);
429 }
430 break;
431 case 'F':
432 {
433 full_sender_name = get_optarg(argv, argc, &arg, &pos);
434 if(!full_sender_name){
435 fprintf(stderr, "-F requires a name as an argument\n");
436 exit(EXIT_FAILURE);
437 }
438 }
439 break;
440 case 'd':
441 if(getuid() == 0){
442 char *lvl = get_optarg(argv, argc, &arg, &pos);
443 if(lvl)
444 debug_level = atoi(lvl);
445 else{
446 fprintf(stderr, "-d requires a number as an argument.\n");
447 exit(EXIT_FAILURE);
448 }
449 }else{
450 fprintf(stderr, "only root may set the debug level.\n");
451 exit(EXIT_FAILURE);
452 }
453 break;
454 case 'f':
455 /* set return path */
456 {
457 gchar *address;
458 address = get_optarg(argv, argc, &arg, &pos);
459 if(address){
460 f_address = g_strdup(address);
461 }else{
462 fprintf(stderr, "-f requires an address as an argument\n");
463 exit(EXIT_FAILURE);
464 }
465 }
466 break;
467 case 'g':
468 do_get = TRUE;
469 if(!mta_mode) mta_mode = MODE_NONE; /* to prevent default MODE_ACCEPT */
470 if(argv[arg][pos] == 'o'){
471 pos++;
472 do_get_online = TRUE;
473 /* can be NULL, then we use online detection method */
474 route_name = get_optarg(argv, argc, &arg, &pos);
475
476 if(route_name != NULL){
477 if(isdigit(route_name[0])){
478 get_interval = time_interval(route_name, &pos);
479 route_name = get_optarg(argv, argc, &arg, &pos);
480 mta_mode = MODE_GET_DAEMON;
481 do_get = FALSE;
482 }
483 }
484 }else{
485 if((optarg = get_optarg(argv, argc, &arg, &pos))){
486 get_name = get_optarg(argv, argc, &arg, &pos);
487 }
488 }
489 break;
490 case 'i':
491 if(argv[arg][pos] == 0){
492 opt_i = TRUE;
493 exit_failure = FALSE; /* may override -oem */
494 }else{
495 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
496 exit(EXIT_FAILURE);
497 }
498 break;
499 case 'M':
500 {
501 mta_mode = MODE_MCMD;
502 M_cmd = g_strdup(&(argv[arg][pos]));
503 }
504 break;
505 case 'o':
506 switch(argv[arg][pos++]){
507 case 'e':
508 if(argv[arg][pos++] == 'm') /* -oem */
509 if(!opt_i) exit_failure = TRUE;
510 opt_oem = TRUE;
511 break;
512 case 'd':
513 if(argv[arg][pos] == 'b') /* -odb */
514 opt_odb = TRUE;
515 else if(argv[arg][pos] == 'q') /* -odq */
516 do_queue = TRUE;
517 break;
518 case 'i':
519 opt_i = TRUE;
520 exit_failure = FALSE; /* may override -oem */
521 break;
522 }
523 break;
524
525 case 'q':
526 {
527 gchar *optarg;
528
529 do_runq = TRUE;
530 mta_mode = MODE_RUNQUEUE;
531 if(argv[arg][pos] == 'o'){
532 pos++;
533 do_runq = FALSE;
534 do_runq_online = TRUE;
535 /* can be NULL, then we use online detection method */
536 route_name = get_optarg(argv, argc, &arg, &pos);
537 }else if((optarg = get_optarg(argv, argc, &arg, &pos))){
538 mta_mode = MODE_DAEMON;
539 queue_interval = time_interval(optarg, &pos);
540 }
541 }
542 break;
543 case 't':
544 if(argv[arg][pos] == 0){
545 opt_t = TRUE;
546 }else{
547 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
548 exit(EXIT_FAILURE);
549 }
550 break;
551 case 'v':
552 do_verbose = TRUE;
553 break;
554 default:
555 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
556 exit(EXIT_FAILURE);
557 }
558 }else{
559 if(argv[arg][pos+1] == '-'){
560 if(argv[arg][pos+2] != '\0'){
561 fprintf(stderr, "unrecognized option '%s'\n", argv[arg]);
562 exit(EXIT_FAILURE);
563 }
564 arg++;
565 }
566 break;
567 }
568 arg++;
569 }
570
571 if(mta_mode == MODE_VERSION){
572 gchar *with_resolver = "", *with_smtp_server = "", *with_pop3 = "", *with_auth = "",
573 *with_maildir = "", *with_ident = "", *with_mserver = "";
574
575 #ifdef ENABLE_RESOLVER
576 with_resolver = " +resolver";
577 #endif
578 #ifdef ENABLE_SMTP_SERVER
579 with_smtp_server = " +smtp-server";
580 #endif
581 #ifdef ENABLE_POP3
582 with_pop3 = " +pop3";
583 #endif
584 #ifdef ENABLE_AUTH
585 with_auth = " +auth";
586 #endif
587 #ifdef ENABLE_MAILDIR
588 with_maildir = " +maildir";
589 #endif
590 #ifdef ENABLE_IDENT
591 with_ident = " +ident";
592 #endif
593 #ifdef ENABLE_MSERVER
594 with_mserver = " +mserver";
595 #endif
596
597 printf("%s %s%s%s%s%s%s%s%s\n", PACKAGE, VERSION,
598 with_resolver, with_smtp_server, with_pop3, with_auth,
599 with_maildir, with_ident, with_mserver);
600
601 exit(EXIT_SUCCESS);
602 }
603
604 /* initialize random generator */
605 srand(time(NULL));
606 /* ignore SIGPIPE signal */
607 signal(SIGPIPE, SIG_IGN);
608
609 /* close all possibly open file descriptors */
610 {
611 int i, max_fd = sysconf(_SC_OPEN_MAX);
612
613 if(max_fd <= 0) max_fd = 64;
614 for(i = 3; i < max_fd; i++)
615 close(i);
616 }
617
618 init_conf();
619
620 /* if we are not privileged, and the config file was changed we
621 implicetely set the the run_as_user flag and give up all
622 privileges.
623
624 So it is possible for a user to run his own daemon without
625 breaking security.
626 */
627 if(strcmp(conf_file, CONF_FILE) != 0){
628 if(conf.orig_uid != 0){
629 conf.run_as_user = TRUE;
630 seteuid(conf.orig_uid);
631 setegid(conf.orig_gid);
632 setuid(conf.orig_uid);
633 setgid(conf.orig_gid);
634 }
635 }
636
637 read_conf(conf_file);
638
639 if(do_queue) conf.do_queue = TRUE;
640 if(do_verbose) conf.do_verbose = TRUE;
641 if(debug_level >= 0) /* if >= 0, it was given by argument */
642 conf.debug_level = debug_level;
643
644 chdir("/");
645
646 if(!conf.run_as_user){
647 if(setgid(0) != 0){
648 fprintf(stderr,
649 "could not set gid to 0. Is the setuid bit set? : %s\n",
650 strerror(errno));
651 exit(EXIT_FAILURE);
652 }
653 if(setuid(0) != 0){
654 fprintf(stderr,
655 "could not gain root privileges. Is the setuid bit set? : %s\n",
656 strerror(errno));
657 exit(EXIT_FAILURE);
658 }
659 }
660
661 if(!logopen()){
662 fprintf(stderr, "could not open log file\n");
663 exit(EXIT_FAILURE);
664 }
665
666 DEBUG(1) debugf("masqmail %s starting\n", VERSION);
667
668 DEBUG(5){
669 gchar **str = argv;
670 debugf("args: \n");
671 while(*str){
672 debugf("%s \n", *str);
673 str++;
674 }
675 }
676 DEBUG(5) debugf("queue_interval = %d\n", queue_interval);
677
678 if(f_address){
679 return_path = create_address_qualified(f_address, TRUE, conf.host_name);
680 g_free(f_address);
681 if(!return_path){
682 fprintf(stderr, "invalid RFC821 address: %s\n", f_address);
683 exit(EXIT_FAILURE);
684 }
685 }
686
687 if(do_get){
688 #ifdef ENABLE_POP3
689 if((mta_mode == MODE_NONE) || (mta_mode == MODE_RUNQUEUE)){
690
691 set_identity(conf.orig_uid, "getting mail");
692
693 if(do_get_online){
694 if(route_name != NULL){
695 conf.online_detect = g_strdup("argument");
696 set_online_name(route_name);
697 }
698 get_online();
699 }else{
700 if(get_name)
701 get_from_name(get_name);
702 else
703 get_all();
704 }
705 }else{
706 logwrite(LOG_ALERT, "get (-g) only allowed alone or together with queue run (-q)\n");
707 }
708 #else
709 fprintf(stderr, "get (pop) support not compiled in\n");
710 #endif
711 }
712
713 switch(mta_mode){
714 case MODE_DAEMON:
715 mode_daemon(do_listen, queue_interval, argv);
716 break;
717 case MODE_RUNQUEUE:
718 {
719 /* queue runs */
720 set_identity(conf.orig_uid, "queue run");
721
722 if(do_runq)
723 exit_code = queue_run() ? EXIT_SUCCESS : EXIT_FAILURE;
724
725 if(do_runq_online){
726 if(route_name != NULL){
727 conf.online_detect = g_strdup("argument");
728 set_online_name(route_name);
729 }
730 exit_code = queue_run_online() ? EXIT_SUCCESS : EXIT_FAILURE;
731 }
732 }
733 break;
734 case MODE_GET_DAEMON:
735 #ifdef ENABLE_POP3
736 if(route_name != NULL){
737 conf.online_detect = g_strdup("argument");
738 set_online_name(route_name);
739 }
740 mode_get_daemon(get_interval, argv);
741 #endif
742 break;
743
744 case MODE_SMTP:
745 #ifdef ENABLE_SMTP_SERVER
746 mode_smtp();
747 #else
748 fprintf(stderr, "smtp server support not compiled in\n");
749 #endif
750 break;
751 case MODE_LIST:
752
753 queue_list();
754 break;
755
756 case MODE_BI:
757
758 exit(EXIT_SUCCESS);
759 break; /* well... */
760
761 case MODE_MCMD:
762 if(strcmp(M_cmd, "rm") == 0){
763 gboolean ok = FALSE;
764
765 set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL);
766
767 if(is_privileged_user(conf.orig_uid)){
768 for(; arg < argc; arg++){
769 if(queue_delete(argv[arg]))
770 ok = TRUE;
771 }
772 }else{
773 struct passwd *pw = getpwuid(conf.orig_uid);
774 if(pw){
775 for(; arg < argc; arg++){
776 message *msg = msg_spool_read(argv[arg], FALSE);
777 #ifdef ENABLE_IDENT
778 if(((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)) ||
779 is_in_netlist(msg->received_host, conf.ident_trusted_nets)){
780 #else
781 if((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)){
782 #endif
783 if(msg->ident){
784 if(strcmp(pw->pw_name, msg->ident) == 0){
785 if(queue_delete(argv[arg]))
786 ok = TRUE;
787 }else{
788 fprintf(stderr, "you do not own message id %s\n", argv[arg]);
789 }
790 }else
791 fprintf(stderr, "message %s does not have an ident.\n", argv[arg]);
792 }else{
793 fprintf(stderr, "message %s was not received locally or from a trusted network.\n", argv[arg]);
794 }
795 }
796 }else{
797 fprintf(stderr, "could not find a passwd entry for uid %d: %s\n", conf.orig_uid, strerror(errno));
798 }
799 }
800 exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
801 }else{
802 fprintf(stderr, "unknown command %s\n", M_cmd);
803 exit(EXIT_FAILURE);
804 }
805 break;
806
807 case MODE_ACCEPT:
808 {
809 guint accept_flags =
810 (opt_t ? ACC_DEL_RCPTS|ACC_DEL_BCC|ACC_RCPT_FROM_HEAD : ACC_HEAD_FROM_RCPT) |
811 (opt_i ? ACC_NODOT_TERM : ACC_NODOT_RELAX);
812
813 mode_accept(return_path, full_sender_name, accept_flags, &(argv[arg]), argc - arg);
814
815 exit(exit_failure ? EXIT_FAILURE : EXIT_SUCCESS);
816 }
817 break;
818 case MODE_NONE:
819 break;
820 default:
821 fprintf(stderr, "unknown mode: %d\n", mta_mode);
822 break;
823 }
824
825 logclose();
826
827 exit(exit_code);
828 }