Mercurial > masqmail
diff src/smtp_out.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 | f671821d8222 |
line wrap: on
line diff
--- a/src/smtp_out.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/smtp_out.c Mon Oct 27 16:23:10 2008 +0100 @@ -4,7 +4,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -47,872 +47,860 @@ #include "base64/base64.h" #endif -void destroy_smtpbase(smtp_base *psb) +void +destroy_smtpbase(smtp_base * psb) { - fclose(psb->in); - fclose(psb->out); + fclose(psb->in); + fclose(psb->out); - close(psb->sock); + close(psb->sock); - if(psb->helo_name) g_free(psb->helo_name); - if(psb->buffer) g_free(psb->buffer); - if(psb->auth_names) g_strfreev(psb->auth_names); + if (psb->helo_name) + g_free(psb->helo_name); + if (psb->buffer) + g_free(psb->buffer); + if (psb->auth_names) + g_strfreev(psb->auth_names); - if(psb->auth_name) g_free(psb->auth_name); - if(psb->auth_login) g_free(psb->auth_login); - if(psb->auth_secret) g_free(psb->auth_secret); + if (psb->auth_name) + g_free(psb->auth_name); + if (psb->auth_login) + g_free(psb->auth_login); + if (psb->auth_secret) + g_free(psb->auth_secret); } -gchar *set_heloname(smtp_base *psb, gchar *default_name, gboolean do_correct) +gchar* +set_heloname(smtp_base * psb, gchar * default_name, gboolean do_correct) { - struct sockaddr_in sname; - int len = sizeof(struct sockaddr_in); - struct hostent *host_entry; + struct sockaddr_in sname; + int len = sizeof(struct sockaddr_in); + struct hostent *host_entry; - if(do_correct){ - getsockname(psb->sock, (struct sockaddr *)(&sname), &len); - DEBUG(5) debugf("socket: name.sin_addr = %s\n", inet_ntoa(sname.sin_addr)); - host_entry = - gethostbyaddr((const char *)&(sname.sin_addr), - sizeof(sname.sin_addr), AF_INET); - if(host_entry){ - psb->helo_name = g_strdup(host_entry->h_name); - }else{ - /* we failed to look up our own name. Instead of giving our local hostname, - we may give our IP number to show the server that we are at least - willing to be honest. For the really picky ones.*/ - DEBUG(5) debugf("failed to look up own host name.\n"); - psb->helo_name = g_strdup_printf("[%s]", inet_ntoa(sname.sin_addr)); - } - DEBUG(5) debugf("helo_name = %s\n", psb->helo_name); - } - if(psb->helo_name == NULL){ - psb->helo_name = g_strdup(default_name); - } - return psb->helo_name; -} + if (do_correct) { + getsockname(psb->sock, (struct sockaddr *) (&sname), &len); + DEBUG(5) debugf("socket: name.sin_addr = %s\n", inet_ntoa(sname.sin_addr)); + host_entry = gethostbyaddr((const char *) &(sname.sin_addr), sizeof(sname.sin_addr), AF_INET); + if (host_entry) { + psb->helo_name = g_strdup(host_entry->h_name); + } else { + /* we failed to look up our own name. Instead of giving our local hostname, + we may give our IP number to show the server that we are at least + willing to be honest. For the really picky ones. */ + DEBUG(5) debugf("failed to look up own host name.\n"); + psb->helo_name = g_strdup_printf("[%s]", inet_ntoa(sname.sin_addr)); + } + DEBUG(5) debugf("helo_name = %s\n", psb->helo_name); + } + if (psb->helo_name == NULL) { + psb->helo_name = g_strdup(default_name); + } + return psb->helo_name; +} #ifdef ENABLE_AUTH -gboolean set_auth(smtp_base *psb, gchar *name, gchar *login, gchar *secret) +gboolean +set_auth(smtp_base * psb, gchar * name, gchar * login, gchar * secret) { - if((strcasecmp(name, "CRAM-MD5") == 0) || - (strcasecmp(name, "LOGIN") == 0)) { - psb->auth_name = g_strdup(name); - psb->auth_login = g_strdup(login); - psb->auth_secret = g_strdup(secret); - - return TRUE; - } - return FALSE; + if ((strcasecmp(name, "CRAM-MD5") == 0) || (strcasecmp(name, "LOGIN") == 0)) { + psb->auth_name = g_strdup(name); + psb->auth_login = g_strdup(login); + psb->auth_secret = g_strdup(secret); + + return TRUE; + } + return FALSE; } #endif -static -smtp_base *create_smtpbase(gint sock) +static smtp_base* +create_smtpbase(gint sock) { - gint dup_sock; + gint dup_sock; - smtp_base *psb = (smtp_base *)g_malloc(sizeof(smtp_base)); + smtp_base *psb = (smtp_base *) g_malloc(sizeof(smtp_base)); - psb->sock = sock; + psb->sock = sock; - psb->use_esmtp = FALSE; - psb->use_size = FALSE; - psb->use_pipelining = FALSE; - psb->use_auth = FALSE; + psb->use_esmtp = FALSE; + psb->use_size = FALSE; + psb->use_pipelining = FALSE; + psb->use_auth = FALSE; - psb->max_size = 0; - psb->auth_names = NULL; + psb->max_size = 0; + psb->auth_names = NULL; - psb->buffer = (gchar *)g_malloc(SMTP_BUF_LEN); + psb->buffer = (gchar *) g_malloc(SMTP_BUF_LEN); - dup_sock = dup(sock); - psb->out = fdopen(sock, "w"); - psb->in = fdopen(dup_sock, "r"); + dup_sock = dup(sock); + psb->out = fdopen(sock, "w"); + psb->in = fdopen(dup_sock, "r"); - psb->error = smtp_ok; + psb->error = smtp_ok; - psb->helo_name = NULL; - - psb->auth_name = psb->auth_login = psb->auth_secret = NULL; + psb->helo_name = NULL; - return psb; + psb->auth_name = psb->auth_login = psb->auth_secret = NULL; + + return psb; } -static -gboolean read_response(smtp_base *psb, int timeout) +static gboolean +read_response(smtp_base * psb, int timeout) { - gint buf_pos = 0; - gchar code[5]; - gint i, len; + gint buf_pos = 0; + gchar code[5]; + gint i, len; - do{ - len = read_sockline(psb->in, &(psb->buffer[buf_pos]), - SMTP_BUF_LEN - buf_pos, timeout, READSOCKL_CHUG); - if(len == -3){ - psb->error = smtp_timeout; - return FALSE; - } - else if(len == -2){ - psb->error = smtp_syntax; - return FALSE; - } - else if(len == -1){ - psb->error = smtp_eof; - return FALSE; - } - for(i = 0; i < 4; i++) - code[i] = psb->buffer[buf_pos+i]; - code[i] = 0; - psb->last_code = atoi(code); + do { + len = read_sockline(psb->in, &(psb->buffer[buf_pos]), SMTP_BUF_LEN - buf_pos, timeout, READSOCKL_CHUG); + if (len == -3) { + psb->error = smtp_timeout; + return FALSE; + } else if (len == -2) { + psb->error = smtp_syntax; + return FALSE; + } else if (len == -1) { + psb->error = smtp_eof; + return FALSE; + } + for (i = 0; i < 4; i++) + code[i] = psb->buffer[buf_pos + i]; + code[i] = 0; + psb->last_code = atoi(code); - buf_pos += len; + buf_pos += len; - }while(code[3] == '-'); + } while (code[3] == '-'); - return TRUE; + return TRUE; } -static -gboolean check_response(smtp_base *psb, gboolean after_data) +static gboolean +check_response(smtp_base * psb, gboolean after_data) { - char c = psb->buffer[0]; + char c = psb->buffer[0]; - if(((c == '2') && !after_data) || ((c == '3') && after_data)){ - psb->error = smtp_ok; - DEBUG(6) debugf("response OK:'%s' after_date = %d\n", psb->buffer, (int)after_data); - return TRUE; - }else{ - if(c == '4') - psb->error = smtp_trylater; - else if(c == '5') - psb->error = smtp_fail; - else - psb->error = smtp_syntax; - DEBUG(6) debugf("response failure:'%s' after_date = %d\n", psb->buffer, (int)after_data); - return FALSE; - } + if (((c == '2') && !after_data) || ((c == '3') && after_data)) { + psb->error = smtp_ok; + DEBUG(6) debugf("response OK:'%s' after_date = %d\n", psb->buffer, (int) after_data); + return TRUE; + } else { + if (c == '4') + psb->error = smtp_trylater; + else if (c == '5') + psb->error = smtp_fail; + else + psb->error = smtp_syntax; + DEBUG(6) debugf("response failure:'%s' after_date = %d\n", psb->buffer, (int) after_data); + return FALSE; + } } -static -gboolean check_init_response(smtp_base *psb) +static gboolean +check_init_response(smtp_base * psb) { - if(check_response(psb, FALSE)){ - psb->use_esmtp = (strstr(psb->buffer, "ESMTP") != NULL); + if (check_response(psb, FALSE)) { + psb->use_esmtp = (strstr(psb->buffer, "ESMTP") != NULL); - DEBUG(4) debugf(psb->use_esmtp ? "uses esmtp\n" : "no esmtp\n"); + DEBUG(4) debugf(psb->use_esmtp ? "uses esmtp\n" : "no esmtp\n"); - return TRUE; - } - return FALSE; + return TRUE; + } + return FALSE; } -static -gchar *get_response_arg(gchar *response) +static gchar* +get_response_arg(gchar * response) { - gchar buf[SMTP_BUF_LEN]; - gchar *p = response, *q = buf; + gchar buf[SMTP_BUF_LEN]; + gchar *p = response, *q = buf; - while(*p && (*p != '\n') && isspace(*p)) p++; - if(*p && (*p != '\n')){ - while(*p && (*p != '\n') && (*p != '\r') && (q < buf+SMTP_BUF_LEN-1)) *(q++) = *(p++); - *q = 0; - return g_strdup(buf); - } - return NULL; + while (*p && (*p != '\n') && isspace(*p)) + p++; + if (*p && (*p != '\n')) { + while (*p && (*p != '\n') && (*p != '\r') && (q < buf + SMTP_BUF_LEN - 1)) + *(q++) = *(p++); + *q = 0; + return g_strdup(buf); + } + return NULL; } -static -gboolean check_helo_response(smtp_base *psb) +static gboolean +check_helo_response(smtp_base * psb) { - gchar *ptr = psb->buffer; + gchar *ptr = psb->buffer; - if(!check_response(psb, FALSE)) - return FALSE; + if (!check_response(psb, FALSE)) + return FALSE; - while(*ptr){ - if(strncasecmp(&(ptr[4]), "SIZE", 4) == 0){ - gchar *arg; - psb->use_size = TRUE; - arg = get_response_arg(&(ptr[8])); - if(arg){ - psb->max_size = atoi(arg); - g_free(arg); - } - } + while (*ptr) { + if (strncasecmp(&(ptr[4]), "SIZE", 4) == 0) { + gchar *arg; + psb->use_size = TRUE; + arg = get_response_arg(&(ptr[8])); + if (arg) { + psb->max_size = atoi(arg); + g_free(arg); + } + } - if(strncasecmp(&(ptr[4]), "PIPELINING", 10) == 0) - psb->use_pipelining = TRUE; + if (strncasecmp(&(ptr[4]), "PIPELINING", 10) == 0) + psb->use_pipelining = TRUE; - if(strncasecmp(&(ptr[4]), "AUTH", 4) == 0){ - if((ptr[8] == ' ') || (ptr[8] == '=') || (ptr[8] == '\t')){ /* not sure about '\t' */ - gchar *arg; - psb->use_auth = TRUE; - arg = get_response_arg(&(ptr[9])); /* after several years I finally learnt to count */ - if(arg){ - psb->auth_names = g_strsplit(arg, " " , 0); - g_free(arg); - - DEBUG(4){ - gint i = 0; - while(psb->auth_names[i]){ - debugf("offered AUTH %s\n", psb->auth_names[i]); - i++; - } - } + if (strncasecmp(&(ptr[4]), "AUTH", 4) == 0) { + if ((ptr[8] == ' ') || (ptr[8] == '=') || (ptr[8] == '\t')) { /* not sure about '\t' */ + gchar *arg; + psb->use_auth = TRUE; + arg = get_response_arg(&(ptr[9])); /* after several years I finally learnt to count */ + if (arg) { + psb->auth_names = g_strsplit(arg, " ", 0); + g_free(arg); + + DEBUG(4) { + gint i = 0; + while (psb->auth_names[i]) { + debugf("offered AUTH %s\n", psb->auth_names[i]); + i++; + } + } + } + } + } + + while (*ptr != '\n') + ptr++; + ptr++; } - } - } - - while(*ptr != '\n') ptr++; - ptr++; - } - DEBUG(4){ - debugf(psb->use_size ? "uses SIZE\n" : "no size\n"); - debugf(psb->use_pipelining ? "uses PIPELINING\n" : "no pipelining\n"); - debugf(psb->use_auth ? "uses AUTH\n" : "no auth\n"); - } + DEBUG(4) { + debugf(psb->use_size ? "uses SIZE\n" : "no size\n"); + debugf(psb->use_pipelining ? "uses PIPELINING\n" : "no pipelining\n"); + debugf(psb->use_auth ? "uses AUTH\n" : "no auth\n"); + } - return TRUE; + return TRUE; } -static -gboolean smtp_helo(smtp_base *psb, gchar *helo) +static gboolean +smtp_helo(smtp_base * psb, gchar * helo) { - while(TRUE){ - if(psb->use_esmtp){ - fprintf(psb->out, "EHLO %s\r\n", helo); fflush(psb->out); - - DEBUG(4) debugf("EHLO %s\r\n", helo); + while (TRUE) { + if (psb->use_esmtp) { + fprintf(psb->out, "EHLO %s\r\n", helo); + fflush(psb->out); - }else{ - fprintf(psb->out, "HELO %s\r\n", helo); fflush(psb->out); - - DEBUG(4) debugf("HELO %s\r\n", helo); + DEBUG(4) debugf("EHLO %s\r\n", helo); - } - - if(!read_response(psb, SMTP_CMD_TIMEOUT)) - return FALSE; + } else { + fprintf(psb->out, "HELO %s\r\n", helo); + fflush(psb->out); + + DEBUG(4) debugf("HELO %s\r\n", helo); + + } - if(check_helo_response(psb)) - return TRUE; - else{ - if(psb->error == smtp_fail){ - if(psb->use_esmtp){ - /* our guess that server understands EHLO was wrong, - try again with HELO - */ - psb->use_esmtp = FALSE; - }else{ - /* what sort of server ist THAT ?! - give up... - */ - return FALSE; + if (!read_response(psb, SMTP_CMD_TIMEOUT)) + return FALSE; + + if (check_helo_response(psb)) + return TRUE; + else { + if (psb->error == smtp_fail) { + if (psb->use_esmtp) { + /* our guess that server understands EHLO was wrong, try again with HELO */ + psb->use_esmtp = FALSE; + } else { + /* what sort of server ist THAT ?! give up... */ + return FALSE; + } + } else + return FALSE; + } } - }else - return FALSE; - } - } } -static -void smtp_cmd_mailfrom(smtp_base *psb, address *return_path, guint size) +static void +smtp_cmd_mailfrom(smtp_base * psb, address * return_path, guint size) { - if(psb->use_size){ - fprintf(psb->out, "MAIL FROM:%s SIZE=%d\r\n", - addr_string(return_path), size); - fflush(psb->out); + if (psb->use_size) { + fprintf(psb->out, "MAIL FROM:%s SIZE=%d\r\n", addr_string(return_path), size); + fflush(psb->out); - DEBUG(4) debugf("MAIL FROM:%s SIZE=%d\r\n", - addr_string(return_path), size); + DEBUG(4) debugf("MAIL FROM:%s SIZE=%d\r\n", addr_string(return_path), size); - }else{ - fprintf(psb->out, "MAIL FROM:%s\r\n", addr_string(return_path)); - fflush(psb->out); + } else { + fprintf(psb->out, "MAIL FROM:%s\r\n", addr_string(return_path)); + fflush(psb->out); - DEBUG(4) debugf("MAIL FROM:%s\r\n", addr_string(return_path)); - } + DEBUG(4) debugf("MAIL FROM:%s\r\n", addr_string(return_path)); + } } -static -void smtp_cmd_rcptto(smtp_base *psb, address *rcpt) +static void +smtp_cmd_rcptto(smtp_base * psb, address * rcpt) { - fprintf(psb->out, "RCPT TO:%s\r\n", addr_string(rcpt)); - fflush(psb->out); - DEBUG(4) debugf("RCPT TO:%s\n", addr_string(rcpt)); + fprintf(psb->out, "RCPT TO:%s\r\n", addr_string(rcpt)); + fflush(psb->out); + DEBUG(4) debugf("RCPT TO:%s\n", addr_string(rcpt)); } -static -void send_data_line(smtp_base *psb, gchar *data) +static void +send_data_line(smtp_base * psb, gchar * data) { - /* According to RFC 821 each line should be terminated with CRLF. - Since a dot on a line itself marks the end of data, each line - beginning with a dot is prepended with another dot. - */ - gchar *ptr; - gboolean new_line = TRUE; /* previous versions assumed that each item was - exactly one line. This is no longer the case */ + /* According to RFC 821 each line should be terminated with CRLF. + Since a dot on a line itself marks the end of data, each line + beginning with a dot is prepended with another dot. + */ + gchar *ptr; + gboolean new_line = TRUE; /* previous versions assumed that each item was exactly one line. This is no longer the case */ - ptr = data; - while(*ptr){ - int c = (int)(*ptr); - if(c == '.') - if(new_line) - putc('.', psb->out); - if(c == '\n'){ - putc('\r', psb->out); - putc('\n', psb->out); - new_line = TRUE; - }else{ - putc(c, psb->out); - new_line = FALSE; - } - ptr++; - } + ptr = data; + while (*ptr) { + int c = (int) (*ptr); + if (c == '.') + if (new_line) + putc('.', psb->out); + if (c == '\n') { + putc('\r', psb->out); + putc('\n', psb->out); + new_line = TRUE; + } else { + putc(c, psb->out); + new_line = FALSE; + } + ptr++; + } } -static -void send_header(smtp_base *psb, GList *hdr_list) +static void +send_header(smtp_base * psb, GList * hdr_list) { - GList *node; - gint num_hdrs = 0; + GList *node; + gint num_hdrs = 0; - /* header */ - if(hdr_list){ - foreach(hdr_list, node){ - if(node->data){ - header *hdr = (header *)(node->data); - if(hdr->header){ - send_data_line(psb, hdr->header); - num_hdrs++; + /* header */ + if (hdr_list) { + foreach(hdr_list, node) { + if (node->data) { + header *hdr = (header *) (node->data); + if (hdr->header) { + send_data_line(psb, hdr->header); + num_hdrs++; + } + } + } } - } - } - } - /* empty line separating headers from data: */ - putc('\r', psb->out); - putc('\n', psb->out); + /* empty line separating headers from data: */ + putc('\r', psb->out); + putc('\n', psb->out); - DEBUG(4) debugf("sent %d headers\n", num_hdrs); + DEBUG(4) debugf("sent %d headers\n", num_hdrs); } -static -void send_data(smtp_base *psb, message *msg) +static void +send_data(smtp_base * psb, message * msg) { - GList *node; - gint num_lines = 0; + GList *node; + gint num_lines = 0; - /* data */ - if(msg->data_list){ - for(node = g_list_first(msg->data_list); node; node = g_list_next(node)){ - if(node->data){ - send_data_line(psb, node->data); - num_lines++; - } - } - } + /* data */ + if (msg->data_list) { + for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) { + if (node->data) { + send_data_line(psb, node->data); + num_lines++; + } + } + } - DEBUG(4) debugf("sent %d lines of data\n", num_lines); + DEBUG(4) debugf("sent %d lines of data\n", num_lines); - fprintf(psb->out, ".\r\n"); - fflush(psb->out); + fprintf(psb->out, ".\r\n"); + fflush(psb->out); } -void smtp_out_mark_rcpts(smtp_base *psb, GList *rcpt_list) +void +smtp_out_mark_rcpts(smtp_base * psb, GList * rcpt_list) { - GList *rcpt_node; - for(rcpt_node = g_list_first(rcpt_list); - rcpt_node; - rcpt_node = g_list_next(rcpt_node)){ - address *rcpt = (address *)(rcpt_node->data); + GList *rcpt_node; + for (rcpt_node = g_list_first(rcpt_list); rcpt_node; rcpt_node = g_list_next(rcpt_node)) { + address *rcpt = (address *) (rcpt_node->data); - addr_unmark_delivered(rcpt); + addr_unmark_delivered(rcpt); - if((psb->error == smtp_trylater) || (psb->error == smtp_timeout) || - (psb->error == smtp_eof)){ - addr_mark_defered(rcpt); - }else{ - addr_mark_failed(rcpt); - } - } + if ((psb->error == smtp_trylater) || (psb->error == smtp_timeout) || (psb->error == smtp_eof)) { + addr_mark_defered(rcpt); + } else { + addr_mark_failed(rcpt); + } + } } -void smtp_out_log_failure(smtp_base *psb, message *msg) +void +smtp_out_log_failure(smtp_base * psb, message * msg) { - gchar *err_str; + gchar *err_str; - if(psb->error == smtp_timeout) - err_str = g_strdup("connection timed out."); - else if(psb->error == smtp_eof) - err_str = g_strdup("connection terminated prematurely."); - else if(psb->error == smtp_syntax) - err_str = g_strdup_printf("got unexpected response: %s", psb->buffer); - else if(psb->error == smtp_cancel) - err_str = g_strdup("delivery was canceled.\n"); - else - /* error message should still be in the buffer */ - err_str = g_strdup_printf("failed: %s\n", psb->buffer); + if (psb->error == smtp_timeout) + err_str = g_strdup("connection timed out."); + else if (psb->error == smtp_eof) + err_str = g_strdup("connection terminated prematurely."); + else if (psb->error == smtp_syntax) + err_str = g_strdup_printf("got unexpected response: %s", psb->buffer); + else if (psb->error == smtp_cancel) + err_str = g_strdup("delivery was canceled.\n"); + else + /* error message should still be in the buffer */ + err_str = g_strdup_printf("failed: %s\n", psb->buffer); - if(msg == NULL) - logwrite(LOG_NOTICE, "host=%s %s\n", - psb->remote_host, err_str); - else - logwrite(LOG_NOTICE, "%s == host=%s %s\n", - msg->uid, psb->remote_host, err_str); + if (msg == NULL) + logwrite(LOG_NOTICE, "host=%s %s\n", psb->remote_host, err_str); + else + logwrite(LOG_NOTICE, "%s == host=%s %s\n", msg->uid, psb->remote_host, err_str); - g_free(err_str); + g_free(err_str); } -smtp_base *smtp_out_open(gchar *host, gint port, GList *resolve_list) +smtp_base* +smtp_out_open(gchar * host, gint port, GList * resolve_list) { - smtp_base *psb; - gint sock; - mxip_addr *addr; + smtp_base *psb; + gint sock; + mxip_addr *addr; - DEBUG(5) debugf("smtp_out_open entered, host = %s\n", host); - - if((addr = connect_resolvelist(&sock, host, port, resolve_list))){ - /* create structure to hold status data: */ - psb = create_smtpbase(sock); - psb->remote_host = addr->name; + DEBUG(5) debugf("smtp_out_open entered, host = %s\n", host); - DEBUG(5){ - struct sockaddr_in name; - int len = sizeof(struct sockaddr); - getsockname(sock, (struct sockaddr *)(&name), &len); - debugf("socket: name.sin_addr = %s\n", inet_ntoa(name.sin_addr)); - } - return psb; - }else{ - DEBUG(5) debugf("connect_resolvelist failed: %s %s\n", strerror(errno), hstrerror(h_errno)); - } + if ((addr = connect_resolvelist(&sock, host, port, resolve_list))) { + /* create structure to hold status data: */ + psb = create_smtpbase(sock); + psb->remote_host = addr->name; - return NULL; + DEBUG(5) { + struct sockaddr_in name; + int len = sizeof(struct sockaddr); + getsockname(sock, (struct sockaddr *) (&name), &len); + debugf("socket: name.sin_addr = %s\n", inet_ntoa(name.sin_addr)); + } + return psb; + } else { + DEBUG(5) debugf("connect_resolvelist failed: %s %s\n", strerror(errno), hstrerror(h_errno)); + } + + return NULL; } -smtp_base *smtp_out_open_child(gchar *cmd) +smtp_base* +smtp_out_open_child(gchar * cmd) { - smtp_base *psb; - gint sock; + smtp_base *psb; + gint sock; - DEBUG(5) debugf("smtp_out_open_child entered, cmd = %s\n", cmd); - - sock = child(cmd); + DEBUG(5) debugf("smtp_out_open_child entered, cmd = %s\n", cmd); - if(sock > 0){ - psb = create_smtpbase(sock); - psb->remote_host = NULL; + sock = child(cmd); - return psb; - } + if (sock > 0) { + psb = create_smtpbase(sock); + psb->remote_host = NULL; - return NULL; + return psb; + } + + return NULL; } -gboolean smtp_out_rset(smtp_base *psb) +gboolean +smtp_out_rset(smtp_base * psb) { - gboolean ok; - - fprintf(psb->out, "RSET\r\n"); fflush(psb->out); - DEBUG(4) debugf("RSET\n"); + gboolean ok; - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))) - if(check_response(psb, FALSE)) - return TRUE; + fprintf(psb->out, "RSET\r\n"); + fflush(psb->out); + DEBUG(4) debugf("RSET\n"); - smtp_out_log_failure(psb, NULL); + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) + if (check_response(psb, FALSE)) + return TRUE; - return FALSE; + smtp_out_log_failure(psb, NULL); + + return FALSE; } #ifdef ENABLE_AUTH -static -gboolean smtp_out_auth_cram_md5(smtp_base *psb) +static gboolean +smtp_out_auth_cram_md5(smtp_base * psb) { - gboolean ok = FALSE; + gboolean ok = FALSE; - fprintf(psb->out, "AUTH CRAM-MD5\r\n"); fflush(psb->out); - DEBUG(4) debugf("AUTH CRAM-MD5\n"); - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))){ - if((ok = check_response(psb, TRUE))){ - gchar *chall64 = get_response_arg(&(psb->buffer[4])); - gint chall_size; - gchar *chall = base64_decode(chall64, &chall_size); - guchar digest[16], *reply64, *reply; - gchar digest_string[33]; - gint i; + fprintf(psb->out, "AUTH CRAM-MD5\r\n"); + fflush(psb->out); + DEBUG(4) debugf("AUTH CRAM-MD5\n"); + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) { + if ((ok = check_response(psb, TRUE))) { + gchar *chall64 = get_response_arg(&(psb->buffer[4])); + gint chall_size; + gchar *chall = base64_decode(chall64, &chall_size); + guchar digest[16], *reply64, *reply; + gchar digest_string[33]; + gint i; #ifdef USE_LIB_CRYPTO - unsigned int digest_len; + unsigned int digest_len; #endif - - DEBUG(5) debugf("encoded challenge = %s\n", chall64); - DEBUG(5) debugf("decoded challenge = %s, size = %d\n", chall, chall_size); - - DEBUG(5) debugf("secret = %s\n", psb->auth_secret); - + + DEBUG(5) debugf("encoded challenge = %s\n", chall64); + DEBUG(5) debugf("decoded challenge = %s, size = %d\n", chall, chall_size); + + DEBUG(5) debugf("secret = %s\n", psb->auth_secret); + #ifdef USE_LIB_CRYPTO - HMAC(EVP_md5(), psb->auth_secret, strlen(psb->auth_secret), chall, chall_size, digest, &digest_len); + HMAC(EVP_md5(), psb->auth_secret, strlen(psb->auth_secret), chall, chall_size, digest, &digest_len); #else - hmac_md5(chall, chall_size, psb->auth_secret, strlen(psb->auth_secret), digest); + hmac_md5(chall, chall_size, psb->auth_secret, strlen(psb->auth_secret), digest); #endif - - for(i = 0; i < 16; i++) - sprintf(&(digest_string[i+i]), "%02x", (unsigned int)(digest[i])); - digest_string[32] = 0; - - DEBUG(5) debugf("digest = %s\n", digest_string); - - reply = g_strdup_printf("%s %s", psb->auth_login, digest_string); - DEBUG(5) debugf("unencoded reply = %s\n", reply); - - reply64 = base64_encode(reply, strlen(reply)); - DEBUG(5) debugf("encoded reply = %s\n", reply64); - - fprintf(psb->out, "%s\r\n", reply64); fflush(psb->out); - DEBUG(4) debugf("%s\n", reply64); - - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))) - ok = check_response(psb, FALSE); - - g_free(reply64); - g_free(reply); - g_free(chall); - g_free(chall64); - } - } - return ok; + + for (i = 0; i < 16; i++) + sprintf(&(digest_string[i + i]), "%02x", (unsigned int) (digest[i])); + digest_string[32] = 0; + + DEBUG(5) debugf("digest = %s\n", digest_string); + + reply = g_strdup_printf("%s %s", psb->auth_login, digest_string); + DEBUG(5) debugf("unencoded reply = %s\n", reply); + + reply64 = base64_encode(reply, strlen(reply)); + DEBUG(5) debugf("encoded reply = %s\n", reply64); + + fprintf(psb->out, "%s\r\n", reply64); + fflush(psb->out); + DEBUG(4) debugf("%s\n", reply64); + + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) + ok = check_response(psb, FALSE); + + g_free(reply64); + g_free(reply); + g_free(chall); + g_free(chall64); + } + } + return ok; } -static -gboolean smtp_out_auth_login(smtp_base *psb) +static gboolean +smtp_out_auth_login(smtp_base * psb) { - gboolean ok = FALSE; - fprintf(psb->out, "AUTH LOGIN\r\n"); fflush(psb->out); - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))){ - if((ok = check_response(psb, TRUE))){ - gchar *resp64; - guchar *resp; - gint resp_size; - gchar *reply64; - - resp64 = get_response_arg(&(psb->buffer[4])); - DEBUG(5) debugf("encoded response = %s\n", resp64); - resp = base64_decode(resp64, &resp_size); - g_free(resp64); - DEBUG(5) debugf("decoded response = %s, size = %d\n", - resp, resp_size); - g_free(resp); - reply64 = base64_encode(psb->auth_login, - strlen(psb->auth_login)); - fprintf(psb->out, "%s\r\n", reply64); fflush(psb->out); - g_free(reply64); - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))) { - if ((ok = check_response(psb, TRUE))) { - resp64 = get_response_arg(&(psb->buffer[4])); - DEBUG(5) debugf("encoded response = %s\n", resp64); - resp = base64_decode(resp64, &resp_size); - g_free(resp64); - DEBUG(5) debugf("decoded response = %s, size = %d\n", - resp, resp_size); - g_free(resp); - reply64 = base64_encode(psb->auth_secret, - strlen(psb->auth_secret)); - fprintf(psb->out, "%s\r\n", reply64); fflush(psb->out); - g_free(reply64); - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))) - ok = check_response(psb, FALSE); + gboolean ok = FALSE; + fprintf(psb->out, "AUTH LOGIN\r\n"); + fflush(psb->out); + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) { + if ((ok = check_response(psb, TRUE))) { + gchar *resp64; + guchar *resp; + gint resp_size; + gchar *reply64; + + resp64 = get_response_arg(&(psb->buffer[4])); + DEBUG(5) debugf("encoded response = %s\n", resp64); + resp = base64_decode(resp64, &resp_size); + g_free(resp64); + DEBUG(5) debugf("decoded response = %s, size = %d\n", resp, resp_size); + g_free(resp); + reply64 = base64_encode(psb->auth_login, strlen(psb->auth_login)); + fprintf(psb->out, "%s\r\n", reply64); + fflush(psb->out); + g_free(reply64); + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) { + if ((ok = check_response(psb, TRUE))) { + resp64 = get_response_arg(&(psb->buffer[4])); + DEBUG(5) debugf("encoded response = %s\n", resp64); + resp = base64_decode(resp64, &resp_size); + g_free(resp64); + DEBUG(5) debugf("decoded response = %s, size = %d\n", resp, resp_size); + g_free(resp); + reply64 = base64_encode(psb->auth_secret, strlen(psb->auth_secret)); + fprintf(psb->out, "%s\r\n", reply64); + fflush(psb->out); + g_free(reply64); + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) + ok = check_response(psb, FALSE); + } + } + } } - } - } - } - return ok; + return ok; } -gboolean smtp_out_auth(smtp_base *psb) +gboolean +smtp_out_auth(smtp_base * psb) { - gboolean ok = FALSE; - gint i = 0; - while(psb->auth_names[i]){ - if(strcasecmp(psb->auth_names[i], psb->auth_name) == 0) - break; - i++; - } - if(psb->auth_names[i]){ - if(strcasecmp(psb->auth_name, "cram-md5") == 0){ - smtp_out_auth_cram_md5(psb); - }else if(strcasecmp(psb->auth_name, "login") == 0){ - smtp_out_auth_login(psb); - }else{ - logwrite(LOG_ERR, "auth method %s not supported\n", psb->auth_name); - } - }else{ - logwrite(LOG_ERR, "no auth method %s found.\n", psb->auth_name); - } - return ok; + gboolean ok = FALSE; + gint i = 0; + while (psb->auth_names[i]) { + if (strcasecmp(psb->auth_names[i], psb->auth_name) == 0) + break; + i++; + } + if (psb->auth_names[i]) { + if (strcasecmp(psb->auth_name, "cram-md5") == 0) { + smtp_out_auth_cram_md5(psb); + } else if (strcasecmp(psb->auth_name, "login") == 0) { + smtp_out_auth_login(psb); + } else { + logwrite(LOG_ERR, "auth method %s not supported\n", psb->auth_name); + } + } else { + logwrite(LOG_ERR, "no auth method %s found.\n", psb->auth_name); + } + return ok; } #endif -gboolean smtp_out_init(smtp_base *psb) +gboolean +smtp_out_init(smtp_base * psb) { - gboolean ok; + gboolean ok; - if((ok = read_response(psb, SMTP_INITIAL_TIMEOUT))){ - if((ok = check_init_response(psb))){ - - if((ok = smtp_helo(psb, psb->helo_name))){ + if ((ok = read_response(psb, SMTP_INITIAL_TIMEOUT))) { + if ((ok = check_init_response(psb))) { + + if ((ok = smtp_helo(psb, psb->helo_name))) { #ifdef ENABLE_AUTH - if(psb->auth_name && psb->use_auth){ - /* we completely disregard the response of server here. If - authentication fails, the server will complain later - anyway. I know, this is not polite... */ - smtp_out_auth(psb); - } + if (psb->auth_name && psb->use_auth) { + /* we completely disregard the response of server here. If + authentication fails, the server will complain later + anyway. I know, this is not polite... */ + smtp_out_auth(psb); + } #endif - } - } - } - if(!ok) - smtp_out_log_failure(psb, NULL); - return ok; + } + } + } + if (!ok) + smtp_out_log_failure(psb, NULL); + return ok; } -gint smtp_out_msg(smtp_base *psb, - message *msg, address *return_path, GList *rcpt_list, - GList *hdr_list) +gint +smtp_out_msg(smtp_base * psb, message * msg, address * return_path, GList * rcpt_list, GList * hdr_list) { - gint i, size; - gboolean ok = TRUE; - int rcpt_cnt; - int rcpt_accept = 0; + gint i, size; + gboolean ok = TRUE; + int rcpt_cnt; + int rcpt_accept = 0; - DEBUG(5) debugf("smtp_out_msg entered\n"); + DEBUG(5) debugf("smtp_out_msg entered\n"); - /* defaults: */ - if(return_path == NULL) - return_path = msg->return_path; - if(hdr_list == NULL) - hdr_list = msg->hdr_list; - if(rcpt_list == NULL) - rcpt_list = msg->rcpt_list; - rcpt_cnt = g_list_length(rcpt_list); + /* defaults: */ + if (return_path == NULL) + return_path = msg->return_path; + if (hdr_list == NULL) + hdr_list = msg->hdr_list; + if (rcpt_list == NULL) + rcpt_list = msg->rcpt_list; + rcpt_cnt = g_list_length(rcpt_list); + + size = msg_calc_size(msg, TRUE); - size = msg_calc_size(msg, TRUE); + /* respect maximum size given by server: */ + if ((psb->max_size > 0) && (size > psb->max_size)) { + logwrite(LOG_WARNING, "%s == host=%s message size (%d) > fixed maximum message size of server (%d)", + msg->uid, psb->remote_host, size, psb->max_size); + psb->error = smtp_cancel; + ok = FALSE; + } - /* respect maximum size given by server: */ - if((psb->max_size > 0) && (size > psb->max_size)){ - logwrite(LOG_WARNING, - "%s == host=%s message size (%d) > fixed maximum message size of server (%d)", - msg->uid, psb->remote_host, size, psb->max_size); - psb->error = smtp_cancel; - ok = FALSE; - } + if (ok) { + smtp_cmd_mailfrom(psb, return_path, psb->use_size ? size + SMTP_SIZE_ADD : 0); - if(ok){ - smtp_cmd_mailfrom(psb, return_path, - psb->use_size ? - size + SMTP_SIZE_ADD : 0); - - if(!psb->use_pipelining){ - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))) - ok = check_response(psb, FALSE); - } - } - if(ok){ - GList *rcpt_node; - rcpt_accept = 0; + if (!psb->use_pipelining) { + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) + ok = check_response(psb, FALSE); + } + } + if (ok) { + GList *rcpt_node; + rcpt_accept = 0; - for(rcpt_node = g_list_first(rcpt_list); - rcpt_node != NULL; - rcpt_node = g_list_next(rcpt_node)){ - address *rcpt = (address *)(rcpt_node->data); - smtp_cmd_rcptto(psb, rcpt); - if(!psb->use_pipelining){ - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))) - if(check_response(psb, FALSE)){ - rcpt_accept++; - addr_mark_delivered(rcpt); - } - else{ - /* if server returned an error for one recp. we - may still try the others. But if it is a timeout, eof - or unexpected response, it is more serious and we should - give up. */ - if((psb->error != smtp_trylater) && - (psb->error != smtp_fail)){ - ok = FALSE; - break; - }else{ - logwrite(LOG_NOTICE, "%s == %s host=%s failed: %s", - msg->uid, addr_string(rcpt), - psb->remote_host, psb->buffer); - if(psb->error == smtp_trylater){ - addr_mark_defered(rcpt); - }else{ - addr_mark_failed(rcpt); - } - } - } - else - break; - } - } + for (rcpt_node = g_list_first(rcpt_list); rcpt_node != NULL; rcpt_node = g_list_next(rcpt_node)) { + address *rcpt = (address *) (rcpt_node->data); + smtp_cmd_rcptto(psb, rcpt); + if (!psb->use_pipelining) { + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) + if (check_response(psb, FALSE)) { + rcpt_accept++; + addr_mark_delivered(rcpt); + } else { + /* if server returned an error for one recp. we + may still try the others. But if it is a timeout, eof + or unexpected response, it is more serious and we should + give up. */ + if ((psb->error != smtp_trylater) && (psb->error != smtp_fail)) { + ok = FALSE; + break; + } else { + logwrite(LOG_NOTICE, "%s == %s host=%s failed: %s", msg->uid, addr_string(rcpt), psb->remote_host, psb->buffer); + if (psb->error == smtp_trylater) { + addr_mark_defered(rcpt); + } else { + addr_mark_failed(rcpt); + } + } + } else + break; + } + } - /* There is no point in going on if no recp.s were accpted. - But we can check that at this point only if not pipelining: */ - ok = (ok && (psb->use_pipelining || (rcpt_accept > 0))); - if(ok){ + /* There is no point in going on if no recp.s were accpted. + But we can check that at this point only if not pipelining: */ + ok = (ok && (psb->use_pipelining || (rcpt_accept > 0))); + if (ok) { - fprintf(psb->out, "DATA\r\n"); fflush(psb->out); + fprintf(psb->out, "DATA\r\n"); + fflush(psb->out); + + DEBUG(4) debugf("DATA\r\n"); - DEBUG(4) debugf("DATA\r\n"); - - if(psb->use_pipelining){ - /* the first pl'ed command was MAIL FROM - the last was DATA, whose response can be handled by the 'normal' code - all in between were RCPT TO: - */ - /* response to MAIL FROM: */ - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))){ - if((ok = check_response(psb, FALSE))){ + if (psb->use_pipelining) { + /* the first pl'ed command was MAIL FROM + the last was DATA, whose response can be handled by the 'normal' code + all in between were RCPT TO: + */ + /* response to MAIL FROM: */ + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) { + if ((ok = check_response(psb, FALSE))) { - /* response(s) to RCPT TO: - this is very similar to the sequence above for no pipeline - */ - for(i = 0; i < rcpt_cnt; i++){ - if((ok = read_response(psb, SMTP_CMD_TIMEOUT))){ - address *rcpt = g_list_nth_data(rcpt_list, i); - if(check_response(psb, FALSE)){ - rcpt_accept++; - addr_mark_delivered(rcpt); - } - else{ - /* if server returned an error 4xx or 5xx for one recp. we - may still try the others. But if it is a timeout, eof - or unexpected response, it is more serious and we - should give up. */ - if((psb->error != smtp_trylater) && - (psb->error != smtp_fail)){ - ok = FALSE; - break; - }else{ - logwrite(LOG_NOTICE, "%s == %s host=%s failed: %s", - msg->uid, addr_string(rcpt), - psb->remote_host, psb->buffer); - if(psb->error == smtp_trylater){ - addr_mark_defered(rcpt); - }else{ - addr_mark_failed(rcpt); - } - } + /* response(s) to RCPT TO: + this is very similar to the sequence above for no pipeline + */ + for (i = 0; i < rcpt_cnt; i++) { + if ((ok = read_response(psb, SMTP_CMD_TIMEOUT))) { + address *rcpt = g_list_nth_data(rcpt_list, i); + if (check_response(psb, FALSE)) { + rcpt_accept++; + addr_mark_delivered(rcpt); + } else { + /* if server returned an error 4xx or 5xx for one recp. we + may still try the others. But if it is a timeout, eof + or unexpected response, it is more serious and we + should give up. */ + if ((psb->error != smtp_trylater) && + (psb->error != smtp_fail)) { + ok = FALSE; + break; + } else { + logwrite(LOG_NOTICE, "%s == %s host=%s failed: %s", msg->uid, + addr_string(rcpt), psb->remote_host, psb->buffer); + if (psb->error == smtp_trylater) { + addr_mark_defered(rcpt); + } else { + addr_mark_failed(rcpt); + } + } + } + } else { + DEBUG(5) debugf("check_response failed after RCPT TO\n"); + break; + } + } + if (rcpt_accept == 0) + ok = FALSE; + } else { + DEBUG(5) debugf("check_response failed after MAIL FROM\n"); + } + } else { + DEBUG(5) + debugf("read_response failed after MAIL FROM\n"); + } + } + + /* if(psb->use_pipelining) */ + /* response to the DATA cmd */ + if (ok) { + if (read_response(psb, SMTP_DATA_TIMEOUT)) { + if (check_response(psb, TRUE)) { + send_header(psb, hdr_list); + send_data(psb, msg); + + if (read_response(psb, SMTP_FINAL_TIMEOUT)) + ok = check_response(psb, FALSE); + } + } + } } - }else{ - DEBUG(5) debugf("check_response failed after RCPT TO\n"); - break; - } - } - if(rcpt_accept == 0) - ok = FALSE; - }else{ - DEBUG(5) debugf("check_response failed after MAIL FROM\n"); - } - }else{ - DEBUG(5) debugf("read_response failed after MAIL FROM\n"); } - } /* if(psb->use_pipelining) */ - /* response to the DATA cmd */ - if(ok){ - if(read_response(psb, SMTP_DATA_TIMEOUT)){ - if(check_response(psb, TRUE)){ - send_header(psb, hdr_list); - send_data(psb, msg); - - if(read_response(psb, SMTP_FINAL_TIMEOUT)) - ok = check_response(psb, FALSE); - } + DEBUG(5) { + debugf("psb->error = %d\n", psb->error); + debugf("ok = %d\n", ok); + debugf("rcpt_accept = %d\n", rcpt_accept); } - } - } - } - - DEBUG(5){ - debugf("psb->error = %d\n", psb->error); - debugf("ok = %d\n", ok); - debugf("rcpt_accept = %d\n", rcpt_accept); - } - if(psb->error == smtp_ok){ - GList *rcpt_node; - for(rcpt_node = g_list_first(rcpt_list); - rcpt_node; - rcpt_node = g_list_next(rcpt_node)){ - address *rcpt = (address *)(rcpt_node->data); - if(addr_is_delivered(rcpt)) - logwrite(LOG_NOTICE, "%s => %s host=%s with %s\n", - msg->uid, addr_string(rcpt), psb->remote_host, - psb->use_esmtp ? "esmtp" : "smtp"); - } - }else{ - /* if something went wrong, - we have to unmark the rcpts prematurely marked as delivered - and mark the status */ - smtp_out_mark_rcpts(psb, rcpt_list); + if (psb->error == smtp_ok) { + GList *rcpt_node; + for (rcpt_node = g_list_first(rcpt_list); rcpt_node; rcpt_node = g_list_next(rcpt_node)) { + address *rcpt = (address *) (rcpt_node->data); + if (addr_is_delivered(rcpt)) + logwrite(LOG_NOTICE, "%s => %s host=%s with %s\n", msg->uid, addr_string(rcpt), + psb->remote_host, psb->use_esmtp ? "esmtp" : "smtp"); + } + } else { + /* if something went wrong, + we have to unmark the rcpts prematurely marked as delivered + and mark the status */ + smtp_out_mark_rcpts(psb, rcpt_list); - /* log the failure: */ - smtp_out_log_failure(psb, msg); - } - return rcpt_accept; + /* log the failure: */ + smtp_out_log_failure(psb, msg); + } + return rcpt_accept; } -gboolean smtp_out_quit(smtp_base *psb) +gboolean +smtp_out_quit(smtp_base * psb) { - fprintf(psb->out, "QUIT\r\n"); fflush(psb->out); - - DEBUG(4) debugf("QUIT\n"); + fprintf(psb->out, "QUIT\r\n"); + fflush(psb->out); - signal(SIGALRM, SIG_DFL); + DEBUG(4) debugf("QUIT\n"); - return TRUE; + signal(SIGALRM, SIG_DFL); + + return TRUE; } - -gint smtp_deliver(gchar *host, gint port, GList *resolve_list, - message *msg, - address *return_path, - GList *rcpt_list) + +gint +smtp_deliver(gchar * host, gint port, GList * resolve_list, message * msg, address * return_path, GList * rcpt_list) { - smtp_base *psb; - smtp_error err; + smtp_base *psb; + smtp_error err; - DEBUG(5) debugf("smtp_deliver entered\n"); + DEBUG(5) debugf("smtp_deliver entered\n"); - if(return_path == NULL) - return_path = msg->return_path; + if (return_path == NULL) + return_path = msg->return_path; - if((psb = smtp_out_open(host, port, resolve_list))){ - set_heloname(psb, return_path->domain, TRUE); - /* initiate connection, send message and quit: */ - if(smtp_out_init(psb)){ - smtp_out_msg(psb, msg, return_path, rcpt_list, NULL); - if(psb->error == smtp_ok || - (psb->error == smtp_fail) || - (psb->error == smtp_trylater) || - (psb->error == smtp_syntax) || - (psb->error == smtp_cancel)) - - smtp_out_quit(psb); - } - - err = psb->error; - destroy_smtpbase(psb); - - return err; - } - return -1; + if ((psb = smtp_out_open(host, port, resolve_list))) { + set_heloname(psb, return_path->domain, TRUE); + /* initiate connection, send message and quit: */ + if (smtp_out_init(psb)) { + smtp_out_msg(psb, msg, return_path, rcpt_list, NULL); + if (psb->error == smtp_ok || (psb->error == smtp_fail) || (psb->error == smtp_trylater) + || (psb->error == smtp_syntax) || (psb->error == smtp_cancel)) + smtp_out_quit(psb); + } + + err = psb->error; + destroy_smtpbase(psb); + + return err; + } + return -1; }