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;