masqmail
diff src/deliver.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 |
line diff
1.1 --- a/src/deliver.c Mon Oct 27 16:21:27 2008 +0100 1.2 +++ b/src/deliver.c Mon Oct 27 16:23:10 2008 +0100 1.3 @@ -25,506 +25,484 @@ 1.4 /* collect failed/defered rcpts for failure/warning messages */ 1.5 /* returns TRUE if either there are no failures or a 1.6 failure message has been successfully sent */ 1.7 -gboolean delivery_failures(message *msg, GList *rcpt_list, gchar *err_fmt, ...) 1.8 +gboolean 1.9 +delivery_failures(message * msg, GList * rcpt_list, gchar * err_fmt, ...) 1.10 { 1.11 - gboolean ok_fail = TRUE, ok_warn = TRUE; 1.12 - time_t now = time(NULL); 1.13 + gboolean ok_fail = TRUE, ok_warn = TRUE; 1.14 + time_t now = time(NULL); 1.15 1.16 - GList *failed_list = NULL, *defered_list = NULL, *rcpt_node; 1.17 - va_list args; 1.18 - va_start(args, err_fmt); 1.19 + GList *failed_list = NULL, *defered_list = NULL, *rcpt_node; 1.20 + va_list args; 1.21 + va_start(args, err_fmt); 1.22 1.23 - foreach(rcpt_list, rcpt_node){ 1.24 - address *rcpt = (address *)(rcpt_node->data); 1.25 - 1.26 - if(addr_is_defered(rcpt)){ 1.27 - if((now - msg->received_time) >= conf.max_defer_time){ 1.28 - addr_mark_failed(rcpt); 1.29 - }else 1.30 - defered_list = g_list_prepend(defered_list, rcpt); 1.31 - } 1.32 - if(addr_is_failed(rcpt)) 1.33 - failed_list = g_list_prepend(failed_list, rcpt); 1.34 - } 1.35 - if(failed_list != NULL){ 1.36 - ok_fail = fail_msg(msg, conf.errmsg_file, failed_list, err_fmt, args); 1.37 - g_list_free(failed_list); 1.38 - } 1.39 - if(defered_list != NULL){ 1.40 - ok_warn = warn_msg(msg, conf.warnmsg_file, defered_list, err_fmt, args); 1.41 - g_list_free(defered_list); 1.42 - } 1.43 - va_end(args); 1.44 - return ok_fail && ok_warn; 1.45 + foreach(rcpt_list, rcpt_node) { 1.46 + address *rcpt = (address *) (rcpt_node->data); 1.47 + 1.48 + if (addr_is_defered(rcpt)) { 1.49 + if ((now - msg->received_time) >= conf.max_defer_time) { 1.50 + addr_mark_failed(rcpt); 1.51 + } else 1.52 + defered_list = g_list_prepend(defered_list, rcpt); 1.53 + } 1.54 + if (addr_is_failed(rcpt)) 1.55 + failed_list = g_list_prepend(failed_list, rcpt); 1.56 + } 1.57 + if (failed_list != NULL) { 1.58 + ok_fail = fail_msg(msg, conf.errmsg_file, failed_list, err_fmt, args); 1.59 + g_list_free(failed_list); 1.60 + } 1.61 + if (defered_list != NULL) { 1.62 + ok_warn = warn_msg(msg, conf.warnmsg_file, defered_list, err_fmt, args); 1.63 + g_list_free(defered_list); 1.64 + } 1.65 + va_end(args); 1.66 + return ok_fail && ok_warn; 1.67 } 1.68 1.69 -static gint _g_list_strcasecmp(gconstpointer a, gconstpointer b) 1.70 +static gint 1.71 +_g_list_strcasecmp(gconstpointer a, gconstpointer b) 1.72 { 1.73 - return (gint)strcasecmp(a, b); 1.74 + return (gint) strcasecmp(a, b); 1.75 } 1.76 1.77 -gboolean deliver_local(msg_out *msgout) 1.78 +gboolean 1.79 +deliver_local(msg_out * msgout) 1.80 { 1.81 - message *msg = msgout->msg; 1.82 - GList *rcpt_list = msgout->rcpt_list; 1.83 - GList *rcpt_node; 1.84 - gboolean ok = TRUE, flag = FALSE, ok_fail = FALSE; 1.85 + message *msg = msgout->msg; 1.86 + GList *rcpt_list = msgout->rcpt_list; 1.87 + GList *rcpt_node; 1.88 + gboolean ok = TRUE, flag = FALSE, ok_fail = FALSE; 1.89 1.90 - DEBUG(5) debugf("deliver_local entered\n"); 1.91 + DEBUG(5) debugf("deliver_local entered\n"); 1.92 1.93 - flag = (msg->data_list == NULL); 1.94 - if(flag){ 1.95 - if(!(ok = spool_read_data(msg))){ 1.96 - logwrite(LOG_ALERT, "could not open data spool file for %s\n", 1.97 - msg->uid); 1.98 - } 1.99 - } 1.100 - if(!ok) return FALSE; 1.101 + flag = (msg->data_list == NULL); 1.102 + if (flag) { 1.103 + if (!(ok = spool_read_data(msg))) { 1.104 + logwrite(LOG_ALERT, "could not open data spool file for %s\n", msg->uid); 1.105 + } 1.106 + } 1.107 + if (!ok) 1.108 + return FALSE; 1.109 1.110 - ok = FALSE; 1.111 - for(rcpt_node = g_list_first(rcpt_list); 1.112 - rcpt_node; 1.113 - rcpt_node = g_list_next(rcpt_node)){ 1.114 - GList *hdr_list; 1.115 - address *rcpt = (address *)(rcpt_node->data); 1.116 - address *env_addr = addr_find_ancestor(rcpt); 1.117 - address *ret_path = msg->return_path; 1.118 - header *retpath_hdr, *envto_hdr; 1.119 + ok = FALSE; 1.120 + for (rcpt_node = g_list_first(rcpt_list); rcpt_node; rcpt_node = g_list_next(rcpt_node)) { 1.121 + GList *hdr_list; 1.122 + address *rcpt = (address *) (rcpt_node->data); 1.123 + address *env_addr = addr_find_ancestor(rcpt); 1.124 + address *ret_path = msg->return_path; 1.125 + header *retpath_hdr, *envto_hdr; 1.126 1.127 - /* we need a private copy of the hdr list because we add headers here 1.128 - that belong to the rcpt only. 1.129 - g_list_copy copies only the nodes, so it is safe to 1.130 - g_list_free it 1.131 - */ 1.132 - hdr_list = g_list_copy(msg->hdr_list); 1.133 - retpath_hdr = create_header(HEAD_ENVELOPE_TO, 1.134 - "Envelope-to: %s\n", addr_string(env_addr)); 1.135 - envto_hdr = create_header(HEAD_RETURN_PATH, 1.136 - "Return-path: %s\n", addr_string(ret_path)); 1.137 - 1.138 - hdr_list = g_list_prepend(hdr_list, envto_hdr); 1.139 - hdr_list = g_list_prepend(hdr_list, retpath_hdr); 1.140 + /* we need a private copy of the hdr list because we add headers here 1.141 + that belong to the rcpt only. 1.142 + g_list_copy copies only the nodes, so it is safe to 1.143 + g_list_free it 1.144 + */ 1.145 + hdr_list = g_list_copy(msg->hdr_list); 1.146 + retpath_hdr = create_header(HEAD_ENVELOPE_TO, "Envelope-to: %s\n", addr_string(env_addr)); 1.147 + envto_hdr = create_header(HEAD_RETURN_PATH, "Return-path: %s\n", addr_string(ret_path)); 1.148 1.149 - if(rcpt->local_part[0] == '|'){ 1.150 - DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); 1.151 - if(pipe_out(msg, hdr_list, rcpt, &(rcpt->local_part[1]), 1.152 - (conf.pipe_fromline ? MSGSTR_FROMLINE : 0) | 1.153 - (conf.pipe_fromhack ? MSGSTR_FROMHACK : 0))){ 1.154 - logwrite(LOG_NOTICE, "%s => %s <%s@%s> with pipe\n", 1.155 - msg->uid, rcpt->local_part, 1.156 - env_addr->local_part, env_addr->domain 1.157 - ); 1.158 - addr_mark_delivered(rcpt); 1.159 - ok = TRUE; 1.160 - }else{ 1.161 - if((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)){ 1.162 - addr_mark_failed(rcpt); 1.163 - }else{ 1.164 - addr_mark_defered(rcpt); /* has no effect yet, 1.165 - except that mail remains in spool */ 1.166 - } 1.167 - } 1.168 - }else{ 1.169 - /* figure out which mailbox type should be used for this user */ 1.170 - gchar *user = rcpt->local_part; 1.171 - gchar *mbox_type = conf.mbox_default; 1.172 - 1.173 - if(g_list_find_custom(conf.mbox_users, user, _g_list_strcasecmp) != NULL) 1.174 - mbox_type = "mbox"; 1.175 - else if(g_list_find_custom(conf.mda_users, user, _g_list_strcasecmp) != NULL) 1.176 - mbox_type = "mda"; 1.177 - else if(g_list_find_custom(conf.maildir_users, user, _g_list_strcasecmp) != NULL) 1.178 - mbox_type = "maildir"; 1.179 + hdr_list = g_list_prepend(hdr_list, envto_hdr); 1.180 + hdr_list = g_list_prepend(hdr_list, retpath_hdr); 1.181 1.182 - if(strcmp(mbox_type, "mbox") == 0){ 1.183 - DEBUG(1) debugf("attempting to deliver %s with mbox\n", msg->uid); 1.184 - if(append_file(msg, hdr_list, rcpt->local_part)){ 1.185 - if(env_addr != rcpt){ 1.186 - logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with mbox\n", 1.187 - msg->uid, rcpt->local_part, rcpt->domain, 1.188 - env_addr->local_part, env_addr->domain 1.189 - ); 1.190 - }else{ 1.191 - logwrite(LOG_NOTICE, "%s => <%s@%s> with mbox\n", 1.192 - msg->uid, rcpt->local_part, rcpt->domain); 1.193 - } 1.194 - addr_mark_delivered(rcpt); 1.195 - ok = TRUE; 1.196 - }else{ 1.197 - if(errno != EAGAIN){ /* prevents 'Resource temporarily unavailable (11)' */ 1.198 - addr_mark_failed(rcpt); 1.199 - }else{ 1.200 - addr_mark_defered(rcpt); 1.201 - } 1.202 - } 1.203 + if (rcpt->local_part[0] == '|') { 1.204 + DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); 1.205 + if (pipe_out(msg, hdr_list, rcpt, &(rcpt->local_part[1]), 1.206 + (conf.pipe_fromline ? MSGSTR_FROMLINE : 0) 1.207 + | (conf.pipe_fromhack ? MSGSTR_FROMHACK : 0))) { 1.208 + logwrite(LOG_NOTICE, "%s => %s <%s@%s> with pipe\n", msg->uid, rcpt->local_part, env_addr->local_part, env_addr->domain); 1.209 + addr_mark_delivered(rcpt); 1.210 + ok = TRUE; 1.211 + } else { 1.212 + if ((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)) { 1.213 + addr_mark_failed(rcpt); 1.214 + } else { 1.215 + addr_mark_defered(rcpt); /* has no effect yet, except that mail remains in spool */ 1.216 + } 1.217 + } 1.218 + } else { 1.219 + /* figure out which mailbox type should be used for this user */ 1.220 + gchar *user = rcpt->local_part; 1.221 + gchar *mbox_type = conf.mbox_default; 1.222 1.223 - }else if(strcmp(mbox_type, "mda") == 0){ 1.224 - if(conf.mda){ 1.225 - gchar *cmd = g_malloc(256); 1.226 - GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); 1.227 - 1.228 - DEBUG(1) debugf("attempting to deliver %s with mda\n", msg->uid); 1.229 - 1.230 - if(expand(var_table, conf.mda, cmd, 256)){ 1.231 - 1.232 - if(pipe_out(msg, hdr_list, rcpt, cmd, 1.233 - (conf.mda_fromline ? MSGSTR_FROMLINE : 0) | 1.234 - (conf.mda_fromhack ? MSGSTR_FROMHACK : 0))){ 1.235 - logwrite(LOG_NOTICE, "%s => %s@%s with mda (cmd = '%s')\n", 1.236 - msg->uid, rcpt->local_part, rcpt->domain, cmd 1.237 - ); 1.238 - addr_mark_delivered(rcpt); 1.239 - ok = TRUE; 1.240 - }else{ 1.241 - if((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)){ 1.242 - addr_mark_failed(rcpt); 1.243 - }else{ 1.244 - addr_mark_defered(rcpt); /* has no effect yet, 1.245 - except that mail remains in spool */ 1.246 - } 1.247 - } 1.248 - }else 1.249 - logwrite(LOG_ALERT, "could not expand string %s\n", conf.mda); 1.250 - 1.251 - destroy_table(var_table); 1.252 - }else 1.253 - logwrite(LOG_ALERT, "mbox type is mda, but no mda command given in configuration\n"); 1.254 + if (g_list_find_custom (conf.mbox_users, user, _g_list_strcasecmp) != NULL) 1.255 + mbox_type = "mbox"; 1.256 + else if (g_list_find_custom (conf.mda_users, user, _g_list_strcasecmp) != NULL) 1.257 + mbox_type = "mda"; 1.258 + else if (g_list_find_custom (conf.maildir_users, user, _g_list_strcasecmp) != NULL) 1.259 + mbox_type = "maildir"; 1.260 + 1.261 + if (strcmp(mbox_type, "mbox") == 0) { 1.262 + DEBUG(1) debugf("attempting to deliver %s with mbox\n", msg->uid); 1.263 + if (append_file(msg, hdr_list, rcpt->local_part)) { 1.264 + if (env_addr != rcpt) { 1.265 + logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with mbox\n", 1.266 + msg->uid, rcpt->local_part, rcpt->domain, 1.267 + env_addr->local_part, env_addr->domain); 1.268 + } else { 1.269 + logwrite(LOG_NOTICE, "%s => <%s@%s> with mbox\n", 1.270 + msg->uid, rcpt->local_part, rcpt->domain); 1.271 + } 1.272 + addr_mark_delivered(rcpt); 1.273 + ok = TRUE; 1.274 + } else { 1.275 + if (errno != EAGAIN) { /* prevents 'Resource temporarily unavailable (11)' */ 1.276 + addr_mark_failed(rcpt); 1.277 + } else { 1.278 + addr_mark_defered(rcpt); 1.279 + } 1.280 + } 1.281 + 1.282 + } else if (strcmp(mbox_type, "mda") == 0) { 1.283 + if (conf.mda) { 1.284 + gchar *cmd = g_malloc(256); 1.285 + GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); 1.286 + 1.287 + DEBUG(1) debugf("attempting to deliver %s with mda\n", msg->uid); 1.288 + 1.289 + if (expand(var_table, conf.mda, cmd, 256)) { 1.290 + 1.291 + if (pipe_out(msg, hdr_list, rcpt, cmd, (conf.mda_fromline ? MSGSTR_FROMLINE : 0) 1.292 + | (conf.mda_fromhack ? MSGSTR_FROMHACK : 0))) { 1.293 + logwrite(LOG_NOTICE, "%s => %s@%s with mda (cmd = '%s')\n", 1.294 + msg->uid, rcpt->local_part, rcpt->domain, cmd); 1.295 + addr_mark_delivered(rcpt); 1.296 + ok = TRUE; 1.297 + } else { 1.298 + if ((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)) { 1.299 + addr_mark_failed(rcpt); 1.300 + } else { 1.301 + addr_mark_defered(rcpt); /* has no effect yet, except that mail remains in spool */ 1.302 + } 1.303 + } 1.304 + } else 1.305 + logwrite(LOG_ALERT, "could not expand string %s\n", conf.mda); 1.306 + 1.307 + destroy_table(var_table); 1.308 + } else 1.309 + logwrite(LOG_ALERT, "mbox type is mda, but no mda command given in configuration\n"); 1.310 1.311 #ifdef ENABLE_MAILDIR 1.312 - }else if(strcmp(mbox_type, "maildir") == 0){ 1.313 - DEBUG(1) debugf("attempting to deliver %s with maildir\n", msg->uid); 1.314 - if(maildir_out(msg, hdr_list, rcpt->local_part, 0)){ 1.315 - if(env_addr != rcpt){ 1.316 - logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with local\n", 1.317 - msg->uid, rcpt->local_part, rcpt->domain, 1.318 - env_addr->local_part, env_addr->domain 1.319 - ); 1.320 - }else{ 1.321 - logwrite(LOG_NOTICE, "%s => <%s@%s> with maildir\n", 1.322 - msg->uid, rcpt->local_part, rcpt->domain); 1.323 - } 1.324 - addr_mark_delivered(rcpt); 1.325 - ok = TRUE; 1.326 - }else 1.327 - addr_mark_failed(rcpt); 1.328 + } else if (strcmp(mbox_type, "maildir") == 0) { 1.329 + DEBUG(1) debugf("attempting to deliver %s with maildir\n", msg->uid); 1.330 + if (maildir_out(msg, hdr_list, rcpt->local_part, 0)) { 1.331 + if (env_addr != rcpt) { 1.332 + logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with local\n", msg->uid, 1.333 + rcpt->local_part, rcpt->domain, env_addr->local_part, env_addr->domain); 1.334 + } else { 1.335 + logwrite(LOG_NOTICE, "%s => <%s@%s> with maildir\n", msg->uid, 1.336 + rcpt->local_part, rcpt->domain); 1.337 + } 1.338 + addr_mark_delivered(rcpt); 1.339 + ok = TRUE; 1.340 + } else 1.341 + addr_mark_failed(rcpt); 1.342 #endif 1.343 - }else 1.344 - logwrite(LOG_ALERT, "unknown mbox type '%s'\n", mbox_type); 1.345 - } 1.346 + } else 1.347 + logwrite(LOG_ALERT, "unknown mbox type '%s'\n", mbox_type); 1.348 + } 1.349 1.350 - destroy_header(retpath_hdr); 1.351 - destroy_header(envto_hdr); 1.352 + destroy_header(retpath_hdr); 1.353 + destroy_header(envto_hdr); 1.354 1.355 - g_list_free(hdr_list); 1.356 - } 1.357 - ok_fail = delivery_failures(msg, rcpt_list, "%s (%d)", ext_strerror(errno), errno); 1.358 + g_list_free(hdr_list); 1.359 + } 1.360 + ok_fail = delivery_failures(msg, rcpt_list, "%s (%d)", ext_strerror(errno), errno); 1.361 1.362 - if(flag) msg_free_data(msg); 1.363 - if(ok || ok_fail) deliver_finish(msgout); 1.364 + if (flag) 1.365 + msg_free_data(msg); 1.366 + if (ok || ok_fail) 1.367 + deliver_finish(msgout); 1.368 1.369 - return ok; 1.370 + return ok; 1.371 } 1.372 1.373 /* make a list of rcpt's of a message that are local 1.374 return a new copy of the list 1.375 */ 1.376 -void msg_rcptlist_local(GList *rcpt_list, GList **p_local_list, GList **p_nonlocal_list) 1.377 +void 1.378 +msg_rcptlist_local(GList * rcpt_list, GList ** p_local_list, GList ** p_nonlocal_list) 1.379 { 1.380 - GList *rcpt_node; 1.381 + GList *rcpt_node; 1.382 1.383 - foreach(rcpt_list, rcpt_node){ 1.384 - address *rcpt = (address *)(rcpt_node->data); 1.385 - GList *dom_node; 1.386 + foreach(rcpt_list, rcpt_node) { 1.387 + address *rcpt = (address *) (rcpt_node->data); 1.388 + GList *dom_node; 1.389 1.390 - DEBUG(5) debugf("checking address %s\n", rcpt->address); 1.391 + DEBUG(5) debugf("checking address %s\n", rcpt->address); 1.392 1.393 - /* search for local host list: */ 1.394 - foreach(conf.local_hosts, dom_node){ 1.395 - if(strcasecmp(dom_node->data, rcpt->domain) == 0){ 1.396 - *p_local_list = g_list_append(*p_local_list, rcpt); 1.397 - DEBUG(5) debugf("<%s@%s> is local\n", rcpt->local_part, rcpt->domain); 1.398 - break; 1.399 - }else{ 1.400 - *p_nonlocal_list = g_list_append(*p_nonlocal_list, rcpt); 1.401 - } 1.402 - } 1.403 - } 1.404 + /* search for local host list: */ 1.405 + foreach(conf.local_hosts, dom_node) { 1.406 + if (strcasecmp(dom_node->data, rcpt->domain) == 0) { 1.407 + *p_local_list = g_list_append(*p_local_list, rcpt); 1.408 + DEBUG(5) debugf("<%s@%s> is local\n", rcpt->local_part, rcpt->domain); 1.409 + break; 1.410 + } else { 1.411 + *p_nonlocal_list = g_list_append(*p_nonlocal_list, rcpt); 1.412 + } 1.413 + } 1.414 + } 1.415 } 1.416 1.417 -gboolean deliver_msglist_host_pipe(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) 1.418 +gboolean 1.419 +deliver_msglist_host_pipe(connect_route * route, GList * msgout_list, gchar * host, GList * res_list) 1.420 { 1.421 - gboolean ok = TRUE; 1.422 - GList *msgout_node; 1.423 + gboolean ok = TRUE; 1.424 + GList *msgout_node; 1.425 1.426 - DEBUG(5) debugf("deliver_msglist_host_pipe entered\n"); 1.427 + DEBUG(5) debugf("deliver_msglist_host_pipe entered\n"); 1.428 1.429 - if(route->pipe == NULL){ 1.430 - logwrite(LOG_ALERT, "no pipe command given for route (protocol is pipe!)\n"); 1.431 - return FALSE; 1.432 - } 1.433 + if (route->pipe == NULL) { 1.434 + logwrite(LOG_ALERT, "no pipe command given for route (protocol is pipe!)\n"); 1.435 + return FALSE; 1.436 + } 1.437 1.438 - foreach(msgout_list, msgout_node){ 1.439 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.440 - gboolean flag, ok_msg = TRUE, ok_fail = FALSE; 1.441 - message *msg = msgout->msg; 1.442 - GList *rcpt_node, *rcpt_list = msgout->rcpt_list; 1.443 + foreach(msgout_list, msgout_node) { 1.444 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.445 + gboolean flag, ok_msg = TRUE, ok_fail = FALSE; 1.446 + message *msg = msgout->msg; 1.447 + GList *rcpt_node, *rcpt_list = msgout->rcpt_list; 1.448 1.449 - DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); 1.450 + DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); 1.451 1.452 - flag = (msg->data_list == NULL); 1.453 - if(flag){ 1.454 - if(!(ok_msg = spool_read_data(msg))){ 1.455 - logwrite(LOG_ALERT, "could not open data spool file for %s\n", 1.456 - msg->uid); 1.457 - } 1.458 - } 1.459 - if(!ok_msg) continue; 1.460 + flag = (msg->data_list == NULL); 1.461 + if (flag) { 1.462 + if (!(ok_msg = spool_read_data(msg))) { 1.463 + logwrite(LOG_ALERT, "could not open data spool file for %s\n", msg->uid); 1.464 + } 1.465 + } 1.466 + if (!ok_msg) 1.467 + continue; 1.468 1.469 - ok = FALSE; 1.470 - foreach(rcpt_list, rcpt_node){ 1.471 - address *rcpt = (address *)(rcpt_node->data); 1.472 - gchar *cmd = g_malloc(256); 1.473 - GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); 1.474 - 1.475 - DEBUG(1) debugf("attempting to deliver %s to %s@%s with pipe\n", 1.476 - msg->uid, rcpt->local_part, rcpt->domain); 1.477 - 1.478 - if(expand(var_table, route->pipe, cmd, 256)){ 1.479 - 1.480 - if(pipe_out(msg, msg->hdr_list, rcpt, cmd, 1.481 - (route->pipe_fromline ? MSGSTR_FROMLINE : 0) | 1.482 - (route->pipe_fromhack ? MSGSTR_FROMHACK : 0))){ 1.483 - logwrite(LOG_NOTICE, "%s => %s@%s with pipe (cmd = '%s')\n", 1.484 - msg->uid, rcpt->local_part, rcpt->domain, cmd 1.485 - ); 1.486 - addr_mark_delivered(rcpt); 1.487 - ok = TRUE; 1.488 - }else{ 1.489 - logwrite(LOG_ALERT, "pipe_out '%s' failed\n", route->pipe); 1.490 + ok = FALSE; 1.491 + foreach(rcpt_list, rcpt_node) { 1.492 + address *rcpt = (address *) (rcpt_node->data); 1.493 + gchar *cmd = g_malloc(256); 1.494 + GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); 1.495 1.496 - if(route->connect_error_fail){ 1.497 - addr_mark_failed(rcpt); 1.498 - }else{ 1.499 - addr_mark_defered(rcpt); 1.500 - } 1.501 + DEBUG(1) debugf("attempting to deliver %s to %s@%s with pipe\n", msg->uid, rcpt->local_part, rcpt->domain); 1.502 + 1.503 + if (expand(var_table, route->pipe, cmd, 256)) { 1.504 + 1.505 + if (pipe_out(msg, msg->hdr_list, rcpt, cmd, (route->pipe_fromline ? MSGSTR_FROMLINE : 0) 1.506 + | (route->pipe_fromhack ? MSGSTR_FROMHACK : 0))) { 1.507 + logwrite(LOG_NOTICE, "%s => %s@%s with pipe (cmd = '%s')\n", 1.508 + msg->uid, rcpt->local_part, rcpt->domain, cmd); 1.509 + addr_mark_delivered(rcpt); 1.510 + ok = TRUE; 1.511 + } else { 1.512 + logwrite(LOG_ALERT, "pipe_out '%s' failed\n", route->pipe); 1.513 + 1.514 + if (route->connect_error_fail) { 1.515 + addr_mark_failed(rcpt); 1.516 + } else { 1.517 + addr_mark_defered(rcpt); 1.518 + } 1.519 + } 1.520 + } else 1.521 + logwrite(LOG_ALERT, "could not expand string %s\n", route->pipe); 1.522 + 1.523 + destroy_table(var_table); 1.524 + } 1.525 + ok_fail = delivery_failures(msg, rcpt_list, "%s", strerror(errno)); 1.526 + 1.527 + if (flag) 1.528 + msg_free_data(msg); 1.529 + 1.530 + if (ok || ok_fail) 1.531 + deliver_finish(msgout); 1.532 } 1.533 - }else 1.534 - logwrite(LOG_ALERT, "could not expand string %s\n", route->pipe); 1.535 - 1.536 - destroy_table(var_table); 1.537 - } 1.538 - ok_fail = delivery_failures(msg, rcpt_list, "%s", strerror(errno)); 1.539 1.540 - if(flag) msg_free_data(msg); 1.541 - 1.542 - if(ok || ok_fail) deliver_finish(msgout); 1.543 - } 1.544 - 1.545 - return ok; 1.546 + return ok; 1.547 } 1.548 1.549 /* deliver list of messages to one host 1.550 - and finishes them if the message was delivered to at least one 1.551 - rcpt. 1.552 - Returns TRUE if at least one msg was delivered to at least one 1.553 - rcpt. 1.554 + and finishes them if the message was delivered to at least one rcpt. 1.555 + Returns TRUE if at least one msg was delivered to at least one rcpt. 1.556 */ 1.557 1.558 -gboolean deliver_msglist_host_smtp(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) 1.559 +gboolean 1.560 +deliver_msglist_host_smtp(connect_route * route, GList * msgout_list, gchar * host, GList * res_list) 1.561 { 1.562 - gboolean ok = FALSE; 1.563 - GList *msgout_node; 1.564 - smtp_base *psb; 1.565 - gint port; 1.566 - 1.567 - /* paranoid check: */ 1.568 - if(msgout_list == NULL){ 1.569 - logwrite(LOG_ALERT, 1.570 - "Ooops: empty list of messages in deliver_msglist_host()\n"); 1.571 - return FALSE; 1.572 - } 1.573 + gboolean ok = FALSE; 1.574 + GList *msgout_node; 1.575 + smtp_base *psb; 1.576 + gint port; 1.577 1.578 - if(host == NULL){ 1.579 - host = route->mail_host->address; 1.580 - port = route->mail_host->port; 1.581 - }else 1.582 - port = conf.remote_port; 1.583 - 1.584 + /* paranoid check: */ 1.585 + if (msgout_list == NULL) { 1.586 + logwrite(LOG_ALERT, "Ooops: empty list of messages in deliver_msglist_host()\n"); 1.587 + return FALSE; 1.588 + } 1.589 + 1.590 + if (host == NULL) { 1.591 + host = route->mail_host->address; 1.592 + port = route->mail_host->port; 1.593 + } else 1.594 + port = conf.remote_port; 1.595 + 1.596 #ifdef ENABLE_POP3 1.597 - if(route->pop3_login){ 1.598 - if(!(pop_before_smtp(route->pop3_login))) 1.599 - return FALSE; 1.600 - } 1.601 + if (route->pop3_login) { 1.602 + if (!(pop_before_smtp(route->pop3_login))) 1.603 + return FALSE; 1.604 + } 1.605 #endif 1.606 1.607 - if((psb = (route->wrapper ? 1.608 - smtp_out_open_child(route->wrapper) : 1.609 - smtp_out_open(host, port, res_list)))){ 1.610 + if ((psb = (route->wrapper ? smtp_out_open_child(route->wrapper) : smtp_out_open(host, port, res_list)))) { 1.611 1.612 - if(route->wrapper) psb->remote_host = host; 1.613 + if (route->wrapper) 1.614 + psb->remote_host = host; 1.615 1.616 - set_heloname(psb, 1.617 - route->helo_name ? route->helo_name : conf.host_name, 1.618 - route->do_correct_helo); 1.619 + set_heloname(psb, route->helo_name ? route->helo_name : conf.host_name, route->do_correct_helo); 1.620 1.621 #ifdef ENABLE_AUTH 1.622 - if((route->auth_name) && (route->auth_login) && (route->auth_secret)) 1.623 - set_auth(psb, route->auth_name, route->auth_login, route->auth_secret); 1.624 + if ((route->auth_name) && (route->auth_login) 1.625 + && (route->auth_secret)) 1.626 + set_auth(psb, route->auth_name, route->auth_login, route->auth_secret); 1.627 #endif 1.628 - if(smtp_out_init(psb)){ 1.629 + if (smtp_out_init(psb)) { 1.630 1.631 - if(!route->do_pipelining) psb->use_pipelining = FALSE; 1.632 + if (!route->do_pipelining) 1.633 + psb->use_pipelining = FALSE; 1.634 1.635 - foreach(msgout_list, msgout_node){ 1.636 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.637 - gboolean flag, ok_msg = FALSE, ok_fail = FALSE; 1.638 - message *msg = msgout->msg; 1.639 + foreach(msgout_list, msgout_node) { 1.640 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.641 + gboolean flag, ok_msg = FALSE, ok_fail = FALSE; 1.642 + message *msg = msgout->msg; 1.643 1.644 - /* we may have to read the data at this point 1.645 - and remember if we did */ 1.646 - flag = (msg->data_list == NULL); 1.647 - if(flag){ 1.648 - if(!spool_read_data(msg)){ 1.649 - logwrite(LOG_ALERT, "could not open data spool file %s\n", 1.650 - msg->uid); 1.651 - break; 1.652 - } 1.653 + /* we may have to read the data at this point 1.654 + and remember if we did */ 1.655 + flag = (msg->data_list == NULL); 1.656 + if (flag) { 1.657 + if (!spool_read_data(msg)) { 1.658 + logwrite(LOG_ALERT, "could not open data spool file %s\n", msg->uid); 1.659 + break; 1.660 + } 1.661 + } 1.662 + 1.663 + smtp_out_msg(psb, msg, msgout->return_path, msgout->rcpt_list, msgout->hdr_list); 1.664 + 1.665 + ok_fail = delivery_failures(msg, msgout->rcpt_list, "while connected with %s, the server replied\n\t%s", host, psb->buffer); 1.666 + 1.667 + if ((psb->error == smtp_eof) 1.668 + || (psb->error == smtp_timeout)) { 1.669 + /* connection lost */ 1.670 + break; 1.671 + } else if (psb->error != smtp_ok) { 1.672 + if (g_list_next(msgout_node) != NULL) 1.673 + if (!smtp_out_rset(psb)) 1.674 + break; 1.675 + } 1.676 + ok_msg = (psb->error == smtp_ok); 1.677 + 1.678 + if (flag) 1.679 + msg_free_data(msg); 1.680 + if (ok_msg) 1.681 + ok = TRUE; 1.682 + if (ok_msg || ok_fail) { 1.683 + deliver_finish(msgout); 1.684 + } 1.685 + } 1.686 + if (psb->error == smtp_ok || (psb->error == smtp_fail) 1.687 + || (psb->error == smtp_trylater) || (psb->error == smtp_syntax)) { 1.688 + smtp_out_quit(psb); 1.689 + } 1.690 + } else { 1.691 + /* smtp_out_init() failed */ 1.692 + if ((psb->error == smtp_fail) || (psb->error == smtp_trylater) || (psb->error == smtp_syntax)) { 1.693 + smtp_out_quit(psb); 1.694 + 1.695 + foreach(msgout_list, msgout_node) { 1.696 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.697 + smtp_out_mark_rcpts(psb, msgout->rcpt_list); 1.698 + 1.699 + if (delivery_failures(msgout->msg, msgout->rcpt_list, 1.700 + "while connected with %s, the server replied\n\t%s", host, psb->buffer)) 1.701 + deliver_finish(msgout); 1.702 + } 1.703 + } 1.704 + } 1.705 + destroy_smtpbase(psb); 1.706 + } else { 1.707 + /* smtp_out_open() failed */ 1.708 + foreach(msgout_list, msgout_node) { 1.709 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.710 + GList *rcpt_node; 1.711 + 1.712 + for (rcpt_node = g_list_first(msgout->rcpt_list); rcpt_node; rcpt_node = g_list_next(rcpt_node)) { 1.713 + address *rcpt = (address *) (rcpt_node->data); 1.714 + 1.715 + addr_unmark_delivered(rcpt); 1.716 + if (route->connect_error_fail) { 1.717 + addr_mark_failed(rcpt); 1.718 + } else { 1.719 + addr_mark_defered(rcpt); 1.720 + } 1.721 + if (route->wrapper 1.722 + ? delivery_failures(msgout->msg, msgout->rcpt_list, 1.723 + "could not open wrapper:\n\t%s", 1.724 + strerror(errno)) 1.725 + : delivery_failures(msgout->msg, msgout->rcpt_list, 1.726 + "could not open connection to %s:%d :\n\t%s", 1.727 + host, port, h_errno != 0 ? hstrerror(h_errno) : strerror(errno))) 1.728 + deliver_finish(msgout); 1.729 + } 1.730 + } 1.731 } 1.732 - 1.733 - smtp_out_msg(psb, msg, 1.734 - msgout->return_path, msgout->rcpt_list, msgout->hdr_list); 1.735 - 1.736 - ok_fail = delivery_failures(msg, msgout->rcpt_list, 1.737 - "while connected with %s, the server replied\n\t%s", 1.738 - host, psb->buffer); 1.739 - 1.740 - if((psb->error == smtp_eof) || 1.741 - (psb->error == smtp_timeout)){ 1.742 - /* connection lost */ 1.743 - break; 1.744 - } 1.745 - else if(psb->error != smtp_ok){ 1.746 - if(g_list_next(msgout_node) != NULL) 1.747 - if(!smtp_out_rset(psb)) 1.748 - break; 1.749 - } 1.750 - ok_msg = (psb->error == smtp_ok); 1.751 - 1.752 - if(flag) msg_free_data(msg); 1.753 - if(ok_msg) ok = TRUE; 1.754 - if(ok_msg || ok_fail){ 1.755 - deliver_finish(msgout); 1.756 - } 1.757 - } 1.758 - if(psb->error == smtp_ok || 1.759 - (psb->error == smtp_fail) || 1.760 - (psb->error == smtp_trylater) || 1.761 - (psb->error == smtp_syntax)){ 1.762 - 1.763 - smtp_out_quit(psb); 1.764 - } 1.765 - }else{ 1.766 - /* smtp_out_init() failed */ 1.767 - if((psb->error == smtp_fail) || 1.768 - (psb->error == smtp_trylater) || 1.769 - (psb->error == smtp_syntax)){ 1.770 - smtp_out_quit(psb); 1.771 - 1.772 - foreach(msgout_list, msgout_node){ 1.773 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.774 - smtp_out_mark_rcpts(psb, msgout->rcpt_list); 1.775 - 1.776 - if(delivery_failures(msgout->msg, msgout->rcpt_list, 1.777 - "while connected with %s, the server replied\n\t%s", 1.778 - host, psb->buffer)) 1.779 - deliver_finish(msgout); 1.780 - } 1.781 - } 1.782 - } 1.783 - destroy_smtpbase(psb); 1.784 - }else{ 1.785 - /* smtp_out_open() failed */ 1.786 - foreach(msgout_list, msgout_node){ 1.787 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.788 - GList *rcpt_node; 1.789 - 1.790 - for(rcpt_node = g_list_first(msgout->rcpt_list); 1.791 - rcpt_node; 1.792 - rcpt_node = g_list_next(rcpt_node)){ 1.793 - address *rcpt = (address *)(rcpt_node->data); 1.794 - 1.795 - addr_unmark_delivered(rcpt); 1.796 - if(route->connect_error_fail){ 1.797 - addr_mark_failed(rcpt); 1.798 - }else{ 1.799 - addr_mark_defered(rcpt); 1.800 - } 1.801 - if(route->wrapper ? 1.802 - delivery_failures(msgout->msg, msgout->rcpt_list, 1.803 - "could not open wrapper:\n\t%s", 1.804 - strerror(errno)) : 1.805 - delivery_failures(msgout->msg, msgout->rcpt_list, 1.806 - "could not open connection to %s:%d :\n\t%s", 1.807 - host, port, h_errno != 0 ? hstrerror(h_errno) : strerror(errno))) 1.808 - deliver_finish(msgout); 1.809 - } 1.810 - } 1.811 - } 1.812 - return ok; 1.813 + return ok; 1.814 } 1.815 1.816 -gboolean deliver_msglist_host(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) 1.817 +gboolean 1.818 +deliver_msglist_host(connect_route * route, GList * msgout_list, gchar * host, GList * res_list) 1.819 { 1.820 - DEBUG(5) debugf("protocol = %s\n", route->protocol); 1.821 + DEBUG(5) debugf("protocol = %s\n", route->protocol); 1.822 1.823 - if(strcmp(route->protocol, "pipe") == 0){ 1.824 - return deliver_msglist_host_pipe(route, msgout_list, host, res_list); 1.825 - }else{ 1.826 - return deliver_msglist_host_smtp(route, msgout_list, host, res_list); 1.827 - } 1.828 + if (strcmp(route->protocol, "pipe") == 0) { 1.829 + return deliver_msglist_host_pipe(route, msgout_list, host, res_list); 1.830 + } else { 1.831 + return deliver_msglist_host_smtp(route, msgout_list, host, res_list); 1.832 + } 1.833 } 1.834 1.835 /* 1.836 delivers messages in msgout_list using route 1.837 */ 1.838 -gboolean deliver_route_msgout_list(connect_route *route, GList *msgout_list) 1.839 +gboolean 1.840 +deliver_route_msgout_list(connect_route * route, GList * msgout_list) 1.841 { 1.842 - gboolean ok = FALSE; 1.843 + gboolean ok = FALSE; 1.844 1.845 - DEBUG(5) debugf("deliver_route_msgout_list entered, route->name = %s\n", 1.846 - route->name); 1.847 + DEBUG(5) 1.848 + debugf("deliver_route_msgout_list entered, route->name = %s\n", route->name); 1.849 1.850 - if(route->mail_host != NULL){ 1.851 - /* this is easy... */ 1.852 - if(deliver_msglist_host(route, msgout_list, 1.853 - NULL, route->resolve_list)) 1.854 - ok = TRUE; 1.855 - 1.856 - }else{ 1.857 - /* this is not easy... */ 1.858 - GList *mo_ph_list; 1.859 + if (route->mail_host != NULL) { 1.860 + /* this is easy... */ 1.861 + if (deliver_msglist_host(route, msgout_list, NULL, route->resolve_list)) 1.862 + ok = TRUE; 1.863 1.864 - mo_ph_list = route_msgout_list(route, msgout_list); 1.865 - /* okay, now we have ordered our messages by the hosts. */ 1.866 - if(mo_ph_list != NULL){ 1.867 - GList *mo_ph_node; 1.868 - /* TODO: It would be nice to be able to fork for each host. 1.869 - We cannot do that yet because of complications with finishing the 1.870 - messages. Threads could be a solution because they use the same 1.871 - memory. But we are not thread safe yet... 1.872 - */ 1.873 - foreach(mo_ph_list, mo_ph_node){ 1.874 - msgout_perhost *mo_ph = (msgout_perhost *)(mo_ph_node->data); 1.875 - if(deliver_msglist_host(route, mo_ph->msgout_list, 1.876 - mo_ph->host, route->resolve_list)) 1.877 - ok = TRUE; 1.878 + } else { 1.879 + /* this is not easy... */ 1.880 + GList *mo_ph_list; 1.881 1.882 - destroy_msgout_perhost(mo_ph); 1.883 - } 1.884 - g_list_free(mo_ph_list); 1.885 - } 1.886 - } 1.887 - return ok; 1.888 + mo_ph_list = route_msgout_list(route, msgout_list); 1.889 + /* okay, now we have ordered our messages by the hosts. */ 1.890 + if (mo_ph_list != NULL) { 1.891 + GList *mo_ph_node; 1.892 + /* TODO: It would be nice to be able to fork for each host. 1.893 + We cannot do that yet because of complications with finishing the 1.894 + messages. Threads could be a solution because they use the same 1.895 + memory. But we are not thread safe yet... 1.896 + */ 1.897 + foreach(mo_ph_list, mo_ph_node) { 1.898 + msgout_perhost *mo_ph = (msgout_perhost *) (mo_ph_node->data); 1.899 + if (deliver_msglist_host (route, mo_ph->msgout_list, mo_ph->host, route->resolve_list)) 1.900 + ok = TRUE; 1.901 + 1.902 + destroy_msgout_perhost(mo_ph); 1.903 + } 1.904 + g_list_free(mo_ph_list); 1.905 + } 1.906 + } 1.907 + return ok; 1.908 } 1.909 1.910 /* 1.911 @@ -532,85 +510,86 @@ 1.912 delivers messages in msg_list using route 1.913 by calling deliver_route_msgout_list() 1.914 */ 1.915 -gboolean deliver_route_msg_list(connect_route *route, GList *msgout_list) 1.916 +gboolean 1.917 +deliver_route_msg_list(connect_route * route, GList * msgout_list) 1.918 { 1.919 - GList *msgout_list_deliver = NULL; 1.920 - GList *msgout_node; 1.921 - gboolean ok = TRUE; 1.922 + GList *msgout_list_deliver = NULL; 1.923 + GList *msgout_node; 1.924 + gboolean ok = TRUE; 1.925 1.926 - DEBUG(6) debugf("deliver_route_msg_list()\n"); 1.927 + DEBUG(6) debugf("deliver_route_msg_list()\n"); 1.928 1.929 - foreach(msgout_list, msgout_node){ 1.930 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.931 - msg_out *msgout_cloned = clone_msg_out(msgout); 1.932 - GList *rcpt_list_non_delivered = NULL; 1.933 - GList *rcpt_node; 1.934 + foreach(msgout_list, msgout_node) { 1.935 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.936 + msg_out *msgout_cloned = clone_msg_out(msgout); 1.937 + GList *rcpt_list_non_delivered = NULL; 1.938 + GList *rcpt_node; 1.939 1.940 - /* we have to delete already delivered rcpt's 1.941 - because a previous route may have delivered to it */ 1.942 - foreach(msgout_cloned->rcpt_list, rcpt_node){ 1.943 - address *rcpt = (address *)(rcpt_node->data); 1.944 - /* failed addresses already have been bounced 1.945 - - there should be a better way to handle those.*/ 1.946 - if(!addr_is_delivered(rcpt) && !addr_is_failed(rcpt) && !(rcpt->flags & ADDR_FLAG_LAST_ROUTE)) 1.947 - rcpt_list_non_delivered = g_list_append(rcpt_list_non_delivered, rcpt); 1.948 - } 1.949 - g_list_free(msgout_cloned->rcpt_list); 1.950 - msgout_cloned->rcpt_list = rcpt_list_non_delivered; 1.951 + /* we have to delete already delivered rcpt's 1.952 + because a previous route may have delivered to it */ 1.953 + foreach(msgout_cloned->rcpt_list, rcpt_node) { 1.954 + address *rcpt = (address *) (rcpt_node->data); 1.955 + /* failed addresses already have been bounced 1.956 + - there should be a better way to handle those. */ 1.957 + if (!addr_is_delivered(rcpt) && !addr_is_failed(rcpt) 1.958 + && !(rcpt->flags & ADDR_FLAG_LAST_ROUTE)) 1.959 + rcpt_list_non_delivered = g_list_append(rcpt_list_non_delivered, rcpt); 1.960 + } 1.961 + g_list_free(msgout_cloned->rcpt_list); 1.962 + msgout_cloned->rcpt_list = rcpt_list_non_delivered; 1.963 1.964 - if(msgout_cloned->rcpt_list){ 1.965 - if(route_is_allowed_mail_local(route, msgout->msg->return_path) && 1.966 - route_is_allowed_return_path(route, msgout->msg->return_path)){ 1.967 - GList *rcpt_list_allowed = NULL, *rcpt_list_notallowed = NULL; 1.968 - msg_rcptlist_route(route, msgout_cloned->rcpt_list, 1.969 - &rcpt_list_allowed, &rcpt_list_notallowed); 1.970 - 1.971 - if(rcpt_list_allowed != NULL){ 1.972 - logwrite(LOG_NOTICE, "%s using '%s'\n", msgout->msg->uid, route->name); 1.973 + if (msgout_cloned->rcpt_list) { 1.974 + if (route_is_allowed_mail_local(route, msgout->msg->return_path) 1.975 + && route_is_allowed_return_path(route, msgout->msg-> return_path)) { 1.976 + GList *rcpt_list_allowed = NULL, *rcpt_list_notallowed = NULL; 1.977 + msg_rcptlist_route(route, msgout_cloned->rcpt_list, &rcpt_list_allowed, &rcpt_list_notallowed); 1.978 1.979 - g_list_free(msgout_cloned->rcpt_list); 1.980 - msgout_cloned->rcpt_list = rcpt_list_allowed; 1.981 - 1.982 - if(route->last_route){ 1.983 - GList *rcpt_node; 1.984 - foreach(msgout_cloned->rcpt_list, rcpt_node){ 1.985 - address *rcpt = (address *)(rcpt_node->data); 1.986 - rcpt->flags |= ADDR_FLAG_LAST_ROUTE; 1.987 - } 1.988 - } 1.989 + if (rcpt_list_allowed != NULL) { 1.990 + logwrite(LOG_NOTICE, "%s using '%s'\n", msgout->msg->uid, route->name); 1.991 1.992 - route_prepare_msgout(route, msgout_cloned); 1.993 - msgout_list_deliver = g_list_append(msgout_list_deliver, msgout_cloned); 1.994 - }else 1.995 - destroy_msg_out(msgout_cloned); 1.996 - } 1.997 - else 1.998 - destroy_msg_out(msgout_cloned); 1.999 - }else 1.1000 - destroy_msg_out(msgout_cloned); 1.1001 - } 1.1002 + g_list_free(msgout_cloned->rcpt_list); 1.1003 + msgout_cloned->rcpt_list = rcpt_list_allowed; 1.1004 1.1005 - if(msgout_list_deliver != NULL){ 1.1006 - if(deliver_route_msgout_list(route, msgout_list_deliver)) 1.1007 - ok = TRUE; 1.1008 - destroy_msg_out_list(msgout_list_deliver); 1.1009 - } 1.1010 - return ok; 1.1011 + if (route->last_route) { 1.1012 + GList *rcpt_node; 1.1013 + foreach(msgout_cloned->rcpt_list, rcpt_node) { 1.1014 + address *rcpt = (address *) (rcpt_node->data); 1.1015 + rcpt->flags |= ADDR_FLAG_LAST_ROUTE; 1.1016 + } 1.1017 + } 1.1018 + 1.1019 + route_prepare_msgout(route, msgout_cloned); 1.1020 + msgout_list_deliver = g_list_append(msgout_list_deliver, msgout_cloned); 1.1021 + } else 1.1022 + destroy_msg_out(msgout_cloned); 1.1023 + } else 1.1024 + destroy_msg_out(msgout_cloned); 1.1025 + } else 1.1026 + destroy_msg_out(msgout_cloned); 1.1027 + } 1.1028 + 1.1029 + if (msgout_list_deliver != NULL) { 1.1030 + if (deliver_route_msgout_list(route, msgout_list_deliver)) 1.1031 + ok = TRUE; 1.1032 + destroy_msg_out_list(msgout_list_deliver); 1.1033 + } 1.1034 + return ok; 1.1035 } 1.1036 1.1037 /* copy pointers of delivered addresses to the msg's non_rcpt_list, 1.1038 to make sure that they will not be delivered again. 1.1039 */ 1.1040 -void update_non_rcpt_list(msg_out *msgout) 1.1041 +void 1.1042 +update_non_rcpt_list(msg_out * msgout) 1.1043 { 1.1044 - GList *rcpt_node; 1.1045 - message *msg = msgout->msg; 1.1046 + GList *rcpt_node; 1.1047 + message *msg = msgout->msg; 1.1048 1.1049 - foreach(msgout->rcpt_list, rcpt_node){ 1.1050 - address *rcpt = (address *)(rcpt_node->data); 1.1051 - if(addr_is_delivered(rcpt) || addr_is_failed(rcpt)) 1.1052 - msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, rcpt); 1.1053 - } 1.1054 + foreach(msgout->rcpt_list, rcpt_node) { 1.1055 + address *rcpt = (address *) (rcpt_node->data); 1.1056 + if (addr_is_delivered(rcpt) || addr_is_failed(rcpt)) 1.1057 + msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, rcpt); 1.1058 + } 1.1059 } 1.1060 1.1061 /* after delivery attempts, we check if there are any 1.1062 @@ -621,209 +600,213 @@ 1.1063 1.1064 returns TRUE if all went well. 1.1065 */ 1.1066 -gboolean deliver_finish(msg_out *msgout) 1.1067 +gboolean 1.1068 +deliver_finish(msg_out * msgout) 1.1069 { 1.1070 - GList *rcpt_node; 1.1071 - gboolean ok = FALSE; 1.1072 - message *msg = msgout->msg; 1.1073 - gboolean finished = TRUE; 1.1074 + GList *rcpt_node; 1.1075 + gboolean ok = FALSE; 1.1076 + message *msg = msgout->msg; 1.1077 + gboolean finished = TRUE; 1.1078 1.1079 - update_non_rcpt_list(msgout); 1.1080 + update_non_rcpt_list(msgout); 1.1081 1.1082 - /* we NEVER made copies of the addresses, flags affecting addresses 1.1083 - were always set on the original address structs */ 1.1084 - foreach(msg->rcpt_list, rcpt_node){ 1.1085 - address *rcpt = (address *)(rcpt_node->data); 1.1086 - if(!addr_is_finished_children(rcpt)) 1.1087 - finished = FALSE; 1.1088 - else{ 1.1089 - /* if ALL children have been delivered, 1.1090 - mark parent as delivered. 1.1091 - if there is one or more not delivered, 1.1092 - it must have failed, we mark the parent as failed as well. 1.1093 - */ 1.1094 - if(addr_is_delivered_children(rcpt)){ 1.1095 - addr_mark_delivered(rcpt); 1.1096 - }else{ 1.1097 - addr_mark_failed(rcpt); 1.1098 - } 1.1099 - } 1.1100 - } 1.1101 - 1.1102 - if(!finished){ 1.1103 - /* one not delivered address was found */ 1.1104 - if(spool_write(msg, FALSE)){ 1.1105 - ok = TRUE; 1.1106 - DEBUG(2) debugf("spool header for %s written back.\n", msg->uid); 1.1107 - }else 1.1108 - logwrite(LOG_ALERT, "could not write back spool header for %s\n", 1.1109 - msg->uid); 1.1110 - }else{ 1.1111 - ok = spool_delete_all(msg); 1.1112 - if(ok) 1.1113 - logwrite(LOG_NOTICE, "%s completed.\n", msg->uid); 1.1114 - } 1.1115 - return ok; 1.1116 + /* we NEVER made copies of the addresses, flags affecting addresses 1.1117 + were always set on the original address structs */ 1.1118 + foreach(msg->rcpt_list, rcpt_node) { 1.1119 + address *rcpt = (address *) (rcpt_node->data); 1.1120 + if (!addr_is_finished_children(rcpt)) 1.1121 + finished = FALSE; 1.1122 + else { 1.1123 + /* if ALL children have been delivered, 1.1124 + mark parent as delivered. 1.1125 + if there is one or more not delivered, 1.1126 + it must have failed, we mark the parent as failed as well. 1.1127 + */ 1.1128 + if (addr_is_delivered_children(rcpt)) { 1.1129 + addr_mark_delivered(rcpt); 1.1130 + } else { 1.1131 + addr_mark_failed(rcpt); 1.1132 + } 1.1133 + } 1.1134 + } 1.1135 + 1.1136 + if (!finished) { 1.1137 + /* one not delivered address was found */ 1.1138 + if (spool_write(msg, FALSE)) { 1.1139 + ok = TRUE; 1.1140 + DEBUG(2) debugf("spool header for %s written back.\n", msg->uid); 1.1141 + } else 1.1142 + logwrite(LOG_ALERT, "could not write back spool header for %s\n", msg->uid); 1.1143 + } else { 1.1144 + ok = spool_delete_all(msg); 1.1145 + if (ok) 1.1146 + logwrite(LOG_NOTICE, "%s completed.\n", msg->uid); 1.1147 + } 1.1148 + return ok; 1.1149 } 1.1150 1.1151 -gboolean deliver_finish_list(GList *msgout_list) 1.1152 +gboolean 1.1153 +deliver_finish_list(GList * msgout_list) 1.1154 { 1.1155 - gboolean ok = TRUE; 1.1156 - GList *msgout_node; 1.1157 - foreach(msgout_list, msgout_node){ 1.1158 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.1159 - if(!deliver_finish(msgout)) 1.1160 - ok = FALSE; 1.1161 - } 1.1162 - return ok; 1.1163 -} 1.1164 - 1.1165 -gboolean deliver_msgout_list_online(GList *msgout_list) 1.1166 -{ 1.1167 - GList *rf_list = NULL; 1.1168 - gchar *connect_name = detect_online(); 1.1169 - gboolean ok = FALSE; 1.1170 - 1.1171 - if(connect_name != NULL){ 1.1172 - logwrite(LOG_NOTICE, "detected online configuration %s\n", connect_name); 1.1173 - /* we are online! */ 1.1174 - rf_list = (GList *)table_find(conf.connect_routes, connect_name); 1.1175 - if(rf_list != NULL){ 1.1176 - GList *route_list = read_route_list(rf_list, FALSE); 1.1177 - if(route_list){ 1.1178 - GList *route_node; 1.1179 - foreach(route_list, route_node){ 1.1180 - connect_route *route = (connect_route *)(route_node->data); 1.1181 - ok = deliver_route_msg_list(route, msgout_list); 1.1182 + gboolean ok = TRUE; 1.1183 + GList *msgout_node; 1.1184 + foreach(msgout_list, msgout_node) { 1.1185 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.1186 + if (!deliver_finish(msgout)) 1.1187 + ok = FALSE; 1.1188 } 1.1189 - destroy_route_list(route_list); 1.1190 - } 1.1191 - else 1.1192 - logwrite(LOG_ALERT, 1.1193 - "could not read route list '%s'\n", connect_name); 1.1194 - }else{ 1.1195 - logwrite(LOG_ALERT, "route list with name '%s' not found.\n", connect_name); 1.1196 - } 1.1197 - } 1.1198 - return ok; 1.1199 + return ok; 1.1200 } 1.1201 1.1202 -gboolean deliver_msg_list(GList *msg_list, guint flags){ 1.1203 - GList *msgout_list = create_msg_out_list(msg_list); 1.1204 - GList *local_msgout_list = NULL, *localnet_msgout_list = NULL, *other_msgout_list = NULL; 1.1205 - GList *msgout_node; 1.1206 - GList *alias_table = NULL; 1.1207 - gboolean ok = TRUE; 1.1208 +gboolean 1.1209 +deliver_msgout_list_online(GList * msgout_list) 1.1210 +{ 1.1211 + GList *rf_list = NULL; 1.1212 + gchar *connect_name = detect_online(); 1.1213 + gboolean ok = FALSE; 1.1214 1.1215 - if(conf.alias_file){ 1.1216 - if(!(alias_table = table_read(conf.alias_file, ':'))) 1.1217 - return FALSE; 1.1218 - } 1.1219 - 1.1220 - /* sort messages for different deliveries */ 1.1221 - foreach(msgout_list, msgout_node){ 1.1222 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.1223 - GList *rcpt_list; 1.1224 - GList *local_rcpt_list = NULL; 1.1225 - GList *localnet_rcpt_list = NULL; 1.1226 - GList *other_rcpt_list; 1.1227 + if (connect_name != NULL) { 1.1228 + logwrite(LOG_NOTICE, "detected online configuration %s\n", connect_name); 1.1229 + /* we are online! */ 1.1230 + rf_list = (GList *) table_find(conf.connect_routes, connect_name); 1.1231 + if (rf_list != NULL) { 1.1232 + GList *route_list = read_route_list(rf_list, FALSE); 1.1233 + if (route_list) { 1.1234 + GList *route_node; 1.1235 + foreach(route_list, route_node) { 1.1236 + connect_route *route = (connect_route *) (route_node->data); 1.1237 + ok = deliver_route_msg_list(route, msgout_list); 1.1238 + } 1.1239 + destroy_route_list(route_list); 1.1240 + } else 1.1241 + logwrite(LOG_ALERT, "could not read route list '%s'\n", connect_name); 1.1242 + } else { 1.1243 + logwrite(LOG_ALERT, "route list with name '%s' not found.\n", connect_name); 1.1244 + } 1.1245 + } 1.1246 + return ok; 1.1247 +} 1.1248 1.1249 - if(!spool_lock(msgout->msg->uid)) continue; 1.1250 +gboolean 1.1251 +deliver_msg_list(GList * msg_list, guint flags) 1.1252 +{ 1.1253 + GList *msgout_list = create_msg_out_list(msg_list); 1.1254 + GList *local_msgout_list = NULL, *localnet_msgout_list = NULL, *other_msgout_list = NULL; 1.1255 + GList *msgout_node; 1.1256 + GList *alias_table = NULL; 1.1257 + gboolean ok = TRUE; 1.1258 1.1259 - rcpt_list = g_list_copy(msgout->msg->rcpt_list); 1.1260 - if(conf.log_user){ 1.1261 - address *addr = create_address_qualified(conf.log_user, TRUE, conf.host_name); 1.1262 - if(addr) 1.1263 - rcpt_list = g_list_prepend(rcpt_list, addr); 1.1264 - } 1.1265 - if(alias_table){ 1.1266 - GList *aliased_rcpt_list; 1.1267 - aliased_rcpt_list = alias_expand(alias_table, rcpt_list, 1.1268 - msgout->msg->non_rcpt_list); 1.1269 - g_list_free(rcpt_list); 1.1270 - rcpt_list = aliased_rcpt_list; 1.1271 - } 1.1272 + if (conf.alias_file) { 1.1273 + if (!(alias_table = table_read(conf.alias_file, ':'))) 1.1274 + return FALSE; 1.1275 + } 1.1276 1.1277 - /* local recipients */ 1.1278 - other_rcpt_list = NULL; 1.1279 - rcptlist_with_addr_is_local(rcpt_list, &local_rcpt_list, &other_rcpt_list); 1.1280 - 1.1281 - if(flags & DLVR_LOCAL){ 1.1282 - if(local_rcpt_list != NULL){ 1.1283 - msg_out *local_msgout = clone_msg_out(msgout); 1.1284 - local_msgout->rcpt_list = local_rcpt_list; 1.1285 - local_msgout_list = g_list_append(local_msgout_list, local_msgout); 1.1286 - } 1.1287 - } 1.1288 + /* sort messages for different deliveries */ 1.1289 + foreach(msgout_list, msgout_node) { 1.1290 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.1291 + GList *rcpt_list; 1.1292 + GList *local_rcpt_list = NULL; 1.1293 + GList *localnet_rcpt_list = NULL; 1.1294 + GList *other_rcpt_list; 1.1295 1.1296 - g_list_free(rcpt_list); 1.1297 + if (!spool_lock(msgout->msg->uid)) 1.1298 + continue; 1.1299 1.1300 - /* local net recipients */ 1.1301 - rcpt_list = other_rcpt_list; 1.1302 - other_rcpt_list = NULL; 1.1303 - rcptlist_with_one_of_hostlist(rcpt_list, conf.local_nets, 1.1304 - &localnet_rcpt_list, &other_rcpt_list); 1.1305 + rcpt_list = g_list_copy(msgout->msg->rcpt_list); 1.1306 + if (conf.log_user) { 1.1307 + address *addr = create_address_qualified(conf.log_user, TRUE, conf.host_name); 1.1308 + if (addr) 1.1309 + rcpt_list = g_list_prepend(rcpt_list, addr); 1.1310 + } 1.1311 + if (alias_table) { 1.1312 + GList *aliased_rcpt_list; 1.1313 + aliased_rcpt_list = alias_expand(alias_table, rcpt_list, msgout->msg->non_rcpt_list); 1.1314 + g_list_free(rcpt_list); 1.1315 + rcpt_list = aliased_rcpt_list; 1.1316 + } 1.1317 1.1318 - if(flags & DLVR_LAN){ 1.1319 - if(localnet_rcpt_list != NULL){ 1.1320 - msg_out *localnet_msgout = clone_msg_out(msgout); 1.1321 - localnet_msgout->rcpt_list = localnet_rcpt_list; 1.1322 - localnet_msgout_list = g_list_append(localnet_msgout_list, localnet_msgout); 1.1323 - } 1.1324 - } 1.1325 + /* local recipients */ 1.1326 + other_rcpt_list = NULL; 1.1327 + rcptlist_with_addr_is_local(rcpt_list, &local_rcpt_list, &other_rcpt_list); 1.1328 1.1329 - if(flags & DLVR_ONLINE){ 1.1330 - /* the rest, this is online delivery */ 1.1331 - if(other_rcpt_list != NULL){ 1.1332 - msg_out *other_msgout = clone_msg_out(msgout); 1.1333 - other_msgout->rcpt_list = other_rcpt_list; 1.1334 - other_msgout_list = g_list_append(other_msgout_list, other_msgout); 1.1335 - } 1.1336 - } 1.1337 - } 1.1338 + if (flags & DLVR_LOCAL) { 1.1339 + if (local_rcpt_list != NULL) { 1.1340 + msg_out *local_msgout = clone_msg_out(msgout); 1.1341 + local_msgout->rcpt_list = local_rcpt_list; 1.1342 + local_msgout_list = g_list_append(local_msgout_list, local_msgout); 1.1343 + } 1.1344 + } 1.1345 1.1346 - if(alias_table) 1.1347 - destroy_table(alias_table); 1.1348 + g_list_free(rcpt_list); 1.1349 1.1350 - /* actual delivery */ 1.1351 - if(local_msgout_list != NULL){ 1.1352 - foreach(local_msgout_list, msgout_node){ 1.1353 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.1354 - if(!deliver_local(msgout)) ok = FALSE; 1.1355 - } 1.1356 - destroy_msg_out_list(local_msgout_list); 1.1357 - } 1.1358 + /* local net recipients */ 1.1359 + rcpt_list = other_rcpt_list; 1.1360 + other_rcpt_list = NULL; 1.1361 + rcptlist_with_one_of_hostlist(rcpt_list, conf.local_nets, &localnet_rcpt_list, &other_rcpt_list); 1.1362 1.1363 - if(localnet_msgout_list != NULL){ 1.1364 - GList *route_list = NULL; 1.1365 - GList *route_node; 1.1366 + if (flags & DLVR_LAN) { 1.1367 + if (localnet_rcpt_list != NULL) { 1.1368 + msg_out *localnet_msgout = clone_msg_out(msgout); 1.1369 + localnet_msgout->rcpt_list = localnet_rcpt_list; 1.1370 + localnet_msgout_list = g_list_append(localnet_msgout_list, localnet_msgout); 1.1371 + } 1.1372 + } 1.1373 1.1374 - if(conf.local_net_routes) 1.1375 - route_list = read_route_list(conf.local_net_routes, TRUE); 1.1376 - else 1.1377 - route_list = g_list_append(NULL, create_local_route()); 1.1378 + if (flags & DLVR_ONLINE) { 1.1379 + /* the rest, this is online delivery */ 1.1380 + if (other_rcpt_list != NULL) { 1.1381 + msg_out *other_msgout = clone_msg_out(msgout); 1.1382 + other_msgout->rcpt_list = other_rcpt_list; 1.1383 + other_msgout_list = g_list_append(other_msgout_list, other_msgout); 1.1384 + } 1.1385 + } 1.1386 + } 1.1387 1.1388 - foreach(route_list, route_node){ 1.1389 - connect_route *route = (connect_route *)(route_node->data); 1.1390 - if(!deliver_route_msg_list(route, localnet_msgout_list)) ok = FALSE; 1.1391 - } 1.1392 - destroy_msg_out_list(localnet_msgout_list); 1.1393 - destroy_route_list(route_list); 1.1394 - } 1.1395 + if (alias_table) 1.1396 + destroy_table(alias_table); 1.1397 1.1398 - if(other_msgout_list != NULL){ 1.1399 - if(!deliver_msgout_list_online(other_msgout_list)) ok = FALSE; 1.1400 - destroy_msg_out_list(other_msgout_list); 1.1401 - } 1.1402 + /* actual delivery */ 1.1403 + if (local_msgout_list != NULL) { 1.1404 + foreach(local_msgout_list, msgout_node) { 1.1405 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.1406 + if (!deliver_local(msgout)) 1.1407 + ok = FALSE; 1.1408 + } 1.1409 + destroy_msg_out_list(local_msgout_list); 1.1410 + } 1.1411 1.1412 - foreach(msgout_list, msgout_node){ 1.1413 - msg_out *msgout = (msg_out *)(msgout_node->data); 1.1414 - spool_unlock(msgout->msg->uid); 1.1415 - } 1.1416 + if (localnet_msgout_list != NULL) { 1.1417 + GList *route_list = NULL; 1.1418 + GList *route_node; 1.1419 1.1420 - destroy_msg_out_list(msgout_list); 1.1421 + if (conf.local_net_routes) 1.1422 + route_list = read_route_list(conf.local_net_routes, TRUE); 1.1423 + else 1.1424 + route_list = g_list_append(NULL, create_local_route()); 1.1425 1.1426 - return ok; 1.1427 + foreach(route_list, route_node) { 1.1428 + connect_route *route = (connect_route *) (route_node->data); 1.1429 + if (!deliver_route_msg_list(route, localnet_msgout_list)) 1.1430 + ok = FALSE; 1.1431 + } 1.1432 + destroy_msg_out_list(localnet_msgout_list); 1.1433 + destroy_route_list(route_list); 1.1434 + } 1.1435 + 1.1436 + if (other_msgout_list != NULL) { 1.1437 + if (!deliver_msgout_list_online(other_msgout_list)) 1.1438 + ok = FALSE; 1.1439 + destroy_msg_out_list(other_msgout_list); 1.1440 + } 1.1441 + 1.1442 + foreach(msgout_list, msgout_node) { 1.1443 + msg_out *msgout = (msg_out *) (msgout_node->data); 1.1444 + spool_unlock(msgout->msg->uid); 1.1445 + } 1.1446 + 1.1447 + destroy_msg_out_list(msgout_list); 1.1448 + 1.1449 + return ok; 1.1450 } 1.1451 1.1452 /* This function searches in the list of rcpt addresses 1.1453 @@ -834,16 +817,14 @@ 1.1454 deliver() is called when a message has just been received and should 1.1455 be delivered immediately. 1.1456 */ 1.1457 -gboolean deliver(message *msg) 1.1458 +gboolean 1.1459 +deliver(message * msg) 1.1460 { 1.1461 - gboolean ok; 1.1462 + gboolean ok; 1.1463 + GList *msg_list = g_list_append(NULL, msg); 1.1464 1.1465 - GList *msg_list = g_list_append(NULL, msg); 1.1466 + ok = deliver_msg_list(msg_list, DLVR_ALL); 1.1467 + g_list_free(msg_list); 1.1468 1.1469 - ok = deliver_msg_list(msg_list, DLVR_ALL); 1.1470 - 1.1471 - g_list_free(msg_list); 1.1472 - 1.1473 - return ok; 1.1474 + return ok; 1.1475 } 1.1476 -