Mercurial > masqmail
comparison src/deliver.c @ 367:b27f66555ba8
Reformated multiline comments to have leading asterisks on each line
Now we use:
/*
** comment
*/
This makes the indent style simpler, too.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Thu, 20 Oct 2011 10:20:59 +0200 |
parents | 41958685480d |
children | d86d7b4b8995 |
comparison
equal
deleted
inserted
replaced
366:41958685480d | 367:b27f66555ba8 |
---|---|
1 /* MasqMail | 1 /* |
2 Copyright (C) 1999-2002 Oliver Kurth | 2 ** MasqMail |
3 Copyright (C) 2008, 2010 markus schnalke <meillo@marmaro.de> | 3 ** Copyright (C) 1999-2002 Oliver Kurth |
4 | 4 ** Copyright (C) 2008, 2010 markus schnalke <meillo@marmaro.de> |
5 This program is free software; you can redistribute it and/or modify | 5 ** |
6 it under the terms of the GNU General Public License as published by | 6 ** This program is free software; you can redistribute it and/or modify |
7 the Free Software Foundation; either version 2 of the License, or | 7 ** it under the terms of the GNU General Public License as published by |
8 (at your option) any later version. | 8 ** the Free Software Foundation; either version 2 of the License, or |
9 | 9 ** (at your option) any later version. |
10 This program is distributed in the hope that it will be useful, | 10 ** |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 ** This program is distributed in the hope that it will be useful, |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 GNU General Public License for more details. | 13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | 14 ** GNU General Public License for more details. |
15 You should have received a copy of the GNU General Public License | 15 ** |
16 along with this program; if not, write to the Free Software | 16 ** You should have received a copy of the GNU General Public License |
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 17 ** along with this program; if not, write to the Free Software |
18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 */ | 19 */ |
19 | 20 |
20 #include <fnmatch.h> | 21 #include <fnmatch.h> |
21 #include <sysexits.h> | 22 #include <sysexits.h> |
22 #include <netdb.h> | 23 #include <netdb.h> |
23 | 24 |
24 #include "masqmail.h" | 25 #include "masqmail.h" |
25 #include "smtp_out.h" | 26 #include "smtp_out.h" |
26 | 27 |
27 /* collect failed/defered rcpts for failure/warning messages */ | 28 /* |
28 /* returns TRUE if either there are no failures or a failure message has been successfully sent */ | 29 ** collect failed/defered rcpts for failure/warning messages |
30 ** returns TRUE if either there are no failures or a failure message has | |
31 ** been successfully sent | |
32 */ | |
29 gboolean | 33 gboolean |
30 delivery_failures(message *msg, GList *rcpt_list, gchar *err_fmt, ...) | 34 delivery_failures(message *msg, GList *rcpt_list, gchar *err_fmt, ...) |
31 { | 35 { |
32 gboolean ok_fail = TRUE, ok_warn = TRUE; | 36 gboolean ok_fail = TRUE, ok_warn = TRUE; |
33 time_t now = time(NULL); | 37 time_t now = time(NULL); |
171 address *rcpt = (address *) (rcpt_node->data); | 175 address *rcpt = (address *) (rcpt_node->data); |
172 address *env_addr = addr_find_ancestor(rcpt); | 176 address *env_addr = addr_find_ancestor(rcpt); |
173 address *ret_path = msg->return_path; | 177 address *ret_path = msg->return_path; |
174 header *retpath_hdr, *envto_hdr; | 178 header *retpath_hdr, *envto_hdr; |
175 | 179 |
176 /* we need a private copy of the hdr list because we add headers | 180 /* |
177 here that belong to the rcpt only. g_list_copy copies only | 181 ** we need a private copy of the hdr list because we add |
178 the nodes, so it is safe to g_list_free it */ | 182 ** headers here that belong to the rcpt only. g_list_copy |
183 ** copies only the nodes, so it is safe to g_list_free it | |
184 */ | |
179 hdr_list = g_list_copy(msg->hdr_list); | 185 hdr_list = g_list_copy(msg->hdr_list); |
180 retpath_hdr = create_header(HEAD_ENVELOPE_TO, "Envelope-to: %s\n", addr_string(env_addr)); | 186 retpath_hdr = create_header(HEAD_ENVELOPE_TO, "Envelope-to: %s\n", addr_string(env_addr)); |
181 envto_hdr = create_header(HEAD_RETURN_PATH, "Return-path: %s\n", addr_string(ret_path)); | 187 envto_hdr = create_header(HEAD_RETURN_PATH, "Return-path: %s\n", addr_string(ret_path)); |
182 | 188 |
183 hdr_list = g_list_prepend(hdr_list, envto_hdr); | 189 hdr_list = g_list_prepend(hdr_list, envto_hdr); |
184 hdr_list = g_list_prepend(hdr_list, retpath_hdr); | 190 hdr_list = g_list_prepend(hdr_list, retpath_hdr); |
185 | 191 |
186 if (rcpt->local_part[0] == '|') { | 192 if (rcpt->local_part[0] == '|') { |
187 /* probably for expanded aliases, but why not done | 193 /* |
188 like with the mda? //meillo 2010-12-06 */ | 194 ** probably for expanded aliases, but why not done |
195 ** like with the mda? //meillo 2010-12-06 | |
196 */ | |
189 if (deliver_local_pipe(msg, hdr_list, rcpt, env_addr)) { | 197 if (deliver_local_pipe(msg, hdr_list, rcpt, env_addr)) { |
190 ok = TRUE; | 198 ok = TRUE; |
191 } | 199 } |
192 } else { | 200 } else { |
193 /* figure out which mailbox type should be used for this user */ | 201 /* figure out which mailbox type should be used for this user */ |
233 } | 241 } |
234 | 242 |
235 return ok; | 243 return ok; |
236 } | 244 } |
237 | 245 |
238 /* make a list of rcpt's of a message that are local | 246 /* |
239 return a new copy of the list */ | 247 ** make a list of rcpt's of a message that are local |
248 ** return a new copy of the list | |
249 */ | |
240 void | 250 void |
241 msg_rcptlist_local(GList *rcpt_list, GList **p_local_list, GList **p_nonlocal_list) | 251 msg_rcptlist_local(GList *rcpt_list, GList **p_local_list, |
252 GList **p_nonlocal_list) | |
242 { | 253 { |
243 GList *rcpt_node; | 254 GList *rcpt_node; |
244 | 255 |
245 foreach(rcpt_list, rcpt_node) { | 256 foreach(rcpt_list, rcpt_node) { |
246 address *rcpt = (address *) (rcpt_node->data); | 257 address *rcpt = (address *) (rcpt_node->data); |
327 } | 338 } |
328 | 339 |
329 return ok; | 340 return ok; |
330 } | 341 } |
331 | 342 |
332 /* deliver list of messages to one host and finishes them if the message was | 343 /* |
333 delivered to at least one rcpt. | 344 ** deliver list of messages to one host and finishes them if the message was |
334 Returns TRUE if at least one msg was delivered to at least one rcpt. | 345 ** delivered to at least one rcpt. |
335 */ | 346 ** Returns TRUE if at least one msg was delivered to at least one rcpt. |
336 gboolean | 347 */ |
337 deliver_msglist_host_smtp(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) | 348 gboolean |
349 deliver_msglist_host_smtp(connect_route *route, GList *msgout_list, | |
350 gchar *host, GList *res_list) | |
338 { | 351 { |
339 gboolean ok = FALSE; | 352 gboolean ok = FALSE; |
340 GList *msgout_node; | 353 GList *msgout_node; |
341 smtp_base *psb; | 354 smtp_base *psb; |
342 gint port = 25; | 355 gint port = 25; |
475 return deliver_msglist_host_smtp(route, msgout_list, host, res_list); | 488 return deliver_msglist_host_smtp(route, msgout_list, host, res_list); |
476 } | 489 } |
477 } | 490 } |
478 | 491 |
479 /* | 492 /* |
480 delivers messages in msgout_list using route | 493 ** delivers messages in msgout_list using route |
481 */ | 494 */ |
482 gboolean | 495 gboolean |
483 deliver_route_msgout_list(connect_route *route, GList *msgout_list) | 496 deliver_route_msgout_list(connect_route *route, GList *msgout_list) |
484 { | 497 { |
485 gboolean ok = FALSE; | 498 gboolean ok = FALSE; |
499 /* okay, now we have ordered our messages by the hosts. */ | 512 /* okay, now we have ordered our messages by the hosts. */ |
500 if (!mo_ph_list) { | 513 if (!mo_ph_list) { |
501 return FALSE; | 514 return FALSE; |
502 } | 515 } |
503 | 516 |
504 /* TODO: It would be nice to be able to fork for each host. | 517 /* |
505 We cannot do that yet because of complications with finishing the | 518 ** TODO: It would be nice to be able to fork for each host. |
506 messages. Threads could be a solution because they use the same | 519 ** We cannot do that yet because of complications with finishing the |
507 memory. But we are not thread safe yet... | 520 ** messages. Threads could be a solution because they use the same |
508 */ | 521 ** memory. But we are not thread safe yet... |
522 */ | |
509 foreach(mo_ph_list, mo_ph_node) { | 523 foreach(mo_ph_list, mo_ph_node) { |
510 msgout_perhost *mo_ph = (msgout_perhost *) (mo_ph_node->data); | 524 msgout_perhost *mo_ph = (msgout_perhost *) (mo_ph_node->data); |
511 if (deliver_msglist_host(route, mo_ph->msgout_list, mo_ph->host, route->resolve_list)) { | 525 if (deliver_msglist_host(route, mo_ph->msgout_list, mo_ph->host, route->resolve_list)) { |
512 ok = TRUE; | 526 ok = TRUE; |
513 } | 527 } |
516 g_list_free(mo_ph_list); | 530 g_list_free(mo_ph_list); |
517 return ok; | 531 return ok; |
518 } | 532 } |
519 | 533 |
520 /* | 534 /* |
521 calls route_prepare_msg() | 535 ** calls route_prepare_msg() |
522 delivers messages in msg_list using route by calling deliver_route_msgout_list() | 536 ** delivers messages in msg_list using route by calling |
537 ** deliver_route_msgout_list() | |
523 */ | 538 */ |
524 gboolean | 539 gboolean |
525 deliver_route_msg_list(connect_route *route, GList *msgout_list) | 540 deliver_route_msg_list(connect_route *route, GList *msgout_list) |
526 { | 541 { |
527 GList *msgout_list_deliver = NULL; | 542 GList *msgout_list_deliver = NULL; |
534 msg_out *msgout = (msg_out *) (msgout_node->data); | 549 msg_out *msgout = (msg_out *) (msgout_node->data); |
535 msg_out *msgout_cloned = clone_msg_out(msgout); | 550 msg_out *msgout_cloned = clone_msg_out(msgout); |
536 GList *rcpt_list_non_delivered = NULL; | 551 GList *rcpt_list_non_delivered = NULL; |
537 GList *rcpt_node; | 552 GList *rcpt_node; |
538 | 553 |
539 /* we have to delete already delivered rcpt's because a | 554 /* |
540 previous route may have delivered to it */ | 555 ** we have to delete already delivered rcpt's because a |
556 ** previous route may have delivered to it | |
557 */ | |
541 foreach(msgout_cloned->rcpt_list, rcpt_node) { | 558 foreach(msgout_cloned->rcpt_list, rcpt_node) { |
542 address *rcpt = (address *) (rcpt_node->data); | 559 address *rcpt = (address *) (rcpt_node->data); |
543 /* failed addresses already have been bounced; | 560 /* |
544 there should be a better way to handle those. */ | 561 ** failed addresses already have been bounced; |
562 ** there should be a better way to handle those. | |
563 */ | |
545 if (!addr_is_delivered(rcpt) && !addr_is_failed(rcpt) | 564 if (!addr_is_delivered(rcpt) && !addr_is_failed(rcpt) |
546 && !(rcpt->flags & ADDR_FLAG_LAST_ROUTE)) { | 565 && !(rcpt->flags & ADDR_FLAG_LAST_ROUTE)) { |
547 rcpt_list_non_delivered = g_list_append(rcpt_list_non_delivered, rcpt); | 566 rcpt_list_non_delivered = g_list_append(rcpt_list_non_delivered, rcpt); |
548 } | 567 } |
549 } | 568 } |
594 destroy_msg_out_list(msgout_list_deliver); | 613 destroy_msg_out_list(msgout_list_deliver); |
595 } | 614 } |
596 return ok; | 615 return ok; |
597 } | 616 } |
598 | 617 |
599 /* copy pointers of delivered addresses to the msg's non_rcpt_list, | 618 /* |
600 to make sure that they will not be delivered again. | 619 ** copy pointers of delivered addresses to the msg's non_rcpt_list, |
620 ** to make sure that they will not be delivered again. | |
601 */ | 621 */ |
602 void | 622 void |
603 update_non_rcpt_list(msg_out *msgout) | 623 update_non_rcpt_list(msg_out *msgout) |
604 { | 624 { |
605 GList *rcpt_node; | 625 GList *rcpt_node; |
611 msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, rcpt); | 631 msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, rcpt); |
612 } | 632 } |
613 } | 633 } |
614 } | 634 } |
615 | 635 |
616 /* after delivery attempts, we check if there are any rcpt addresses left in | 636 /* |
617 the message. If all addresses have been completed, the spool files will be | 637 ** after delivery attempts, we check if there are any rcpt addresses left in |
618 deleted, otherwise the header spool will be written back. We never changed | 638 ** the message. If all addresses have been completed, the spool files will be |
619 the data spool, so there is no need to write that back. | 639 ** deleted, otherwise the header spool will be written back. We never changed |
620 | 640 ** the data spool, so there is no need to write that back. |
621 returns TRUE if all went well. | 641 ** |
642 ** returns TRUE if all went well. | |
622 */ | 643 */ |
623 gboolean | 644 gboolean |
624 deliver_finish(msg_out *msgout) | 645 deliver_finish(msg_out *msgout) |
625 { | 646 { |
626 GList *rcpt_node; | 647 GList *rcpt_node; |
627 message *msg = msgout->msg; | 648 message *msg = msgout->msg; |
628 gboolean finished = TRUE; | 649 gboolean finished = TRUE; |
629 | 650 |
630 update_non_rcpt_list(msgout); | 651 update_non_rcpt_list(msgout); |
631 | 652 |
632 /* we NEVER made copies of the addresses, flags affecting addresses | 653 /* |
633 were always set on the original address structs */ | 654 ** we NEVER made copies of the addresses, flags affecting addresses |
655 ** were always set on the original address structs | |
656 */ | |
634 foreach(msg->rcpt_list, rcpt_node) { | 657 foreach(msg->rcpt_list, rcpt_node) { |
635 address *rcpt = (address *) (rcpt_node->data); | 658 address *rcpt = (address *) (rcpt_node->data); |
636 if (!addr_is_finished_children(rcpt)) { | 659 if (!addr_is_finished_children(rcpt)) { |
637 finished = FALSE; | 660 finished = FALSE; |
638 } else { | 661 } else { |
639 /* if ALL children have been delivered, mark parent as | 662 /* |
640 delivered. if there is one or more not delivered, | 663 ** if ALL children have been delivered, mark parent as |
641 it must have failed, we mark the parent as failed | 664 ** delivered. if there is one or more not delivered, |
642 as well. | 665 ** it must have failed, we mark the parent as failed |
643 */ | 666 ** as well. |
667 */ | |
644 if (addr_is_delivered_children(rcpt)) { | 668 if (addr_is_delivered_children(rcpt)) { |
645 addr_mark_delivered(rcpt); | 669 addr_mark_delivered(rcpt); |
646 } else { | 670 } else { |
647 addr_mark_failed(rcpt); | 671 addr_mark_failed(rcpt); |
648 } | 672 } |
726 | 750 |
727 return ok; | 751 return ok; |
728 } | 752 } |
729 | 753 |
730 /* | 754 /* |
731 This function splits the list of rcpt addresses | 755 ** This function splits the list of rcpt addresses |
732 into local and remote addresses and processes them accordingly. | 756 ** into local and remote addresses and processes them accordingly. |
733 */ | 757 */ |
734 gboolean | 758 gboolean |
735 deliver_msg_list(GList *msg_list, guint flags) | 759 deliver_msg_list(GList *msg_list, guint flags) |
736 { | 760 { |
737 GList *msgout_list = NULL; | 761 GList *msgout_list = NULL; |
837 | 861 |
838 return ok; | 862 return ok; |
839 } | 863 } |
840 | 864 |
841 /* | 865 /* |
842 deliver() is called when a message has just been received | 866 ** deliver() is called when a message has just been received |
843 (mode_accept and smtp_in) and should be delivered immediately | 867 ** (mode_accept and smtp_in) and should be delivered immediately |
844 (neither -odq nor do_queue). Only this one message will be tried to | 868 ** (neither -odq nor do_queue). Only this one message will be tried to |
845 deliver then. | 869 ** deliver then. |
846 */ | 870 */ |
847 gboolean | 871 gboolean |
848 deliver(message *msg) | 872 deliver(message *msg) |
849 { | 873 { |
850 gboolean ok; | 874 gboolean ok; |