# HG changeset patch # User meillo@marmaro.de # Date 1225120990 -3600 # Node ID 26e34ae9a3e32c70555501e255982d1267aee918 # Parent 31cc8a89cb74a59dcc71c44bb8f32f69dfda2de6 changed indention and line wrapping to a more consistent style diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/accept.c --- a/src/accept.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/accept.c Mon Oct 27 16:23:10 2008 +0100 @@ -19,41 +19,40 @@ #include "masqmail.h" #include "readsock.h" -gchar *prot_names[] = -{ - "local", - "bsmtp", - "smtp", - "esmtp", - "pop3", - "apop", - "(unknown)" /* should not happen, but better than crashing. */ +gchar *prot_names[] = { + "local", + "bsmtp", + "smtp", + "esmtp", + "pop3", + "apop", + "(unknown)" /* should not happen, but better than crashing. */ }; -static -gchar *string_base62(gchar *res, guint value, gchar len) +static gchar* +string_base62(gchar * res, guint value, gchar len) { - static gchar base62_chars[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - gchar *p = res + len; - *p = 0; - while (p > res){ - *(--p) = base62_chars[value % 62]; - value /= 62; - } - return res; + static gchar base62_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + gchar *p = res + len; + *p = 0; + while (p > res) { + *(--p) = base62_chars[value % 62]; + value /= 62; + } + return res; } -static gint _g_list_addr_isequal(gconstpointer a, gconstpointer b) +static gint +_g_list_addr_isequal(gconstpointer a, gconstpointer b) { - address *addr1 = (address *)a; - address *addr2 = (address *)b; - int ret; + address *addr1 = (address *) a; + address *addr2 = (address *) b; + int ret; - if((ret = strcasecmp(addr1->domain, addr2->domain)) == 0) - return strcmp(addr1->local_part, addr2->local_part); - else - return ret; + if ((ret = strcasecmp(addr1->domain, addr2->domain)) == 0) + return strcmp(addr1->local_part, addr2->local_part); + else + return ret; } /* accept message from anywhere. @@ -64,415 +63,392 @@ (from To/Cc/Bcc headers if ACC_RCPT_TO is set) rcpt_list. */ -accept_error accept_message_stream(FILE *in, message *msg, guint flags) +accept_error +accept_message_stream(FILE * in, message * msg, guint flags) { - gchar *line, *line1; - int line_size = MAX_DATALINE; - gboolean in_headers = TRUE; - header *hdr = NULL; - gint line_cnt = 0, data_size = 0; + gchar *line, *line1; + int line_size = MAX_DATALINE; + gboolean in_headers = TRUE; + header *hdr = NULL; + gint line_cnt = 0, data_size = 0; - line = g_malloc(line_size); - line[0] = 0; + line = g_malloc(line_size); + line[0] = 0; - while(TRUE){ - int len = read_sockline1(in, &line, &line_size, 5*60, READSOCKL_CVT_CRLF); + while (TRUE) { + int len = read_sockline1(in, &line, &line_size, 5 * 60, READSOCKL_CVT_CRLF); - line1 = line; + line1 = line; - if((line[0] == '.') && (!(flags & ACC_NODOT_TERM))){ - if(line[1] == '\n'){ - g_free(line); - break; - } - line1++; - } - - if(len <= 0){ - if((len == -1) && ((flags & ACC_NODOT_TERM) || (flags & ACC_NODOT_RELAX))){ - /* we got an EOF, and the last line was not terminated by a CR */ - gint len1 = strlen(line1); - if(len1 > 0){ /* == 0 is 'normal' (EOF after a CR) */ - if(line1[len1-1] != '\n'){ /* some mail clients allow unterminated lines */ - line1[len1] = '\n'; - line1[len1+1] = 0; - msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); - data_size += strlen(line1); - line_cnt++; - } + if ((line[0] == '.') && (!(flags & ACC_NODOT_TERM))) { + if (line[1] == '\n') { + g_free(line); + break; + } + line1++; + } + + if (len <= 0) { + if ((len == -1) && ((flags & ACC_NODOT_TERM) || (flags & ACC_NODOT_RELAX))) { + /* we got an EOF, and the last line was not terminated by a CR */ + gint len1 = strlen(line1); + if (len1 > 0) { /* == 0 is 'normal' (EOF after a CR) */ + if (line1[len1 - 1] != '\n') { /* some mail clients allow unterminated lines */ + line1[len1] = '\n'; + line1[len1 + 1] = 0; + msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); + data_size += strlen(line1); + line_cnt++; + } + } + break; + } else { + g_free(line); + if (len == -1) { + return AERR_EOF; + } else if (len == -2) { + /* should not happen any more */ + return AERR_OVERFLOW; + } else if (len == -3) { + return AERR_TIMEOUT; + } else { + /* does not happen */ + DEBUG(5) debugf("read_sockline returned %d\n", len); + return AERR_UNKNOWN; + } + } + } else { + if (in_headers) { + + /* some pop servers send the 'From ' line, skip it: */ + if (msg->hdr_list == NULL) + if (strncmp(line1, "From ", 5) == 0) + continue; + + if (line1[0] == ' ' || line1[0] == '\t') { + /* continuation of 'folded' header: */ + if (hdr) { + hdr->header = + g_strconcat(hdr->header, line1, NULL); + } + + } else if (line1[0] == '\n') { + /* an empty line marks end of headers */ + in_headers = FALSE; + } else { + /* in all other cases we expect another header */ + if ((hdr = get_header(line1))) + msg->hdr_list = g_list_append(msg->hdr_list, hdr); + else { + /* if get_header() returns NULL, no header was recognized, + so this seems to be the first data line of a broken mailer + which does not send an empty line after the headers */ + in_headers = FALSE; + msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); + } + } + } else { + msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); + data_size += strlen(line1); + line_cnt++; + } + } } - break; - }else{ - g_free(line); - if(len == -1){ - return AERR_EOF; - }else if(len == -2){ - /* should not happen any more */ - return AERR_OVERFLOW; - }else if(len == -3){ - return AERR_TIMEOUT; - }else{ - /* does not happen */ - DEBUG(5) debugf("read_sockline returned %d\n", len); - return AERR_UNKNOWN; - } - } - } - else{ - if(in_headers){ - /* some pop servers send the 'From ' line, skip it: */ - if(msg->hdr_list == NULL) - if(strncmp(line1, "From ", 5) == 0) - continue; + if (msg->data_list != NULL) + msg->data_list = g_list_reverse(msg->data_list); + else + /* make sure data list is not NULL: */ + msg->data_list = g_list_append(NULL, g_strdup("")); - if(line1[0] == ' ' || line1[0] == '\t'){ - /* continuation of 'folded' header: */ - if(hdr){ - hdr->header = g_strconcat(hdr->header, line1, NULL); - } + DEBUG(4) debugf("received %d lines of data (%d bytes)\n", line_cnt, data_size); + /* we get here after we succesfully received the mail data */ - }else if(line1[0] == '\n'){ - /* an empty line marks end of headers */ - in_headers = FALSE; - }else{ - /* in all other cases we expect another header */ - if((hdr = get_header(line1))) - msg->hdr_list = g_list_append(msg->hdr_list, hdr); - else{ - /* if get_header() returns NULL, no header was recognized, - so this seems to be the first data line of a broken mailer - which does not send an empty line after the headers */ - in_headers = FALSE; - msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); - } - } - }else{ - msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); - data_size += strlen(line1); - line_cnt++; - } - } - } + msg->data_size = data_size; + msg->received_time = time(NULL); - if(msg->data_list != NULL) - msg->data_list = g_list_reverse(msg->data_list); - else - /* make sure data list is not NULL: */ - msg->data_list = g_list_append(NULL, g_strdup("")); - - DEBUG(4) debugf("received %d lines of data (%d bytes)\n", - line_cnt, data_size); - /* we get here after we succesfully - received the mail data */ - - msg->data_size = data_size; - msg->received_time = time(NULL); - - return AERR_OK; + return AERR_OK; } -accept_error accept_message_prepare(message *msg, guint flags) +accept_error +accept_message_prepare(message * msg, guint flags) { - struct passwd *passwd = NULL; - GList *non_rcpt_list = NULL; - time_t rec_time = time(NULL); + struct passwd *passwd = NULL; + GList *non_rcpt_list = NULL; + time_t rec_time = time(NULL); - DEBUG(5) debugf("accept_message_prepare()\n"); + DEBUG(5) debugf("accept_message_prepare()\n"); - /* create unique message id */ - msg->uid = g_malloc(14); + /* create unique message id */ + msg->uid = g_malloc(14); - string_base62(msg->uid, rec_time, 6); - msg->uid[6] = '-'; - string_base62(&(msg->uid[7]), getpid(), 3); - msg->uid[10] = '-'; - string_base62(&(msg->uid[11]), msg->transfer_id, 2); - msg->uid[13] = 0; + string_base62(msg->uid, rec_time, 6); + msg->uid[6] = '-'; + string_base62(&(msg->uid[7]), getpid(), 3); + msg->uid[10] = '-'; + string_base62(&(msg->uid[11]), msg->transfer_id, 2); + msg->uid[13] = 0; - /* if local, get password entry */ - if(msg->received_host == NULL){ - passwd = g_memdup(getpwuid(geteuid()), sizeof(struct passwd)); - msg->ident = g_strdup(passwd->pw_name); - } + /* if local, get password entry */ + if (msg->received_host == NULL) { + passwd = g_memdup(getpwuid(geteuid()), sizeof(struct passwd)); + msg->ident = g_strdup(passwd->pw_name); + } - /* set return path if local */ - if(msg->return_path == NULL){ + /* set return path if local */ + if (msg->return_path == NULL) { - if(msg->received_host == NULL){ - gchar *path = g_strdup_printf("<%s@%s>", - passwd->pw_name, conf.host_name); - DEBUG(3) debugf("setting return_path for local accept: %s\n", path); - msg->return_path = create_address(path, TRUE); - g_free(path); - } - } + if (msg->received_host == NULL) { + gchar *path = g_strdup_printf("<%s@%s>", passwd->pw_name, conf.host_name); + DEBUG(3) debugf("setting return_path for local accept: %s\n", path); + msg->return_path = create_address(path, TRUE); + g_free(path); + } + } - /* -t option */ - if(flags & ACC_DEL_RCPTS){ - non_rcpt_list = msg->rcpt_list; - msg->rcpt_list = NULL; - } + /* -t option */ + if (flags & ACC_DEL_RCPTS) { + non_rcpt_list = msg->rcpt_list; + msg->rcpt_list = NULL; + } - /* scan headers */ - { - gboolean has_id = FALSE; - gboolean has_date = FALSE; - gboolean has_sender = FALSE; - gboolean has_from = FALSE; - gboolean has_rcpt = FALSE; - gboolean has_to_or_cc = FALSE; - GList *hdr_node, *hdr_node_next; - header *hdr; + /* scan headers */ + { + gboolean has_id = FALSE; + gboolean has_date = FALSE; + gboolean has_sender = FALSE; + gboolean has_from = FALSE; + gboolean has_rcpt = FALSE; + gboolean has_to_or_cc = FALSE; + GList *hdr_node, *hdr_node_next; + header *hdr; - for(hdr_node = g_list_first(msg->hdr_list); - hdr_node != NULL; - hdr_node = hdr_node_next){ - hdr_node_next = g_list_next(hdr_node); - hdr = ((header *)(hdr_node->data)); - DEBUG(5) debugf("scanning headers: %s", hdr->header); - switch(hdr->id){ - case HEAD_MESSAGE_ID: - has_id = TRUE; break; - case HEAD_DATE: - has_date = TRUE; break; - case HEAD_FROM: - has_from = TRUE; - break; - case HEAD_SENDER: - has_sender = TRUE; - break; - case HEAD_TO: - case HEAD_CC: - case HEAD_BCC: - has_rcpt = TRUE; - if(flags & ACC_RCPT_FROM_HEAD){ - DEBUG(5) debugf("hdr->value = %s\n", hdr->value); - if(hdr->value){ - msg->rcpt_list = - addr_list_append_rfc822(msg->rcpt_list, hdr->value, conf.host_name); - } + for (hdr_node = g_list_first(msg->hdr_list); + hdr_node != NULL; hdr_node = hdr_node_next) { + hdr_node_next = g_list_next(hdr_node); + hdr = ((header *) (hdr_node->data)); + DEBUG(5) debugf("scanning headers: %s", hdr->header); + switch (hdr->id) { + case HEAD_MESSAGE_ID: + has_id = TRUE; + break; + case HEAD_DATE: + has_date = TRUE; + break; + case HEAD_FROM: + has_from = TRUE; + break; + case HEAD_SENDER: + has_sender = TRUE; + break; + case HEAD_TO: + case HEAD_CC: + case HEAD_BCC: + has_rcpt = TRUE; + if (flags & ACC_RCPT_FROM_HEAD) { + DEBUG(5) debugf("hdr->value = %s\n", hdr->value); + if (hdr->value) { + msg->rcpt_list = addr_list_append_rfc822(msg->rcpt_list, hdr->value, conf.host_name); + } + } + if ((flags & ACC_DEL_BCC) && (hdr->id == HEAD_BCC)) { + DEBUG(3) debugf("removing 'Bcc' header\n"); + msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); + g_list_free_1(hdr_node); + destroy_header(hdr); + } else + has_to_or_cc = TRUE; + break; + case HEAD_ENVELOPE_TO: + if (flags & ACC_SAVE_ENVELOPE_TO) { + DEBUG(3) debugf("creating 'X-Orig-Envelope-To' header\n"); + msg->hdr_list = g_list_prepend(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Orig-Envelope-to: %s", hdr->value)); + } + DEBUG(3) debugf("removing 'Envelope-To' header\n"); + msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); + g_list_free_1(hdr_node); + destroy_header(hdr); + break; + case HEAD_RETURN_PATH: + if (flags & ACC_MAIL_FROM_HEAD) { + /* usually POP3 accept */ + msg->return_path = create_address_qualified(hdr->value, TRUE, msg->received_host); + DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); + } + DEBUG(3) debugf("removing 'Return-Path' header\n"); + msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); + g_list_free_1(hdr_node); + destroy_header(hdr); + break; + default: + break; /* make compiler happy */ + } + } + + if (msg->return_path == NULL) { + /* this can happen for pop3 accept only and if no Return-path: header was given */ + GList *hdr_list; + header *hdr; + + DEBUG(3) debugf("return_path == NULL\n"); + + hdr_list = find_header(msg->hdr_list, HEAD_SENDER, NULL); + if (!hdr_list) + hdr_list = find_header(msg->hdr_list, HEAD_FROM, NULL); + if (hdr_list) { + gchar *addr; + hdr = (header *) (g_list_first(hdr_list)->data); + + DEBUG(5) debugf("hdr->value = '%s'\n", hdr->value); + + addr = g_strdup(hdr->value); + g_strchomp(addr); + + if ((msg->return_path = create_address_qualified(addr, FALSE, msg->received_host)) != NULL) { + DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); + msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Warning: return path set from %s address\n", hdr->id == HEAD_SENDER ? "Sender:" : "From:")); + } + g_free(addr); + } + if (msg->return_path == NULL) { /* no Sender: or From: or create_address_qualified failed */ + msg->return_path = create_address_qualified("postmaster", TRUE, conf.host_name); + DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); + msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Warning: real return path is unkown\n")); + } + } + + if (flags & ACC_DEL_RCPTS) { + GList *rcpt_node; + foreach(non_rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + GList *node; + if ((node = g_list_find_custom(msg->rcpt_list, rcpt, _g_list_addr_isequal))) { + DEBUG(3) debugf("removing rcpt address %s\n", addr_string(node->data)); + msg->rcpt_list = g_list_remove_link(msg->rcpt_list, node); + destroy_address((address *) (node->data)); + g_list_free_1(node); + } + } + } + + /* here we should have our recipients, fail if not: */ + if (msg->rcpt_list == NULL) { + logwrite(LOG_WARNING, "no recipients found in message\n"); + return AERR_NORCPT; + } + + if (!(has_sender || has_from)) { + DEBUG(3) debugf("adding 'From' header\n"); + msg->hdr_list = g_list_append(msg->hdr_list, + msg->full_sender_name + ? + create_header(HEAD_FROM, + "From: \"%s\" <%s@%s>\n", + msg->full_sender_name, + msg->return_path->local_part, + msg->return_path-> + domain) + : + create_header(HEAD_FROM, "From: <%s@%s>\n", + msg->return_path->local_part, + msg->return_path->domain) + ); + } + if ((flags & ACC_HEAD_FROM_RCPT) && !has_rcpt) { + GList *node; + DEBUG(3) debugf("adding 'To' header(s)\n"); + for (node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)) { + msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_TO, "To: %s\n", addr_string(msg-> return_path))); + } + } + if ((flags & ACC_DEL_BCC) && !has_to_or_cc) { + /* Bcc headers have been removed, and there are no remaining rcpt headers */ + DEBUG(3) debugf("adding empty 'Bcc:' header\n"); + msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_BCC, "Bcc:\n")); + } + if (!has_date) { + DEBUG(3) debugf("adding 'Date:' header\n"); + msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_DATE, "Date: %s\n", rec_timestamp())); + } + if (!has_id) { + DEBUG(3) debugf("adding 'Message-ID:' header\n"); + msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_MESSAGE_ID, "Message-ID: <%s@%s>\n", msg->uid, conf.host_name)); + } } - if((flags & ACC_DEL_BCC) && (hdr->id == HEAD_BCC)){ - DEBUG(3) debugf("removing 'Bcc' header\n"); - msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); - g_list_free_1(hdr_node); - destroy_header(hdr); - }else - has_to_or_cc = TRUE; - break; - case HEAD_ENVELOPE_TO: - if(flags & ACC_SAVE_ENVELOPE_TO){ - DEBUG(3) debugf("creating 'X-Orig-Envelope-To' header\n"); - msg->hdr_list = - g_list_prepend(msg->hdr_list, - create_header(HEAD_UNKNOWN, - "X-Orig-Envelope-to: %s", hdr->value)); + + /* Received header: */ + /* At this point because we have to know the rcpts for the 'for' part */ + if (!(flags & ACC_NO_RECVD_HDR)) { + gchar *for_string = NULL; + header *hdr = NULL; + + DEBUG(3) debugf("adding 'Received:' header\n"); + + if (g_list_length(msg->rcpt_list) == 1) { + address *addr = (address *) (g_list_first(msg->rcpt_list)->data); + for_string = g_strdup_printf(" for %s", addr_string(addr)); + } + + if (msg->received_host == NULL) { + hdr = create_header(HEAD_RECEIVED, + "Received: from %s by %s" + " with %s (%s %s) id %s%s;" + " %s\n", + passwd->pw_name, conf.host_name, + prot_names[msg->received_prot], + PACKAGE, VERSION, + msg->uid, for_string ? for_string : "", + rec_timestamp()); + } else { +#ifdef ENABLE_IDENT + DEBUG(5) debugf("adding 'Received:' header (5)\n"); + hdr = create_header(HEAD_RECEIVED, + "Received: from %s (ident=%s) by %s" + " with %s (%s %s) id %s%s;" + " %s\n", + msg->received_host, + msg->ident ? msg->ident : "unknown", + conf.host_name, + prot_names[msg->received_prot], + PACKAGE, VERSION, + msg->uid, for_string ? for_string : "", + rec_timestamp()); +#else + hdr = create_header(HEAD_RECEIVED, + "Received: from %s by %s" + " with %s (%s %s) id %s%s;" + " %s\n", + msg->received_host, + conf.host_name, + prot_names[msg->received_prot], + PACKAGE, VERSION, + msg->uid, for_string ? for_string : "", + rec_timestamp()); +#endif + } + header_fold(hdr); + msg->hdr_list = g_list_prepend(msg->hdr_list, hdr); + + if (for_string) + g_free(for_string); } - DEBUG(3) debugf("removing 'Envelope-To' header\n"); - msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); - g_list_free_1(hdr_node); - destroy_header(hdr); - break; - case HEAD_RETURN_PATH: - if(flags & ACC_MAIL_FROM_HEAD){ - /* usually POP3 accept */ - msg->return_path = create_address_qualified(hdr->value, TRUE, msg->received_host); - DEBUG(3) debugf("setting return_path to %s\n", - addr_string(msg->return_path)); - } - DEBUG(3) debugf("removing 'Return-Path' header\n"); - msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); - g_list_free_1(hdr_node); - destroy_header(hdr); - break; - default: - break; /* make compiler happy */ - } - } - if(msg->return_path == NULL){ - /* this can happen for pop3 accept only - and if no Return-path: header was given */ - GList *hdr_list; - header *hdr; - - DEBUG(3) debugf("return_path == NULL\n"); - - hdr_list = find_header(msg->hdr_list, HEAD_SENDER, NULL); - if(!hdr_list) hdr_list = find_header(msg->hdr_list, HEAD_FROM, NULL); - if(hdr_list){ - gchar *addr; - hdr = (header *)(g_list_first(hdr_list)->data); - - DEBUG(5) debugf("hdr->value = '%s'\n", hdr->value); - - addr = g_strdup(hdr->value); - g_strchomp(addr); - - if((msg->return_path = - create_address_qualified(addr, FALSE, msg->received_host)) - != NULL){ - DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); - msg->hdr_list = - g_list_append(msg->hdr_list, - create_header(HEAD_UNKNOWN, - "X-Warning: return path set from %s address\n", - hdr->id == HEAD_SENDER ? "Sender:" : "From:")); - } - g_free(addr); - } - if(msg->return_path == NULL){ /* no Sender: or From: or create_address_qualified failed */ - msg->return_path = create_address_qualified("postmaster", TRUE, conf.host_name); - DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); - msg->hdr_list = - g_list_append(msg->hdr_list, - create_header(HEAD_UNKNOWN, - "X-Warning: real return path is unkown\n")); - } - } - - if(flags & ACC_DEL_RCPTS){ - GList *rcpt_node; - foreach(non_rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - GList *node; - if((node = g_list_find_custom(msg->rcpt_list, rcpt, - _g_list_addr_isequal))){ - DEBUG(3) debugf("removing rcpt address %s\n", addr_string(node->data)); - - msg->rcpt_list = g_list_remove_link(msg->rcpt_list, node); - destroy_address((address *)(node->data)); - g_list_free_1(node); - } - } - } - - /* here we should have our recipients, fail if not: */ - if(msg->rcpt_list == NULL){ - logwrite(LOG_WARNING, "no recipients found in message\n"); - return AERR_NORCPT; - } - - if(!(has_sender || has_from)){ - DEBUG(3) debugf("adding 'From' header\n"); - msg->hdr_list = - g_list_append(msg->hdr_list, - msg->full_sender_name ? - create_header(HEAD_FROM, "From: \"%s\" <%s@%s>\n", - msg->full_sender_name, - msg->return_path->local_part, - msg->return_path->domain) : - create_header(HEAD_FROM, "From: <%s@%s>\n", - msg->return_path->local_part, - msg->return_path->domain) - ); - } - if((flags & ACC_HEAD_FROM_RCPT) && !has_rcpt){ - GList *node; - DEBUG(3) debugf("adding 'To' header(s)\n"); - for(node = g_list_first(msg->rcpt_list); - node; - node = g_list_next(node)){ - msg->hdr_list = - g_list_append(msg->hdr_list, - create_header(HEAD_TO, "To: %s\n", addr_string(msg->return_path))); - } - } - if((flags & ACC_DEL_BCC) && !has_to_or_cc){ - /* Bcc headers have been removed, and there are no remaining rcpt headers */ - DEBUG(3) debugf("adding empty 'Bcc:' header\n"); - msg->hdr_list = - g_list_append(msg->hdr_list, create_header(HEAD_BCC, "Bcc:\n")); - } - if(!has_date){ - DEBUG(3) debugf("adding 'Date:' header\n"); - msg->hdr_list = - g_list_append(msg->hdr_list, - create_header(HEAD_DATE, "Date: %s\n", rec_timestamp())); - } - if(!has_id){ - DEBUG(3) debugf("adding 'Message-ID:' header\n"); - msg->hdr_list = - g_list_append(msg->hdr_list, - create_header(HEAD_MESSAGE_ID, - "Message-ID: <%s@%s>\n", - msg->uid, conf.host_name)); - } - } - - /* Received header: */ - /* At this point because we have to know the rcpts for the 'for' part */ - if(!(flags & ACC_NO_RECVD_HDR)){ - gchar *for_string = NULL; - header *hdr = NULL; - - DEBUG(3) debugf("adding 'Received:' header\n"); - - if(g_list_length(msg->rcpt_list) == 1){ - address *addr = (address *)(g_list_first(msg->rcpt_list)->data); - for_string = g_strdup_printf(" for %s", addr_string(addr)); - } - - if(msg->received_host == NULL){ - hdr = create_header(HEAD_RECEIVED, - "Received: from %s by %s" - " with %s (%s %s) id %s%s;" - " %s\n", - passwd->pw_name, conf.host_name, - prot_names[msg->received_prot], - PACKAGE, VERSION, - msg->uid, for_string ? for_string : "", - rec_timestamp()); - }else{ -#ifdef ENABLE_IDENT - DEBUG(5) debugf("adding 'Received:' header (5)\n"); - hdr = create_header(HEAD_RECEIVED, - "Received: from %s (ident=%s) by %s" - " with %s (%s %s) id %s%s;" - " %s\n", - msg->received_host, - msg->ident ? msg->ident : "unknown", - conf.host_name, - prot_names[msg->received_prot], - PACKAGE, VERSION, - msg->uid, for_string ? for_string : "", - rec_timestamp()); -#else - hdr = create_header(HEAD_RECEIVED, - "Received: from %s by %s" - " with %s (%s %s) id %s%s;" - " %s\n", - msg->received_host, - conf.host_name, - prot_names[msg->received_prot], - PACKAGE, VERSION, - msg->uid, for_string ? for_string : "", - rec_timestamp()); -#endif - } - header_fold(hdr); - msg->hdr_list = g_list_prepend(msg->hdr_list, hdr); - - if(for_string) g_free(for_string); - } - - /* write message to spool: */ - /* accept is no longer responsible for this - if(!spool_write(msg, TRUE)) - return AERR_NOSPOOL; - */ - return AERR_OK; + /* write message to spool: */ + /* accept is no longer responsible for this + if(!spool_write(msg, TRUE)) + return AERR_NOSPOOL; + */ + return AERR_OK; } -accept_error accept_message(FILE *in, message *msg, guint flags) +accept_error +accept_message(FILE * in, message * msg, guint flags) { - accept_error err; + accept_error err; - err = accept_message_stream(in, msg, flags); - if(err == AERR_OK) - err = accept_message_prepare(msg, flags); + err = accept_message_stream(in, msg, flags); + if (err == AERR_OK) + err = accept_message_prepare(msg, flags); - return err; + return err; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/address.c --- a/src/address.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/address.c Mon Oct 27 16:23:10 2008 +0100 @@ -19,171 +19,182 @@ #include "masqmail.h" #include -address *create_address(gchar *path, gboolean is_rfc821) +address* +create_address(gchar * path, gboolean is_rfc821) { - address *addr; - addr = _create_address(path, NULL, is_rfc821); - - if(addr != NULL){ - addr_unmark_delivered(addr); - } - return addr; + address *addr; + addr = _create_address(path, NULL, is_rfc821); + + if (addr != NULL) { + addr_unmark_delivered(addr); + } + return addr; } -address *create_address_qualified(gchar *path, gboolean is_rfc821, - gchar *domain) +address* +create_address_qualified(gchar * path, gboolean is_rfc821, gchar * domain) { - address *addr = create_address(path, is_rfc821); - if(addr != NULL){ - if(addr->domain == NULL) - addr->domain = g_strdup(domain); - } + address *addr = create_address(path, is_rfc821); + if (addr != NULL) { + if (addr->domain == NULL) + addr->domain = g_strdup(domain); + } - return addr; + return addr; } /* nothing special about pipes here, but its only called for that purpose */ -address *create_address_pipe(gchar *path) +address* +create_address_pipe(gchar * path) { - address *addr = g_malloc(sizeof(address)); + address *addr = g_malloc(sizeof(address)); - if(addr){ - memset(addr, 0, sizeof(address)); - addr->address = g_strchomp(g_strdup(path)); - addr->local_part = g_strdup(addr->address); - - addr->domain = g_strdup("localhost"); /* quick hack */ - } - return addr; + if (addr) { + memset(addr, 0, sizeof(address)); + addr->address = g_strchomp(g_strdup(path)); + addr->local_part = g_strdup(addr->address); + + addr->domain = g_strdup("localhost"); /* quick hack */ + } + return addr; } -void destroy_address(address *addr) +void +destroy_address(address * addr) { - DEBUG(6) debugf("destroy_address entered\n"); + DEBUG(6) debugf("destroy_address entered\n"); - g_free(addr->address); - g_free(addr->local_part); - g_free(addr->domain); + g_free(addr->address); + g_free(addr->local_part); + g_free(addr->domain); - g_free(addr); + g_free(addr); } -address *copy_modify_address(const address *orig, gchar *l_part, gchar *dom) +address* +copy_modify_address(const address * orig, gchar * l_part, gchar * dom) { - address *addr = NULL; + address *addr = NULL; - if(orig){ - addr = g_malloc(sizeof(address)); - if(addr){ - addr->address = g_strdup(orig->address); + if (orig) { + addr = g_malloc(sizeof(address)); + if (addr) { + addr->address = g_strdup(orig->address); - if(l_part == NULL) - addr->local_part = g_strdup(orig->local_part); - else - addr->local_part = g_strdup(l_part); + if (l_part == NULL) + addr->local_part = g_strdup(orig->local_part); + else + addr->local_part = g_strdup(l_part); - if(dom == NULL) - addr->domain = g_strdup(orig->domain); - else - addr->domain = g_strdup(dom); + if (dom == NULL) + addr->domain = g_strdup(orig->domain); + else + addr->domain = g_strdup(dom); - addr->flags = 0; - addr->children = NULL; - addr->parent = NULL; - } - } - return addr; + addr->flags = 0; + addr->children = NULL; + addr->parent = NULL; + } + } + return addr; } -gboolean addr_isequal(address *addr1, address *addr2) +gboolean +addr_isequal(address * addr1, address * addr2) { - return - (strcmp(addr1->local_part, addr2->local_part) == 0) && - (strcasecmp(addr1->domain, addr2->domain) == 0); + return + (strcmp(addr1->local_part, addr2->local_part) == 0) && + (strcasecmp(addr1->domain, addr2->domain) == 0); } /* searches in ancestors of addr1 */ -gboolean addr_isequal_parent(address *addr1, address *addr2) +gboolean +addr_isequal_parent(address * addr1, address * addr2) { - address *addr; + address *addr; - for(addr = addr1; addr; addr = addr->parent) - if(addr_isequal(addr, addr2)) - return TRUE; + for (addr = addr1; addr; addr = addr->parent) + if (addr_isequal(addr, addr2)) + return TRUE; - return FALSE; + return FALSE; } /* careful, this is recursive */ /* returns TRUE if ALL children have been delivered */ -gboolean addr_is_delivered_children(address *addr) +gboolean +addr_is_delivered_children(address * addr) { - GList *addr_node; + GList *addr_node; - if(addr->children == NULL) return addr_is_delivered(addr); + if (addr->children == NULL) + return addr_is_delivered(addr); - foreach(addr->children, addr_node){ - address *addr = (address *)(addr_node->data); - if(!addr_is_delivered_children(addr)) - return FALSE; - } - return TRUE; + foreach(addr->children, addr_node) { + address *addr = (address *) (addr_node->data); + if (!addr_is_delivered_children(addr)) + return FALSE; + } + return TRUE; } /* careful, this is recursive */ /* returns TRUE if ALL children have been either delivered or have failed */ -gboolean addr_is_finished_children(address *addr) +gboolean +addr_is_finished_children(address * addr) { - GList *addr_node; + GList *addr_node; - if(addr->children == NULL) return (addr_is_failed(addr) || addr_is_delivered(addr)); + if (addr->children == NULL) + return (addr_is_failed(addr) || addr_is_delivered(addr)); - foreach(addr->children, addr_node){ - address *addr = (address *)(addr_node->data); - if(!addr_is_finished_children(addr)) - return FALSE; - } - return TRUE; + foreach(addr->children, addr_node) { + address *addr = (address *) (addr_node->data); + if (!addr_is_finished_children(addr)) + return FALSE; + } + return TRUE; } /* find original address */ -address *addr_find_ancestor(address *addr) +address* +addr_find_ancestor(address * addr) { - while(addr->parent) addr = addr->parent; - return addr; + while (addr->parent) + addr = addr->parent; + return addr; } -gchar *addr_string(address *addr) +gchar* +addr_string(address * addr) { - static gchar *buffer = NULL; + static gchar *buffer = NULL; - if(addr == NULL){ - g_free(buffer); - buffer = NULL; - return NULL; - } - if(buffer) - g_free(buffer); + if (addr == NULL) { + g_free(buffer); + buffer = NULL; + return NULL; + } + if (buffer) + g_free(buffer); - if(addr->local_part[0] == 0){ - buffer = g_strdup("<>"); - }else{ - buffer = g_strdup_printf("<%s@%s>", - addr->local_part ? addr->local_part : "", - addr->domain ? addr->domain : ""); - } - return buffer; + if (addr->local_part[0] == 0) { + buffer = g_strdup("<>"); + } else { + buffer = g_strdup_printf("<%s@%s>", addr->local_part ? addr->local_part : "", addr->domain ? addr->domain : ""); + } + return buffer; } -gint addr_match(address *addr1, address *addr2) +gint +addr_match(address * addr1, address * addr2) { - int res; + int res; - if((res = fnmatch(addr1->local_part, addr2->local_part, 0)) == 0){ - if((res = fnmatch(addr1->domain, addr2->domain, FNM_CASEFOLD)) == 0) - return 0; - } - return res; + if ((res = fnmatch(addr1->local_part, addr2->local_part, 0)) == 0) { + if ((res = fnmatch(addr1->domain, addr2->domain, FNM_CASEFOLD)) == 0) + return 0; + } + return res; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/alias.c --- a/src/alias.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/alias.c Mon Oct 27 16:23:10 2008 +0100 @@ -19,177 +19,179 @@ #include "masqmail.h" #include -gboolean addr_is_local(address *addr) +gboolean +addr_is_local(address * addr) { - GList *dom_node; - GList *addr_node; - address *a; + GList *dom_node; + GList *addr_node; + address *a; - foreach(conf.local_hosts, dom_node){ - if(addr->domain == NULL) - return TRUE; - if(fnmatch(dom_node->data, addr->domain, FNM_CASEFOLD) == 0){ - foreach(conf.not_local_addresses,addr_node){ - a = create_address_qualified(addr_node->data, TRUE, conf.host_name); - if(addr_isequal(a,addr)){ - destroy_address(a); - return FALSE; + foreach(conf.local_hosts, dom_node) { + if (addr->domain == NULL) + return TRUE; + if (fnmatch(dom_node->data, addr->domain, FNM_CASEFOLD) == 0) { + foreach(conf.not_local_addresses, addr_node) { + a = create_address_qualified(addr_node->data, TRUE, conf.host_name); + if (addr_isequal(a, addr)) { + destroy_address(a); + return FALSE; + } + destroy_address(a); + } + return TRUE; + } } - destroy_address(a); - } - return TRUE; - } - } - foreach(conf.local_addresses,addr_node){ - a = create_address_qualified(addr_node->data, TRUE, conf.host_name); - if(addr_isequal(a,addr)){ - destroy_address(a); - return TRUE; - } - destroy_address(a); - } - return FALSE; + foreach(conf.local_addresses, addr_node) { + a = create_address_qualified(addr_node->data, TRUE, conf.host_name); + if (addr_isequal(a, addr)) { + destroy_address(a); + return TRUE; + } + destroy_address(a); + } + return FALSE; } -static -gboolean addr_isequal_alias(address *addr1, address *addr2) +static gboolean +addr_isequal_alias(address * addr1, address * addr2) { - return - (conf.alias_local_cmp(addr1->local_part, addr2->local_part) == 0) && - (strcasecmp(addr1->domain, addr2->domain) == 0); + return (conf.alias_local_cmp(addr1->local_part, addr2->local_part) == 0) + && (strcasecmp(addr1->domain, addr2->domain) == 0); } -static -GList *parse_list(gchar *line) +static GList* +parse_list(gchar * line) { - GList *list = NULL; - gchar buf[256]; - gchar *p, *q; + GList *list = NULL; + gchar buf[256]; + gchar *p, *q; - p = line; - while(*p != 0){ - q = buf; - while(isspace(*p)) p++; - if(*p != '\"'){ - while(*p && (*p != ',') && (q < buf+255)) - *(q++) = *(p++); - *q = 0; - }else{ - gboolean escape = FALSE; - p++; - while(*p && (*p != '\"' || escape) && (q < buf+255)){ - if((*p == '\\') && !escape) - escape = TRUE; - else{ - escape = FALSE; - *(q++) = *p; + p = line; + while (*p != 0) { + q = buf; + while (isspace(*p)) + p++; + if (*p != '\"') { + while (*p && (*p != ',') && (q < buf + 255)) + *(q++) = *(p++); + *q = 0; + } else { + gboolean escape = FALSE; + p++; + while (*p && (*p != '\"' || escape) && (q < buf + 255)) { + if ((*p == '\\') && !escape) + escape = TRUE; + else { + escape = FALSE; + *(q++) = *p; + } + p++; + } + *q = 0; + while (*p && (*p != ',')) + p++; + } + list = g_list_append(list, g_strdup(g_strchomp(buf))); + if (*p) + p++; } - p++; - } - *q = 0; - while(*p && (*p != ',')) p++; - } - list = g_list_append(list, g_strdup(g_strchomp(buf))); - if(*p) p++; - } - return list; + return list; } -GList *alias_expand(GList *alias_table, GList *rcpt_list, GList *non_rcpt_list) +GList* +alias_expand(GList * alias_table, GList * rcpt_list, GList * non_rcpt_list) { - GList *done_list = NULL; - GList *rcpt_node = g_list_copy(rcpt_list); + GList *done_list = NULL; + GList *rcpt_node = g_list_copy(rcpt_list); - while(rcpt_node != NULL){ - address *addr = (address *)(rcpt_node->data); - DEBUG(5) debugf("alias_expand begin: '%s@%s'\n", addr->local_part, addr->domain); -// if(addr_is_local(addr) && (addr->local_part[0] != '|') && - if(addr_is_local(addr) && - !(addr->flags & ADDR_FLAG_NOEXPAND)){ - gchar *val; - - /* special handling for postmaster */ - if(strcasecmp(addr->local_part, "postmaster") == 0) - val = (gchar *)table_find_func(alias_table, addr->local_part, strcasecmp); - else - val = (gchar *)table_find_func(alias_table, addr->local_part, conf.alias_local_cmp); + while (rcpt_node != NULL) { + address *addr = (address *) (rcpt_node->data); + DEBUG(5) debugf("alias_expand begin: '%s@%s'\n", addr->local_part, addr->domain); + /* if(addr_is_local(addr) && (addr->local_part[0] != '|') && */ + if (addr_is_local(addr) && !(addr->flags & ADDR_FLAG_NOEXPAND)) { + gchar *val; - DEBUG(5) debugf("alias: '%s' is local\n", addr->local_part); - if(val != NULL){ - GList *val_list = parse_list(val); - GList *val_node; - GList *alias_list = NULL; + /* special handling for postmaster */ + if (strcasecmp(addr->local_part, "postmaster") == 0) + val = (gchar *) table_find_func(alias_table, addr->local_part, strcasecmp); + else + val = (gchar *) table_find_func(alias_table, addr->local_part, conf.alias_local_cmp); - DEBUG(5) debugf("alias: '%s' -> '%s'\n", addr->local_part, val); - foreach(val_list, val_node){ - gchar *val = (gchar *)(val_node->data); - address *alias_addr; - address *addr_parent = NULL; + DEBUG(5) debugf("alias: '%s' is local\n", addr->local_part); + if (val != NULL) { + GList *val_list = parse_list(val); + GList *val_node; + GList *alias_list = NULL; - if(val[0] == '|'){ - DEBUG(5) debugf("alias: %s is a pipe address\n", val); - alias_addr = create_address_pipe(val); - DEBUG(5) debugf("alias_pipe: %s is a pipe address\n", alias_addr->local_part); - }else if(val[0] == '\\'){ - DEBUG(5) debugf("alias: shall not be expanded: '%s'\n", val); - alias_addr = create_address_qualified(&(val[1]), TRUE, conf.host_name); - alias_addr->flags |= ADDR_FLAG_NOEXPAND; - DEBUG(5) debugf("alias: not expanded: '%s'\n",alias_addr->local_part); - }else{ - alias_addr = create_address_qualified(val, TRUE, conf.host_name); + DEBUG(5) debugf("alias: '%s' -> '%s'\n", addr->local_part, val); + foreach(val_list, val_node) { + gchar *val = (gchar *) (val_node->data); + address *alias_addr; + address *addr_parent = NULL; - /* search in parents for loops: */ - for(addr_parent = addr; addr_parent; addr_parent = addr_parent->parent){ - if(addr_isequal_alias(alias_addr, addr_parent)){ - logwrite(LOG_ALERT, "detected alias loop, (ignoring): %s@%s -> %s@%s\n", - addr_parent->local_part, addr_parent->domain, - addr->local_part, addr->domain); - break; - } - } - } - if(!addr_parent){ - alias_list = g_list_append(alias_list, alias_addr); - alias_addr->parent = addr; - } - g_free(val); + if (val[0] == '|') { + DEBUG(5) debugf("alias: %s is a pipe address\n", val); + alias_addr = create_address_pipe(val); + DEBUG(5) debugf("alias_pipe: %s is a pipe address\n", alias_addr->local_part); + } else if (val[0] == '\\') { + DEBUG(5) debugf("alias: shall not be expanded: '%s'\n", val); + alias_addr = create_address_qualified(&(val[1]), TRUE, conf.host_name); + alias_addr->flags |= ADDR_FLAG_NOEXPAND; + DEBUG(5) debugf("alias: not expanded: '%s'\n", alias_addr->local_part); + } else { + alias_addr = create_address_qualified(val, TRUE, conf.host_name); + + /* search in parents for loops: */ + for (addr_parent = addr; addr_parent; addr_parent = addr_parent->parent) { + if (addr_isequal_alias (alias_addr, addr_parent)) { + logwrite(LOG_ALERT, + "detected alias loop, (ignoring): %s@%s -> %s@%s\n", + addr_parent->local_part, + addr_parent->domain, + addr->local_part, addr->domain); + break; + } + } + } + if (!addr_parent) { + alias_list = g_list_append(alias_list, alias_addr); + alias_addr->parent = addr; + } + g_free(val); + } + g_list_free(val_list); + addr->children = g_list_copy(alias_list); + rcpt_node = g_list_concat(rcpt_node, alias_list); + } else { + DEBUG(5) debugf("alias: '%s' is completed\n", addr->local_part); + done_list = g_list_append(done_list, addr); + } + } else { + DEBUG(5) debugf("alias: '%s@%s' is not local\n", addr->local_part, addr->domain); + done_list = g_list_append(done_list, addr); + } + rcpt_node = g_list_next(rcpt_node); } - g_list_free(val_list); - addr->children = g_list_copy(alias_list); - rcpt_node = g_list_concat(rcpt_node, alias_list); - }else{ - DEBUG(5) debugf("alias: '%s' is completed\n", addr->local_part); - done_list = g_list_append(done_list, addr); - } - }else{ - DEBUG(5) debugf("alias: '%s@%s' is not local\n", addr->local_part, addr->domain); - done_list = g_list_append(done_list, addr); - } - rcpt_node = g_list_next(rcpt_node); - } - /* delete addresses from done_list if they are in the non_rcpt_list */ - if(non_rcpt_list){ - GList *rcpt_node_next; - for(rcpt_node = g_list_first(done_list); - rcpt_node; - rcpt_node = rcpt_node_next){ - address *addr = (address *)(rcpt_node->data); - GList *non_node; + /* delete addresses from done_list if they are in the non_rcpt_list */ + if (non_rcpt_list) { + GList *rcpt_node_next; + for (rcpt_node = g_list_first(done_list); rcpt_node; rcpt_node = rcpt_node_next) { + address *addr = (address *) (rcpt_node->data); + GList *non_node; - rcpt_node_next = g_list_next(rcpt_node); + rcpt_node_next = g_list_next(rcpt_node); - foreach(non_rcpt_list, non_node){ - address *non_addr = (address *)(non_node->data); - if(addr_isequal(addr, non_addr)){ - done_list = g_list_remove_link(done_list, rcpt_node); - g_list_free_1(rcpt_node); - addr_mark_delivered(addr); /* this address is still in the children lists - of the original address */ - break; + foreach(non_rcpt_list, non_node) { + address *non_addr = (address *) (non_node->data); + if (addr_isequal(addr, non_addr)) { + done_list = g_list_remove_link(done_list, rcpt_node); + g_list_free_1(rcpt_node); + addr_mark_delivered(addr); /* this address is still in the children lists of the original address */ + break; + } + } + } } - } - } - } - return done_list; + return done_list; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/base64/base64.c --- a/src/base64/base64.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/base64/base64.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 @@ -25,104 +25,109 @@ #include #include "base64.h" -gchar *base64_encode(guchar *buf, gint len) +gchar* +base64_encode(guchar * buf, gint len) { - guchar *outbuf, *q; - gchar enc[64]; - gint i = 0, j = 0; - guint in0, in1, in2; + guchar *outbuf, *q; + gchar enc[64]; + gint i = 0, j = 0; + guint in0, in1, in2; - for(; i < 26; i++) enc[i] = (gchar)('A' + j++); j = 0; - for(; i < 52; i++) enc[i] = (gchar)('a' + j++); j = 0; - for(; i < 62; i++) enc[i] = (gchar)('0' + j++); - enc[i++] = '+'; - enc[i++] = '/'; + for (; i < 26; i++) + enc[i] = (gchar) ('A' + j++); + j = 0; + for (; i < 52; i++) + enc[i] = (gchar) ('a' + j++); + j = 0; + for (; i < 62; i++) + enc[i] = (gchar) ('0' + j++); + enc[i++] = '+'; + enc[i++] = '/'; - outbuf = g_malloc(((len+3) * 8)/6); - q = outbuf; + outbuf = g_malloc(((len + 3) * 8) / 6); + q = outbuf; - i = 0; - while(i < len-2){ - in0 = buf[i++]; - in1 = buf[i++]; - in2 = buf[i++]; + i = 0; + while (i < len - 2) { + in0 = buf[i++]; + in1 = buf[i++]; + in2 = buf[i++]; - *(q++) = enc[(in0 >> 2) & 0x3f]; - *(q++) = enc[((in0 << 4) | (in1 >> 4)) & 0x3f]; - *(q++) = enc[((in1 << 2) | (in2 >> 6)) & 0x3f]; - *(q++) = enc[in2 & 0x3f]; - } - if((len - i) == 1){ - in0 = buf[i++]; - *(q++) = enc[(in0 >> 2) & 0x3f]; - *(q++) = enc[(in0 << 4) & 0x3f]; - *(q++) = '='; - *(q++) = '='; - }else if((len - i) == 2){ - in0 = buf[i++]; - in1 = buf[i++]; - *(q++) = enc[(in0 >> 2) & 0x3f]; - *(q++) = enc[((in0 << 4) | (in1 >> 4)) & 0x3f]; - *(q++) = enc[(in1 << 2) & 0x3f]; - *(q++) = '='; - } - *q = 0; - - return outbuf; -} - -gchar *base64_decode(gchar *buf, gint *size) -{ - guchar *p = buf, *q; - guint in[4]; - // gchar *out = g_malloc(((strlen(buf)+3) * 3) / 4 + 1); - gchar *out = g_malloc((strlen(buf)+3) + 1); + *(q++) = enc[(in0 >> 2) & 0x3f]; + *(q++) = enc[((in0 << 4) | (in1 >> 4)) & 0x3f]; + *(q++) = enc[((in1 << 2) | (in2 >> 6)) & 0x3f]; + *(q++) = enc[in2 & 0x3f]; + } + if ((len - i) == 1) { + in0 = buf[i++]; + *(q++) = enc[(in0 >> 2) & 0x3f]; + *(q++) = enc[(in0 << 4) & 0x3f]; + *(q++) = '='; + *(q++) = '='; + } else if ((len - i) == 2) { + in0 = buf[i++]; + in1 = buf[i++]; + *(q++) = enc[(in0 >> 2) & 0x3f]; + *(q++) = enc[((in0 << 4) | (in1 >> 4)) & 0x3f]; + *(q++) = enc[(in1 << 2) & 0x3f]; + *(q++) = '='; + } + *q = 0; - q = out; - *size = 0; - - *q = 0; - - while(*p){ - int i = 0; - while(i < 4){ - if(!*p) break; - if((*p >= 'A') && (*p <= 'Z')) - in[i++] = *p - 'A'; - else if((*p >= 'a') && (*p <= 'z')) - in[i++] = (*p - 'a') + 26; - else if((*p >= '0') && (*p <= '9')) - in[i++] = (*p - '0') + 52; - else if(*p == '+') - in[i++] = 62; - else if(*p == '/') - in[i++] = 63; - else if(*p == '='){ - in[i++] = 0; - p++; - break; - }else if((*p != '\r') && (*p != '\n')){ - p++; - break; - } - p++; - } - if((i == 4) || (p[-1] == '=')){ - *(q++) = ((in[0] << 2) | (in[1] >> 4)); - *(q++) = ((in[1] << 4) | (in[2] >> 2)); - *(q++) = ((in[2] << 6) | in[3]); - if(p[-1] == '='){ - if(i == 3){ - (*size)++; - } - else if(i == 4){ - (*size) += 2; - } - }else{ - *size += 3; - } - } - } - return out; + return outbuf; } +gchar *base64_decode(gchar * buf, gint * size) +{ + guchar *p = buf, *q; + guint in[4]; + /* gchar *out = g_malloc(((strlen(buf)+3) * 3) / 4 + 1); */ + gchar *out = g_malloc((strlen(buf) + 3) + 1); + + q = out; + *size = 0; + + *q = 0; + + while (*p) { + int i = 0; + while (i < 4) { + if (!*p) + break; + if ((*p >= 'A') && (*p <= 'Z')) + in[i++] = *p - 'A'; + else if ((*p >= 'a') && (*p <= 'z')) + in[i++] = (*p - 'a') + 26; + else if ((*p >= '0') && (*p <= '9')) + in[i++] = (*p - '0') + 52; + else if (*p == '+') + in[i++] = 62; + else if (*p == '/') + in[i++] = 63; + else if (*p == '=') { + in[i++] = 0; + p++; + break; + } else if ((*p != '\r') && (*p != '\n')) { + p++; + break; + } + p++; + } + if ((i == 4) || (p[-1] == '=')) { + *(q++) = ((in[0] << 2) | (in[1] >> 4)); + *(q++) = ((in[1] << 4) | (in[2] >> 2)); + *(q++) = ((in[2] << 6) | in[3]); + if (p[-1] == '=') { + if (i == 3) { + (*size)++; + } else if (i == 4) { + (*size) += 2; + } + } else { + *size += 3; + } + } + } + return out; +} diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/base64/base64.h --- a/src/base64/base64.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/base64/base64.h 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 @@ -15,5 +15,5 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -gchar *base64_encode(guchar *buf, gint len); -gchar *base64_decode(gchar *buf, gint *size); +gchar *base64_encode(guchar * buf, gint len); +gchar *base64_decode(gchar * buf, gint * size); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/base64/base64dec.c --- a/src/base64/base64dec.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/base64/base64dec.c Mon Oct 27 16:23:10 2008 +0100 @@ -4,16 +4,17 @@ #include "base64.h" -int main() +int +main() { - gchar line[100]; - gchar *buf; - gint size; + gchar line[100]; + gchar *buf; + gint size; - while(fgets(line, 100, stdin)){ - buf = base64_decode(line, &size); - fwrite(buf, size, 1, stdout); - g_free(buf); - } - exit(0); + while (fgets(line, 100, stdin)) { + buf = base64_decode(line, &size); + fwrite(buf, size, 1, stdout); + g_free(buf); + } + exit(0); } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/base64/base64enc.c --- a/src/base64/base64enc.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/base64/base64enc.c Mon Oct 27 16:23:10 2008 +0100 @@ -1,24 +1,23 @@ - #include #include #include #include "base64.h" -int main() +int +main() { - gchar in[58]; - gint size; + gchar in[58]; + gint size; - do{ - gchar *out; + do { + gchar *out; - size = fread(in, 1, 54, stdin); - out = base64_encode(in, size); - fputs(out, stdout); - putchar('\n'); - g_free(out); - }while(size == 54); - exit(0); + size = fread(in, 1, 54, stdin); + out = base64_encode(in, size); + fputs(out, stdout); + putchar('\n'); + g_free(out); + } while (size == 54); + exit(0); } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/child.c --- a/src/child.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/child.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 @@ -29,51 +29,51 @@ int volatile sigchild_seen = 0; -static -void sigchild_handler(int sig) +static void +sigchild_handler(int sig) { - sigchild_seen = 1; - signal(SIGHUP, sigchild_handler); + sigchild_seen = 1; + signal(SIGHUP, sigchild_handler); } -int child(const char *command) +int +child(const char *command) { - int pipe[2]; + int pipe[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) == 0){ - pid_t pid; - - /* - sigchild_seen = 0; - signal(SIGCHLD, sigchild_handler); - */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) == 0) { + pid_t pid; - pid = fork(); - if(pid == 0){ - int i, max_fd = sysconf(_SC_OPEN_MAX); - /* child */ - dup2(pipe[0], 0); - dup2(pipe[0], 1); - dup2(pipe[0], 2); + /* + sigchild_seen = 0; + signal(SIGCHLD, sigchild_handler); + */ - if(max_fd <= 0) max_fd = 64; - for(i = 3; i < max_fd; i++) - close(i); + pid = fork(); + if (pid == 0) { + int i, max_fd = sysconf(_SC_OPEN_MAX); + /* child */ + dup2(pipe[0], 0); + dup2(pipe[0], 1); + dup2(pipe[0], 2); - { - char *argv [] = { "/bin/sh", "-c", (char*) command, NULL }; - execve (*argv, argv, NULL); - } - logwrite(LOG_ALERT, "execve failed: %s\n", strerror(errno)); - _exit(EXIT_FAILURE); - }else if(pid == -1){ - return -1; - }else{ - close(pipe[0]); - return pipe[1]; - } - } - return -2; + if (max_fd <= 0) + max_fd = 64; + for (i = 3; i < max_fd; i++) + close(i); + + { + char *argv[] = { "/bin/sh", "-c", (char *) command, NULL }; + execve(*argv, argv, NULL); + } + logwrite(LOG_ALERT, "execve failed: %s\n", strerror(errno)); + _exit(EXIT_FAILURE); + } else if (pid == -1) { + return -1; + } else { + close(pipe[0]); + return pipe[1]; + } + } + return -2; } - - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/conf.c --- a/src/conf.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/conf.c Mon Oct 27 16:23:10 2008 +0100 @@ -23,973 +23,973 @@ masqmail_conf conf; -void init_conf() +void +init_conf() { - struct passwd *passwd; - struct group *group; + struct passwd *passwd; + struct group *group; - memset(&conf, 0, sizeof(masqmail_conf)); + memset(&conf, 0, sizeof(masqmail_conf)); - conf.orig_uid = getuid(); - conf.orig_gid = getgid(); + conf.orig_uid = getuid(); + conf.orig_gid = getgid(); - if((passwd = getpwnam(DEF_MAIL_USER))) - conf.mail_uid = passwd->pw_uid; - else{ - fprintf(stderr, "user %s not found! (terminating)\n", DEF_MAIL_USER); - exit(EXIT_FAILURE); - } - if((group = getgrnam(DEF_MAIL_GROUP))) - conf.mail_gid = group->gr_gid; - else{ - fprintf(stderr, "group %s not found! (terminating)\n", DEF_MAIL_GROUP); - exit(EXIT_FAILURE); - } + if ((passwd = getpwnam(DEF_MAIL_USER))) + conf.mail_uid = passwd->pw_uid; + else { + fprintf(stderr, "user %s not found! (terminating)\n", DEF_MAIL_USER); + exit(EXIT_FAILURE); + } + if ((group = getgrnam(DEF_MAIL_GROUP))) + conf.mail_gid = group->gr_gid; + else { + fprintf(stderr, "group %s not found! (terminating)\n", DEF_MAIL_GROUP); + exit(EXIT_FAILURE); + } } -static gchar *true_strings[] = -{ - "yes", "on", "true", NULL +static gchar* true_strings[] = { + "yes", "on", "true", NULL }; -static gchar *false_strings[] = -{ - "no", "off", "false", NULL +static gchar *false_strings[] = { + "no", "off", "false", NULL }; -static -gboolean parse_boolean(gchar *rval) +static gboolean +parse_boolean(gchar * rval) { - gchar **str; + gchar **str; - DEBUG(6) fprintf(stderr, "parse_boolean: %s\n", rval); + DEBUG(6) fprintf(stderr, "parse_boolean: %s\n", rval); - str = true_strings; - while(*str){ - if(strncasecmp(*str, rval, strlen(*str)) == 0) - return TRUE; - str++; - } + str = true_strings; + while (*str) { + if (strncasecmp(*str, rval, strlen(*str)) == 0) + return TRUE; + str++; + } - str = false_strings; - while(*str){ - if(strncasecmp(*str, rval, strlen(*str)) == 0) - return FALSE; - str++; - } + str = false_strings; + while (*str) { + if (strncasecmp(*str, rval, strlen(*str)) == 0) + return FALSE; + str++; + } - fprintf(stderr, "cannot parse value '%s'\n", rval); - exit(EXIT_FAILURE); + fprintf(stderr, "cannot parse value '%s'\n", rval); + exit(EXIT_FAILURE); } /* make a list from each line in a file */ -static -GList *parse_list_file(gchar *fname) +static GList* +parse_list_file(gchar * fname) { - GList *list = NULL; - FILE *fptr; + GList *list = NULL; + FILE *fptr; - if((fptr = fopen(fname, "rt"))){ - gchar buf[256]; + if ((fptr = fopen(fname, "rt"))) { + gchar buf[256]; - while(!feof(fptr)){ - fgets(buf, 255, fptr); - if(buf[0] && (buf[0] != '#') && (buf[0] != '\n')){ - g_strchomp(buf); - list = g_list_append(list, g_strdup(buf)); - } - } - fclose(fptr); - }else{ - logwrite(LOG_ALERT, "could not open %s for reading: %s\n", fname, strerror(errno)); - exit(EXIT_FAILURE); - } + while (!feof(fptr)) { + fgets(buf, 255, fptr); + if (buf[0] && (buf[0] != '#') && (buf[0] != '\n')) { + g_strchomp(buf); + list = g_list_append(list, g_strdup(buf)); + } + } + fclose(fptr); + } else { + logwrite(LOG_ALERT, "could not open %s for reading: %s\n", fname, strerror(errno)); + exit(EXIT_FAILURE); + } - return list; + return list; } /* given a semicolon separated string, this function makes a GList out of it. */ -GList *parse_list(gchar *line, gboolean read_file) +GList* +parse_list(gchar * line, gboolean read_file) { - GList *list = NULL; - gchar buf[256]; - gchar *p, *q; + GList *list = NULL; + gchar buf[256]; + gchar *p, *q; - DEBUG(6) fprintf(stderr, "parsing list %s\n", line); + DEBUG(6) fprintf(stderr, "parsing list %s\n", line); - p = line; - while(*p != 0){ - q = buf; + p = line; + while (*p != 0) { + q = buf; - while(*p && (*p != ';') && (q < buf+255)) - *(q++) = *(p++); - *q = 0; + while (*p && (*p != ';') && (q < buf + 255)) + *(q++) = *(p++); + *q = 0; - if((buf[0] == '/') && (read_file)) - /* item is a filename, include its contents */ - list = g_list_concat(list, parse_list_file(buf)); - else - /* just a normal item */ - list = g_list_append(list, g_strdup(buf)); + if ((buf[0] == '/') && (read_file)) + /* item is a filename, include its contents */ + list = g_list_concat(list, parse_list_file(buf)); + else + /* just a normal item */ + list = g_list_append(list, g_strdup(buf)); - DEBUG(6) printf("item = %s\n", buf); + DEBUG(6) printf("item = %s\n", buf); - if(*p) p++; - } - return list; + if (*p) + p++; + } + return list; } -static -GList *parse_address_list(gchar *line, gboolean read_file) +static GList* +parse_address_list(gchar * line, gboolean read_file) { - GList *plain_list = parse_list(line, read_file); - GList *node; - GList *list = NULL; + GList *plain_list = parse_list(line, read_file); + GList *node; + GList *list = NULL; - foreach(plain_list, node){ - gchar *item = (gchar *)(node->data); - address *addr = create_address(item, TRUE); - if(addr) - list = g_list_append(list, addr); - g_free(item); - } - g_list_free(plain_list); + foreach(plain_list, node) { + gchar *item = (gchar *) (node->data); + address *addr = create_address(item, TRUE); + if (addr) + list = g_list_append(list, addr); + g_free(item); + } + g_list_free(plain_list); - return list; + return list; } -static -GList *parse_resolve_list(gchar *line) +static GList* +parse_resolve_list(gchar * line) { - GList *list; - GList *list_node; - GList *res_list = NULL; + GList *list; + GList *list_node; + GList *res_list = NULL; - list = parse_list(line, FALSE); - if(list){ - foreach(list, list_node){ - gchar *item = (gchar *)(list_node->data); - if(strcmp(item, "byname") == 0){ - res_list = g_list_append(res_list, resolve_byname); + list = parse_list(line, FALSE); + if (list) { + foreach(list, list_node) { + gchar *item = (gchar *) (list_node->data); + if (strcmp(item, "byname") == 0) { + res_list = g_list_append(res_list, resolve_byname); #ifdef ENABLE_RESOLVER - }else if(strcmp(item, "dns_a") == 0){ - res_list = g_list_append(res_list, resolve_dns_a); - }else if(strcmp(item, "dns_mx") == 0){ - res_list = g_list_append(res_list, resolve_dns_mx); + } else if (strcmp(item, "dns_a") == 0) { + res_list = g_list_append(res_list, resolve_dns_a); + } else if (strcmp(item, "dns_mx") == 0) { + res_list = g_list_append(res_list, resolve_dns_mx); #endif - }else{ - logwrite(LOG_ALERT, "unknown resolver %s\n", item); - exit(EXIT_FAILURE); - } - g_free(item); - } - g_list_free(list); - } - return res_list; + } else { + logwrite(LOG_ALERT, "unknown resolver %s\n", item); + exit(EXIT_FAILURE); + } + g_free(item); + } + g_list_free(list); + } + return res_list; } -static -interface *parse_interface(gchar *line, gint def_port) +static interface* +parse_interface(gchar * line, gint def_port) { - gchar buf[256]; - gchar *p, *q; - interface *iface; + gchar buf[256]; + gchar *p, *q; + interface *iface; - DEBUG(6) fprintf(stderr, "parse_interface: %s\n", line); + DEBUG(6) fprintf(stderr, "parse_interface: %s\n", line); - p = line; - q = buf; - while((*p != 0) && (*p != ':') && (q < buf+255)) - *(q++) = *(p++); - *q = 0; + p = line; + q = buf; + while ((*p != 0) && (*p != ':') && (q < buf + 255)) + *(q++) = *(p++); + *q = 0; - iface = g_malloc(sizeof(interface)); - iface->address = g_strdup(buf); + iface = g_malloc(sizeof(interface)); + iface->address = g_strdup(buf); - if(*p){ - p++; - iface->port = atoi(p); - }else - iface->port = def_port; + if (*p) { + p++; + iface->port = atoi(p); + } else + iface->port = def_port; - return iface; + return iface; } -#ifdef ENABLE_IDENT /* so far used for that only */ -static -struct in_addr *parse_network(gchar *line, gint def_port) +#ifdef ENABLE_IDENT /* so far used for that only */ +static struct in_addr* +parse_network(gchar * line, gint def_port) { - gchar buf[256]; - gchar *p, *q; - struct in_addr addr, mask_addr, net_addr, *p_net_addr; - guint n; + gchar buf[256]; + gchar *p, *q; + struct in_addr addr, mask_addr, net_addr, *p_net_addr; + guint n; - DEBUG(6) fprintf(stderr, "parse_network: %s\n", line); + DEBUG(6) fprintf(stderr, "parse_network: %s\n", line); - p = line; - q = buf; - while((*p != 0) && (*p != '/') && (q < buf+255)) - *(q++) = *(p++); - *q = 0; + p = line; + q = buf; + while ((*p != 0) && (*p != '/') && (q < buf + 255)) + *(q++) = *(p++); + *q = 0; - if((addr.s_addr = inet_addr(buf)) != INADDR_NONE){ - if(*p){ - guint i; - p++; - i = atoi(p); - if((i >= 0) && (i <= 32)) - n = i ? ~((1 << (32 - i)) - 1) : 0; - else{ - fprintf(stderr, "'%d' is not a valid net mask (must be >= 0 and <= 32)\n", i); - exit(EXIT_FAILURE); - } - }else - n = 0; - - mask_addr.s_addr = htonl(n); - net_addr.s_addr = mask_addr.s_addr & addr.s_addr; - }else{ - fprintf(stderr, "'%s' is not a valid address (must be ip)\n", buf); - exit(EXIT_FAILURE); - } + if ((addr.s_addr = inet_addr(buf)) != INADDR_NONE) { + if (*p) { + guint i; + p++; + i = atoi(p); + if ((i >= 0) && (i <= 32)) + n = i ? ~((1 << (32 - i)) - 1) : 0; + else { + fprintf(stderr, "'%d' is not a valid net mask (must be >= 0 and <= 32)\n", i); + exit(EXIT_FAILURE); + } + } else + n = 0; - p_net_addr = g_malloc(sizeof(struct in_addr)); - p_net_addr->s_addr = net_addr.s_addr; - return p_net_addr; + mask_addr.s_addr = htonl(n); + net_addr.s_addr = mask_addr.s_addr & addr.s_addr; + } else { + fprintf(stderr, "'%s' is not a valid address (must be ip)\n", buf); + exit(EXIT_FAILURE); + } + + p_net_addr = g_malloc(sizeof(struct in_addr)); + p_net_addr->s_addr = net_addr.s_addr; + return p_net_addr; } #endif -static -gboolean eat_comments(FILE *in) +static gboolean +eat_comments(FILE * in) { - gint c; + gint c; - for(c = fgetc(in); (c == '#' || isspace(c)) && c != EOF; c = fgetc(in)){ - if(c == '#'){ - gint c; - for(c = fgetc(in); (c != '\n') && (c != EOF); c = fgetc(in)); - } - } - if(c == EOF) return FALSE; - ungetc(c, in); - return TRUE; + for (c = fgetc(in); (c == '#' || isspace(c)) && c != EOF; + c = fgetc(in)) { + if (c == '#') { + gint c; + for (c = fgetc(in); (c != '\n') && (c != EOF); c = fgetc(in)); + } + } + if (c == EOF) + return FALSE; + ungetc(c, in); + return TRUE; } /* after parsing, eat trailing character until LF */ -static -gboolean eat_line_trailing(FILE *in) +static gboolean +eat_line_trailing(FILE * in) { - gint c; + gint c; - for(c = fgetc(in); c != EOF && c != '\n'; c = fgetc(in)); - if(c == EOF) return FALSE; - return TRUE; + for (c = fgetc(in); c != EOF && c != '\n'; c = fgetc(in)); + if (c == EOF) + return FALSE; + return TRUE; } -static -gboolean eat_spaces(FILE *in) +static gboolean +eat_spaces(FILE * in) { - gint c; - - for(c = fgetc(in); c != EOF && isspace(c); c = fgetc(in)); - if(c == EOF) return FALSE; - ungetc(c, in); - return TRUE; + gint c; + + for (c = fgetc(in); c != EOF && isspace(c); c = fgetc(in)); + if (c == EOF) + return FALSE; + ungetc(c, in); + return TRUE; } -static -gboolean read_lval(FILE *in, gchar *buf, gint size) +static gboolean +read_lval(FILE * in, gchar * buf, gint size) { - gint c; - gchar *ptr = buf; - - DEBUG(6) fprintf(stderr, "read_lval()\n"); + gint c; + gchar *ptr = buf; - if(!eat_spaces(in)) return FALSE; + DEBUG(6) fprintf(stderr, "read_lval()\n"); - c = fgetc(in); - DEBUG(6) fprintf(stderr, "read_lval() 2\n"); - while((isalnum(c) || c == '_' || c == '-' || c == '.') - && (ptr < buf+size-1) - && (c != EOF) - ){ - *ptr = c; ptr++; - c = fgetc(in); - } - *ptr = 0; - ungetc(c, in); + if (!eat_spaces(in)) + return FALSE; - if(c == EOF){ - fprintf(stderr, "unexpected EOF after %s\n", buf); - return FALSE; - }else if(ptr >= buf+size-1){ - fprintf(stderr, "lval too long\n"); - } + c = fgetc(in); + DEBUG(6) fprintf(stderr, "read_lval() 2\n"); + while ((isalnum(c) || c == '_' || c == '-' || c == '.') + && (ptr < buf + size - 1) + && (c != EOF)) { + *ptr = c; + ptr++; + c = fgetc(in); + } + *ptr = 0; + ungetc(c, in); - eat_spaces(in); + if (c == EOF) { + fprintf(stderr, "unexpected EOF after %s\n", buf); + return FALSE; + } else if (ptr >= buf + size - 1) { + fprintf(stderr, "lval too long\n"); + } - DEBUG(6) fprintf(stderr, "lval = %s\n", buf); + eat_spaces(in); - return buf[0] != 0; + DEBUG(6) fprintf(stderr, "lval = %s\n", buf); + + return buf[0] != 0; } -static -gboolean read_rval(FILE *in, gchar *buf, gint size) +static gboolean +read_rval(FILE * in, gchar * buf, gint size) { - gint c; - gchar *ptr = buf; - - DEBUG(6) fprintf(stderr, "read_rval()\n"); + gint c; + gchar *ptr = buf; - if(!eat_spaces(in)) return FALSE; + DEBUG(6) fprintf(stderr, "read_rval()\n"); - c = fgetc(in); - if(c != '\"'){ - while((isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/' || c == '@' || c == ';') - && (ptr < buf+size-1) - && (c != EOF) - ){ - *ptr = c; ptr++; - c = fgetc(in); - } - *ptr = 0; - ungetc(c, in); - }else{ - gboolean escape = FALSE; - c = fgetc(in); - while(((c != '\"') || escape) && (ptr < buf+size-1)){ - if(c != '\n'){ /* ignore line breaks */ - if((c == '\\') && (!escape)){ - escape = TRUE; - }else{ - *ptr = c; ptr++; - escape = FALSE; + if (!eat_spaces(in)) + return FALSE; + + c = fgetc(in); + if (c != '\"') { + while ((isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/' + || c == '@' || c == ';') + && (ptr < buf + size - 1) + && (c != EOF)) { + *ptr = c; + ptr++; + c = fgetc(in); + } + *ptr = 0; + ungetc(c, in); + } else { + gboolean escape = FALSE; + c = fgetc(in); + while (((c != '\"') || escape) && (ptr < buf + size - 1)) { + if (c != '\n') { /* ignore line breaks */ + if ((c == '\\') && (!escape)) { + escape = TRUE; + } else { + *ptr = c; + ptr++; + escape = FALSE; + } + } + c = fgetc(in); + } + *ptr = 0; } - } - c = fgetc(in); - } - *ptr = 0; - } - - eat_line_trailing(in); - DEBUG(6) fprintf(stderr, "rval = %s\n", buf); + eat_line_trailing(in); - return TRUE; + DEBUG(6) fprintf(stderr, "rval = %s\n", buf); + + return TRUE; } -static -gboolean read_statement(FILE *in, - gchar *lval, gint lsize, - gchar *rval, gint rsize) +static gboolean +read_statement(FILE * in, gchar * lval, gint lsize, gchar * rval, gint rsize) { - gint c; + gint c; - DEBUG(6) fprintf(stderr, "read_statement()\n"); + DEBUG(6) fprintf(stderr, "read_statement()\n"); - /* eat comments and empty lines: */ - if(!eat_comments(in)) return FALSE; + /* eat comments and empty lines: */ + if (!eat_comments(in)) + return FALSE; - DEBUG(6) fprintf(stderr, "read_statement() 1\n"); + DEBUG(6) fprintf(stderr, "read_statement() 1\n"); - if(read_lval(in, lval, lsize)){ - DEBUG(6) fprintf(stderr, "lval = %s\n", lval); - if((c = fgetc(in) == '=')){ - if(read_rval(in, rval, rsize)){ - DEBUG(6) fprintf(stderr, "rval = %s\n", rval); - return TRUE; - } - }else{ - fprintf(stderr, "'=' expected after %s, char was '%c'\n", lval, c); - } - } - return FALSE; + if (read_lval(in, lval, lsize)) { + DEBUG(6) fprintf(stderr, "lval = %s\n", lval); + if ((c = fgetc(in) == '=')) { + if (read_rval(in, rval, rsize)) { + DEBUG(6) fprintf(stderr, "rval = %s\n", rval); + return TRUE; + } + } else { + fprintf(stderr, "'=' expected after %s, char was '%c'\n", lval, + c); + } + } + return FALSE; } -gboolean read_conf(gchar *filename) +gboolean +read_conf(gchar * filename) { - FILE *in; + FILE *in; - conf.log_max_pri = 7; + conf.log_max_pri = 7; + conf.remote_port = 25; + conf.do_relay = TRUE; + conf.alias_local_cmp = strcmp; + conf.max_defer_time = 86400 * 4; /* 4 days */ - conf.remote_port = 25; + if ((in = fopen(filename, "r"))) { + gchar lval[256], rval[2048]; + while (read_statement(in, lval, 256, rval, 2048)) { + if (strcmp(lval, "debug_level") == 0) + conf.debug_level = atoi(rval); + else if (strcmp(lval, "run_as_user") == 0) { + if (!conf.run_as_user) /* you should not be able to reset that flag */ + conf.run_as_user = parse_boolean(rval); + } else if (strcmp(lval, "use_syslog") == 0) + conf.use_syslog = parse_boolean(rval); + else if (strcmp(lval, "mail_dir") == 0) + conf.mail_dir = g_strdup(rval); + else if (strcmp(lval, "lock_dir") == 0) + conf.lock_dir = g_strdup(rval); + else if (strcmp(lval, "spool_dir") == 0) + conf.spool_dir = g_strdup(rval); + else if (strcmp(lval, "log_dir") == 0) + conf.log_dir = g_strdup(rval); + else if (strcmp(lval, "host_name") == 0) { + if (rval[0] != '/') + conf.host_name = g_strdup(rval); + else { + char buf[256]; + FILE *fptr = fopen(rval, "rt"); + if (fptr) { + fgets(buf, 255, fptr); + g_strchomp(buf); + conf.host_name = g_strdup(buf); + fclose(fptr); + } else { + fprintf(stderr, "could not open %s: %s\n", rval, + strerror(errno)); + return FALSE; + } + } + } else if (strcmp(lval, "remote_port") == 0) { + fprintf(stderr, "the remote_port option is now deprecated. Use 'mail_host' in the\n" + "route configuration instead. See man masqmail.route\n"); + conf.remote_port = atoi(rval); + } else if (strcmp(lval, "local_hosts") == 0) + conf.local_hosts = parse_list(rval, FALSE); + else if (strcmp(lval, "local_addresses") == 0) + conf.local_addresses = parse_list(rval, TRUE); + else if (strcmp(lval, "not_local_addresses") == 0) + conf.not_local_addresses = parse_list(rval, TRUE); + else if (strcmp(lval, "local_nets") == 0) + conf.local_nets = parse_list(rval, FALSE); + else if (strcmp(lval, "do_save_envelope_to") == 0) + conf.do_save_envelope_to = parse_boolean(rval); + else if (strcmp(lval, "defer_all") == 0) + conf.defer_all = parse_boolean(rval); + else if (strcmp(lval, "do_relay") == 0) + conf.do_relay = parse_boolean(rval); + else if (strcmp(lval, "alias_file") == 0) { + conf.alias_file = g_strdup(rval); + } else if (strcmp(lval, "alias_local_caseless") == 0) { + conf.alias_local_cmp = parse_boolean(rval) ? strcasecmp : strcmp; + } else if (strcmp(lval, "mbox_default") == 0) { + conf.mbox_default = g_strdup(rval); + } else if (strcmp(lval, "mbox_users") == 0) { + conf.mbox_users = parse_list(rval, TRUE); + } else if (strcmp(lval, "mda_users") == 0) { + conf.mda_users = parse_list(rval, TRUE); + } else if (strcmp(lval, "maildir_users") == 0) { + conf.maildir_users = parse_list(rval, TRUE); + } else if (strcmp(lval, "mda") == 0) { + conf.mda = g_strdup(rval); + } else if (strcmp(lval, "mda_fromline") == 0) { + conf.mda_fromline = parse_boolean(rval); + } else if (strcmp(lval, "mda_fromhack") == 0) { + conf.mda_fromhack = parse_boolean(rval); + } else if (strcmp(lval, "pipe_fromline") == 0) { + conf.pipe_fromline = parse_boolean(rval); + } else if (strcmp(lval, "pipe_fromhack") == 0) { + conf.pipe_fromhack = parse_boolean(rval); + } else if (strcmp(lval, "listen_addresses") == 0) { + GList *node; + GList *tmp_list = parse_list(rval, FALSE); - conf.do_relay = TRUE; + conf.listen_addresses = NULL; + foreach(tmp_list, node) { + conf.listen_addresses = g_list_append(conf.listen_addresses, parse_interface((gchar *) (node-> data), 25)); + g_free(node->data); + } + g_list_free(tmp_list); + } else if (strcmp(lval, "ident_trusted_nets") == 0) { +#ifdef ENABLE_IDENT + GList *node; + GList *tmp_list = parse_list(rval, FALSE); - conf.alias_local_cmp = strcmp; + conf.ident_trusted_nets = NULL; + foreach(tmp_list, node) { + conf.ident_trusted_nets = g_list_append(conf.ident_trusted_nets, parse_network((gchar *) (node->data), 25)); + g_free(node->data); + } + g_list_free(tmp_list); +#else + fprintf(stderr, "%s ignored: not compiled with ident support\n", lval); +#endif + } else if ((strncmp(lval, "connect_route.", 14) == 0) + || (strncmp(lval, "online_routes.", 14) == 0)) { + GList *file_list = parse_list(rval, FALSE); + table_pair *pair = create_pair(&(lval[14]), file_list); + conf.connect_routes = g_list_append(conf.connect_routes, pair); + } else if (strcmp(lval, "local_net_route") == 0) { + conf.local_net_routes = parse_list(rval, FALSE); + } else if (strcmp(lval, "online_detect") == 0) + conf.online_detect = g_strdup(rval); + else if (strcmp(lval, "online_file") == 0) + conf.online_file = g_strdup(rval); + else if (strcmp(lval, "online_pipe") == 0) + conf.online_pipe = g_strdup(rval); + else if (strcmp(lval, "mserver_iface") == 0) + conf.mserver_iface = parse_interface(rval, 224); + else if (strcmp(lval, "do_queue") == 0) + conf.do_queue = parse_boolean(rval); + else if (strncmp(lval, "get.", 4) == 0) { +#ifdef ENABLE_POP3 + table_pair *pair = create_pair_string(&(lval[4]), rval); + conf.get_names = g_list_append(conf.get_names, pair); +#else + fprintf(stderr, "get. ignored: not compiled with pop support\n"); +#endif + } else if (strncmp(lval, "online_gets.", 12) == 0) { +#ifdef ENABLE_POP3 + GList *file_list = parse_list(rval, FALSE); + table_pair *pair = create_pair(&(lval[12]), file_list); + conf.online_gets = g_list_append(conf.online_gets, pair); +#else + fprintf(stderr, "online_gets. ignored: not compiled with pop support\n"); +#endif + } else if (strcmp(lval, "errmsg_file") == 0) + conf.errmsg_file = g_strdup(rval); + else if (strcmp(lval, "warnmsg_file") == 0) + conf.warnmsg_file = g_strdup(rval); + else if (strcmp(lval, "warn_intervals") == 0) + conf.warn_intervals = parse_list(rval, FALSE); + else if (strcmp(lval, "max_defer_time") == 0) { + gint dummy; + gint ival = time_interval(rval, &dummy); + if (ival < 0) + fprintf(stderr, "invalid time interval for 'max_defer_time': %s\n", rval); + else + conf.max_defer_time = ival; + } else if (strcmp(lval, "log_user") == 0) + conf.log_user = g_strdup(rval); - conf.max_defer_time = 86400*4; /* 4 days */ + else + fprintf(stderr, "var '%s' not (yet) known, ignored\n", lval); + } + fclose(in); - if((in = fopen(filename, "r"))){ - gchar lval[256], rval[2048]; - while(read_statement(in, lval, 256, rval, 2048)){ - if(strcmp(lval, "debug_level") == 0) - conf.debug_level = atoi(rval); - else if(strcmp(lval, "run_as_user") == 0){ - if(!conf.run_as_user) /* you should not be able - to reset that flag */ - conf.run_as_user = parse_boolean(rval); - }else if(strcmp(lval, "use_syslog") == 0) - conf.use_syslog = parse_boolean(rval); - else if(strcmp(lval, "mail_dir") == 0) - conf.mail_dir = g_strdup(rval); - else if(strcmp(lval, "lock_dir") == 0) - conf.lock_dir = g_strdup(rval); - else if(strcmp(lval, "spool_dir") == 0) - conf.spool_dir = g_strdup(rval); - else if(strcmp(lval, "log_dir") == 0) - conf.log_dir = g_strdup(rval); - else if(strcmp(lval, "host_name") == 0){ - if(rval[0] != '/') - conf.host_name = g_strdup(rval); - else{ - char buf[256]; - FILE *fptr = fopen(rval, "rt"); - if(fptr){ - fgets(buf, 255, fptr); - g_strchomp(buf); - conf.host_name = g_strdup(buf); - fclose(fptr); - }else{ - fprintf(stderr, "could not open %s: %s\n", rval, strerror(errno)); - return FALSE; - } - } - } - else if(strcmp(lval, "remote_port") == 0){ - fprintf(stderr, - "the remote_port option is now deprecated. Use 'mail_host' in the\n" - "route configuration instead. See man masqmail.route\n"); - conf.remote_port = atoi(rval); - }else if(strcmp(lval, "local_hosts") == 0) - conf.local_hosts = parse_list(rval, FALSE); - else if(strcmp(lval, "local_addresses") == 0) - conf.local_addresses = parse_list(rval, TRUE); - else if(strcmp(lval, "not_local_addresses") == 0) - conf.not_local_addresses = parse_list(rval, TRUE); - else if(strcmp(lval, "local_nets") == 0) - conf.local_nets = parse_list(rval, FALSE); - else if(strcmp(lval, "do_save_envelope_to") == 0) - conf.do_save_envelope_to = parse_boolean(rval); - else if(strcmp(lval, "defer_all") == 0) - conf.defer_all = parse_boolean(rval); - else if(strcmp(lval, "do_relay") == 0) - conf.do_relay = parse_boolean(rval); - else if(strcmp(lval, "alias_file") == 0){ - conf.alias_file = g_strdup(rval); - }else if(strcmp(lval, "alias_local_caseless") == 0){ - conf.alias_local_cmp = parse_boolean(rval) ? strcasecmp : strcmp; - }else if(strcmp(lval, "mbox_default") == 0){ - conf.mbox_default = g_strdup(rval); - }else if(strcmp(lval, "mbox_users") == 0){ - conf.mbox_users = parse_list(rval, TRUE); - }else if(strcmp(lval, "mda_users") == 0){ - conf.mda_users = parse_list(rval, TRUE); - }else if(strcmp(lval, "maildir_users") == 0){ - conf.maildir_users = parse_list(rval, TRUE); - }else if(strcmp(lval, "mda") == 0){ - conf.mda = g_strdup(rval); - }else if(strcmp(lval, "mda_fromline") == 0){ - conf.mda_fromline = parse_boolean(rval); - }else if(strcmp(lval, "mda_fromhack") == 0){ - conf.mda_fromhack = parse_boolean(rval); - }else if(strcmp(lval, "pipe_fromline") == 0){ - conf.pipe_fromline = parse_boolean(rval); - }else if(strcmp(lval, "pipe_fromhack") == 0){ - conf.pipe_fromhack = parse_boolean(rval); - }else if(strcmp(lval, "listen_addresses") == 0){ - GList *node; - GList *tmp_list = parse_list(rval, FALSE); - - conf.listen_addresses = NULL; - foreach(tmp_list, node){ - conf.listen_addresses = - g_list_append(conf.listen_addresses, - parse_interface((gchar *)(node->data), 25)); - g_free(node->data); - } - g_list_free(tmp_list); - } - else if(strcmp(lval, "ident_trusted_nets") == 0){ -#ifdef ENABLE_IDENT - GList *node; - GList *tmp_list = parse_list(rval, FALSE); - - conf.ident_trusted_nets = NULL; - foreach(tmp_list, node){ - conf.ident_trusted_nets = - g_list_append(conf.ident_trusted_nets, - parse_network((gchar *)(node->data), 25)); - g_free(node->data); - } - g_list_free(tmp_list); -#else - fprintf(stderr, "%s ignored: not compiled with ident support\n", lval); -#endif - } - else if((strncmp(lval, "connect_route.", 14) == 0) || - (strncmp(lval, "online_routes.", 14) == 0)){ - GList *file_list = parse_list(rval, FALSE); - table_pair *pair = create_pair(&(lval[14]), file_list); - conf.connect_routes = g_list_append(conf.connect_routes, pair); - } - else if(strcmp(lval, "local_net_route") == 0){ - conf.local_net_routes = parse_list(rval, FALSE); - } - else if(strcmp(lval, "online_detect") == 0) - conf.online_detect = g_strdup(rval); - else if(strcmp(lval, "online_file") == 0) - conf.online_file = g_strdup(rval); - else if(strcmp(lval, "online_pipe") == 0) - conf.online_pipe = g_strdup(rval); - else if(strcmp(lval, "mserver_iface") == 0) - conf.mserver_iface = parse_interface(rval, 224); - else if(strcmp(lval, "do_queue") == 0) - conf.do_queue = parse_boolean(rval); - else if(strncmp(lval, "get.", 4) == 0){ -#ifdef ENABLE_POP3 - table_pair *pair = create_pair_string(&(lval[4]), rval); - conf.get_names = g_list_append(conf.get_names, pair); -#else - fprintf(stderr, "get. ignored: not compiled with pop support\n"); -#endif - } - else if(strncmp(lval, "online_gets.", 12) == 0){ -#ifdef ENABLE_POP3 - GList *file_list = parse_list(rval, FALSE); - table_pair *pair = create_pair(&(lval[12]), file_list); - conf.online_gets = g_list_append(conf.online_gets, pair); -#else - fprintf(stderr, "online_gets. ignored: not compiled with pop support\n"); -#endif - } - else if(strcmp(lval, "errmsg_file") == 0) - conf.errmsg_file = g_strdup(rval); - else if(strcmp(lval, "warnmsg_file") == 0) - conf.warnmsg_file = g_strdup(rval); - else if(strcmp(lval, "warn_intervals") == 0) - conf.warn_intervals = parse_list(rval, FALSE); - else if(strcmp(lval, "max_defer_time") == 0){ - gint dummy; - gint ival = time_interval(rval, &dummy); - if(ival < 0) - fprintf(stderr, "invalid time interval for 'max_defer_time': %s\n", rval); - else - conf.max_defer_time = ival; - }else if(strcmp(lval, "log_user") == 0) - conf.log_user = g_strdup(rval); + if (conf.errmsg_file == NULL) + conf.errmsg_file = g_strdup(DATA_DIR "/tpl/failmsg.tpl"); + if (conf.warnmsg_file == NULL) + conf.warnmsg_file = g_strdup(DATA_DIR "/tpl/warnmsg.tpl"); - else - fprintf(stderr, "var '%s' not (yet) known, ignored\n", lval); - } - fclose(in); + if (conf.lock_dir == NULL) + conf.lock_dir = g_strdup_printf("%s/lock/", conf.spool_dir); - if(conf.errmsg_file == NULL) - conf.errmsg_file = g_strdup(DATA_DIR"/tpl/failmsg.tpl"); - if(conf.warnmsg_file == NULL) - conf.warnmsg_file = g_strdup(DATA_DIR"/tpl/warnmsg.tpl"); + if (conf.mbox_default == NULL) + conf.mbox_default = g_strdup("mbox"); - if(conf.lock_dir == NULL) - conf.lock_dir = g_strdup_printf("%s/lock/", conf.spool_dir); + if (conf.warn_intervals == NULL) + conf.warn_intervals = parse_list("1h;4h;8h;1d;2d;3d", FALSE); - if(conf.mbox_default == NULL) - conf.mbox_default = g_strdup("mbox"); - - if(conf.warn_intervals == NULL) - conf.warn_intervals = parse_list("1h;4h;8h;1d;2d;3d", FALSE); - - return TRUE; - }else - fprintf(stderr, "could not open config file %s: %s\n", filename, strerror(errno)); - return FALSE; + return TRUE; + } else + fprintf(stderr, "could not open config file %s: %s\n", filename, strerror(errno)); + return FALSE; } -connect_route *read_route(gchar *filename, gboolean is_local_net) +connect_route* +read_route(gchar * filename, gboolean is_local_net) { - gboolean ok = FALSE; - FILE *in; + gboolean ok = FALSE; + FILE *in; - connect_route *route = g_malloc(sizeof(connect_route)); - memset(route, 0, sizeof(connect_route)); + connect_route *route = g_malloc(sizeof(connect_route)); + memset(route, 0, sizeof(connect_route)); - DEBUG(5) debugf("read_route, filename = %s\n", filename); + DEBUG(5) debugf("read_route, filename = %s\n", filename); - route->filename = g_strdup(filename); - route->name = g_strdup(filename); /* quick hack */ + route->filename = g_strdup(filename); + route->name = g_strdup(filename); /* quick hack */ - route->protocol = g_strdup("smtp"); - route->expand_h_sender_address = TRUE; + route->protocol = g_strdup("smtp"); + route->expand_h_sender_address = TRUE; - route->is_local_net = is_local_net; + route->is_local_net = is_local_net; - route->do_pipelining = TRUE; + route->do_pipelining = TRUE; - if((in = fopen(route->filename, "r"))){ - gchar lval[256], rval[2048]; - while(read_statement(in, lval, 256, rval, 2048)){ - if(strcmp(lval, "protocol") == 0) - route->protocol = g_strdup(rval); - else if(strcmp(lval, "mail_host") == 0) - route->mail_host = parse_interface(rval, conf.remote_port); - else if(strcmp(lval, "helo_name") == 0) - route->helo_name = g_strdup(rval); - else if(strcmp(lval, "wrapper") == 0) - route->wrapper = g_strdup(rval); - else if(strcmp(lval, "connect_error_fail") == 0) - route->connect_error_fail = parse_boolean(rval); - else if(strcmp(lval, "do_correct_helo") == 0) - route->do_correct_helo = parse_boolean(rval); - else if(strcmp(lval, "do_pipelining") == 0) - route->do_pipelining = parse_boolean(rval); - else if(strcmp(lval, "allowed_return_paths") == 0) - route->allowed_return_paths = parse_address_list(rval, TRUE); - else if(strcmp(lval, "allowed_mail_locals") == 0) - route->allowed_mail_locals = parse_list(rval, TRUE); - else if(strcmp(lval, "not_allowed_return_paths") == 0) - route->not_allowed_return_paths = parse_address_list(rval, TRUE); - else if(strcmp(lval, "not_allowed_mail_locals") == 0) - route->not_allowed_mail_locals = parse_list(rval, TRUE); - else if(strcmp(lval, "allowed_rcpt_domains") == 0) - route->allowed_rcpt_domains = parse_list(rval, TRUE); - else if(strcmp(lval, "not_allowed_rcpt_domains") == 0) - route->not_allowed_rcpt_domains = parse_list(rval, TRUE); - else if(strcmp(lval, "set_h_from_domain") == 0) - route->set_h_from_domain = g_strdup(rval); - else if(strcmp(lval, "set_h_reply_to_domain") == 0) - route->set_h_reply_to_domain = g_strdup(rval); - else if(strcmp(lval, "set_return_path_domain") == 0) - route->set_return_path_domain = g_strdup(rval); - else if(strcmp(lval, "map_return_path_addresses") == 0){ - GList *node, *list; + if ((in = fopen(route->filename, "r"))) { + gchar lval[256], rval[2048]; + while (read_statement(in, lval, 256, rval, 2048)) { + if (strcmp(lval, "protocol") == 0) + route->protocol = g_strdup(rval); + else if (strcmp(lval, "mail_host") == 0) + route->mail_host = parse_interface(rval, conf.remote_port); + else if (strcmp(lval, "helo_name") == 0) + route->helo_name = g_strdup(rval); + else if (strcmp(lval, "wrapper") == 0) + route->wrapper = g_strdup(rval); + else if (strcmp(lval, "connect_error_fail") == 0) + route->connect_error_fail = parse_boolean(rval); + else if (strcmp(lval, "do_correct_helo") == 0) + route->do_correct_helo = parse_boolean(rval); + else if (strcmp(lval, "do_pipelining") == 0) + route->do_pipelining = parse_boolean(rval); + else if (strcmp(lval, "allowed_return_paths") == 0) + route->allowed_return_paths = parse_address_list(rval, TRUE); + else if (strcmp(lval, "allowed_mail_locals") == 0) + route->allowed_mail_locals = parse_list(rval, TRUE); + else if (strcmp(lval, "not_allowed_return_paths") == 0) + route->not_allowed_return_paths = parse_address_list(rval, TRUE); + else if (strcmp(lval, "not_allowed_mail_locals") == 0) + route->not_allowed_mail_locals = parse_list(rval, TRUE); + else if (strcmp(lval, "allowed_rcpt_domains") == 0) + route->allowed_rcpt_domains = parse_list(rval, TRUE); + else if (strcmp(lval, "not_allowed_rcpt_domains") == 0) + route->not_allowed_rcpt_domains = parse_list(rval, TRUE); + else if (strcmp(lval, "set_h_from_domain") == 0) + route->set_h_from_domain = g_strdup(rval); + else if (strcmp(lval, "set_h_reply_to_domain") == 0) + route->set_h_reply_to_domain = g_strdup(rval); + else if (strcmp(lval, "set_return_path_domain") == 0) + route->set_return_path_domain = g_strdup(rval); + else if (strcmp(lval, "map_return_path_addresses") == 0) { + GList *node, *list; - list = parse_list(rval, TRUE); - foreach(list, node){ - gchar *item = (gchar *)(node->data); - table_pair *pair = parse_table_pair(item, ':'); - address *addr = create_address((gchar *)(pair->value), TRUE); - g_free(pair->value); - pair->value = (gpointer *)addr; - route->map_return_path_addresses = - g_list_append(route->map_return_path_addresses, pair); - g_free(item); + list = parse_list(rval, TRUE); + foreach(list, node) { + gchar *item = (gchar *) (node->data); + table_pair *pair = parse_table_pair(item, ':'); + address *addr = create_address((gchar *) (pair->value), TRUE); + g_free(pair->value); + pair->value = (gpointer *) addr; + route->map_return_path_addresses = g_list_append(route->map_return_path_addresses, pair); + g_free(item); + } + g_list_free(list); + } else if (strcmp(lval, "map_h_from_addresses") == 0) { + GList *list, *node; + + list = parse_list(rval, TRUE); + foreach(list, node) { + gchar *item = (gchar *) (node->data); + table_pair *pair = parse_table_pair(item, ':'); + route->map_h_from_addresses = g_list_append(route->map_h_from_addresses, pair); + g_free(item); + } + g_list_free(list); + } else if (strcmp(lval, "map_h_reply_to_addresses") == 0) { + GList *list, *node; + + list = parse_list(rval, TRUE); + foreach(list, node) { + gchar *item = (gchar *) (node->data); + table_pair *pair = parse_table_pair(item, ':'); + route->map_h_reply_to_addresses = g_list_append(route->map_h_reply_to_addresses, pair); + g_free(item); + } + g_list_free(list); + } else if (strcmp(lval, "map_h_mail_followup_to_addresses") == 0) { + GList *list, *node; + + list = parse_list(rval, TRUE); + foreach(list, node) { + gchar *item = (gchar *) (node->data); + table_pair *pair = parse_table_pair(item, ':'); + route->map_h_mail_followup_to_addresses = g_list_append(route->map_h_mail_followup_to_addresses, pair); + g_free(item); + } + g_list_free(list); + } else if (strcmp(lval, "expand_h_sender_domain") == 0) { + route->expand_h_sender_domain = parse_boolean(rval); + } else if (strcmp(lval, "expand_h_sender_address") == 0) { + route->expand_h_sender_address = parse_boolean(rval); + } else if (strcmp(lval, "resolve_list") == 0) + route->resolve_list = parse_resolve_list(rval); + else if (strcmp(lval, "do_ssl") == 0) { + /* we ignore this. This option is used by sqilconf */ + ; + } +#ifdef ENABLE_AUTH + else if (strcmp(lval, "auth_name") == 0) { + route->auth_name = g_strdup(rval); + } else if (strcmp(lval, "auth_login") == 0) { + route->auth_login = g_strdup(rval); + } else if (strcmp(lval, "auth_secret") == 0) { + route->auth_secret = g_strdup(rval); + } +#else + else if ((strcmp(lval, "auth_name") == 0) + || (strcmp(lval, "auth_login") == 0) + || (strcmp(lval, "auth_secret") == 0)) { + logwrite(LOG_WARNING, "%s ignored: not compiled with auth support.\n", lval); + } +#endif + else if (strcmp(lval, "pop3_login") == 0) { +#ifdef ENABLE_POP3 + route->pop3_login = g_strdup(rval); +#else + logwrite(LOG_WARNING, "pop3_login ignored: not compiled with pop support.\n"); +#endif + } else if (strcmp(lval, "pipe") == 0) { + route->pipe = g_strdup(rval); + } else if (strcmp(lval, "pipe_fromline") == 0) { + route->pipe_fromline = parse_boolean(rval); + } else if (strcmp(lval, "pipe_fromhack") == 0) { + route->pipe_fromhack = parse_boolean(rval); + } else if (strcmp(lval, "last_route") == 0) { + route->last_route = parse_boolean(rval); + } else + logwrite(LOG_WARNING, "var '%s' not (yet) known, ignored\n", lval); + } + + if (route->resolve_list == NULL) { + if (is_local_net) { + route->resolve_list = g_list_append(NULL, resolve_byname); + } else { +#ifdef ENABLE_RESOLVER + route->resolve_list = g_list_append(route->resolve_list, resolve_dns_mx); + route->resolve_list = g_list_append(route->resolve_list, resolve_dns_a); +#endif + route->resolve_list = g_list_append(route->resolve_list, resolve_byname); + } + } + fclose(in); + ok = TRUE; + + /* warn user about misconfigurations: */ + if ((route->map_h_from_addresses != NULL) + && (route->set_h_from_domain != NULL)) { + logwrite(LOG_WARNING, "'map_h_from_addresses' overrides 'set_h_from_domain'\n"); + g_free(route->set_h_from_domain); + route->set_h_from_domain = NULL; + } + if ((route->map_h_reply_to_addresses != NULL) + && (route->set_h_reply_to_domain != NULL)) { + logwrite(LOG_WARNING, "'map_h_reply_to_addresses' overrides 'set_h_reply_to_domain'\n"); + g_free(route->set_h_reply_to_domain); + route->set_h_reply_to_domain = NULL; + } + } else { + logwrite(LOG_ALERT, "could not open route file %s: %s\n", route->filename, strerror(errno)); + } + + if (!ok) { + g_free(route); + route = NULL; + } + + return route; +} + +static void +_g_list_free_all(GList * list) +{ + GList *node; + if (list) { + foreach(list, node) + g_free(node->data); + g_list_free(list); + } +} + +void +destroy_route(connect_route * r) +{ + if (r->filename) + g_free(r->filename); + if (r->protocol) + g_free(r->protocol); + if (r->mail_host) { + g_free(r->mail_host->address); + g_free(r->mail_host); + } + if (r->wrapper) + g_free(r->wrapper); + if (r->helo_name) + g_free(r->helo_name); + _g_list_free_all(r->allowed_mail_locals); + _g_list_free_all(r->not_allowed_mail_locals); + _g_list_free_all(r->allowed_rcpt_domains); + _g_list_free_all(r->not_allowed_rcpt_domains); + if (r->set_h_from_domain) + g_free(r->set_h_from_domain); + if (r->set_h_reply_to_domain) + g_free(r->set_h_reply_to_domain); + if (r->set_return_path_domain) + g_free(r->set_return_path_domain); + if (r->map_h_reply_to_addresses) + destroy_table(r->map_h_reply_to_addresses); + if (r->resolve_list) + g_list_free(r->resolve_list); +#ifdef ENABLE_AUTH + if (r->auth_name) + g_free(r->auth_name); + if (r->auth_login) + g_free(r->auth_login); + if (r->auth_secret) + g_free(r->auth_secret); +#endif +#ifdef ENABLE_POP3 + if (r->pop3_login) + g_free(r->pop3_login); +#endif + if (r->pipe) + g_free(r->pipe); + g_free(r); +} + +GList* +read_route_list(GList * rf_list, gboolean is_local_net) +{ + GList *list = NULL; + GList *node; + uid_t saved_uid, saved_gid; + + if (!conf.run_as_user) { + set_euidgid(0, 0, &saved_uid, &saved_gid); + } + + foreach(rf_list, node) { + gchar *fname = (gchar *) (node->data); + connect_route *route = read_route(fname, is_local_net); + if (route) + list = g_list_append(list, route); + else + logwrite(LOG_ALERT, "could not read route configuration %s\n", fname); + } + + /* set uid and gid back */ + if (!conf.run_as_user) { + set_euidgid(saved_uid, saved_gid, NULL, NULL); + } + + return list; +} + +void +destroy_route_list(GList * list) +{ + GList *node; + + foreach(list, node) { + connect_route *route = (connect_route *) (node->data); + destroy_route(route); } g_list_free(list); - } - else if(strcmp(lval, "map_h_from_addresses") == 0){ - GList *list, *node; - - list = parse_list(rval, TRUE); - foreach(list, node){ - gchar *item = (gchar *)(node->data); - table_pair *pair = parse_table_pair(item, ':'); - route->map_h_from_addresses = - g_list_append(route->map_h_from_addresses, pair); - g_free(item); - } - g_list_free(list); - } - else if(strcmp(lval, "map_h_reply_to_addresses") == 0){ - GList *list, *node; - - list = parse_list(rval, TRUE); - foreach(list, node){ - gchar *item = (gchar *)(node->data); - table_pair *pair = parse_table_pair(item, ':'); - route->map_h_reply_to_addresses = - g_list_append(route->map_h_reply_to_addresses, pair); - g_free(item); - } - g_list_free(list); - } - else if(strcmp(lval, "map_h_mail_followup_to_addresses") == 0){ - GList *list, *node; - - list = parse_list(rval, TRUE); - foreach(list, node){ - gchar *item = (gchar *)(node->data); - table_pair *pair = parse_table_pair(item, ':'); - route->map_h_mail_followup_to_addresses = - g_list_append(route->map_h_mail_followup_to_addresses, pair); - g_free(item); - } - g_list_free(list); - } - else if(strcmp(lval, "expand_h_sender_domain") == 0){ - route->expand_h_sender_domain = parse_boolean(rval); - } - else if(strcmp(lval, "expand_h_sender_address") == 0){ - route->expand_h_sender_address = parse_boolean(rval); - } - else if(strcmp(lval, "resolve_list") == 0) - route->resolve_list = parse_resolve_list(rval); - else if(strcmp(lval, "do_ssl") == 0){ - /* we ignore this. This option is used by sqilconf */ - ; - } -#ifdef ENABLE_AUTH - else if(strcmp(lval, "auth_name") == 0){ - route->auth_name = g_strdup(rval); - } - else if(strcmp(lval, "auth_login") == 0){ - route->auth_login = g_strdup(rval); - } - else if(strcmp(lval, "auth_secret") == 0){ - route->auth_secret = g_strdup(rval); - } -#else - else if((strcmp(lval, "auth_name") == 0) || - (strcmp(lval, "auth_login") == 0) || - (strcmp(lval, "auth_secret") == 0)){ - logwrite(LOG_WARNING, "%s ignored: not compiled with auth support.\n", lval); - } -#endif - else if(strcmp(lval, "pop3_login") == 0){ -#ifdef ENABLE_POP3 - route->pop3_login = g_strdup(rval); -#else - logwrite(LOG_WARNING, "pop3_login ignored: not compiled with pop support.\n"); -#endif - } - else if(strcmp(lval, "pipe") == 0){ - route->pipe = g_strdup(rval); - } - else if(strcmp(lval, "pipe_fromline") == 0){ - route->pipe_fromline = parse_boolean(rval); - } - else if(strcmp(lval, "pipe_fromhack") == 0){ - route->pipe_fromhack = parse_boolean(rval); - } - else if(strcmp(lval, "last_route") == 0){ - route->last_route = parse_boolean(rval); - } - else - logwrite(LOG_WARNING, "var '%s' not (yet) known, ignored\n", lval); - } - - if(route->resolve_list == NULL){ - if(is_local_net){ - route->resolve_list = - g_list_append(NULL, resolve_byname); - }else{ -#ifdef ENABLE_RESOLVER - route->resolve_list = - g_list_append(route->resolve_list, resolve_dns_mx); - route->resolve_list = - g_list_append(route->resolve_list, resolve_dns_a); -#endif - route->resolve_list = - g_list_append(route->resolve_list, resolve_byname); - } - } - fclose(in); - ok = TRUE; - - /* warn user about misconfigurations: */ - if((route->map_h_from_addresses != NULL) && (route->set_h_from_domain != NULL)){ - logwrite(LOG_WARNING, "'map_h_from_addresses' overrides 'set_h_from_domain'\n"); - g_free(route->set_h_from_domain); - route->set_h_from_domain = NULL; - } - if((route->map_h_reply_to_addresses != NULL) && (route->set_h_reply_to_domain != NULL)){ - logwrite(LOG_WARNING, "'map_h_reply_to_addresses' overrides 'set_h_reply_to_domain'\n"); - g_free(route->set_h_reply_to_domain); - route->set_h_reply_to_domain = NULL; - } - }else{ - logwrite(LOG_ALERT, "could not open route file %s: %s\n", - route->filename, strerror(errno)); - } - - if(!ok){ - g_free(route); - route = NULL; - } - - return route; -} - -static -void _g_list_free_all(GList *list) -{ - GList *node; - if(list){ - foreach(list, node) - g_free(node->data); - g_list_free(list); - } -} - -void destroy_route(connect_route *r) -{ - if(r->filename) g_free(r->filename); - if(r->protocol) g_free(r->protocol); - if(r->mail_host){ - g_free(r->mail_host->address); - g_free(r->mail_host); - } - if(r->wrapper) g_free(r->wrapper); - if(r->helo_name) g_free(r->helo_name); - _g_list_free_all(r->allowed_mail_locals); - _g_list_free_all(r->not_allowed_mail_locals); - _g_list_free_all(r->allowed_rcpt_domains); - _g_list_free_all(r->not_allowed_rcpt_domains); - if(r->set_h_from_domain) g_free(r->set_h_from_domain); - if(r->set_h_reply_to_domain) g_free(r->set_h_reply_to_domain); - if(r->set_return_path_domain) g_free(r->set_return_path_domain); - if(r->map_h_reply_to_addresses) destroy_table(r->map_h_reply_to_addresses); - if(r->resolve_list) g_list_free(r->resolve_list); -#ifdef ENABLE_AUTH - if(r->auth_name) g_free(r->auth_name); - if(r->auth_login) g_free(r->auth_login); - if(r->auth_secret) g_free(r->auth_secret); -#endif -#ifdef ENABLE_POP3 - if(r->pop3_login) g_free(r->pop3_login); -#endif - if(r->pipe) g_free(r->pipe); - g_free(r); -} - -GList *read_route_list(GList *rf_list, gboolean is_local_net) -{ - GList *list = NULL; - GList *node; - uid_t saved_uid, saved_gid; - - if(!conf.run_as_user){ - set_euidgid(0, 0, &saved_uid, &saved_gid); - } - - foreach(rf_list, node){ - gchar *fname = (gchar *)(node->data); - connect_route *route = read_route(fname, is_local_net); - if(route) - list = g_list_append(list, route); - else - logwrite(LOG_ALERT, "could not read route configuration %s\n", fname); - } - - /* set uid and gid back */ - if(!conf.run_as_user){ - set_euidgid(saved_uid, saved_gid, NULL, NULL); - } - - return list; -} - -void destroy_route_list(GList *list) -{ - GList *node; - - foreach(list, node){ - connect_route *route = (connect_route *)(node->data); - destroy_route(route); - } - g_list_free(list); } #ifdef ENABLE_POP3 -get_conf *read_get_conf(gchar *filename) +get_conf* +read_get_conf(gchar * filename) { - FILE *in; + FILE *in; - get_conf *gc = g_malloc(sizeof(get_conf)); - memset(gc, 0, sizeof(get_conf)); + get_conf *gc = g_malloc(sizeof(get_conf)); + memset(gc, 0, sizeof(get_conf)); - gc->server_port = 110; + gc->server_port = 110; - if((in = fopen(filename, "r"))){ - gchar lval[256], rval[2048]; - while(read_statement(in, lval, 256, rval, 2048)){ - if(strcmp(lval, "protocol") == 0) - gc->protocol = g_strdup(rval); - else if(strcmp(lval, "server") == 0) - gc->server_name = g_strdup(rval); - else if(strcmp(lval, "port") == 0) - gc->server_port = atoi(rval); - else if(strcmp(lval, "wrapper") == 0) - gc->wrapper = g_strdup(rval); - else if(strcmp(lval, "user") == 0) - gc->login_user = g_strdup(rval); - else if(strcmp(lval, "pass") == 0) - gc->login_pass = g_strdup(rval); - else if(strcmp(lval, "address") == 0) - gc->address = create_address_qualified(rval, TRUE, conf.host_name); - else if(strcmp(lval, "return_path") == 0) - gc->return_path = create_address_qualified(rval, TRUE, conf.host_name); - else if(strcmp(lval, "do_ssl") == 0) - /* we ignore this. This option is used by sqilconf */ - ; - else if(strcmp(lval, "do_keep") == 0) - gc->do_keep = parse_boolean(rval); - else if(strcmp(lval, "do_uidl") == 0) - gc->do_uidl = parse_boolean(rval); - else if(strcmp(lval, "do_uidl_dele") == 0) - gc->do_uidl_dele = parse_boolean(rval); - else if(strcmp(lval, "max_size") == 0) - gc->max_size = atoi(rval); - else if(strcmp(lval, "max_size_delete") == 0) - gc->max_size = parse_boolean(rval); - else if(strcmp(lval, "max_count") == 0) - gc->max_count = atoi(rval); - else if(strcmp(lval, "resolve_list") == 0) - gc->resolve_list = parse_resolve_list(rval); - else - logwrite(LOG_WARNING, "var '%s' not (yet) known, ignored\n", lval); - } - fclose(in); + if ((in = fopen(filename, "r"))) { + gchar lval[256], rval[2048]; + while (read_statement(in, lval, 256, rval, 2048)) { + if (strcmp(lval, "protocol") == 0) + gc->protocol = g_strdup(rval); + else if (strcmp(lval, "server") == 0) + gc->server_name = g_strdup(rval); + else if (strcmp(lval, "port") == 0) + gc->server_port = atoi(rval); + else if (strcmp(lval, "wrapper") == 0) + gc->wrapper = g_strdup(rval); + else if (strcmp(lval, "user") == 0) + gc->login_user = g_strdup(rval); + else if (strcmp(lval, "pass") == 0) + gc->login_pass = g_strdup(rval); + else if (strcmp(lval, "address") == 0) + gc->address = create_address_qualified(rval, TRUE, conf.host_name); + else if (strcmp(lval, "return_path") == 0) + gc->return_path = create_address_qualified(rval, TRUE, conf.host_name); + else if (strcmp(lval, "do_ssl") == 0) + /* we ignore this. This option is used by sqilconf */ + ; + else if (strcmp(lval, "do_keep") == 0) + gc->do_keep = parse_boolean(rval); + else if (strcmp(lval, "do_uidl") == 0) + gc->do_uidl = parse_boolean(rval); + else if (strcmp(lval, "do_uidl_dele") == 0) + gc->do_uidl_dele = parse_boolean(rval); + else if (strcmp(lval, "max_size") == 0) + gc->max_size = atoi(rval); + else if (strcmp(lval, "max_size_delete") == 0) + gc->max_size = parse_boolean(rval); + else if (strcmp(lval, "max_count") == 0) + gc->max_count = atoi(rval); + else if (strcmp(lval, "resolve_list") == 0) + gc->resolve_list = parse_resolve_list(rval); + else + logwrite(LOG_WARNING, "var '%s' not (yet) known, ignored\n", lval); + } + fclose(in); - if(gc->resolve_list == NULL){ + if (gc->resolve_list == NULL) { #ifdef ENABLE_RESOLVER - gc->resolve_list = - g_list_append(NULL, resolve_dns_a); + gc->resolve_list = g_list_append(NULL, resolve_dns_a); #endif - gc->resolve_list = - g_list_append(NULL, resolve_byname); - } - - if(gc->protocol == NULL) - gc->protocol = g_strdup("pop3"); - return gc; - } - logwrite(LOG_ALERT, "could not open get file %s: %s\n", filename, strerror(errno)); + gc->resolve_list = g_list_append(NULL, resolve_byname); + } - g_free(gc); - return NULL; + if (gc->protocol == NULL) + gc->protocol = g_strdup("pop3"); + return gc; + } + logwrite(LOG_ALERT, "could not open get file %s: %s\n", filename, strerror(errno)); + + g_free(gc); + return NULL; } -void destroy_get_conf(get_conf *gc) +void +destroy_get_conf(get_conf * gc) { - if(gc->protocol) g_free(gc->protocol); - if(gc->server_name) g_free(gc->server_name); - if(gc->login_user) g_free(gc->login_user); - if(gc->login_pass) g_free(gc->login_pass); - if(gc->wrapper) g_free(gc->wrapper); - if(gc->address) destroy_address(gc->address); - if(gc->return_path) destroy_address(gc->return_path); - if(gc->resolve_list) g_list_free(gc->resolve_list); - g_free(gc); + if (gc->protocol) + g_free(gc->protocol); + if (gc->server_name) + g_free(gc->server_name); + if (gc->login_user) + g_free(gc->login_user); + if (gc->login_pass) + g_free(gc->login_pass); + if (gc->wrapper) + g_free(gc->wrapper); + if (gc->address) + destroy_address(gc->address); + if (gc->return_path) + destroy_address(gc->return_path); + if (gc->resolve_list) + g_list_free(gc->resolve_list); + g_free(gc); } #endif -connect_route *create_local_route() +connect_route* +create_local_route() { - connect_route *route; + connect_route *route; - route = g_malloc(sizeof(connect_route)); - if(route){ - memset(route, 0, sizeof(connect_route)); - route->protocol = g_strdup("smtp"); - route->is_local_net = TRUE; - route->name = g_strdup("local_net (default)"); - route->expand_h_sender_address = TRUE; - route->resolve_list = - g_list_append(NULL, resolve_byname); - route->connect_error_fail = TRUE; - } - return route; + route = g_malloc(sizeof(connect_route)); + if (route) { + memset(route, 0, sizeof(connect_route)); + route->protocol = g_strdup("smtp"); + route->is_local_net = TRUE; + route->name = g_strdup("local_net (default)"); + route->expand_h_sender_address = TRUE; + route->resolve_list = g_list_append(NULL, resolve_byname); + route->connect_error_fail = TRUE; + } + return route; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/connect.c --- a/src/connect.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/connect.c Mon Oct 27 16:23:10 2008 +0100 @@ -17,67 +17,63 @@ */ #include "masqmail.h" -static -GList *resolve_ip(GList *list, gchar *ip) +static GList* +resolve_ip(GList * list, gchar * ip) { - struct in_addr ia; - if(inet_aton(ip, &ia)){ - mxip_addr mxip; - - mxip.name = g_strdup(ip); - mxip.pref = 0; - mxip.ip = (guint32) *(guint32 *)(&ia); - list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); - } - /* logwrite(LOG_ALERT, "invalid address '%s': inet_aton() failed\n", ip);*/ - return NULL; + struct in_addr ia; + if (inet_aton(ip, &ia)) { + mxip_addr mxip; + + mxip.name = g_strdup(ip); + mxip.pref = 0; + mxip.ip = (guint32) * (guint32 *) (&ia); + list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); + } + /* logwrite(LOG_ALERT, "invalid address '%s': inet_aton() failed\n", ip); */ + return NULL; } -mxip_addr *connect_hostlist(int *psockfd, gchar *host, guint port, - GList *addr_list) +mxip_addr* +connect_hostlist(int *psockfd, gchar * host, guint port, GList * addr_list) { - GList *addr_node; - struct sockaddr_in saddr; + GList *addr_node; + struct sockaddr_in saddr; - DEBUG(5) debugf("connect_hostlist entered\n"); + DEBUG(5) debugf("connect_hostlist entered\n"); - for(addr_node = g_list_first(addr_list); - addr_node; - addr_node = g_list_next(addr_node)){ - mxip_addr *addr = (mxip_addr *)(addr_node->data); + for (addr_node = g_list_first(addr_list); addr_node; addr_node = g_list_next(addr_node)) { + mxip_addr *addr = (mxip_addr *) (addr_node->data); - *psockfd = socket(PF_INET, SOCK_STREAM, 0); + *psockfd = socket(PF_INET, SOCK_STREAM, 0); - memset(&saddr, 0, sizeof(saddr)); + memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); - /* clumsy, but makes compiler happy: */ - saddr.sin_addr = *(struct in_addr*)(&(addr->ip)); - DEBUG(5) debugf("trying ip %s port %d\n", inet_ntoa(saddr.sin_addr), port); - if(connect(*psockfd, (struct sockaddr *)(&saddr), sizeof(saddr)) == 0){ - DEBUG(5) debugf("connected to %s\n", inet_ntoa(saddr.sin_addr)); - return addr; - }else{ - int saved_errno = errno; + /* clumsy, but makes compiler happy: */ + saddr.sin_addr = *(struct in_addr *) (&(addr->ip)); + DEBUG(5) debugf("trying ip %s port %d\n", inet_ntoa(saddr.sin_addr), port); + if (connect(*psockfd, (struct sockaddr *) (&saddr), sizeof(saddr)) == 0) { + DEBUG(5) debugf("connected to %s\n", inet_ntoa(saddr.sin_addr)); + return addr; + } else { + int saved_errno = errno; - close(*psockfd); + close(*psockfd); - logwrite(LOG_WARNING, "connection to %s failed: %s\n", - inet_ntoa(saddr.sin_addr), strerror(errno)); + logwrite(LOG_WARNING, "connection to %s failed: %s\n", inet_ntoa(saddr.sin_addr), strerror(errno)); - errno = saved_errno; + errno = saved_errno; - if((saved_errno != ECONNREFUSED) && - (saved_errno != ETIMEDOUT) && - (saved_errno != ENETUNREACH) && - (saved_errno != EHOSTUNREACH)) - + if ((saved_errno != ECONNREFUSED) + && (saved_errno != ETIMEDOUT) + && (saved_errno != ENETUNREACH) + && (saved_errno != EHOSTUNREACH)) + return NULL; + } + } return NULL; - } - } - return NULL; } /* Given a list of resolver functions, this function @@ -89,63 +85,62 @@ if attempt failed for one it should not be tried again. */ -mxip_addr *connect_resolvelist(int *psockfd, gchar *host, guint port, - GList *res_func_list) +mxip_addr* +connect_resolvelist(int *psockfd, gchar * host, guint port, GList * res_func_list) { - GList *res_node; - GList *addr_list; + GList *res_node; + GList *addr_list; - DEBUG(5) debugf("connect_resolvelist entered\n"); + DEBUG(5) debugf("connect_resolvelist entered\n"); - h_errno = 0; + h_errno = 0; - if(isdigit(host[0])){ - mxip_addr *addr; - - addr_list = resolve_ip(NULL, host); - if(addr_list){ - addr = connect_hostlist(psockfd, host, port, addr_list); - g_list_free(addr_list); - return addr; - } - /* previous versions complained, until someone tried to use a hostname - out there that begins with a digit. eg. '3dwars.de'. */ - } + if (isdigit(host[0])) { + mxip_addr *addr; - if(res_func_list == NULL){ - logwrite(LOG_ALERT, "res_funcs == NULL !!!\n"); - exit(EXIT_FAILURE); - } + addr_list = resolve_ip(NULL, host); + if (addr_list) { + addr = connect_hostlist(psockfd, host, port, addr_list); + g_list_free(addr_list); + return addr; + } + /* previous versions complained, until someone tried to use a hostname + out there that begins with a digit. eg. '3dwars.de'. */ + } - foreach(res_func_list, res_node){ - resolve_func res_func; - DEBUG(6) debugf("connect_resolvelist 1a\n"); - res_func = (resolve_func)(res_node->data); - - if(res_func == NULL){ - logwrite(LOG_ALERT, "res_func == NULL !!!\n"); - exit(EXIT_FAILURE); - } - - errno = 0; - if((addr_list = res_func(NULL, host))){ - - mxip_addr *addr; - if((addr = connect_hostlist(psockfd, host, port, addr_list))) - return addr; + if (res_func_list == NULL) { + logwrite(LOG_ALERT, "res_funcs == NULL !!!\n"); + exit(EXIT_FAILURE); + } - DEBUG(5){ - debugf("connect_hostlist failed: %s\n", strerror(errno)); - } - - g_list_free(addr_list); - }else{ - if(!g_list_next(res_node)){ - logwrite(LOG_ALERT, "could not resolve %s: %s\n", host, hstrerror(h_errno)); - } - } - } - return NULL; + foreach(res_func_list, res_node) { + resolve_func res_func; + DEBUG(6) debugf("connect_resolvelist 1a\n"); + res_func = (resolve_func) (res_node->data); + + if (res_func == NULL) { + logwrite(LOG_ALERT, "res_func == NULL !!!\n"); + exit(EXIT_FAILURE); + } + + errno = 0; + if ((addr_list = res_func(NULL, host))) { + + mxip_addr *addr; + if ((addr = connect_hostlist(psockfd, host, port, addr_list))) + return addr; + + DEBUG(5) { + debugf("connect_hostlist failed: %s\n", strerror(errno)); + } + + g_list_free(addr_list); + } else { + if (!g_list_next(res_node)) { + logwrite(LOG_ALERT, "could not resolve %s: %s\n", host, hstrerror(h_errno)); + } + } + } + return NULL; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/deliver.c --- a/src/deliver.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/deliver.c Mon Oct 27 16:23:10 2008 +0100 @@ -25,506 +25,484 @@ /* collect failed/defered rcpts for failure/warning messages */ /* returns TRUE if either there are no failures or a failure message has been successfully sent */ -gboolean delivery_failures(message *msg, GList *rcpt_list, gchar *err_fmt, ...) +gboolean +delivery_failures(message * msg, GList * rcpt_list, gchar * err_fmt, ...) { - gboolean ok_fail = TRUE, ok_warn = TRUE; - time_t now = time(NULL); + gboolean ok_fail = TRUE, ok_warn = TRUE; + time_t now = time(NULL); - GList *failed_list = NULL, *defered_list = NULL, *rcpt_node; - va_list args; - va_start(args, err_fmt); + GList *failed_list = NULL, *defered_list = NULL, *rcpt_node; + va_list args; + va_start(args, err_fmt); - foreach(rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - - if(addr_is_defered(rcpt)){ - if((now - msg->received_time) >= conf.max_defer_time){ - addr_mark_failed(rcpt); - }else - defered_list = g_list_prepend(defered_list, rcpt); - } - if(addr_is_failed(rcpt)) - failed_list = g_list_prepend(failed_list, rcpt); - } - if(failed_list != NULL){ - ok_fail = fail_msg(msg, conf.errmsg_file, failed_list, err_fmt, args); - g_list_free(failed_list); - } - if(defered_list != NULL){ - ok_warn = warn_msg(msg, conf.warnmsg_file, defered_list, err_fmt, args); - g_list_free(defered_list); - } - va_end(args); - return ok_fail && ok_warn; + foreach(rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + + if (addr_is_defered(rcpt)) { + if ((now - msg->received_time) >= conf.max_defer_time) { + addr_mark_failed(rcpt); + } else + defered_list = g_list_prepend(defered_list, rcpt); + } + if (addr_is_failed(rcpt)) + failed_list = g_list_prepend(failed_list, rcpt); + } + if (failed_list != NULL) { + ok_fail = fail_msg(msg, conf.errmsg_file, failed_list, err_fmt, args); + g_list_free(failed_list); + } + if (defered_list != NULL) { + ok_warn = warn_msg(msg, conf.warnmsg_file, defered_list, err_fmt, args); + g_list_free(defered_list); + } + va_end(args); + return ok_fail && ok_warn; } -static gint _g_list_strcasecmp(gconstpointer a, gconstpointer b) +static gint +_g_list_strcasecmp(gconstpointer a, gconstpointer b) { - return (gint)strcasecmp(a, b); + return (gint) strcasecmp(a, b); } -gboolean deliver_local(msg_out *msgout) +gboolean +deliver_local(msg_out * msgout) { - message *msg = msgout->msg; - GList *rcpt_list = msgout->rcpt_list; - GList *rcpt_node; - gboolean ok = TRUE, flag = FALSE, ok_fail = FALSE; + message *msg = msgout->msg; + GList *rcpt_list = msgout->rcpt_list; + GList *rcpt_node; + gboolean ok = TRUE, flag = FALSE, ok_fail = FALSE; - DEBUG(5) debugf("deliver_local entered\n"); + DEBUG(5) debugf("deliver_local entered\n"); - flag = (msg->data_list == NULL); - if(flag){ - if(!(ok = spool_read_data(msg))){ - logwrite(LOG_ALERT, "could not open data spool file for %s\n", - msg->uid); - } - } - if(!ok) return FALSE; + flag = (msg->data_list == NULL); + if (flag) { + if (!(ok = spool_read_data(msg))) { + logwrite(LOG_ALERT, "could not open data spool file for %s\n", msg->uid); + } + } + if (!ok) + return FALSE; - ok = FALSE; - for(rcpt_node = g_list_first(rcpt_list); - rcpt_node; - rcpt_node = g_list_next(rcpt_node)){ - GList *hdr_list; - address *rcpt = (address *)(rcpt_node->data); - address *env_addr = addr_find_ancestor(rcpt); - address *ret_path = msg->return_path; - header *retpath_hdr, *envto_hdr; + ok = FALSE; + for (rcpt_node = g_list_first(rcpt_list); rcpt_node; rcpt_node = g_list_next(rcpt_node)) { + GList *hdr_list; + address *rcpt = (address *) (rcpt_node->data); + address *env_addr = addr_find_ancestor(rcpt); + address *ret_path = msg->return_path; + header *retpath_hdr, *envto_hdr; - /* we need a private copy of the hdr list because we add headers here - that belong to the rcpt only. - g_list_copy copies only the nodes, so it is safe to - g_list_free it - */ - hdr_list = g_list_copy(msg->hdr_list); - retpath_hdr = create_header(HEAD_ENVELOPE_TO, - "Envelope-to: %s\n", addr_string(env_addr)); - envto_hdr = create_header(HEAD_RETURN_PATH, - "Return-path: %s\n", addr_string(ret_path)); - - hdr_list = g_list_prepend(hdr_list, envto_hdr); - hdr_list = g_list_prepend(hdr_list, retpath_hdr); + /* we need a private copy of the hdr list because we add headers here + that belong to the rcpt only. + g_list_copy copies only the nodes, so it is safe to + g_list_free it + */ + hdr_list = g_list_copy(msg->hdr_list); + retpath_hdr = create_header(HEAD_ENVELOPE_TO, "Envelope-to: %s\n", addr_string(env_addr)); + envto_hdr = create_header(HEAD_RETURN_PATH, "Return-path: %s\n", addr_string(ret_path)); - if(rcpt->local_part[0] == '|'){ - DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); - if(pipe_out(msg, hdr_list, rcpt, &(rcpt->local_part[1]), - (conf.pipe_fromline ? MSGSTR_FROMLINE : 0) | - (conf.pipe_fromhack ? MSGSTR_FROMHACK : 0))){ - logwrite(LOG_NOTICE, "%s => %s <%s@%s> with pipe\n", - msg->uid, rcpt->local_part, - env_addr->local_part, env_addr->domain - ); - addr_mark_delivered(rcpt); - ok = TRUE; - }else{ - if((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)){ - addr_mark_failed(rcpt); - }else{ - addr_mark_defered(rcpt); /* has no effect yet, - except that mail remains in spool */ - } - } - }else{ - /* figure out which mailbox type should be used for this user */ - gchar *user = rcpt->local_part; - gchar *mbox_type = conf.mbox_default; - - if(g_list_find_custom(conf.mbox_users, user, _g_list_strcasecmp) != NULL) - mbox_type = "mbox"; - else if(g_list_find_custom(conf.mda_users, user, _g_list_strcasecmp) != NULL) - mbox_type = "mda"; - else if(g_list_find_custom(conf.maildir_users, user, _g_list_strcasecmp) != NULL) - mbox_type = "maildir"; + hdr_list = g_list_prepend(hdr_list, envto_hdr); + hdr_list = g_list_prepend(hdr_list, retpath_hdr); - if(strcmp(mbox_type, "mbox") == 0){ - DEBUG(1) debugf("attempting to deliver %s with mbox\n", msg->uid); - if(append_file(msg, hdr_list, rcpt->local_part)){ - if(env_addr != rcpt){ - logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with mbox\n", - msg->uid, rcpt->local_part, rcpt->domain, - env_addr->local_part, env_addr->domain - ); - }else{ - logwrite(LOG_NOTICE, "%s => <%s@%s> with mbox\n", - msg->uid, rcpt->local_part, rcpt->domain); - } - addr_mark_delivered(rcpt); - ok = TRUE; - }else{ - if(errno != EAGAIN){ /* prevents 'Resource temporarily unavailable (11)' */ - addr_mark_failed(rcpt); - }else{ - addr_mark_defered(rcpt); - } - } + if (rcpt->local_part[0] == '|') { + DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); + if (pipe_out(msg, hdr_list, rcpt, &(rcpt->local_part[1]), + (conf.pipe_fromline ? MSGSTR_FROMLINE : 0) + | (conf.pipe_fromhack ? MSGSTR_FROMHACK : 0))) { + logwrite(LOG_NOTICE, "%s => %s <%s@%s> with pipe\n", msg->uid, rcpt->local_part, env_addr->local_part, env_addr->domain); + addr_mark_delivered(rcpt); + ok = TRUE; + } else { + if ((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)) { + addr_mark_failed(rcpt); + } else { + addr_mark_defered(rcpt); /* has no effect yet, except that mail remains in spool */ + } + } + } else { + /* figure out which mailbox type should be used for this user */ + gchar *user = rcpt->local_part; + gchar *mbox_type = conf.mbox_default; - }else if(strcmp(mbox_type, "mda") == 0){ - if(conf.mda){ - gchar *cmd = g_malloc(256); - GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); - - DEBUG(1) debugf("attempting to deliver %s with mda\n", msg->uid); - - if(expand(var_table, conf.mda, cmd, 256)){ - - if(pipe_out(msg, hdr_list, rcpt, cmd, - (conf.mda_fromline ? MSGSTR_FROMLINE : 0) | - (conf.mda_fromhack ? MSGSTR_FROMHACK : 0))){ - logwrite(LOG_NOTICE, "%s => %s@%s with mda (cmd = '%s')\n", - msg->uid, rcpt->local_part, rcpt->domain, cmd - ); - addr_mark_delivered(rcpt); - ok = TRUE; - }else{ - if((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)){ - addr_mark_failed(rcpt); - }else{ - addr_mark_defered(rcpt); /* has no effect yet, - except that mail remains in spool */ - } - } - }else - logwrite(LOG_ALERT, "could not expand string %s\n", conf.mda); - - destroy_table(var_table); - }else - logwrite(LOG_ALERT, "mbox type is mda, but no mda command given in configuration\n"); + if (g_list_find_custom (conf.mbox_users, user, _g_list_strcasecmp) != NULL) + mbox_type = "mbox"; + else if (g_list_find_custom (conf.mda_users, user, _g_list_strcasecmp) != NULL) + mbox_type = "mda"; + else if (g_list_find_custom (conf.maildir_users, user, _g_list_strcasecmp) != NULL) + mbox_type = "maildir"; + + if (strcmp(mbox_type, "mbox") == 0) { + DEBUG(1) debugf("attempting to deliver %s with mbox\n", msg->uid); + if (append_file(msg, hdr_list, rcpt->local_part)) { + if (env_addr != rcpt) { + logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with mbox\n", + msg->uid, rcpt->local_part, rcpt->domain, + env_addr->local_part, env_addr->domain); + } else { + logwrite(LOG_NOTICE, "%s => <%s@%s> with mbox\n", + msg->uid, rcpt->local_part, rcpt->domain); + } + addr_mark_delivered(rcpt); + ok = TRUE; + } else { + if (errno != EAGAIN) { /* prevents 'Resource temporarily unavailable (11)' */ + addr_mark_failed(rcpt); + } else { + addr_mark_defered(rcpt); + } + } + + } else if (strcmp(mbox_type, "mda") == 0) { + if (conf.mda) { + gchar *cmd = g_malloc(256); + GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); + + DEBUG(1) debugf("attempting to deliver %s with mda\n", msg->uid); + + if (expand(var_table, conf.mda, cmd, 256)) { + + if (pipe_out(msg, hdr_list, rcpt, cmd, (conf.mda_fromline ? MSGSTR_FROMLINE : 0) + | (conf.mda_fromhack ? MSGSTR_FROMHACK : 0))) { + logwrite(LOG_NOTICE, "%s => %s@%s with mda (cmd = '%s')\n", + msg->uid, rcpt->local_part, rcpt->domain, cmd); + addr_mark_delivered(rcpt); + ok = TRUE; + } else { + if ((errno != (1024 + EX_TEMPFAIL)) && (errno != EAGAIN)) { + addr_mark_failed(rcpt); + } else { + addr_mark_defered(rcpt); /* has no effect yet, except that mail remains in spool */ + } + } + } else + logwrite(LOG_ALERT, "could not expand string %s\n", conf.mda); + + destroy_table(var_table); + } else + logwrite(LOG_ALERT, "mbox type is mda, but no mda command given in configuration\n"); #ifdef ENABLE_MAILDIR - }else if(strcmp(mbox_type, "maildir") == 0){ - DEBUG(1) debugf("attempting to deliver %s with maildir\n", msg->uid); - if(maildir_out(msg, hdr_list, rcpt->local_part, 0)){ - if(env_addr != rcpt){ - logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with local\n", - msg->uid, rcpt->local_part, rcpt->domain, - env_addr->local_part, env_addr->domain - ); - }else{ - logwrite(LOG_NOTICE, "%s => <%s@%s> with maildir\n", - msg->uid, rcpt->local_part, rcpt->domain); - } - addr_mark_delivered(rcpt); - ok = TRUE; - }else - addr_mark_failed(rcpt); + } else if (strcmp(mbox_type, "maildir") == 0) { + DEBUG(1) debugf("attempting to deliver %s with maildir\n", msg->uid); + if (maildir_out(msg, hdr_list, rcpt->local_part, 0)) { + if (env_addr != rcpt) { + logwrite(LOG_NOTICE, "%s => %s@%s <%s@%s> with local\n", msg->uid, + rcpt->local_part, rcpt->domain, env_addr->local_part, env_addr->domain); + } else { + logwrite(LOG_NOTICE, "%s => <%s@%s> with maildir\n", msg->uid, + rcpt->local_part, rcpt->domain); + } + addr_mark_delivered(rcpt); + ok = TRUE; + } else + addr_mark_failed(rcpt); #endif - }else - logwrite(LOG_ALERT, "unknown mbox type '%s'\n", mbox_type); - } + } else + logwrite(LOG_ALERT, "unknown mbox type '%s'\n", mbox_type); + } - destroy_header(retpath_hdr); - destroy_header(envto_hdr); + destroy_header(retpath_hdr); + destroy_header(envto_hdr); - g_list_free(hdr_list); - } - ok_fail = delivery_failures(msg, rcpt_list, "%s (%d)", ext_strerror(errno), errno); + g_list_free(hdr_list); + } + ok_fail = delivery_failures(msg, rcpt_list, "%s (%d)", ext_strerror(errno), errno); - if(flag) msg_free_data(msg); - if(ok || ok_fail) deliver_finish(msgout); + if (flag) + msg_free_data(msg); + if (ok || ok_fail) + deliver_finish(msgout); - return ok; + return ok; } /* make a list of rcpt's of a message that are local return a new copy of the list */ -void msg_rcptlist_local(GList *rcpt_list, GList **p_local_list, GList **p_nonlocal_list) +void +msg_rcptlist_local(GList * rcpt_list, GList ** p_local_list, GList ** p_nonlocal_list) { - GList *rcpt_node; + GList *rcpt_node; - foreach(rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - GList *dom_node; + foreach(rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + GList *dom_node; - DEBUG(5) debugf("checking address %s\n", rcpt->address); + DEBUG(5) debugf("checking address %s\n", rcpt->address); - /* search for local host list: */ - foreach(conf.local_hosts, dom_node){ - if(strcasecmp(dom_node->data, rcpt->domain) == 0){ - *p_local_list = g_list_append(*p_local_list, rcpt); - DEBUG(5) debugf("<%s@%s> is local\n", rcpt->local_part, rcpt->domain); - break; - }else{ - *p_nonlocal_list = g_list_append(*p_nonlocal_list, rcpt); - } - } - } + /* search for local host list: */ + foreach(conf.local_hosts, dom_node) { + if (strcasecmp(dom_node->data, rcpt->domain) == 0) { + *p_local_list = g_list_append(*p_local_list, rcpt); + DEBUG(5) debugf("<%s@%s> is local\n", rcpt->local_part, rcpt->domain); + break; + } else { + *p_nonlocal_list = g_list_append(*p_nonlocal_list, rcpt); + } + } + } } -gboolean deliver_msglist_host_pipe(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) +gboolean +deliver_msglist_host_pipe(connect_route * route, GList * msgout_list, gchar * host, GList * res_list) { - gboolean ok = TRUE; - GList *msgout_node; + gboolean ok = TRUE; + GList *msgout_node; - DEBUG(5) debugf("deliver_msglist_host_pipe entered\n"); + DEBUG(5) debugf("deliver_msglist_host_pipe entered\n"); - if(route->pipe == NULL){ - logwrite(LOG_ALERT, "no pipe command given for route (protocol is pipe!)\n"); - return FALSE; - } + if (route->pipe == NULL) { + logwrite(LOG_ALERT, "no pipe command given for route (protocol is pipe!)\n"); + return FALSE; + } - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - gboolean flag, ok_msg = TRUE, ok_fail = FALSE; - message *msg = msgout->msg; - GList *rcpt_node, *rcpt_list = msgout->rcpt_list; + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + gboolean flag, ok_msg = TRUE, ok_fail = FALSE; + message *msg = msgout->msg; + GList *rcpt_node, *rcpt_list = msgout->rcpt_list; - DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); + DEBUG(1) debugf("attempting to deliver %s with pipe\n", msg->uid); - flag = (msg->data_list == NULL); - if(flag){ - if(!(ok_msg = spool_read_data(msg))){ - logwrite(LOG_ALERT, "could not open data spool file for %s\n", - msg->uid); - } - } - if(!ok_msg) continue; + flag = (msg->data_list == NULL); + if (flag) { + if (!(ok_msg = spool_read_data(msg))) { + logwrite(LOG_ALERT, "could not open data spool file for %s\n", msg->uid); + } + } + if (!ok_msg) + continue; - ok = FALSE; - foreach(rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - gchar *cmd = g_malloc(256); - GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); - - DEBUG(1) debugf("attempting to deliver %s to %s@%s with pipe\n", - msg->uid, rcpt->local_part, rcpt->domain); - - if(expand(var_table, route->pipe, cmd, 256)){ - - if(pipe_out(msg, msg->hdr_list, rcpt, cmd, - (route->pipe_fromline ? MSGSTR_FROMLINE : 0) | - (route->pipe_fromhack ? MSGSTR_FROMHACK : 0))){ - logwrite(LOG_NOTICE, "%s => %s@%s with pipe (cmd = '%s')\n", - msg->uid, rcpt->local_part, rcpt->domain, cmd - ); - addr_mark_delivered(rcpt); - ok = TRUE; - }else{ - logwrite(LOG_ALERT, "pipe_out '%s' failed\n", route->pipe); + ok = FALSE; + foreach(rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + gchar *cmd = g_malloc(256); + GList *var_table = var_table_rcpt(var_table_msg(NULL, msg), rcpt); - if(route->connect_error_fail){ - addr_mark_failed(rcpt); - }else{ - addr_mark_defered(rcpt); - } + DEBUG(1) debugf("attempting to deliver %s to %s@%s with pipe\n", msg->uid, rcpt->local_part, rcpt->domain); + + if (expand(var_table, route->pipe, cmd, 256)) { + + if (pipe_out(msg, msg->hdr_list, rcpt, cmd, (route->pipe_fromline ? MSGSTR_FROMLINE : 0) + | (route->pipe_fromhack ? MSGSTR_FROMHACK : 0))) { + logwrite(LOG_NOTICE, "%s => %s@%s with pipe (cmd = '%s')\n", + msg->uid, rcpt->local_part, rcpt->domain, cmd); + addr_mark_delivered(rcpt); + ok = TRUE; + } else { + logwrite(LOG_ALERT, "pipe_out '%s' failed\n", route->pipe); + + if (route->connect_error_fail) { + addr_mark_failed(rcpt); + } else { + addr_mark_defered(rcpt); + } + } + } else + logwrite(LOG_ALERT, "could not expand string %s\n", route->pipe); + + destroy_table(var_table); + } + ok_fail = delivery_failures(msg, rcpt_list, "%s", strerror(errno)); + + if (flag) + msg_free_data(msg); + + if (ok || ok_fail) + deliver_finish(msgout); } - }else - logwrite(LOG_ALERT, "could not expand string %s\n", route->pipe); - - destroy_table(var_table); - } - ok_fail = delivery_failures(msg, rcpt_list, "%s", strerror(errno)); - if(flag) msg_free_data(msg); - - if(ok || ok_fail) deliver_finish(msgout); - } - - return ok; + return ok; } /* deliver list of messages to one host - and finishes them if the message was delivered to at least one - rcpt. - Returns TRUE if at least one msg was delivered to at least one - rcpt. + and finishes them if the message was delivered to at least one rcpt. + Returns TRUE if at least one msg was delivered to at least one rcpt. */ -gboolean deliver_msglist_host_smtp(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) +gboolean +deliver_msglist_host_smtp(connect_route * route, GList * msgout_list, gchar * host, GList * res_list) { - gboolean ok = FALSE; - GList *msgout_node; - smtp_base *psb; - gint port; - - /* paranoid check: */ - if(msgout_list == NULL){ - logwrite(LOG_ALERT, - "Ooops: empty list of messages in deliver_msglist_host()\n"); - return FALSE; - } + gboolean ok = FALSE; + GList *msgout_node; + smtp_base *psb; + gint port; - if(host == NULL){ - host = route->mail_host->address; - port = route->mail_host->port; - }else - port = conf.remote_port; - + /* paranoid check: */ + if (msgout_list == NULL) { + logwrite(LOG_ALERT, "Ooops: empty list of messages in deliver_msglist_host()\n"); + return FALSE; + } + + if (host == NULL) { + host = route->mail_host->address; + port = route->mail_host->port; + } else + port = conf.remote_port; + #ifdef ENABLE_POP3 - if(route->pop3_login){ - if(!(pop_before_smtp(route->pop3_login))) - return FALSE; - } + if (route->pop3_login) { + if (!(pop_before_smtp(route->pop3_login))) + return FALSE; + } #endif - if((psb = (route->wrapper ? - smtp_out_open_child(route->wrapper) : - smtp_out_open(host, port, res_list)))){ + if ((psb = (route->wrapper ? smtp_out_open_child(route->wrapper) : smtp_out_open(host, port, res_list)))) { - if(route->wrapper) psb->remote_host = host; + if (route->wrapper) + psb->remote_host = host; - set_heloname(psb, - route->helo_name ? route->helo_name : conf.host_name, - route->do_correct_helo); + set_heloname(psb, route->helo_name ? route->helo_name : conf.host_name, route->do_correct_helo); #ifdef ENABLE_AUTH - if((route->auth_name) && (route->auth_login) && (route->auth_secret)) - set_auth(psb, route->auth_name, route->auth_login, route->auth_secret); + if ((route->auth_name) && (route->auth_login) + && (route->auth_secret)) + set_auth(psb, route->auth_name, route->auth_login, route->auth_secret); #endif - if(smtp_out_init(psb)){ + if (smtp_out_init(psb)) { - if(!route->do_pipelining) psb->use_pipelining = FALSE; + if (!route->do_pipelining) + psb->use_pipelining = FALSE; - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - gboolean flag, ok_msg = FALSE, ok_fail = FALSE; - message *msg = msgout->msg; + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + gboolean flag, ok_msg = FALSE, ok_fail = FALSE; + message *msg = msgout->msg; - /* we may have to read the data at this point - and remember if we did */ - flag = (msg->data_list == NULL); - if(flag){ - if(!spool_read_data(msg)){ - logwrite(LOG_ALERT, "could not open data spool file %s\n", - msg->uid); - break; - } + /* we may have to read the data at this point + and remember if we did */ + flag = (msg->data_list == NULL); + if (flag) { + if (!spool_read_data(msg)) { + logwrite(LOG_ALERT, "could not open data spool file %s\n", msg->uid); + break; + } + } + + smtp_out_msg(psb, msg, msgout->return_path, msgout->rcpt_list, msgout->hdr_list); + + ok_fail = delivery_failures(msg, msgout->rcpt_list, "while connected with %s, the server replied\n\t%s", host, psb->buffer); + + if ((psb->error == smtp_eof) + || (psb->error == smtp_timeout)) { + /* connection lost */ + break; + } else if (psb->error != smtp_ok) { + if (g_list_next(msgout_node) != NULL) + if (!smtp_out_rset(psb)) + break; + } + ok_msg = (psb->error == smtp_ok); + + if (flag) + msg_free_data(msg); + if (ok_msg) + ok = TRUE; + if (ok_msg || ok_fail) { + deliver_finish(msgout); + } + } + if (psb->error == smtp_ok || (psb->error == smtp_fail) + || (psb->error == smtp_trylater) || (psb->error == smtp_syntax)) { + smtp_out_quit(psb); + } + } else { + /* smtp_out_init() failed */ + if ((psb->error == smtp_fail) || (psb->error == smtp_trylater) || (psb->error == smtp_syntax)) { + smtp_out_quit(psb); + + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + smtp_out_mark_rcpts(psb, msgout->rcpt_list); + + if (delivery_failures(msgout->msg, msgout->rcpt_list, + "while connected with %s, the server replied\n\t%s", host, psb->buffer)) + deliver_finish(msgout); + } + } + } + destroy_smtpbase(psb); + } else { + /* smtp_out_open() failed */ + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + GList *rcpt_node; + + for (rcpt_node = g_list_first(msgout->rcpt_list); rcpt_node; rcpt_node = g_list_next(rcpt_node)) { + address *rcpt = (address *) (rcpt_node->data); + + addr_unmark_delivered(rcpt); + if (route->connect_error_fail) { + addr_mark_failed(rcpt); + } else { + addr_mark_defered(rcpt); + } + if (route->wrapper + ? delivery_failures(msgout->msg, msgout->rcpt_list, + "could not open wrapper:\n\t%s", + strerror(errno)) + : delivery_failures(msgout->msg, msgout->rcpt_list, + "could not open connection to %s:%d :\n\t%s", + host, port, h_errno != 0 ? hstrerror(h_errno) : strerror(errno))) + deliver_finish(msgout); + } + } } - - smtp_out_msg(psb, msg, - msgout->return_path, msgout->rcpt_list, msgout->hdr_list); - - ok_fail = delivery_failures(msg, msgout->rcpt_list, - "while connected with %s, the server replied\n\t%s", - host, psb->buffer); - - if((psb->error == smtp_eof) || - (psb->error == smtp_timeout)){ - /* connection lost */ - break; - } - else if(psb->error != smtp_ok){ - if(g_list_next(msgout_node) != NULL) - if(!smtp_out_rset(psb)) - break; - } - ok_msg = (psb->error == smtp_ok); - - if(flag) msg_free_data(msg); - if(ok_msg) ok = TRUE; - if(ok_msg || ok_fail){ - deliver_finish(msgout); - } - } - if(psb->error == smtp_ok || - (psb->error == smtp_fail) || - (psb->error == smtp_trylater) || - (psb->error == smtp_syntax)){ - - smtp_out_quit(psb); - } - }else{ - /* smtp_out_init() failed */ - if((psb->error == smtp_fail) || - (psb->error == smtp_trylater) || - (psb->error == smtp_syntax)){ - smtp_out_quit(psb); - - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - smtp_out_mark_rcpts(psb, msgout->rcpt_list); - - if(delivery_failures(msgout->msg, msgout->rcpt_list, - "while connected with %s, the server replied\n\t%s", - host, psb->buffer)) - deliver_finish(msgout); - } - } - } - destroy_smtpbase(psb); - }else{ - /* smtp_out_open() failed */ - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - GList *rcpt_node; - - for(rcpt_node = g_list_first(msgout->rcpt_list); - rcpt_node; - rcpt_node = g_list_next(rcpt_node)){ - address *rcpt = (address *)(rcpt_node->data); - - addr_unmark_delivered(rcpt); - if(route->connect_error_fail){ - addr_mark_failed(rcpt); - }else{ - addr_mark_defered(rcpt); - } - if(route->wrapper ? - delivery_failures(msgout->msg, msgout->rcpt_list, - "could not open wrapper:\n\t%s", - strerror(errno)) : - delivery_failures(msgout->msg, msgout->rcpt_list, - "could not open connection to %s:%d :\n\t%s", - host, port, h_errno != 0 ? hstrerror(h_errno) : strerror(errno))) - deliver_finish(msgout); - } - } - } - return ok; + return ok; } -gboolean deliver_msglist_host(connect_route *route, GList *msgout_list, gchar *host, GList *res_list) +gboolean +deliver_msglist_host(connect_route * route, GList * msgout_list, gchar * host, GList * res_list) { - DEBUG(5) debugf("protocol = %s\n", route->protocol); + DEBUG(5) debugf("protocol = %s\n", route->protocol); - if(strcmp(route->protocol, "pipe") == 0){ - return deliver_msglist_host_pipe(route, msgout_list, host, res_list); - }else{ - return deliver_msglist_host_smtp(route, msgout_list, host, res_list); - } + if (strcmp(route->protocol, "pipe") == 0) { + return deliver_msglist_host_pipe(route, msgout_list, host, res_list); + } else { + return deliver_msglist_host_smtp(route, msgout_list, host, res_list); + } } /* delivers messages in msgout_list using route */ -gboolean deliver_route_msgout_list(connect_route *route, GList *msgout_list) +gboolean +deliver_route_msgout_list(connect_route * route, GList * msgout_list) { - gboolean ok = FALSE; + gboolean ok = FALSE; - DEBUG(5) debugf("deliver_route_msgout_list entered, route->name = %s\n", - route->name); + DEBUG(5) + debugf("deliver_route_msgout_list entered, route->name = %s\n", route->name); - if(route->mail_host != NULL){ - /* this is easy... */ - if(deliver_msglist_host(route, msgout_list, - NULL, route->resolve_list)) - ok = TRUE; - - }else{ - /* this is not easy... */ - GList *mo_ph_list; + if (route->mail_host != NULL) { + /* this is easy... */ + if (deliver_msglist_host(route, msgout_list, NULL, route->resolve_list)) + ok = TRUE; - mo_ph_list = route_msgout_list(route, msgout_list); - /* okay, now we have ordered our messages by the hosts. */ - if(mo_ph_list != NULL){ - GList *mo_ph_node; - /* TODO: It would be nice to be able to fork for each host. - We cannot do that yet because of complications with finishing the - messages. Threads could be a solution because they use the same - memory. But we are not thread safe yet... - */ - foreach(mo_ph_list, mo_ph_node){ - msgout_perhost *mo_ph = (msgout_perhost *)(mo_ph_node->data); - if(deliver_msglist_host(route, mo_ph->msgout_list, - mo_ph->host, route->resolve_list)) - ok = TRUE; + } else { + /* this is not easy... */ + GList *mo_ph_list; - destroy_msgout_perhost(mo_ph); - } - g_list_free(mo_ph_list); - } - } - return ok; + mo_ph_list = route_msgout_list(route, msgout_list); + /* okay, now we have ordered our messages by the hosts. */ + if (mo_ph_list != NULL) { + GList *mo_ph_node; + /* TODO: It would be nice to be able to fork for each host. + We cannot do that yet because of complications with finishing the + messages. Threads could be a solution because they use the same + memory. But we are not thread safe yet... + */ + foreach(mo_ph_list, mo_ph_node) { + msgout_perhost *mo_ph = (msgout_perhost *) (mo_ph_node->data); + if (deliver_msglist_host (route, mo_ph->msgout_list, mo_ph->host, route->resolve_list)) + ok = TRUE; + + destroy_msgout_perhost(mo_ph); + } + g_list_free(mo_ph_list); + } + } + return ok; } /* @@ -532,85 +510,86 @@ delivers messages in msg_list using route by calling deliver_route_msgout_list() */ -gboolean deliver_route_msg_list(connect_route *route, GList *msgout_list) +gboolean +deliver_route_msg_list(connect_route * route, GList * msgout_list) { - GList *msgout_list_deliver = NULL; - GList *msgout_node; - gboolean ok = TRUE; + GList *msgout_list_deliver = NULL; + GList *msgout_node; + gboolean ok = TRUE; - DEBUG(6) debugf("deliver_route_msg_list()\n"); + DEBUG(6) debugf("deliver_route_msg_list()\n"); - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - msg_out *msgout_cloned = clone_msg_out(msgout); - GList *rcpt_list_non_delivered = NULL; - GList *rcpt_node; + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + msg_out *msgout_cloned = clone_msg_out(msgout); + GList *rcpt_list_non_delivered = NULL; + GList *rcpt_node; - /* we have to delete already delivered rcpt's - because a previous route may have delivered to it */ - foreach(msgout_cloned->rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - /* failed addresses already have been bounced - - there should be a better way to handle those.*/ - if(!addr_is_delivered(rcpt) && !addr_is_failed(rcpt) && !(rcpt->flags & ADDR_FLAG_LAST_ROUTE)) - rcpt_list_non_delivered = g_list_append(rcpt_list_non_delivered, rcpt); - } - g_list_free(msgout_cloned->rcpt_list); - msgout_cloned->rcpt_list = rcpt_list_non_delivered; + /* we have to delete already delivered rcpt's + because a previous route may have delivered to it */ + foreach(msgout_cloned->rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + /* failed addresses already have been bounced + - there should be a better way to handle those. */ + if (!addr_is_delivered(rcpt) && !addr_is_failed(rcpt) + && !(rcpt->flags & ADDR_FLAG_LAST_ROUTE)) + rcpt_list_non_delivered = g_list_append(rcpt_list_non_delivered, rcpt); + } + g_list_free(msgout_cloned->rcpt_list); + msgout_cloned->rcpt_list = rcpt_list_non_delivered; - if(msgout_cloned->rcpt_list){ - if(route_is_allowed_mail_local(route, msgout->msg->return_path) && - route_is_allowed_return_path(route, msgout->msg->return_path)){ - GList *rcpt_list_allowed = NULL, *rcpt_list_notallowed = NULL; - msg_rcptlist_route(route, msgout_cloned->rcpt_list, - &rcpt_list_allowed, &rcpt_list_notallowed); - - if(rcpt_list_allowed != NULL){ - logwrite(LOG_NOTICE, "%s using '%s'\n", msgout->msg->uid, route->name); + if (msgout_cloned->rcpt_list) { + if (route_is_allowed_mail_local(route, msgout->msg->return_path) + && route_is_allowed_return_path(route, msgout->msg-> return_path)) { + GList *rcpt_list_allowed = NULL, *rcpt_list_notallowed = NULL; + msg_rcptlist_route(route, msgout_cloned->rcpt_list, &rcpt_list_allowed, &rcpt_list_notallowed); - g_list_free(msgout_cloned->rcpt_list); - msgout_cloned->rcpt_list = rcpt_list_allowed; - - if(route->last_route){ - GList *rcpt_node; - foreach(msgout_cloned->rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - rcpt->flags |= ADDR_FLAG_LAST_ROUTE; - } - } + if (rcpt_list_allowed != NULL) { + logwrite(LOG_NOTICE, "%s using '%s'\n", msgout->msg->uid, route->name); - route_prepare_msgout(route, msgout_cloned); - msgout_list_deliver = g_list_append(msgout_list_deliver, msgout_cloned); - }else - destroy_msg_out(msgout_cloned); - } - else - destroy_msg_out(msgout_cloned); - }else - destroy_msg_out(msgout_cloned); - } + g_list_free(msgout_cloned->rcpt_list); + msgout_cloned->rcpt_list = rcpt_list_allowed; - if(msgout_list_deliver != NULL){ - if(deliver_route_msgout_list(route, msgout_list_deliver)) - ok = TRUE; - destroy_msg_out_list(msgout_list_deliver); - } - return ok; + if (route->last_route) { + GList *rcpt_node; + foreach(msgout_cloned->rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + rcpt->flags |= ADDR_FLAG_LAST_ROUTE; + } + } + + route_prepare_msgout(route, msgout_cloned); + msgout_list_deliver = g_list_append(msgout_list_deliver, msgout_cloned); + } else + destroy_msg_out(msgout_cloned); + } else + destroy_msg_out(msgout_cloned); + } else + destroy_msg_out(msgout_cloned); + } + + if (msgout_list_deliver != NULL) { + if (deliver_route_msgout_list(route, msgout_list_deliver)) + ok = TRUE; + destroy_msg_out_list(msgout_list_deliver); + } + return ok; } /* copy pointers of delivered addresses to the msg's non_rcpt_list, to make sure that they will not be delivered again. */ -void update_non_rcpt_list(msg_out *msgout) +void +update_non_rcpt_list(msg_out * msgout) { - GList *rcpt_node; - message *msg = msgout->msg; + GList *rcpt_node; + message *msg = msgout->msg; - foreach(msgout->rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - if(addr_is_delivered(rcpt) || addr_is_failed(rcpt)) - msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, rcpt); - } + foreach(msgout->rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + if (addr_is_delivered(rcpt) || addr_is_failed(rcpt)) + msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, rcpt); + } } /* after delivery attempts, we check if there are any @@ -621,209 +600,213 @@ returns TRUE if all went well. */ -gboolean deliver_finish(msg_out *msgout) +gboolean +deliver_finish(msg_out * msgout) { - GList *rcpt_node; - gboolean ok = FALSE; - message *msg = msgout->msg; - gboolean finished = TRUE; + GList *rcpt_node; + gboolean ok = FALSE; + message *msg = msgout->msg; + gboolean finished = TRUE; - update_non_rcpt_list(msgout); + update_non_rcpt_list(msgout); - /* we NEVER made copies of the addresses, flags affecting addresses - were always set on the original address structs */ - foreach(msg->rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - if(!addr_is_finished_children(rcpt)) - finished = FALSE; - else{ - /* if ALL children have been delivered, - mark parent as delivered. - if there is one or more not delivered, - it must have failed, we mark the parent as failed as well. - */ - if(addr_is_delivered_children(rcpt)){ - addr_mark_delivered(rcpt); - }else{ - addr_mark_failed(rcpt); - } - } - } - - if(!finished){ - /* one not delivered address was found */ - if(spool_write(msg, FALSE)){ - ok = TRUE; - DEBUG(2) debugf("spool header for %s written back.\n", msg->uid); - }else - logwrite(LOG_ALERT, "could not write back spool header for %s\n", - msg->uid); - }else{ - ok = spool_delete_all(msg); - if(ok) - logwrite(LOG_NOTICE, "%s completed.\n", msg->uid); - } - return ok; + /* we NEVER made copies of the addresses, flags affecting addresses + were always set on the original address structs */ + foreach(msg->rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + if (!addr_is_finished_children(rcpt)) + finished = FALSE; + else { + /* if ALL children have been delivered, + mark parent as delivered. + if there is one or more not delivered, + it must have failed, we mark the parent as failed as well. + */ + if (addr_is_delivered_children(rcpt)) { + addr_mark_delivered(rcpt); + } else { + addr_mark_failed(rcpt); + } + } + } + + if (!finished) { + /* one not delivered address was found */ + if (spool_write(msg, FALSE)) { + ok = TRUE; + DEBUG(2) debugf("spool header for %s written back.\n", msg->uid); + } else + logwrite(LOG_ALERT, "could not write back spool header for %s\n", msg->uid); + } else { + ok = spool_delete_all(msg); + if (ok) + logwrite(LOG_NOTICE, "%s completed.\n", msg->uid); + } + return ok; } -gboolean deliver_finish_list(GList *msgout_list) +gboolean +deliver_finish_list(GList * msgout_list) { - gboolean ok = TRUE; - GList *msgout_node; - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - if(!deliver_finish(msgout)) - ok = FALSE; - } - return ok; -} - -gboolean deliver_msgout_list_online(GList *msgout_list) -{ - GList *rf_list = NULL; - gchar *connect_name = detect_online(); - gboolean ok = FALSE; - - if(connect_name != NULL){ - logwrite(LOG_NOTICE, "detected online configuration %s\n", connect_name); - /* we are online! */ - rf_list = (GList *)table_find(conf.connect_routes, connect_name); - if(rf_list != NULL){ - GList *route_list = read_route_list(rf_list, FALSE); - if(route_list){ - GList *route_node; - foreach(route_list, route_node){ - connect_route *route = (connect_route *)(route_node->data); - ok = deliver_route_msg_list(route, msgout_list); + gboolean ok = TRUE; + GList *msgout_node; + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + if (!deliver_finish(msgout)) + ok = FALSE; } - destroy_route_list(route_list); - } - else - logwrite(LOG_ALERT, - "could not read route list '%s'\n", connect_name); - }else{ - logwrite(LOG_ALERT, "route list with name '%s' not found.\n", connect_name); - } - } - return ok; + return ok; } -gboolean deliver_msg_list(GList *msg_list, guint flags){ - GList *msgout_list = create_msg_out_list(msg_list); - GList *local_msgout_list = NULL, *localnet_msgout_list = NULL, *other_msgout_list = NULL; - GList *msgout_node; - GList *alias_table = NULL; - gboolean ok = TRUE; +gboolean +deliver_msgout_list_online(GList * msgout_list) +{ + GList *rf_list = NULL; + gchar *connect_name = detect_online(); + gboolean ok = FALSE; - if(conf.alias_file){ - if(!(alias_table = table_read(conf.alias_file, ':'))) - return FALSE; - } - - /* sort messages for different deliveries */ - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - GList *rcpt_list; - GList *local_rcpt_list = NULL; - GList *localnet_rcpt_list = NULL; - GList *other_rcpt_list; + if (connect_name != NULL) { + logwrite(LOG_NOTICE, "detected online configuration %s\n", connect_name); + /* we are online! */ + rf_list = (GList *) table_find(conf.connect_routes, connect_name); + if (rf_list != NULL) { + GList *route_list = read_route_list(rf_list, FALSE); + if (route_list) { + GList *route_node; + foreach(route_list, route_node) { + connect_route *route = (connect_route *) (route_node->data); + ok = deliver_route_msg_list(route, msgout_list); + } + destroy_route_list(route_list); + } else + logwrite(LOG_ALERT, "could not read route list '%s'\n", connect_name); + } else { + logwrite(LOG_ALERT, "route list with name '%s' not found.\n", connect_name); + } + } + return ok; +} - if(!spool_lock(msgout->msg->uid)) continue; +gboolean +deliver_msg_list(GList * msg_list, guint flags) +{ + GList *msgout_list = create_msg_out_list(msg_list); + GList *local_msgout_list = NULL, *localnet_msgout_list = NULL, *other_msgout_list = NULL; + GList *msgout_node; + GList *alias_table = NULL; + gboolean ok = TRUE; - rcpt_list = g_list_copy(msgout->msg->rcpt_list); - if(conf.log_user){ - address *addr = create_address_qualified(conf.log_user, TRUE, conf.host_name); - if(addr) - rcpt_list = g_list_prepend(rcpt_list, addr); - } - if(alias_table){ - GList *aliased_rcpt_list; - aliased_rcpt_list = alias_expand(alias_table, rcpt_list, - msgout->msg->non_rcpt_list); - g_list_free(rcpt_list); - rcpt_list = aliased_rcpt_list; - } + if (conf.alias_file) { + if (!(alias_table = table_read(conf.alias_file, ':'))) + return FALSE; + } - /* local recipients */ - other_rcpt_list = NULL; - rcptlist_with_addr_is_local(rcpt_list, &local_rcpt_list, &other_rcpt_list); - - if(flags & DLVR_LOCAL){ - if(local_rcpt_list != NULL){ - msg_out *local_msgout = clone_msg_out(msgout); - local_msgout->rcpt_list = local_rcpt_list; - local_msgout_list = g_list_append(local_msgout_list, local_msgout); - } - } + /* sort messages for different deliveries */ + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + GList *rcpt_list; + GList *local_rcpt_list = NULL; + GList *localnet_rcpt_list = NULL; + GList *other_rcpt_list; - g_list_free(rcpt_list); + if (!spool_lock(msgout->msg->uid)) + continue; - /* local net recipients */ - rcpt_list = other_rcpt_list; - other_rcpt_list = NULL; - rcptlist_with_one_of_hostlist(rcpt_list, conf.local_nets, - &localnet_rcpt_list, &other_rcpt_list); + rcpt_list = g_list_copy(msgout->msg->rcpt_list); + if (conf.log_user) { + address *addr = create_address_qualified(conf.log_user, TRUE, conf.host_name); + if (addr) + rcpt_list = g_list_prepend(rcpt_list, addr); + } + if (alias_table) { + GList *aliased_rcpt_list; + aliased_rcpt_list = alias_expand(alias_table, rcpt_list, msgout->msg->non_rcpt_list); + g_list_free(rcpt_list); + rcpt_list = aliased_rcpt_list; + } - if(flags & DLVR_LAN){ - if(localnet_rcpt_list != NULL){ - msg_out *localnet_msgout = clone_msg_out(msgout); - localnet_msgout->rcpt_list = localnet_rcpt_list; - localnet_msgout_list = g_list_append(localnet_msgout_list, localnet_msgout); - } - } + /* local recipients */ + other_rcpt_list = NULL; + rcptlist_with_addr_is_local(rcpt_list, &local_rcpt_list, &other_rcpt_list); - if(flags & DLVR_ONLINE){ - /* the rest, this is online delivery */ - if(other_rcpt_list != NULL){ - msg_out *other_msgout = clone_msg_out(msgout); - other_msgout->rcpt_list = other_rcpt_list; - other_msgout_list = g_list_append(other_msgout_list, other_msgout); - } - } - } + if (flags & DLVR_LOCAL) { + if (local_rcpt_list != NULL) { + msg_out *local_msgout = clone_msg_out(msgout); + local_msgout->rcpt_list = local_rcpt_list; + local_msgout_list = g_list_append(local_msgout_list, local_msgout); + } + } - if(alias_table) - destroy_table(alias_table); + g_list_free(rcpt_list); - /* actual delivery */ - if(local_msgout_list != NULL){ - foreach(local_msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - if(!deliver_local(msgout)) ok = FALSE; - } - destroy_msg_out_list(local_msgout_list); - } + /* local net recipients */ + rcpt_list = other_rcpt_list; + other_rcpt_list = NULL; + rcptlist_with_one_of_hostlist(rcpt_list, conf.local_nets, &localnet_rcpt_list, &other_rcpt_list); - if(localnet_msgout_list != NULL){ - GList *route_list = NULL; - GList *route_node; + if (flags & DLVR_LAN) { + if (localnet_rcpt_list != NULL) { + msg_out *localnet_msgout = clone_msg_out(msgout); + localnet_msgout->rcpt_list = localnet_rcpt_list; + localnet_msgout_list = g_list_append(localnet_msgout_list, localnet_msgout); + } + } - if(conf.local_net_routes) - route_list = read_route_list(conf.local_net_routes, TRUE); - else - route_list = g_list_append(NULL, create_local_route()); + if (flags & DLVR_ONLINE) { + /* the rest, this is online delivery */ + if (other_rcpt_list != NULL) { + msg_out *other_msgout = clone_msg_out(msgout); + other_msgout->rcpt_list = other_rcpt_list; + other_msgout_list = g_list_append(other_msgout_list, other_msgout); + } + } + } - foreach(route_list, route_node){ - connect_route *route = (connect_route *)(route_node->data); - if(!deliver_route_msg_list(route, localnet_msgout_list)) ok = FALSE; - } - destroy_msg_out_list(localnet_msgout_list); - destroy_route_list(route_list); - } + if (alias_table) + destroy_table(alias_table); - if(other_msgout_list != NULL){ - if(!deliver_msgout_list_online(other_msgout_list)) ok = FALSE; - destroy_msg_out_list(other_msgout_list); - } + /* actual delivery */ + if (local_msgout_list != NULL) { + foreach(local_msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + if (!deliver_local(msgout)) + ok = FALSE; + } + destroy_msg_out_list(local_msgout_list); + } - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - spool_unlock(msgout->msg->uid); - } + if (localnet_msgout_list != NULL) { + GList *route_list = NULL; + GList *route_node; - destroy_msg_out_list(msgout_list); + if (conf.local_net_routes) + route_list = read_route_list(conf.local_net_routes, TRUE); + else + route_list = g_list_append(NULL, create_local_route()); - return ok; + foreach(route_list, route_node) { + connect_route *route = (connect_route *) (route_node->data); + if (!deliver_route_msg_list(route, localnet_msgout_list)) + ok = FALSE; + } + destroy_msg_out_list(localnet_msgout_list); + destroy_route_list(route_list); + } + + if (other_msgout_list != NULL) { + if (!deliver_msgout_list_online(other_msgout_list)) + ok = FALSE; + destroy_msg_out_list(other_msgout_list); + } + + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + spool_unlock(msgout->msg->uid); + } + + destroy_msg_out_list(msgout_list); + + return ok; } /* This function searches in the list of rcpt addresses @@ -834,16 +817,14 @@ deliver() is called when a message has just been received and should be delivered immediately. */ -gboolean deliver(message *msg) +gboolean +deliver(message * msg) { - gboolean ok; + gboolean ok; + GList *msg_list = g_list_append(NULL, msg); - GList *msg_list = g_list_append(NULL, msg); + ok = deliver_msg_list(msg_list, DLVR_ALL); + g_list_free(msg_list); - ok = deliver_msg_list(msg_list, DLVR_ALL); - - g_list_free(msg_list); - - return ok; + return ok; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/dotlock.c --- a/src/dotlock.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/dotlock.c Mon Oct 27 16:23:10 2008 +0100 @@ -29,52 +29,52 @@ #include "masqmail.h" #include "dotlock.h" -gboolean dot_lock(gchar *lock_name, gchar *hitch_name) +gboolean +dot_lock(gchar * lock_name, gchar * hitch_name) { - gboolean ok = FALSE; - int fd; + gboolean ok = FALSE; + int fd; - fd = open(hitch_name, O_WRONLY | O_CREAT | O_EXCL, 0); - if(fd != -1){ - struct stat stat_buf; + fd = open(hitch_name, O_WRONLY | O_CREAT | O_EXCL, 0); + if (fd != -1) { + struct stat stat_buf; - close(fd); - link(hitch_name, lock_name); - if(stat(hitch_name, &stat_buf) == 0){ - if(stat_buf.st_nlink == 2){ - unlink(hitch_name); - ok = TRUE; - } - else{ - if(stat(lock_name, &stat_buf) == 0){ - if((time(NULL) - stat_buf.st_mtime) > MAX_LOCKAGE){ - /* remove lock if uncredibly old */ - unlink(lock_name); + close(fd); + link(hitch_name, lock_name); + if (stat(hitch_name, &stat_buf) == 0) { + if (stat_buf.st_nlink == 2) { + unlink(hitch_name); + ok = TRUE; + } else { + if (stat(lock_name, &stat_buf) == 0) { + if ((time(NULL) - stat_buf.st_mtime) > MAX_LOCKAGE) { + /* remove lock if uncredibly old */ + unlink(lock_name); - link(hitch_name, lock_name); - if(stat(hitch_name, &stat_buf) == 0){ - if(stat_buf.st_nlink == 2){ - unlink(hitch_name); - ok = TRUE; - } - } - } - } - } - } - if(!ok){ - unlink(hitch_name); - } - }else - logwrite(LOG_WARNING, "could not create lock file %s: %s\n", - lock_name, strerror(errno)); + link(hitch_name, lock_name); + if (stat(hitch_name, &stat_buf) == 0) { + if (stat_buf.st_nlink == 2) { + unlink(hitch_name); + ok = TRUE; + } + } + } + } + } + } + if (!ok) { + unlink(hitch_name); + } + } else + logwrite(LOG_WARNING, "could not create lock file %s: %s\n", lock_name, strerror(errno)); - return ok; + return ok; } -gboolean dot_unlock(gchar *lock_name) +gboolean +dot_unlock(gchar * lock_name) { - unlink(lock_name); + unlink(lock_name); - return TRUE; + return TRUE; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/dotlock.h --- a/src/dotlock.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/dotlock.h Mon Oct 27 16:23:10 2008 +0100 @@ -18,5 +18,5 @@ #define MAX_LOCKAGE 300 -gboolean dot_lock(gchar *lock_name, gchar *hitch_name); -gboolean dot_unlock(gchar *lock_name); +gboolean dot_lock(gchar * lock_name, gchar * hitch_name); +gboolean dot_unlock(gchar * lock_name); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/expand.c --- a/src/expand.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/expand.c Mon Oct 27 16:23:10 2008 +0100 @@ -20,106 +20,110 @@ #define MAX_VAR 50 -GList *var_table_rcpt(GList *var_table, address *rcpt) +GList* +var_table_rcpt(GList * var_table, address * rcpt) { - gchar *tmp_str; - - var_table = g_list_prepend(var_table, create_pair_string("rcpt_local", rcpt->local_part)); - var_table = g_list_prepend(var_table, create_pair_string("rcpt_domain", rcpt->domain)); - - tmp_str = g_strdup_printf("%s@%s", rcpt->local_part, rcpt->domain); - var_table = g_list_prepend(var_table, create_pair_string("rcpt", tmp_str)); - g_free(tmp_str); + gchar *tmp_str; - return var_table; + var_table = g_list_prepend(var_table, create_pair_string("rcpt_local", rcpt->local_part)); + var_table = g_list_prepend(var_table, create_pair_string("rcpt_domain", rcpt->domain)); + + tmp_str = g_strdup_printf("%s@%s", rcpt->local_part, rcpt->domain); + var_table = g_list_prepend(var_table, create_pair_string("rcpt", tmp_str)); + g_free(tmp_str); + + return var_table; } -GList *var_table_msg(GList *var_table, message *msg) +GList* +var_table_msg(GList * var_table, message * msg) { - address *ret_path = msg->return_path; - gchar *tmp_str; - - var_table = g_list_prepend(var_table, create_pair_string("uid", msg->uid)); - var_table = g_list_prepend(var_table, create_pair_string("received_host", - msg->received_host ? msg->received_host : "")); - var_table = g_list_prepend(var_table, create_pair_string("ident", msg->ident ? msg->ident : "")); - var_table = g_list_prepend(var_table, create_pair_string("return_path_local", ret_path->local_part)); - var_table = g_list_prepend(var_table, create_pair_string("return_path_domain", ret_path->domain)); - - tmp_str = g_strdup_printf("%s@%s", ret_path->local_part, ret_path->domain); - var_table = g_list_prepend(var_table, create_pair_string("return_path", tmp_str)); - g_free(tmp_str); + address *ret_path = msg->return_path; + gchar *tmp_str; - return var_table; + var_table = g_list_prepend(var_table, create_pair_string("uid", msg->uid)); + var_table = g_list_prepend(var_table, create_pair_string("received_host", msg->received_host ? msg->received_host : "")); + var_table = g_list_prepend(var_table, create_pair_string("ident", msg->ident ? msg->ident : "")); + var_table = g_list_prepend(var_table, create_pair_string("return_path_local", ret_path->local_part)); + var_table = g_list_prepend(var_table, create_pair_string("return_path_domain", ret_path->domain)); + + tmp_str = g_strdup_printf("%s@%s", ret_path->local_part, ret_path->domain); + var_table = g_list_prepend(var_table, create_pair_string("return_path", tmp_str)); + g_free(tmp_str); + + return var_table; } -GList *var_table_conf(GList *var_table) +GList* +var_table_conf(GList * var_table) { - var_table = g_list_prepend(var_table, create_pair_string("host_name", conf.host_name)); - var_table = g_list_prepend(var_table, create_pair_string("package", PACKAGE)); - var_table = g_list_prepend(var_table, create_pair_string("version", VERSION)); + var_table = g_list_prepend(var_table, create_pair_string("host_name", conf.host_name)); + var_table = g_list_prepend(var_table, create_pair_string("package", PACKAGE)); + var_table = g_list_prepend(var_table, create_pair_string("version", VERSION)); - return var_table; + return var_table; } -gint expand(GList *var_list, gchar *format, gchar *result, gint result_len) +gint +expand(GList * var_list, gchar * format, gchar * result, gint result_len) { - gchar *p = format, *q = result; - gchar *vq; - gint i = 0; - gboolean escape = FALSE; + gchar *p = format, *q = result; + gchar *vq; + gint i = 0; + gboolean escape = FALSE; - while(*p && (i < (result_len -1))){ - if((*p == '$') && !escape){ - gchar *value; - gchar var[MAX_VAR+1]; - int j = 0; + while (*p && (i < (result_len - 1))) { + if ((*p == '$') && !escape) { + gchar *value; + gchar var[MAX_VAR + 1]; + int j = 0; - p++; /* skip '$' */ - vq = var; + p++; /* skip '$' */ + vq = var; - if(*p == '{'){ - /* ${var} style */ - p++; /* skip '{' */ - while(*p && (*p != '}') && (j < MAX_VAR)){ - *(vq++) = *(p++); - j++; + if (*p == '{') { + /* ${var} style */ + p++; /* skip '{' */ + while (*p && (*p != '}') && (j < MAX_VAR)) { + *(vq++) = *(p++); + j++; + } + p++; + } else { + /* $var style */ + while (*p && (isalnum(*p) || (*p == '_') || (*p == '-')) && (j < MAX_VAR)) { + *(vq++) = *(p++); + j++; + } + } + *vq = 0; + + if (j < MAX_VAR) { + /* search var */ + value = (gchar *) table_find(var_list, var); + if (value) { + gchar *vp = value; + while (*vp && (i < (result_len - 1))) { + *(q++) = *(vp++); + i++; + } + } + } + } else { + if ((*p == '\\') && (!escape)) { + escape = TRUE; + } else { + *(q++) = *p; + i++; + escape = FALSE; + } + p++; + } } - p++; - }else{ - /* $var style */ - while(*p && (isalnum(*p) || (*p == '_') || (*p == '-')) && (j < MAX_VAR)){ - *(vq++) = *(p++); - j++; - } - } - *vq = 0; + *q = 0; - if(j < MAX_VAR){ - /* search var */ - value = (gchar *)table_find(var_list, var); - if(value){ - gchar *vp = value; - while(*vp && (i < (result_len -1))){ - *(q++) = *(vp++); i++; - } - } - } - }else{ - if((*p == '\\') && (!escape)){ - escape = TRUE; - }else{ - *(q++) = *p; i++; - escape = FALSE; - } - p++; - } - } - *q = 0; + if (i >= (result_len - 1)) + return -3; - if(i >= (result_len -1)) - return -3; - - return i; + return i; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/fail_msg.c --- a/src/fail_msg.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/fail_msg.c Mon Oct 27 16:23:10 2008 +0100 @@ -5,7 +5,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 @@ -22,109 +22,107 @@ #include "peopen.h" #include "readsock.h" -gboolean fail_msg(message *msg, gchar *template, - GList *failed_rcpts, gchar *err_fmt, va_list args) +gboolean +fail_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args) { - gboolean ok = FALSE; - address *ret_path = NULL; + gboolean ok = FALSE; + address *ret_path = NULL; - /* do not bounce bounces, send to postmaster instead */ - if(msg->return_path->local_part[0] == 0){ - GList *node; + /* do not bounce bounces, send to postmaster instead */ + if (msg->return_path->local_part[0] == 0) { + GList *node; - ret_path = create_address_qualified("postmaster", TRUE, conf.host_name); - foreach(failed_rcpts, node){ - address *addr = (address *)(node->data); - if(addr_isequal_parent(addr, ret_path)){ - logwrite(LOG_ALERT, "%s == %s: postmaster address failed\n", - msg->uid, addr_string(ret_path)); - return FALSE; - } - } - }else - ret_path = copy_address(msg->return_path); + ret_path = create_address_qualified("postmaster", TRUE, conf.host_name); + foreach(failed_rcpts, node) { + address *addr = (address *) (node->data); + if (addr_isequal_parent(addr, ret_path)) { + logwrite(LOG_ALERT, "%s == %s: postmaster address failed\n", msg->uid, addr_string(ret_path)); + return FALSE; + } + } + } else + ret_path = copy_address(msg->return_path); - DEBUG(1) debugf("sending failure notice to %s.\n", addr_string(ret_path)); + DEBUG(1) debugf("sending failure notice to %s.\n", addr_string(ret_path)); - if(template){ - FILE *file; - GList *var_table = var_table_conf(var_table_msg(NULL, msg)); - gchar *err_msg = g_strdup_vprintf(err_fmt, args); + if (template) { + FILE *file; + GList *var_table = var_table_conf(var_table_msg(NULL, msg)); + gchar *err_msg = g_strdup_vprintf(err_fmt, args); - var_table = g_list_prepend(var_table, create_pair_string("err_msg", err_msg)); - g_free(err_msg); + var_table = g_list_prepend(var_table, create_pair_string("err_msg", err_msg)); + g_free(err_msg); - if((file = fopen(template, "r"))){ - FILE *out; - gchar *cmd; - pid_t pid; + if ((file = fopen(template, "r"))) { + FILE *out; + gchar *cmd; + pid_t pid; - // cmd = g_strdup_printf(SBINDIR"/masqmail -oi -f \"<>\" %s@%s", - // ret_path->local_part, ret_path->domain); - cmd = g_strdup_printf(SBINDIR"/masqmail -oi -f <> %s@%s", - ret_path->local_part, ret_path->domain); - if((out = peidopen(cmd, "w", environ, &pid, conf.mail_uid, conf.mail_gid))){ - gchar fmt[256], line[256]; - int status, ret; + // cmd = g_strdup_printf(SBINDIR"/masqmail -oi -f \"<>\" %s@%s", + // ret_path->local_part, ret_path->domain); + cmd = g_strdup_printf(SBINDIR "/masqmail -oi -f <> %s@%s", ret_path->local_part, ret_path->domain); + if ((out = peidopen(cmd, "w", environ, &pid, conf.mail_uid, conf.mail_gid))) { + gchar fmt[256], line[256]; + int status, ret; - while((ret = read_sockline(file, fmt, 256, 0, 0)) > 0){ - if(fmt[0] == '@'){ - GList *node; - if(strncmp(fmt, "@failed_rcpts", 13) == 0){ - foreach(failed_rcpts, node){ - address *rcpt = (address *)(node->data); - fprintf(out, "\t%s\n", addr_string(rcpt)); - } - }else if(strncmp(fmt, "@msg_headers", 12) == 0){ - foreach(msg->hdr_list, node){ - header *hdr = (header *)(node->data); - fputs(hdr->header, out); - } - }else if(strncmp(fmt, "@msg_body", 9) == 0){ - /* we may have to read the data at this point - and remember if we did */ - gboolean flag = (msg->data_list == NULL); - if(flag){ - if(!spool_read_data(msg)){ - logwrite(LOG_ALERT, "could not open data spool file %s\n", - msg->uid); - } - } - foreach(msg->data_list, node){ - gchar *line = (gchar *)(node->data); - fputs(line, out); - } - if(flag) msg_free_data(msg); - } - }else{ - expand(var_table, fmt, line, 256); - fputs(line, out); - } + while ((ret = read_sockline(file, fmt, 256, 0, 0)) > 0) { + if (fmt[0] == '@') { + GList *node; + if (strncmp(fmt, "@failed_rcpts", 13) == 0) { + foreach(failed_rcpts, node) { + address *rcpt = (address *) (node->data); + fprintf(out, "\t%s\n", addr_string(rcpt)); + } + } else if (strncmp(fmt, "@msg_headers", 12) == 0) { + foreach(msg->hdr_list, node) { + header *hdr = (header *) (node->data); + fputs(hdr->header, out); + } + } else if (strncmp(fmt, "@msg_body", 9) == 0) { + /* we may have to read the data at this point + and remember if we did */ + gboolean flag = (msg->data_list == NULL); + if (flag) { + if (!spool_read_data(msg)) { + logwrite(LOG_ALERT, "could not open data spool file %s\n", msg->uid); + } + } + foreach(msg->data_list, node) { + gchar *line = (gchar *) (node->data); + fputs(line, out); + } + if (flag) + msg_free_data(msg); + } + } else { + expand(var_table, fmt, line, 256); + fputs(line, out); + } + } + + fclose(out); + waitpid(pid, &status, 0); + if ((WEXITSTATUS(status) != EXIT_SUCCESS) || WIFSIGNALED(status)) { + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "child returned %d\n", WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "child got signal: %d\n", WTERMSIG(status)); + } else + ok = TRUE; + } else { + logwrite(LOG_ERR, "peopen failed: %s\n", strerror(errno)); + } + g_free(cmd); + fclose(file); + } else + logwrite(LOG_ALERT, "could not open failure message template %s: %s\n", conf.errmsg_file, strerror(errno)); + + destroy_table(var_table); } - fclose(out); - waitpid(pid, &status, 0); - if((WEXITSTATUS(status) != EXIT_SUCCESS) || WIFSIGNALED(status)){ - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, "child returned %d\n", WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, "child got signal: %d\n", WTERMSIG(status)); - }else ok = TRUE; - }else{ - logwrite(LOG_ERR, "peopen failed: %s\n", strerror(errno)); - } - g_free(cmd); - fclose(file); - }else - logwrite(LOG_ALERT, "could not open failure message template %s: %s\n", - conf.errmsg_file, strerror(errno)); + destroy_address(ret_path); - destroy_table(var_table); - } - - destroy_address(ret_path); - - return ok; + return ok; } /* @@ -133,45 +131,43 @@ result: |nnnyyyynnnnyyyyyyyyyynnnnnnn */ -static -gboolean warn_msg_is_due(message *msg) +static gboolean +warn_msg_is_due(message * msg) { - time_t now = time(NULL); - gint dummy; - - GList *node; - for(node = g_list_last(conf.warn_intervals); node; node = g_list_previous(node)){ - gchar *str_ival = (gchar *)(node->data); - gint ival = time_interval(str_ival, &dummy); - if(ival >= 0){ - DEBUG(5) debugf("ival = %d\n", ival); - DEBUG(5) debugf("now - msg->received_time = %d\n", now - msg->received_time); - if((now - msg->received_time) > ival){ - if(msg->warned_time != 0){ - if((msg->warned_time - msg->received_time) < ival) - return TRUE; - }else - return TRUE; - } - }else - logwrite(LOG_WARNING, "invalid time interval: %s\n", str_ival); - } - return FALSE; + time_t now = time(NULL); + gint dummy; + + GList *node; + for (node = g_list_last(conf.warn_intervals); node; node = g_list_previous(node)) { + gchar *str_ival = (gchar *) (node->data); + gint ival = time_interval(str_ival, &dummy); + if (ival >= 0) { + DEBUG(5) debugf("ival = %d\n", ival); + DEBUG(5) debugf("now - msg->received_time = %d\n", now - msg->received_time); + if ((now - msg->received_time) > ival) { + if (msg->warned_time != 0) { + if ((msg->warned_time - msg->received_time) < ival) + return TRUE; + } else + return TRUE; + } + } else + logwrite(LOG_WARNING, "invalid time interval: %s\n", str_ival); + } + return FALSE; } -gboolean warn_msg(message *msg, gchar *template, - GList *defered_rcpts, gchar *err_fmt, va_list args) +gboolean +warn_msg(message * msg, gchar * template, GList * defered_rcpts, gchar * err_fmt, va_list args) { - time_t now = time(NULL); + time_t now = time(NULL); - if(warn_msg_is_due(msg)){ - if(fail_msg(msg, template, defered_rcpts, err_fmt, args)){ - msg->warned_time = now; - return TRUE; - }else - return FALSE; - } - return TRUE; + if (warn_msg_is_due(msg)) { + if (fail_msg(msg, template, defered_rcpts, err_fmt, args)) { + msg->warned_time = now; + return TRUE; + } else + return FALSE; + } + return TRUE; } - - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/get.c --- a/src/get.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/get.c Mon Oct 27 16:23:10 2008 +0100 @@ -27,384 +27,368 @@ static int volatile sighup_seen = 0; -static -void sighup_handler(int sig) +static void +sighup_handler(int sig) { - sighup_seen = 1; - signal(SIGHUP, sighup_handler); + sighup_seen = 1; + signal(SIGHUP, sighup_handler); } -static -void sigchld_handler(int sig) +static void +sigchld_handler(int sig) { - pid_t pid; - int status; - - pid = waitpid(0, &status, 0); - if(pid > 0){ - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, "process %d exited with %d\n", - pid, WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, - "process with pid %d got signal: %d\n", - pid, WTERMSIG(status)); - } - signal(SIGCHLD, sigchld_handler); + pid_t pid; + int status; + + pid = waitpid(0, &status, 0); + if (pid > 0) { + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "process %d exited with %d\n", pid, WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "process with pid %d got signal: %d\n", pid, WTERMSIG(status)); + } + signal(SIGCHLD, sigchld_handler); } -static -int get_lock(get_conf *gc) +static int +get_lock(get_conf * gc) { #ifdef USE_DOTLOCK - gboolean ok = FALSE; - gchar *hitch_name; - gchar *lock_name; + gboolean ok = FALSE; + gchar *hitch_name; + gchar *lock_name; - /* the name of the lock is constructed from the user - and the server name, to prevent more than one connection at the same time - to the same server and the same user. This way concurrent connections - are possible to different servers or different users */ - hitch_name = g_strdup_printf("%s/masqmail-get-%s@%s-%d.lock", - conf.lock_dir, gc->login_user, - gc->server_name, getpid()); - lock_name = g_strdup_printf("%s/masqmail-get-%s@%s.lock", - conf.lock_dir, gc->login_user, gc->server_name); - - ok = dot_lock(lock_name, hitch_name); - if(!ok) logwrite(LOG_WARNING, - "getting mail for %s@%s is locked\n", - gc->login_user, gc->server_name); + /* the name of the lock is constructed from the user + and the server name, to prevent more than one connection at the same time + to the same server and the same user. This way concurrent connections + are possible to different servers or different users */ + hitch_name = g_strdup_printf("%s/masqmail-get-%s@%s-%d.lock", conf.lock_dir, gc->login_user, gc->server_name, getpid()); + lock_name = g_strdup_printf("%s/masqmail-get-%s@%s.lock", conf.lock_dir, gc->login_user, gc->server_name); - g_free(lock_name); - g_free(hitch_name); + ok = dot_lock(lock_name, hitch_name); + if (!ok) + logwrite(LOG_WARNING, "getting mail for %s@%s is locked\n", gc->login_user, gc->server_name); - return ok; + g_free(lock_name); + g_free(hitch_name); + + return ok; #else - gchar *lock_name; - int fd; + gchar *lock_name; + int fd; - lock_name = g_strdup_printf("%s/masqmail-get-%s@%s.lock", - conf.lock_dir, gc->login_user, gc->server_name); + lock_name = g_strdup_printf("%s/masqmail-get-%s@%s.lock", conf.lock_dir, gc->login_user, gc->server_name); - if((fd = open(lock_name, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600)) >= 0){ - if(flock(fd, LOCK_EX|LOCK_NB) != 0){ - close(fd); - logwrite(LOG_WARNING, - "getting mail for %s@%s is locked\n", - gc->login_user, gc->server_name); - fd = -1; - } - }else - logwrite(LOG_WARNING, - "could not open lock %s: %s\n", lock_name, strerror(errno)); + if ((fd = open(lock_name, O_WRONLY | O_NDELAY | O_APPEND | O_CREAT, 0600)) >= 0) { + if (flock(fd, LOCK_EX | LOCK_NB) != 0) { + close(fd); + logwrite(LOG_WARNING, "getting mail for %s@%s is locked\n", gc->login_user, gc->server_name); + fd = -1; + } + } else + logwrite(LOG_WARNING, "could not open lock %s: %s\n", lock_name, strerror(errno)); - g_free(lock_name); + g_free(lock_name); - return fd; + return fd; #endif } #ifdef USE_DOTLOCK -static -gboolean get_unlock(get_conf *gc) +static gboolean +get_unlock(get_conf * gc) { - gchar *lock_name lock_name = - g_strdup_printf("%s/masqmail-get-%s@%s.lock", - conf.lock_dir, gc->login_user, gc->server_name); - - dot_unlock(lock_name); + gchar *lock_name lock_name = g_strdup_printf("%s/masqmail-get-%s@%s.lock", conf.lock_dir, gc->login_user, gc->server_name); - g_free(lock_name); + dot_unlock(lock_name); + g_free(lock_name); - return TRUE; + return TRUE; } #else -static void get_unlock(get_conf *gc, int fd) +static void +get_unlock(get_conf * gc, int fd) { - gchar *lock_name = - g_strdup_printf("%s/masqmail-get-%s@%s.lock", - conf.lock_dir, gc->login_user, gc->server_name); + gchar *lock_name = g_strdup_printf("%s/masqmail-get-%s@%s.lock", conf.lock_dir, gc->login_user, gc->server_name); - flock(fd, LOCK_UN); - close(fd); + flock(fd, LOCK_UN); + close(fd); - unlink(lock_name); - g_free(lock_name); + unlink(lock_name); + g_free(lock_name); } #endif -gboolean get_from_file(gchar *fname) +gboolean +get_from_file(gchar * fname) { - guint flags = 0; - get_conf *gc = read_get_conf(fname); - gboolean ok = TRUE; - int lock; + guint flags = 0; + get_conf *gc = read_get_conf(fname); + gboolean ok = TRUE; + int lock; - if(gc){ - if(!gc->do_keep) flags |= POP3_FLAG_DELETE; - if(gc->do_uidl) flags |= POP3_FLAG_UIDL; - if(gc->do_uidl_dele) flags |= POP3_FLAG_UIDL_DELE; - - if(!(gc->server_name)){ - logwrite(LOG_ALERT, "no server name given in %s\n", fname); return FALSE; - } - if(!(gc->address)){ - logwrite(LOG_ALERT, "no address given in %s\n", fname); return FALSE; - } - if(!(gc->login_user)){ - logwrite(LOG_ALERT, "no user name given in %s\n", fname); return FALSE; - } - if(!(gc->login_pass)){ - logwrite(LOG_ALERT, "no password given in %s\n", fname); return FALSE; - } + if (gc) { + if (!gc->do_keep) + flags |= POP3_FLAG_DELETE; + if (gc->do_uidl) + flags |= POP3_FLAG_UIDL; + if (gc->do_uidl_dele) + flags |= POP3_FLAG_UIDL_DELE; - DEBUG(3) debugf("flags = %d\n", flags); - - if((strcmp(gc->protocol, "pop3") == 0) || (strcmp(gc->protocol, "apop") == 0)){ - pop3_base *popb = NULL; + if (!(gc->server_name)) { + logwrite(LOG_ALERT, "no server name given in %s\n", fname); + return FALSE; + } + if (!(gc->address)) { + logwrite(LOG_ALERT, "no address given in %s\n", fname); + return FALSE; + } + if (!(gc->login_user)) { + logwrite(LOG_ALERT, "no user name given in %s\n", fname); + return FALSE; + } + if (!(gc->login_pass)) { + logwrite(LOG_ALERT, "no password given in %s\n", fname); + return FALSE; + } - if(strcmp(gc->protocol, "apop") == 0){ - flags |= POP3_FLAG_APOP; - DEBUG(3) debugf("attempting to get mail for user %s at host %s" - " for %s@%s with apop\n", - gc->login_user, gc->server_name, - gc->address->local_part, gc->address->domain); - }else{ - DEBUG(3) debugf("attempting to get mail for user %s at host %s" - " for %s@%s with pop3\n", - gc->login_user, gc->server_name, - gc->address->local_part, gc->address->domain); - } + DEBUG(3) debugf("flags = %d\n", flags); + + if ((strcmp(gc->protocol, "pop3") == 0) || (strcmp(gc->protocol, "apop") == 0)) { + pop3_base *popb = NULL; + + if (strcmp(gc->protocol, "apop") == 0) { + flags |= POP3_FLAG_APOP; + DEBUG(3) debugf("attempting to get mail for user %s at host %s for %s@%s with apop\n", + gc->login_user, gc->server_name, gc->address->local_part, gc->address->domain); + } else { + DEBUG(3) debugf("attempting to get mail for user %s at host %s for %s@%s with pop3\n", + gc->login_user, gc->server_name, gc->address->local_part, gc->address->domain); + } #ifdef USE_DOTLOCK - if((lock = get_lock(gc))){ + if ((lock = get_lock(gc))) { #else - if((lock = get_lock(gc)) >= 0){ + if ((lock = get_lock(gc)) >= 0) { #endif - if(gc->wrapper){ - popb = pop3_in_open_child(gc->wrapper, flags); - /* quick hack */ - popb->remote_host = gc->server_name; - }else{ - popb = pop3_in_open(gc->server_name, gc->server_port, - gc->resolve_list, flags); + if (gc->wrapper) { + popb = pop3_in_open_child(gc->wrapper, flags); + /* quick hack */ + popb->remote_host = gc->server_name; + } else { + popb = pop3_in_open(gc->server_name, gc->server_port, gc->resolve_list, flags); + } + if (popb) { + ok = pop3_get(popb, gc->login_user, gc->login_pass, gc->address, gc->return_path, + gc->max_count, gc->max_size, gc->max_size_delete); + pop3_in_close(popb); + } else { + ok = FALSE; + logwrite(LOG_ALERT, "failed to connect to host %s\n", gc->server_name); + } +#ifdef USE_DOTLOCK + get_unlock(gc); +#else + get_unlock(gc, lock); +#endif + } + } else { + logwrite(LOG_ALERT, "get protocol %s unknown\n", gc->protocol); + ok = FALSE; + } + + destroy_get_conf(gc); } - if(popb){ - ok = pop3_get(popb, gc->login_user, gc->login_pass, - gc->address, gc->return_path, - gc->max_count, gc->max_size, gc->max_size_delete); - pop3_in_close(popb); - }else{ - ok = FALSE; - logwrite(LOG_ALERT, "failed to connect to host %s\n", gc->server_name); - } -#ifdef USE_DOTLOCK - get_unlock(gc); -#else - get_unlock(gc, lock); -#endif - } - }else{ - logwrite(LOG_ALERT, "get protocol %s unknown\n", gc->protocol); - ok = FALSE; - } - - destroy_get_conf(gc); - } - return ok; + return ok; } -gboolean get_from_name(gchar *name) +gboolean +get_from_name(gchar * name) { - gchar *fname = (gchar *)table_find(conf.get_names, name); - if(fname) - return get_from_file(fname); - return FALSE; + gchar *fname = (gchar *) table_find(conf.get_names, name); + if (fname) + return get_from_file(fname); + return FALSE; } -gboolean get_all() +gboolean +get_all() { - GList *get_table = conf.get_names; - GList *get_node; - void (*old_signal)(int); + GList *get_table = conf.get_names; + GList *get_node; + void (*old_signal) (int); - old_signal = signal(SIGCHLD, SIG_DFL); + old_signal = signal(SIGCHLD, SIG_DFL); - foreach(get_table, get_node){ - table_pair *pair = (table_pair *)(get_node->data); - gchar *fname = (gchar *)pair->value; - pid_t pid; + foreach(get_table, get_node) { + table_pair *pair = (table_pair *) (get_node->data); + gchar *fname = (gchar *) pair->value; + pid_t pid; - pid = fork(); - if(pid == 0){ - signal(SIGCHLD, old_signal); - exit(get_from_file(fname) ? EXIT_SUCCESS : EXIT_FAILURE); - }else if(pid > 0){ - int status; - waitpid(pid, &status, 0); - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, "child returned %d\n", WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, "child got signal: %d\n", WTERMSIG(status)); - }else - logwrite(LOG_WARNING, "forking child failed: %s\n", strerror(errno)); - } - - signal(SIGCHLD, old_signal); + pid = fork(); + if (pid == 0) { + signal(SIGCHLD, old_signal); + exit(get_from_file(fname) ? EXIT_SUCCESS : EXIT_FAILURE); + } else if (pid > 0) { + int status; + waitpid(pid, &status, 0); + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "child returned %d\n", WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "child got signal: %d\n", WTERMSIG(status)); + } else + logwrite(LOG_WARNING, "forking child failed: %s\n", strerror(errno)); + } - return TRUE; + signal(SIGCHLD, old_signal); + + return TRUE; } -void get_online() +void +get_online() { - GList *gf_list = NULL; - gchar *connect_name = detect_online(); + GList *gf_list = NULL; + gchar *connect_name = detect_online(); - if(connect_name != NULL){ - void (*old_signal)(int); + if (connect_name != NULL) { + void (*old_signal) (int); - old_signal = signal(SIGCHLD, SIG_DFL); + old_signal = signal(SIGCHLD, SIG_DFL); - logwrite(LOG_NOTICE, "detected online configuration %s\n", connect_name); - /* we are online! */ - gf_list = (GList *)table_find(conf.online_gets, connect_name); - if(gf_list != NULL){ - GList *node; - foreach(gf_list, node){ - gchar *fname = (gchar *)(node->data); - pid_t pid; + logwrite(LOG_NOTICE, "detected online configuration %s\n", connect_name); + /* we are online! */ + gf_list = (GList *) table_find(conf.online_gets, connect_name); + if (gf_list != NULL) { + GList *node; + foreach(gf_list, node) { + gchar *fname = (gchar *) (node->data); + pid_t pid; - if(fname[0] != '/') - fname = (gchar *)table_find(conf.get_names, fname); + if (fname[0] != '/') + fname = (gchar *) table_find(conf.get_names, fname); - if(fname != NULL){ - pid = fork(); - if(pid == 0){ - signal(SIGCHLD, old_signal); - exit(get_from_file(fname) ? EXIT_SUCCESS : EXIT_FAILURE); - }else if(pid > 0){ - int status; - waitpid(pid, &status, 0); - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, "child returned %d\n", WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, "child got signal: %d\n", WTERMSIG(status)); - }else - logwrite(LOG_WARNING, "forking child failed: %s\n", strerror(errno)); + if (fname != NULL) { + pid = fork(); + if (pid == 0) { + signal(SIGCHLD, old_signal); + exit(get_from_file(fname) ? EXIT_SUCCESS : EXIT_FAILURE); + } else if (pid > 0) { + int status; + waitpid(pid, &status, 0); + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "child returned %d\n", WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "child got signal: %d\n", WTERMSIG(status)); + } else + logwrite(LOG_WARNING, "forking child failed: %s\n", strerror(errno)); + } + } + } + signal(SIGCHLD, old_signal); } - } - } - signal(SIGCHLD, old_signal); - } } -void get_daemon(gint gival, char *argv[]) +void +get_daemon(gint gival, char *argv[]) { - struct timeval tm; - time_t time_before, time_now; - int sel_ret; + struct timeval tm; + time_t time_before, time_now; + int sel_ret; - /* setup handler for HUP signal: */ - signal(SIGHUP, sighup_handler); + /* setup handler for HUP signal: */ + signal(SIGHUP, sighup_handler); - /* we can give up root privileges */ - if(!conf.run_as_user){ - if(setegid(conf.mail_gid) != 0){ - logwrite(LOG_ALERT, "could not change gid to %d: %s\n", - conf.mail_gid, strerror(errno)); - exit(EXIT_FAILURE); - } - if(seteuid(conf.mail_uid) != 0){ - logwrite(LOG_ALERT, "could not change uid to %d: %s\n", - conf.mail_uid, strerror(errno)); - exit(EXIT_FAILURE); - } - } + /* we can give up root privileges */ + if (!conf.run_as_user) { + if (setegid(conf.mail_gid) != 0) { + logwrite(LOG_ALERT, "could not change gid to %d: %s\n", conf.mail_gid, strerror(errno)); + exit(EXIT_FAILURE); + } + if (seteuid(conf.mail_uid) != 0) { + logwrite(LOG_ALERT, "could not change uid to %d: %s\n", conf.mail_uid, strerror(errno)); + exit(EXIT_FAILURE); + } + } - /* sel_ret = 0;*/ - time(&time_before); - time_before -= gival; - sel_ret = -1; + /* sel_ret = 0; */ + time(&time_before); + time_before -= gival; + sel_ret = -1; - while (1){ - /* see listen_port() in listen.c */ - if(gival > 0){ - time(&time_now); - if(sel_ret == 0){ /* we are either just starting or did a queue run */ - tm.tv_sec = gival; - tm.tv_usec = 0; - time_before = time_now; - }else{ - tm.tv_sec = gival - (time_now - time_before); - tm.tv_usec = 0; + while (1) { + /* see listen_port() in listen.c */ + if (gival > 0) { + time(&time_now); + if (sel_ret == 0) { /* we are either just starting or did a queue run */ + tm.tv_sec = gival; + tm.tv_usec = 0; + time_before = time_now; + } else { + tm.tv_sec = gival - (time_now - time_before); + tm.tv_usec = 0; - /* race condition, very unlikely (but possible): */ - if(tm.tv_sec < 0) - tm.tv_sec = 0; - } - } + /* race condition, very unlikely (but possible): */ + if (tm.tv_sec < 0) + tm.tv_sec = 0; + } + } - if ((sel_ret = select(0, NULL, NULL, NULL, &tm)) < 0){ - if(errno != EINTR){ - logwrite(LOG_ALERT, "select: (terminating): %s\n", strerror(errno)); - exit (EXIT_FAILURE); - }else{ - if(sighup_seen){ - logwrite(LOG_NOTICE, "HUP signal received. Restarting daemon\n"); + if ((sel_ret = select(0, NULL, NULL, NULL, &tm)) < 0) { + if (errno != EINTR) { + logwrite(LOG_ALERT, "select: (terminating): %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } else { + if (sighup_seen) { + logwrite(LOG_NOTICE, "HUP signal received. Restarting daemon\n"); - if(argv == NULL) exit(EXIT_SUCCESS); + if (argv == NULL) + exit(EXIT_SUCCESS); - execv(argv[0], &(argv[0])); - logwrite(LOG_ALERT, "restarting failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); + execv(argv[0], &(argv[0])); + logwrite(LOG_ALERT, "restarting failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } + } else { + /* If select returns 0, the interval time has elapsed. + We start a new get process */ + int pid; + signal(SIGCHLD, sigchld_handler); + if ((pid = fork()) == 0) { + get_online(); + + _exit(EXIT_SUCCESS); + } else if (pid < 0) { + logwrite(LOG_ALERT, "could not fork for get run"); + } + } } - } - }else{ - /* If select returns 0, the interval time has elapsed. - We start a new get process */ - int pid; - signal(SIGCHLD, sigchld_handler); - if((pid = fork()) == 0){ - get_online(); - - _exit(EXIT_SUCCESS); - } - else if(pid < 0){ - logwrite(LOG_ALERT, "could not fork for get run"); - } - } - } } -gboolean pop_before_smtp(gchar *fname) +gboolean +pop_before_smtp(gchar * fname) { - gboolean ok = FALSE; - GList *resolve_list = NULL; - get_conf *gc = read_get_conf(fname); - guint flags = 0; + gboolean ok = FALSE; + GList *resolve_list = NULL; + get_conf *gc = read_get_conf(fname); + guint flags = 0; #ifdef ENABLE_RESOLVER - resolve_list = g_list_append(resolve_list, resolve_dns_a); + resolve_list = g_list_append(resolve_list, resolve_dns_a); #endif - resolve_list = g_list_append(resolve_list, resolve_byname); + resolve_list = g_list_append(resolve_list, resolve_byname); - if(strcmp(gc->protocol, "pop3") == 0){ - DEBUG(3) debugf("attempting to login for user %s, host = %s with pop3\n", - gc->login_user, gc->server_name); - ok = pop3_login(gc->server_name, gc->server_port, resolve_list, - gc->login_user, gc->login_pass, - flags); - }else if(strcmp(gc->protocol, "apop") == 0){ - DEBUG(3) debugf("attempting to login for user %s, host = %s with apop\n", - gc->login_user, gc->server_name); - ok = pop3_login(gc->server_name, gc->server_port, resolve_list, - gc->login_user, gc->login_pass, - flags | POP3_FLAG_APOP); - }else{ - logwrite(LOG_ALERT, "get protocol %s unknown\n", gc->protocol); - } - return ok; + if (strcmp(gc->protocol, "pop3") == 0) { + DEBUG(3) debugf("attempting to login for user %s, host = %s with pop3\n", gc->login_user, gc->server_name); + ok = pop3_login(gc->server_name, gc->server_port, resolve_list, gc->login_user, gc->login_pass, flags); + } else if (strcmp(gc->protocol, "apop") == 0) { + DEBUG(3) debugf ("attempting to login for user %s, host = %s with apop\n", gc->login_user, gc->server_name); + ok = pop3_login(gc->server_name, gc->server_port, resolve_list, gc->login_user, gc->login_pass, flags | POP3_FLAG_APOP); + } else { + logwrite(LOG_ALERT, "get protocol %s unknown\n", gc->protocol); + } + return ok; } #endif diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/header.c --- a/src/header.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/header.c Mon Oct 27 16:23:10 2008 +0100 @@ -17,243 +17,269 @@ */ #include "masqmail.h" -header_name header_names[] = -{ - { "From", HEAD_FROM, }, - { "Sender", HEAD_SENDER, }, - { "To", HEAD_TO, }, - { "Cc", HEAD_CC, }, - { "Bcc", HEAD_BCC, }, - { "Date", HEAD_DATE, }, - { "Message-Id", HEAD_MESSAGE_ID, }, - { "Reply-To", HEAD_REPLY_TO, }, - { "Subject", HEAD_SUBJECT, }, - { "Return-Path", HEAD_RETURN_PATH, }, - { "Envelope-To", HEAD_ENVELOPE_TO, }, - { "Received", HEAD_RECEIVED }, +header_name header_names[] = { + {"From", HEAD_FROM,} + , + {"Sender", HEAD_SENDER,} + , + {"To", HEAD_TO,} + , + {"Cc", HEAD_CC,} + , + {"Bcc", HEAD_BCC,} + , + {"Date", HEAD_DATE,} + , + {"Message-Id", HEAD_MESSAGE_ID,} + , + {"Reply-To", HEAD_REPLY_TO,} + , + {"Subject", HEAD_SUBJECT,} + , + {"Return-Path", HEAD_RETURN_PATH,} + , + {"Envelope-To", HEAD_ENVELOPE_TO,} + , + {"Received", HEAD_RECEIVED} + , }; /* this was borrowed from exim and slightly changed */ -gchar *rec_timestamp() +gchar* +rec_timestamp() { - static gchar buf[64]; - int len; - - time_t now = time(NULL); - struct tm *t = localtime(&now); + static gchar buf[64]; + int len; - int diff_hour, diff_min; - struct tm local; - struct tm *gmt; + time_t now = time(NULL); + struct tm *t = localtime(&now); - memcpy(&local, t, sizeof(struct tm)); - gmt = gmtime(&now); - diff_min = 60*(local.tm_hour - gmt->tm_hour) + local.tm_min - gmt->tm_min; - if (local.tm_year != gmt->tm_year) - diff_min += (local.tm_year > gmt->tm_year)? 1440 : -1440; - else if (local.tm_yday != gmt->tm_yday) - diff_min += (local.tm_yday > gmt->tm_yday)? 1440 : -1440; - diff_hour = diff_min/60; - diff_min = abs(diff_min - diff_hour*60); + int diff_hour, diff_min; + struct tm local; + struct tm *gmt; - len = strftime(buf, sizeof(buf), "%a, ", &local); - g_snprintf(buf + len, sizeof(buf) - len, "%02d ", local.tm_mday); - len += strlen(buf + len); - len += strftime(buf + len, sizeof(buf) - len, "%b %Y %H:%M:%S", &local); - g_snprintf(buf + len, sizeof(buf) - len, " %+03d%02d", diff_hour, diff_min); + memcpy(&local, t, sizeof(struct tm)); + gmt = gmtime(&now); + diff_min = 60 * (local.tm_hour - gmt->tm_hour) + local.tm_min - gmt->tm_min; + if (local.tm_year != gmt->tm_year) + diff_min += (local.tm_year > gmt->tm_year) ? 1440 : -1440; + else if (local.tm_yday != gmt->tm_yday) + diff_min += (local.tm_yday > gmt->tm_yday) ? 1440 : -1440; + diff_hour = diff_min / 60; + diff_min = abs(diff_min - diff_hour * 60); - return buf; + len = strftime(buf, sizeof(buf), "%a, ", &local); + g_snprintf(buf + len, sizeof(buf) - len, "%02d ", local.tm_mday); + len += strlen(buf + len); + len += strftime(buf + len, sizeof(buf) - len, "%b %Y %H:%M:%S", &local); + g_snprintf(buf + len, sizeof(buf) - len, " %+03d%02d", diff_hour, diff_min); + + return buf; } /* finds list of headers matching id if id == HEAD_UNKNOWN and header == NULL finds all unknown headers else finds all headers matching header */ -GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str) +GList* +find_header(GList * hdr_list, header_id id, gchar * hdr_str) { - GList *found_list = NULL; - GList *node; + GList *found_list = NULL; + GList *node; - if((id != HEAD_UNKNOWN) || (hdr_str == NULL)){ - foreach(hdr_list, node){ - header *hdr = (header *)(node->data); - if(hdr->id == id) - found_list = g_list_append(found_list, hdr); - } - }else{ - foreach(hdr_list, node){ - header *hdr = (header *)(node->data); - gchar buf[64], *q = buf, *p = hdr->header; - - while(*p != ':' && q < buf+63 && *p) *(q++) = *(p++); - *q = 0; - - if(strcasecmp(buf, hdr_str) == 0) - found_list = g_list_append(found_list, hdr); - } - } - return found_list; + if ((id != HEAD_UNKNOWN) || (hdr_str == NULL)) { + foreach(hdr_list, node) { + header *hdr = (header *) (node->data); + if (hdr->id == id) + found_list = g_list_append(found_list, hdr); + } + } else { + foreach(hdr_list, node) { + header *hdr = (header *) (node->data); + gchar buf[64], *q = buf, *p = hdr->header; + + while (*p != ':' && q < buf + 63 && *p) + *(q++) = *(p++); + *q = 0; + + if (strcasecmp(buf, hdr_str) == 0) + found_list = g_list_append(found_list, hdr); + } + } + return found_list; } -void header_unfold(header *hdr) +void +header_unfold(header * hdr) { - gchar *tmp_hdr = g_malloc(strlen(hdr->header)); - gchar *p = hdr->header, *q = tmp_hdr; - gboolean flag = FALSE; + gchar *tmp_hdr = g_malloc(strlen(hdr->header)); + gchar *p = hdr->header, *q = tmp_hdr; + gboolean flag = FALSE; - while(*p){ - if(*p != '\n') - *(q++) = *p; - else - flag = TRUE; - p++; - } - *(q++) = '\n'; + while (*p) { + if (*p != '\n') + *(q++) = *p; + else + flag = TRUE; + p++; + } + *(q++) = '\n'; - if(flag){ - gchar *new_hdr; + if (flag) { + gchar *new_hdr; - g_free(hdr->header); - new_hdr = g_strdup(tmp_hdr); - g_free(tmp_hdr); - hdr->value = new_hdr + (hdr->value - hdr->header); - hdr->header = new_hdr; - } + g_free(hdr->header); + new_hdr = g_strdup(tmp_hdr); + g_free(tmp_hdr); + hdr->value = new_hdr + (hdr->value - hdr->header); + hdr->header = new_hdr; + } } #define MAX_HDR_LEN 72 -void header_fold(header *hdr) +void +header_fold(header * hdr) { - gint len = strlen(hdr->header); - gchar *p, *q; - /* size is probably overestimated, but so we are on the safe side */ - gchar *tmp_hdr = g_malloc(len + 2*len/MAX_HDR_LEN); + gint len = strlen(hdr->header); + gchar *p, *q; + /* size is probably overestimated, but so we are on the safe side */ + gchar *tmp_hdr = g_malloc(len + 2 * len / MAX_HDR_LEN); - p = hdr->header; - q = tmp_hdr; + p = hdr->header; + q = tmp_hdr; - if(p[len-1] == '\n') - p[len-1] = 0; + if (p[len - 1] == '\n') + p[len - 1] = 0; - while(*p){ - gint i,l; - gchar *pp; - - /* look forward and find potential break points */ - i = 0; l = -1; - pp = p; - while(*pp && (i < MAX_HDR_LEN)){ - if((*pp == ' ') || (*pp == '\t')) - l = i; - pp++; - i++; - } - if(!*pp) l = pp-p; /* take rest, if EOS found */ + while (*p) { + gint i, l; + gchar *pp; - if(l == -1){ - /* no potential break point was found within MAX_HDR_LEN - so advance further until the next */ - while(*pp && *pp != ' ' && *pp != '\t'){ - pp++; - i++; - } - l = i; - } + /* look forward and find potential break points */ + i = 0; + l = -1; + pp = p; + while (*pp && (i < MAX_HDR_LEN)) { + if ((*pp == ' ') || (*pp == '\t')) + l = i; + pp++; + i++; + } + if (!*pp) + l = pp - p; /* take rest, if EOS found */ - /* copy */ - i = 0; - while(i < l){ - *(q++) = *(p++); - i++; - } - *(q++) = '\n'; - *(q++) = *(p++); /* this is either space, tab or 0 */ - } - { - gchar *new_hdr; - - g_free(hdr->header); - new_hdr = g_strdup(tmp_hdr); - g_free(tmp_hdr); - hdr->value = new_hdr + (hdr->value - hdr->header); - hdr->header = new_hdr; - } + if (l == -1) { + /* no potential break point was found within MAX_HDR_LEN so advance further until the next */ + while (*pp && *pp != ' ' && *pp != '\t') { + pp++; + i++; + } + l = i; + } + + /* copy */ + i = 0; + while (i < l) { + *(q++) = *(p++); + i++; + } + *(q++) = '\n'; + *(q++) = *(p++); /* this is either space, tab or 0 */ + } + { + gchar *new_hdr; + + g_free(hdr->header); + new_hdr = g_strdup(tmp_hdr); + g_free(tmp_hdr); + hdr->value = new_hdr + (hdr->value - hdr->header); + hdr->header = new_hdr; + } } -header *create_header(header_id id, gchar *fmt, ...) +header* +create_header(header_id id, gchar * fmt, ...) { - gchar *p; - header *hdr; - va_list args; - va_start(args, fmt); + gchar *p; + header *hdr; + va_list args; + va_start(args, fmt); - if((hdr = g_malloc(sizeof(header)))){ + if ((hdr = g_malloc(sizeof(header)))) { - hdr->id = id; - hdr->header = g_strdup_vprintf(fmt, args); - hdr->value = NULL; + hdr->id = id; + hdr->header = g_strdup_vprintf(fmt, args); + hdr->value = NULL; - p = hdr->header; - while(*p && *p != ':') p++; - if(*p) - hdr->value = p+1; - } + p = hdr->header; + while (*p && *p != ':') + p++; + if (*p) + hdr->value = p + 1; + } - va_end(args); - return hdr; + va_end(args); + return hdr; } -void destroy_header(header *hdr) +void +destroy_header(header * hdr) { - if(hdr){ - if(hdr->header) g_free(hdr->header); - g_free(hdr); - } + if (hdr) { + if (hdr->header) + g_free(hdr->header); + g_free(hdr); + } } -header *copy_header(header *hdr) +header* +copy_header(header * hdr) { - header *new_hdr = NULL; + header *new_hdr = NULL; - if(hdr){ - if((new_hdr = g_malloc(sizeof(header)))){ - new_hdr->id = hdr->id; - new_hdr->header = g_strdup(hdr->header); - new_hdr->value = new_hdr->header + (hdr->value - hdr->header); - } - } - return new_hdr; + if (hdr) { + if ((new_hdr = g_malloc(sizeof(header)))) { + new_hdr->id = hdr->id; + new_hdr->header = g_strdup(hdr->header); + new_hdr->value = new_hdr->header + (hdr->value - hdr->header); + } + } + return new_hdr; } -header *get_header(gchar *line) +header* +get_header(gchar * line) { - gchar *p = line; - gchar buf[64], *q = buf; - gint i; - header *hdr; - - while(*p && (*p != ':') && (q < buf+63)) *(q++) = *(p++); - *q = 0; - - if(*p != ':') return NULL; + gchar *p = line; + gchar buf[64], *q = buf; + gint i; + header *hdr; - hdr = g_malloc(sizeof(header)); + while (*p && (*p != ':') && (q < buf + 63)) + *(q++) = *(p++); + *q = 0; - hdr->value = NULL; - p++; + if (*p != ':') + return NULL; - while(*p && (*p == ' ' || *p == '\t')) p++; - hdr->value = p; + hdr = g_malloc(sizeof(header)); - for(i = 0; i < HEAD_NUM_IDS; i++){ - if(strcasecmp(header_names[i].header, buf) == 0) - break; - } - hdr->id = (header_id)i; - hdr->header = g_strdup(line); - hdr->value = hdr->header + (hdr->value - line); + hdr->value = NULL; + p++; - DEBUG(4) debugf("header: %d = %s", hdr->id, hdr->header); + while (*p && (*p == ' ' || *p == '\t')) + p++; + hdr->value = p; - return hdr; + for (i = 0; i < HEAD_NUM_IDS; i++) { + if (strcasecmp(header_names[i].header, buf) == 0) + break; + } + hdr->id = (header_id) i; + hdr->header = g_strdup(line); + hdr->value = hdr->header + (hdr->value - line); + + DEBUG(4) debugf("header: %d = %s", hdr->id, hdr->header); + + return hdr; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/interface.c --- a/src/interface.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/interface.c Mon Oct 27 16:23:10 2008 +0100 @@ -21,79 +21,75 @@ /* define if you get problems... */ /*#define SOCKADDR_OLD 1*/ -gboolean init_sockaddr(struct sockaddr_in *name, interface *iface) +gboolean +init_sockaddr(struct sockaddr_in * name, interface * iface) { - struct hostent *he; - struct in_addr ia; - + struct hostent *he; + struct in_addr ia; + #ifdef SOCKADDR_OLD - /* here I tried to be intelligent and failed. */ - if(isalpha(iface->address[0])){ - if ((he = gethostbyname(iface->address)) == NULL) { - logwrite(LOG_ALERT, - "local address '%s' unknown. (deleting)\n", - iface->address); - return FALSE; - } - memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); - }else if(isdigit(iface->address[0])){ - if(inet_aton(iface->address, &ia)){ - memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); - }else{ - logwrite(LOG_ALERT, - "invalid address '%s': inet_aton() failed (deleting)\n", - iface->address); - return FALSE; - } - }else{ - logwrite(LOG_ALERT, - "invalid address '%s', should begin with a aphanumeric (deleting)\n", - iface->address); - return FALSE; - } + /* here I tried to be intelligent and failed. */ + if (isalpha(iface->address[0])) { + if ((he = gethostbyname(iface->address)) == NULL) { + logwrite(LOG_ALERT, "local address '%s' unknown. (deleting)\n", iface->address); + return FALSE; + } + memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); + } else if (isdigit(iface->address[0])) { + if (inet_aton(iface->address, &ia)) { + memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); + } else { + logwrite(LOG_ALERT, "invalid address '%s': inet_aton() failed (deleting)\n", iface->address); + return FALSE; + } + } else { + logwrite(LOG_ALERT, "invalid address '%s', should begin with a aphanumeric (deleting)\n", iface->address); + return FALSE; + } #else - /* this is how others to it. I follow the crowd... */ - if(inet_aton(iface->address, &ia) != 0){ - /* IP address */ - memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); - }else{ - if ((he = gethostbyname(iface->address)) == NULL) { - logwrite(LOG_ALERT, "local address '%s' unknown. (deleting)\n", iface->address); - return FALSE; - } - memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); - } + /* this is how others to it. I follow the crowd... */ + if (inet_aton(iface->address, &ia) != 0) { + /* IP address */ + memcpy(&(name->sin_addr), &ia, sizeof(name->sin_addr)); + } else { + if ((he = gethostbyname(iface->address)) == NULL) { + logwrite(LOG_ALERT, "local address '%s' unknown. (deleting)\n", iface->address); + return FALSE; + } + memcpy(&(name->sin_addr), he->h_addr, sizeof(name->sin_addr)); + } #endif - name->sin_family = AF_INET; - name->sin_port = htons(iface->port); + name->sin_family = AF_INET; + name->sin_port = htons(iface->port); - return TRUE; + return TRUE; } -int make_server_socket(interface *iface) +int +make_server_socket(interface * iface) { - int sock = -1; - struct sockaddr_in server; - - memset(&server, 0, sizeof(struct sockaddr_in)); + int sock = -1; + struct sockaddr_in server; - /* Create the socket. */ - sock = socket (PF_INET, SOCK_STREAM, 0); - if (sock < 0){ - logwrite(LOG_ALERT, "socket: %s\n", strerror(errno)); - return -1; - } - - if(init_sockaddr(&server, iface)){ - /* bind the socket */ - if (bind (sock, (struct sockaddr *) &server, sizeof (server)) < 0){ - logwrite(LOG_ALERT, "bind: %s\n", strerror(errno)); - return -1; - } - }else{ - close(sock); - return -1; - } - - return sock; + memset(&server, 0, sizeof(struct sockaddr_in)); + + /* Create the socket. */ + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + logwrite(LOG_ALERT, "socket: %s\n", strerror(errno)); + return -1; + } + + if (init_sockaddr(&server, iface)) { + /* bind the socket */ + if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { + logwrite(LOG_ALERT, "bind: %s\n", strerror(errno)); + return -1; + } + } else { + close(sock); + return -1; + } + + return sock; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/id_close.c --- a/src/libident/id_close.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/id_close.c Mon Oct 27 16:23:10 2008 +0100 @@ -16,14 +16,13 @@ #define IN_LIBIDENT_SRC #include "ident.h" -int id_close __P1(ident_t *, id) +int +id_close __P1(ident_t *, id) { - int res; - - res = close(id->fd); - free(id); - - return res; + int res; + + res = close(id->fd); + free(id); + + return res; } - - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/id_open.c --- a/src/libident/id_open.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/id_open.c Mon Oct 27 16:23:10 2008 +0100 @@ -39,129 +39,120 @@ /* -ident_t *id_open __P3(struct in_addr *, laddr, - struct in_addr *, faddr, - struct timeval *, timeout) +ident_t *id_open __P3(struct in_addr *, laddr, struct in_addr *, faddr, struct timeval *, timeout) */ -ident_t *id_open __P(( __STRUCT_IN_ADDR_P laddr, - __STRUCT_IN_ADDR_P faddr, - __STRUCT_TIMEVAL_P timeout)) +ident_t* +id_open __P((__STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P faddr, __STRUCT_TIMEVAL_P timeout)) { - ident_t *id; - int res, tmperrno; - struct sockaddr_in sin_laddr, sin_faddr; - fd_set rs, ws, es; + ident_t *id; + int res, tmperrno; + struct sockaddr_in sin_laddr, sin_faddr; + fd_set rs, ws, es; #ifndef OLD_SETSOCKOPT - int on = 1; - struct linger linger; + int on = 1; + struct linger linger; #endif - - if ((id = (ident_t *) malloc(sizeof(*id))) == 0) - return 0; - - if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - free(id); - return 0; - } - - if (timeout) - { - if ((res = fcntl(id->fd, F_GETFL, 0)) < 0) - goto ERROR; + + if ((id = (ident_t *) malloc(sizeof(*id))) == 0) + return 0; + + if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + free(id); + return 0; + } + + if (timeout) { + if ((res = fcntl(id->fd, F_GETFL, 0)) < 0) + goto ERROR; #ifndef VMS - if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0) - goto ERROR; + if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0) + goto ERROR; #endif - } + } - /* We silently ignore errors if we can't change LINGER */ + /* We silently ignore errors if we can't change LINGER */ #ifdef OLD_SETSOCKOPT - /* Old style setsockopt() */ - (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER); - (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR); + /* Old style setsockopt() */ + (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER); + (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR); #else - /* New style setsockopt() */ - linger.l_onoff = 0; - linger.l_linger = 0; - - (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); - (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); + /* New style setsockopt() */ + linger.l_onoff = 0; + linger.l_linger = 0; + + (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); + (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); #endif - - id->buf[0] = '\0'; - - bzero((char *)&sin_laddr, sizeof(sin_laddr)); - sin_laddr.sin_family = AF_INET; - sin_laddr.sin_addr = *laddr; - sin_laddr.sin_port = 0; - - if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0) - { + + id->buf[0] = '\0'; + + bzero((char *) &sin_laddr, sizeof(sin_laddr)); + sin_laddr.sin_family = AF_INET; + sin_laddr.sin_addr = *laddr; + sin_laddr.sin_port = 0; + + if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0) { #ifdef DEBUG - perror("libident: bind"); + perror("libident: bind"); #endif - goto ERROR; - } - - bzero((char *)&sin_faddr, sizeof(sin_faddr)); - sin_faddr.sin_family = AF_INET; - sin_faddr.sin_addr = *faddr; - sin_faddr.sin_port = htons(IDPORT); + goto ERROR; + } - errno = 0; - res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr)); - if (res < 0 && errno != EINPROGRESS) - { + bzero((char *) &sin_faddr, sizeof(sin_faddr)); + sin_faddr.sin_family = AF_INET; + sin_faddr.sin_addr = *faddr; + sin_faddr.sin_port = htons(IDPORT); + + errno = 0; + res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr)); + if (res < 0 && errno != EINPROGRESS) { #ifdef DEBUG - perror("libident: connect"); + perror("libident: connect"); #endif - goto ERROR; - } + goto ERROR; + } - if (timeout) - { - FD_ZERO(&rs); - FD_ZERO(&ws); - FD_ZERO(&es); - - FD_SET(id->fd, &rs); - FD_SET(id->fd, &ws); - FD_SET(id->fd, &es); + if (timeout) { + FD_ZERO(&rs); + FD_ZERO(&ws); + FD_ZERO(&es); + + FD_SET(id->fd, &rs); + FD_SET(id->fd, &ws); + FD_SET(id->fd, &es); #ifdef __hpux - if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0) + if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0) #else - if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0) + if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0) #endif - { + { #ifdef DEBUG - perror("libident: select"); + perror("libident: select"); #endif - goto ERROR; + goto ERROR; + } + + if (res == 0) { + errno = ETIMEDOUT; + goto ERROR; + } + + if (FD_ISSET(id->fd, &es)) + goto ERROR; + + if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws)) + goto ERROR; } - - if (res == 0) - { - errno = ETIMEDOUT; - goto ERROR; - } - - if (FD_ISSET(id->fd, &es)) - goto ERROR; - - if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws)) - goto ERROR; - } - - return id; - + + return id; + ERROR: - tmperrno = errno; /* Save, so close() won't erase it */ - close(id->fd); - free(id); - errno = tmperrno; - return 0; + tmperrno = errno; /* Save, so close() won't erase it */ + close(id->fd); + free(id); + errno = tmperrno; + return 0; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/id_parse.c --- a/src/libident/id_parse.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/id_parse.c Mon Oct 27 16:23:10 2008 +0100 @@ -32,198 +32,184 @@ # include #endif #ifdef VMS -# include /* for fd_set */ +# include /* for fd_set */ #endif #define IN_LIBIDENT_SRC #include "ident.h" /* -int id_parse __P7(ident_t *, id, - struct timeval *, timeout, - int *, lport, - int *, fport, - char **, identifier, - char **, opsys, - char **, charset) +int +id_parse __P7(ident_t *, id, + struct timeval *, timeout, + int *, lport, + int *, fport, + char **, identifier, + char **, opsys, + char **, charset) */ -int id_parse __P(( ident_t *id, - __STRUCT_TIMEVAL_P timeout, - int *lport, - int *fport, - char **identifier, - char **opsys, - char **charset)) +int +id_parse __P((ident_t * id, + __STRUCT_TIMEVAL_P timeout, + int *lport, + int *fport, + char **identifier, + char **opsys, + char **charset)) { - char c, *cp, *tmp_charset; - fd_set rs; - int pos, res=0, lp, fp; - - errno = 0; - - tmp_charset = 0; - - if (!id) - return -1; - if (lport) - *lport = 0; - if (fport) - *fport = 0; - if (identifier) - *identifier = 0; - if (opsys) - *opsys = 0; - if (charset) - *charset = 0; - - pos = strlen(id->buf); - - if (timeout) - { - FD_ZERO(&rs); - FD_SET(id->fd, &rs); + char c, *cp, *tmp_charset; + fd_set rs; + int pos, res = 0, lp, fp; + + errno = 0; + + tmp_charset = 0; + + if (!id) + return -1; + if (lport) + *lport = 0; + if (fport) + *fport = 0; + if (identifier) + *identifier = 0; + if (opsys) + *opsys = 0; + if (charset) + *charset = 0; + + pos = strlen(id->buf); + + if (timeout) { + FD_ZERO(&rs); + FD_SET(id->fd, &rs); #ifdef __hpux - if ((res = select(FD_SETSIZE, (int *) &rs, (int *)0, (int *)0, timeout)) < 0) + if ((res = select(FD_SETSIZE, (int *) &rs, (int *) 0, (int *) 0, timeout)) < 0) #else - if ((res = select(FD_SETSIZE, &rs, (fd_set *)0, (fd_set *)0, timeout)) < 0) + if ((res = select(FD_SETSIZE, &rs, (fd_set *) 0, (fd_set *) 0, timeout)) < 0) #endif - return -1; - - if (res == 0) - { - errno = ETIMEDOUT; - return -1; + return -1; + + if (res == 0) { + errno = ETIMEDOUT; + return -1; + } } - } - - /* Every octal value is allowed except 0, \n and \r */ - while (pos < sizeof(id->buf) && - (res = read(id->fd, id->buf + pos, 1)) == 1 && - id->buf[pos] != '\n' && id->buf[pos] != '\r') - pos++; - - if (res < 0) - return -1; - - if (res == 0) - { - errno = ENOTCONN; - return -1; - } - - if (id->buf[pos] != '\n' && id->buf[pos] != '\r') - return 0; /* Not properly terminated string */ - - id->buf[pos++] = '\0'; - - /* - ** Get first field ( , ) - */ - cp = id_strtok(id->buf, ":", &c); - if (!cp) - return -2; - - if (sscanf(cp, " %d , %d", &lp, &fp) != 2) - { - if (identifier) - { - *identifier = id_strdup(cp); - if (*identifier == NULL) - return -4; + + /* Every octal value is allowed except 0, \n and \r */ + while (pos < sizeof(id->buf) + && (res = read(id->fd, id->buf + pos, 1)) == 1 + && id->buf[pos] != '\n' && id->buf[pos] != '\r') + pos++; + + if (res < 0) + return -1; + + if (res == 0) { + errno = ENOTCONN; + return -1; } - return -2; - } - - if (lport) - *lport = lp; - if (fport) - *fport = fp; - - /* - ** Get second field (USERID or ERROR) - */ - cp = id_strtok((char *)0, ":", &c); - if (!cp) - return -2; - - if (strcmp(cp, "ERROR") == 0) - { - cp = id_strtok((char *)0, "\n\r", &c); + + if (id->buf[pos] != '\n' && id->buf[pos] != '\r') + return 0; /* Not properly terminated string */ + + id->buf[pos++] = '\0'; + + /* + ** Get first field ( , ) + */ + cp = id_strtok(id->buf, ":", &c); if (!cp) - return -2; - - if (identifier) - { - *identifier = id_strdup(cp); - if (*identifier == NULL) - return -4; + return -2; + + if (sscanf(cp, " %d , %d", &lp, &fp) != 2) { + if (identifier) { + *identifier = id_strdup(cp); + if (*identifier == NULL) + return -4; + } + return -2; } - - return 2; - } - else if (strcmp(cp, "USERID") == 0) - { + + if (lport) + *lport = lp; + if (fport) + *fport = fp; + /* - ** Get first subfield of third field - */ - cp = id_strtok((char *) 0, ",:", &c); + ** Get second field (USERID or ERROR) + */ + cp = id_strtok((char *) 0, ":", &c); if (!cp) - return -2; - - if (opsys) - { - *opsys = id_strdup(cp); - if (*opsys == NULL) - return -4; + return -2; + + if (strcmp(cp, "ERROR") == 0) { + cp = id_strtok((char *) 0, "\n\r", &c); + if (!cp) + return -2; + + if (identifier) { + *identifier = id_strdup(cp); + if (*identifier == NULL) + return -4; + } + + return 2; + } else if (strcmp(cp, "USERID") == 0) { + /* + ** Get first subfield of third field + */ + cp = id_strtok((char *) 0, ",:", &c); + if (!cp) + return -2; + + if (opsys) { + *opsys = id_strdup(cp); + if (*opsys == NULL) + return -4; + } + + /* + ** We have a second subfield () + */ + if (c == ',') { + cp = id_strtok((char *) 0, ":", &c); + if (!cp) + return -2; + + tmp_charset = cp; + if (charset) { + *charset = id_strdup(cp); + if (*charset == NULL) + return -4; + } + + /* + ** We have even more subfields - ignore them + */ + if (c == ',') + id_strtok((char *) 0, ":", &c); + } + + if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0) + cp = id_strtok((char *) 0, (char *) 0, &c); + else + cp = id_strtok((char *) 0, "\n\r", &c); + + if (identifier) { + *identifier = id_strdup(cp); + if (*identifier == NULL) + return -4; + } + return 1; + } else { + if (identifier) { + *identifier = id_strdup(cp); + if (*identifier == NULL) + return -4; + } + return -3; } - - /* - ** We have a second subfield () - */ - if (c == ',') - { - cp = id_strtok((char *)0, ":", &c); - if (!cp) - return -2; - - tmp_charset = cp; - if (charset) - { - *charset = id_strdup(cp); - if (*charset == NULL) - return -4; - } - - /* - ** We have even more subfields - ignore them - */ - if (c == ',') - id_strtok((char *)0, ":", &c); - } - - if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0) - cp = id_strtok((char *)0, (char *)0, &c); - else - cp = id_strtok((char *)0, "\n\r", &c); - - if (identifier) - { - *identifier = id_strdup(cp); - if (*identifier == NULL) - return -4; - } - return 1; - } - else - { - if (identifier) - { - *identifier = id_strdup(cp); - if (*identifier == NULL) - return -4; - } - return -3; - } } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/id_query.c --- a/src/libident/id_query.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/id_query.c Mon Oct 27 16:23:10 2008 +0100 @@ -30,59 +30,53 @@ # include #endif #ifdef VMS -# include /* for fd_set */ +# include /* for fd_set */ #endif #define IN_LIBIDENT_SRC #include "ident.h" /* -int id_query __P4(ident_t *, id, - int, lport, - int, fport, - struct timeval *, timeout) +int +id_query __P4(ident_t *, id, int, lport, int, fport, struct timeval *, timeout) */ -int id_query __P(( ident_t *id, - int lport, - int fport, - __STRUCT_TIMEVAL_P timeout)) +int +id_query __P((ident_t * id, int lport, int fport, __STRUCT_TIMEVAL_P timeout)) { #ifdef SIGRETURNTYPE - SIGRETURNTYPE (*old_sig)(); + SIGRETURNTYPE(*old_sig) (); #else - void (*old_sig) __P((int)); + void (*old_sig) __P((int)); #endif - int res; - char buf[80]; - fd_set ws; - - sprintf(buf, "%d , %d\r\n", lport, fport); - - if (timeout) - { - FD_ZERO(&ws); - FD_SET(id->fd, &ws); + int res; + char buf[80]; + fd_set ws; + + sprintf(buf, "%d , %d\r\n", lport, fport); + + if (timeout) { + FD_ZERO(&ws); + FD_SET(id->fd, &ws); #ifdef __hpux - if ((res = select(FD_SETSIZE, (int *)0, (int *)&ws, (int *)0, timeout)) < 0) + if ((res = select(FD_SETSIZE, (int *) 0, (int *) &ws, (int *) 0, timeout)) < 0) #else - if ((res = select(FD_SETSIZE, (fd_set *)0, &ws, (fd_set *)0, timeout)) < 0) + if ((res = select(FD_SETSIZE, (fd_set *) 0, &ws, (fd_set *) 0, timeout)) < 0) #endif - return -1; - - if (res == 0) - { - errno = ETIMEDOUT; - return -1; + return -1; + + if (res == 0) { + errno = ETIMEDOUT; + return -1; + } } - } - old_sig = signal(SIGPIPE, SIG_IGN); - - res = write(id->fd, buf, strlen(buf)); - - signal(SIGPIPE, old_sig); - - return res; + old_sig = signal(SIGPIPE, SIG_IGN); + + res = write(id->fd, buf, strlen(buf)); + + signal(SIGPIPE, old_sig); + + return res; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/ident.c --- a/src/libident/ident.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/ident.c Mon Oct 27 16:23:10 2008 +0100 @@ -1,5 +1,5 @@ /* -** ident.c High-level calls to the ident lib +** ident.c High-level calls to the ident lib ** ** Author: Pär Emanuelsson ** Hacked by: Peter Eriksson @@ -31,125 +31,106 @@ /* Do a complete ident query and return result */ -IDENT *ident_lookup __P2(int, fd, - int, timeout) +IDENT* +ident_lookup __P2(int, fd, int, timeout) { - struct sockaddr_in localaddr, remoteaddr; - int len; - - len = sizeof(remoteaddr); - if (getpeername(fd, (struct sockaddr*) &remoteaddr, &len) < 0) - return 0; - - len = sizeof(localaddr); - if (getsockname(fd, (struct sockaddr *) &localaddr, &len) < 0) - return 0; + struct sockaddr_in localaddr, remoteaddr; + int len; - return ident_query( &localaddr.sin_addr, &remoteaddr.sin_addr, - ntohs(localaddr.sin_port), ntohs(remoteaddr.sin_port), - timeout); + len = sizeof(remoteaddr); + if (getpeername(fd, (struct sockaddr *) &remoteaddr, &len) < 0) + return 0; + + len = sizeof(localaddr); + if (getsockname(fd, (struct sockaddr *) &localaddr, &len) < 0) + return 0; + + return ident_query(&localaddr.sin_addr, &remoteaddr.sin_addr, ntohs(localaddr.sin_port), ntohs(remoteaddr.sin_port), timeout); } -IDENT *ident_query __P5(struct in_addr *, laddr, - struct in_addr *, raddr, - int, lport, - int, rport, - int, timeout) +IDENT* +ident_query __P5(struct in_addr *, laddr, struct in_addr *, raddr, int, lport, int, rport, int, timeout) { - int res; - ident_t *id; - struct timeval timout; - IDENT *ident=0; + int res; + ident_t *id; + struct timeval timout; + IDENT *ident = 0; - - timout.tv_sec = timeout; - timout.tv_usec = 0; - - if (timeout) - id = id_open( laddr, raddr, &timout); - else - id = id_open( laddr, raddr, (struct timeval *)0); - - if (!id) - { - errno = EINVAL; - return 0; - } - - if (timeout) - res = id_query(id, rport, lport, &timout); - else - res = id_query(id, rport, lport, (struct timeval *) 0); - - if (res < 0) - { + + timout.tv_sec = timeout; + timout.tv_usec = 0; + + if (timeout) + id = id_open(laddr, raddr, &timout); + else + id = id_open(laddr, raddr, (struct timeval *) 0); + + if (!id) { + errno = EINVAL; + return 0; + } + + if (timeout) + res = id_query(id, rport, lport, &timout); + else + res = id_query(id, rport, lport, (struct timeval *) 0); + + if (res < 0) { + id_close(id); + return 0; + } + + ident = (IDENT *) malloc(sizeof(IDENT)); + if (!ident) { + id_close(id); + return 0; + } + + if (timeout) + res = id_parse(id, &timout, &ident->lport, &ident->fport, &ident->identifier, &ident->opsys, &ident->charset); + else + res = id_parse(id, (struct timeval *) 0, &ident->lport, &ident->fport, &ident->identifier, &ident->opsys, &ident->charset); + + if (res != 1) { + free(ident); + id_close(id); + return 0; + } + id_close(id); - return 0; - } - - ident = (IDENT *) malloc(sizeof(IDENT)); - if (!ident) { - id_close(id); - return 0; - } - - if (timeout) - res = id_parse(id, &timout, - &ident->lport, - &ident->fport, - &ident->identifier, - &ident->opsys, - &ident->charset); - else - res = id_parse(id, (struct timeval *) 0, - &ident->lport, - &ident->fport, - &ident->identifier, - &ident->opsys, - &ident->charset); - - if (res != 1) - { - free(ident); - id_close(id); - return 0; - } - - id_close(id); - return ident; /* At last! */ + return ident; /* At last! */ } -char *ident_id __P2(int, fd, - int, timeout) +char* +ident_id __P2(int, fd, int, timeout) { - IDENT *ident; - char *id=0; - - ident = ident_lookup(fd, timeout); - if (ident && ident->identifier && *ident->identifier) - { - id = id_strdup(ident->identifier); - if (id == NULL) - return NULL; - } + IDENT *ident; + char *id = 0; - ident_free(ident); - return id; + ident = ident_lookup(fd, timeout); + if (ident && ident->identifier && *ident->identifier) { + id = id_strdup(ident->identifier); + if (id == NULL) + return NULL; + } + + ident_free(ident); + return id; } -void ident_free __P1(IDENT *, id) +void +ident_free __P1(IDENT *, id) { - if (!id) - return; - if (id->identifier) - free(id->identifier); - if (id->opsys) - free(id->opsys); - if (id->charset) - free(id->charset); - free(id); + if (!id) + return; + if (id->identifier) + free(id->identifier); + if (id->opsys) + free(id->opsys); + if (id->charset) + free(id->charset); + free(id); } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/ident.h --- a/src/libident/ident.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/ident.h Mon Oct 27 16:23:10 2008 +0100 @@ -8,7 +8,7 @@ #ifndef __IDENT_H__ #define __IDENT_H__ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -22,21 +22,21 @@ #ifdef __P # undef __P #endif - + #ifdef IS_STDC -# define __P(AL) AL +# define __P(AL) AL #ifdef IN_LIBIDENT_SRC - + # define __P1(t1,a1) \ (t1 a1) - + # define __P2(t1,a1,t2,a2) \ (t1 a1, t2 a2) - + # define __P3(t1,a1,t2,a2,t3,a3) \ (t1 a1, t2 a2, t3 a3) - + # define __P4(t1,a1,t2,a2,t3,a3,t4,a4) \ (t1 a1, t2 a2, t3 a3, t4 a4) @@ -46,13 +46,13 @@ # define __P7(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) \ (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) #endif - + #else -# define __P(AL) () +# define __P(AL) () #ifdef IN_LIBIDENT_SRC - + # define __P1(t1,a1) (a1) \ t1 a1; # define __P2(t1,a1,t2,a2) (a1, a2) \ @@ -108,87 +108,74 @@ * in function prototypes... */ #if defined(__GNUC__) && !defined(INADDR_ANY) -# define __STRUCT_IN_ADDR_P void * +# define __STRUCT_IN_ADDR_P void * #else -# define __STRUCT_IN_ADDR_P struct in_addr * +# define __STRUCT_IN_ADDR_P struct in_addr * #endif #if defined(__GNUC__) && !defined(DST_NONE) -# define __STRUCT_TIMEVAL_P void * +# define __STRUCT_TIMEVAL_P void * #else -# define __STRUCT_TIMEVAL_P struct timeval * +# define __STRUCT_TIMEVAL_P struct timeval * #endif #if defined(__sgi) && defined(_POSIX_SOURCE) # undef __STRUCT_TIMEVAL_P -# define __STRUCT_TIMEVAL_P void * +# define __STRUCT_TIMEVAL_P void * #endif - + #ifndef IDBUFSIZE # define IDBUFSIZE 2048 #endif #ifndef IDPORT -# define IDPORT 113 +# define IDPORT 113 #endif -typedef struct -{ - int fd; - char buf[IDBUFSIZE]; -} ident_t; + typedef struct { + int fd; + char buf[IDBUFSIZE]; + } ident_t; -typedef struct { - int lport; /* Local port */ - int fport; /* Far (remote) port */ - char *identifier; /* Normally user name */ - char *opsys; /* OS */ - char *charset; /* Charset (what did you expect?) */ -} IDENT; /* For higher-level routines */ + typedef struct { + int lport; /* Local port */ + int fport; /* Far (remote) port */ + char *identifier; /* Normally user name */ + char *opsys; /* OS */ + char *charset; /* Charset (what did you expect?) */ + } IDENT; /* For higher-level routines */ /* Low-level calls and macros */ -#define id_fileno(ID) ((ID)->fd) +#define id_fileno(ID) ((ID)->fd) -extern ident_t * id_open __P((__STRUCT_IN_ADDR_P laddr, - __STRUCT_IN_ADDR_P faddr, - __STRUCT_TIMEVAL_P timeout)); - -extern int id_close __P((ident_t *id)); - -extern int id_query __P((ident_t *id, - int lport, - int fport, - __STRUCT_TIMEVAL_P timeout)); - -extern int id_parse __P((ident_t *id, - __STRUCT_TIMEVAL_P timeout, - int *lport, - int *fport, - char **identifier, - char **opsys, - char **charset)); - + extern ident_t *id_open __P((__STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P faddr, __STRUCT_TIMEVAL_P timeout)); + + extern int id_close __P((ident_t * id)); + + extern int id_query __P((ident_t * id, int lport, int fport, __STRUCT_TIMEVAL_P timeout)); + + extern int id_parse __P((ident_t * id, __STRUCT_TIMEVAL_P timeout, int *lport, int *fport, char **identifier, char **opsys, char **charset)); + /* High-level calls */ -extern IDENT *ident_lookup __P((int fd, int timeout)); + extern IDENT *ident_lookup __P((int fd, int timeout)); -extern char *ident_id __P((int fd, int timeout)); + extern char *ident_id __P((int fd, int timeout)); -extern IDENT *ident_query __P(( __STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P raddr, int lport, int rport, int timeout)); + extern IDENT *ident_query __P((__STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P raddr, int lport, int rport, int timeout)); -extern void ident_free __P((IDENT *id)); + extern void ident_free __P((IDENT * id)); -extern char id_version[]; + extern char id_version[]; #ifdef IN_LIBIDENT_SRC -extern char *id_strdup __P((char *str)); -extern char *id_strtok __P((char *cp, char *cs, char *dc)); + extern char *id_strdup __P((char *str)); + extern char *id_strtok __P((char *cp, char *cs, char *dc)); #endif -#ifdef __cplusplus +#ifdef __cplusplus } #endif - #endif diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/libident/support.c --- a/src/libident/support.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/libident/support.c Mon Oct 27 16:23:10 2008 +0100 @@ -18,69 +18,66 @@ #include "ident.h" -char *id_strdup __P1(char *, str) +char* +id_strdup __P1(char *, str) { - char *cp; + char *cp; - cp = (char *) malloc(strlen(str)+1); - if (cp == NULL) - { + cp = (char *) malloc(strlen(str) + 1); + if (cp == NULL) { #ifdef DEBUG - perror("libident: malloc"); + perror("libident: malloc"); #endif - return NULL; - } + return NULL; + } - strcpy(cp, str); + strcpy(cp, str); - return cp; + return cp; } -char *id_strtok __P3(char *, cp, - char *, cs, - char *, dc) +char* +id_strtok __P3(char *, cp, char *, cs, char *, dc) { - static char *bp = 0; - - if (cp) - bp = cp; - - /* - ** No delimitor cs - return whole buffer and point at end - */ - if (!cs) - { - while (*bp) - bp++; - return cs; - } - - /* - ** Skip leading spaces - */ - while (isspace(*bp)) + static char *bp = 0; + + if (cp) + bp = cp; + + /* + ** No delimitor cs - return whole buffer and point at end + */ + if (!cs) { + while (*bp) + bp++; + return cs; + } + + /* + ** Skip leading spaces + */ + while (isspace(*bp)) + bp++; + + /* + ** No token found? + */ + if (!*bp) + return 0; + + cp = bp; + while (*bp && !strchr(cs, *bp)) + bp++; + + /* + ** Remove trailing spaces + */ + *dc = *bp; + for (dc = bp - 1; dc > cp && isspace(*dc); dc--); + *++dc = '\0'; + bp++; - - /* - ** No token found? - */ - if (!*bp) - return 0; - - cp = bp; - while (*bp && !strchr(cs, *bp)) - bp++; - - /* - ** Remove trailing spaces - */ - *dc = *bp; - for (dc = bp-1; dc > cp && isspace(*dc); dc--) - ; - *++dc = '\0'; - - bp++; - - return cp; + + return cp; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/listen.c --- a/src/listen.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/listen.c Mon Oct 27 16:23:10 2008 +0100 @@ -22,222 +22,205 @@ static int volatile sighup_seen = 0; -static -void sighup_handler(int sig) +static void +sighup_handler(int sig) { - sighup_seen = 1; - signal(SIGHUP, sighup_handler); + sighup_seen = 1; + signal(SIGHUP, sighup_handler); } -static -void sigchld_handler(int sig) +static void +sigchld_handler(int sig) { - pid_t pid; - int status; - - pid = waitpid(0, &status, 0); - if(pid > 0){ - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, "process %d exited with %d\n", - pid, WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, - "process with pid %d got signal: %d\n", - pid, WTERMSIG(status)); - } - signal(SIGCHLD, sigchld_handler); + pid_t pid; + int status; + + pid = waitpid(0, &status, 0); + if (pid > 0) { + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "process %d exited with %d\n", pid, WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "process with pid %d got signal: %d\n", pid, WTERMSIG(status)); + } + signal(SIGCHLD, sigchld_handler); } #ifdef ENABLE_SMTP_SERVER -void accept_connect(int listen_sock, int sock, struct sockaddr_in* sock_addr) +void +accept_connect(int listen_sock, int sock, struct sockaddr_in *sock_addr) { - pid_t pid; - int dup_sock = dup(sock); - FILE *out, *in; - gchar *rem_host; - gchar *ident = NULL; + pid_t pid; + int dup_sock = dup(sock); + FILE *out, *in; + gchar *rem_host; + gchar *ident = NULL; - rem_host = g_strdup(inet_ntoa(sock_addr->sin_addr)); + rem_host = g_strdup(inet_ntoa(sock_addr->sin_addr)); #ifdef ENABLE_IDENT - { - gchar *id = NULL; - if((id = (gchar *)ident_id(sock, 60))){ - ident = g_strdup(id); - } - logwrite(LOG_NOTICE, "connect from host %s, port %hd ident=%s\n", - rem_host, - ntohs (sock_addr->sin_port), - ident ? ident : "(unknown)"); - } + { + gchar *id = NULL; + if ((id = (gchar *) ident_id(sock, 60))) { + ident = g_strdup(id); + } + logwrite(LOG_NOTICE, "connect from host %s, port %hd ident=%s\n", rem_host, + ntohs(sock_addr->sin_port), ident ? ident : "(unknown)"); + } #else - logwrite(LOG_NOTICE, "connect from host %s, port %hd\n", - rem_host, - ntohs (sock_addr->sin_port)); + logwrite(LOG_NOTICE, "connect from host %s, port %hd\n", rem_host, ntohs(sock_addr->sin_port)); #endif - // start child for connection: - signal(SIGCHLD, sigchld_handler); - pid = fork(); - if(pid == 0){ - close(listen_sock); - out = fdopen(sock, "w"); - in = fdopen(dup_sock, "r"); - - smtp_in(in, out, rem_host, ident); + // start child for connection: + signal(SIGCHLD, sigchld_handler); + pid = fork(); + if (pid == 0) { + close(listen_sock); + out = fdopen(sock, "w"); + in = fdopen(dup_sock, "r"); - _exit(EXIT_SUCCESS); - }else if(pid < 0){ - logwrite(LOG_WARNING, "could not fork for incoming smtp connection: %s\n", - strerror(errno)); - } + smtp_in(in, out, rem_host, ident); + _exit(EXIT_SUCCESS); + } else if (pid < 0) { + logwrite(LOG_WARNING, "could not fork for incoming smtp connection: %s\n", strerror(errno)); + } #ifdef ENABLE_IDENT - if(ident != NULL) g_free(ident); + if (ident != NULL) + g_free(ident); #endif - close(sock); - close(dup_sock); + close(sock); + close(dup_sock); } -#endif /*ifdef ENABLE_SMTP_SERVER*/ +#endif /*ifdef ENABLE_SMTP_SERVER */ -void listen_port(GList *iface_list, gint qival, char *argv[]) +void +listen_port(GList * iface_list, gint qival, char *argv[]) { - int i; - fd_set active_fd_set, read_fd_set; - struct timeval tm; - time_t time_before, time_now; - struct sockaddr_in clientname; - size_t size; - GList *node, *node_next; - int sel_ret; + int i; + fd_set active_fd_set, read_fd_set; + struct timeval tm; + time_t time_before, time_now; + struct sockaddr_in clientname; + size_t size; + GList *node, *node_next; + int sel_ret; - /* Create the sockets and set them up to accept connections. */ - FD_ZERO (&active_fd_set); + /* Create the sockets and set them up to accept connections. */ + FD_ZERO(&active_fd_set); #ifdef ENABLE_SMTP_SERVER - for(node = g_list_first(iface_list); - node; - node = node_next){ - interface *iface = (interface *)(node->data); - int sock; + for (node = g_list_first(iface_list); node; node = node_next) { + interface *iface = (interface *) (node->data); + int sock; - node_next=g_list_next(node); - if ((sock = make_server_socket (iface))<0){ - iface_list= g_list_remove_link(iface_list, node); - g_list_free_1(node); - continue; - } - if (listen (sock, 1) < 0){ - logwrite(LOG_ALERT, "listen: (terminating): %s\n", strerror(errno)); - exit (EXIT_FAILURE); - } - logwrite(LOG_NOTICE, "listening on interface %s:%d\n", - iface->address, iface->port); - DEBUG(5) debugf("sock = %d\n", sock); - FD_SET (sock, &active_fd_set); - } + node_next = g_list_next(node); + if ((sock = make_server_socket(iface)) < 0) { + iface_list = g_list_remove_link(iface_list, node); + g_list_free_1(node); + continue; + } + if (listen(sock, 1) < 0) { + logwrite(LOG_ALERT, "listen: (terminating): %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + logwrite(LOG_NOTICE, "listening on interface %s:%d\n", iface->address, iface->port); + DEBUG(5) debugf("sock = %d\n", sock); + FD_SET(sock, &active_fd_set); + } #endif - /* setup handler for HUP signal: */ - signal(SIGHUP, sighup_handler); - signal(SIGCHLD, sigchld_handler); + /* setup handler for HUP signal: */ + signal(SIGHUP, sighup_handler); + signal(SIGCHLD, sigchld_handler); - /* now that we have our socket(s), - we can give up root privileges */ - if(!conf.run_as_user){ - if(setegid(conf.mail_gid) != 0){ - logwrite(LOG_ALERT, "could not change gid to %d: %s\n", - conf.mail_gid, strerror(errno)); - exit(EXIT_FAILURE); - } - if(seteuid(conf.mail_uid) != 0){ - logwrite(LOG_ALERT, "could not change uid to %d: %s\n", - conf.mail_uid, strerror(errno)); - exit(EXIT_FAILURE); - } - } + /* now that we have our socket(s), + we can give up root privileges */ + if (!conf.run_as_user) { + if (setegid(conf.mail_gid) != 0) { + logwrite(LOG_ALERT, "could not change gid to %d: %s\n", conf.mail_gid, strerror(errno)); + exit(EXIT_FAILURE); + } + if (seteuid(conf.mail_uid) != 0) { + logwrite(LOG_ALERT, "could not change uid to %d: %s\n", conf.mail_uid, strerror(errno)); + exit(EXIT_FAILURE); + } + } - /* sel_ret = 0;*/ - time(&time_before); - time_before -= qival; - sel_ret = -1; + /* sel_ret = 0; */ + time(&time_before); + time_before -= qival; + sel_ret = -1; - while (1){ + while (1) { - /* if we were interrupted by an incoming connection (or a signal) - we have to recalculate the time until the next queue run should - occur. select may put a value into tm, but doc for select() says - we should not use it.*/ - if(qival > 0){ - time(&time_now); - if(sel_ret == 0){ /* we are either just starting or did a queue run */ - tm.tv_sec = qival; - tm.tv_usec = 0; - time_before = time_now; - }else{ - tm.tv_sec = qival - (time_now - time_before); - tm.tv_usec = 0; + /* if we were interrupted by an incoming connection (or a signal) + we have to recalculate the time until the next queue run should + occur. select may put a value into tm, but doc for select() says + we should not use it. */ + if (qival > 0) { + time(&time_now); + if (sel_ret == 0) { /* we are either just starting or did a queue run */ + tm.tv_sec = qival; + tm.tv_usec = 0; + time_before = time_now; + } else { + tm.tv_sec = qival - (time_now - time_before); + tm.tv_usec = 0; - /* race condition, very unlikely (but possible): */ - if(tm.tv_sec < 0) - tm.tv_sec = 0; - } - } - /* Block until input arrives on one or more active sockets, - or signal arrives, - or queuing interval time elapsed (if qival > 0) */ - read_fd_set = active_fd_set; - if ((sel_ret = select(FD_SETSIZE, &read_fd_set, NULL, NULL, - qival > 0 ? &tm : NULL)) < 0){ - if(errno != EINTR){ - logwrite(LOG_ALERT, "select: (terminating): %s\n", strerror(errno)); - exit (EXIT_FAILURE); - }else{ - if(sighup_seen){ - logwrite(LOG_NOTICE, "HUP signal received. Restarting daemon\n"); + /* race condition, very unlikely (but possible): */ + if (tm.tv_sec < 0) + tm.tv_sec = 0; + } + } + /* Block until input arrives on one or more active sockets, + or signal arrives, + or queuing interval time elapsed (if qival > 0) */ + read_fd_set = active_fd_set; + if ((sel_ret = select(FD_SETSIZE, &read_fd_set, NULL, NULL, qival > 0 ? &tm : NULL)) < 0) { + if (errno != EINTR) { + logwrite(LOG_ALERT, "select: (terminating): %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } else { + if (sighup_seen) { + logwrite(LOG_NOTICE, "HUP signal received. Restarting daemon\n"); - for(i = 0; i < FD_SETSIZE; i++) - if(FD_ISSET(i, &active_fd_set)) - close(i); + for (i = 0; i < FD_SETSIZE; i++) + if (FD_ISSET(i, &active_fd_set)) + close(i); - execv(argv[0], &(argv[0])); - logwrite(LOG_ALERT, "restarting failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); + execv(argv[0], &(argv[0])); + logwrite(LOG_ALERT, "restarting failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } + } else if (sel_ret > 0) { +#ifdef ENABLE_SMTP_SERVER + for (i = 0; i < FD_SETSIZE; i++) { + if (FD_ISSET(i, &read_fd_set)) { + int sock = i; + int new; + size = sizeof(clientname); + new = accept(sock, (struct sockaddr *) &clientname, &size); + if (new < 0) { + logwrite(LOG_ALERT, "accept: (ignoring): %s\n", strerror(errno)); + } else + accept_connect(sock, new, &clientname); + } + } +#else + ; +#endif + } else { + /* If select returns 0, the interval time has elapsed. + We start a new queue runner process */ + int pid; + signal(SIGCHLD, sigchld_handler); + if ((pid = fork()) == 0) { + queue_run(); + + _exit(EXIT_SUCCESS); + } else if (pid < 0) { + logwrite(LOG_ALERT, "could not fork for queue run"); + } + } } - } - } - else if(sel_ret > 0){ -#ifdef ENABLE_SMTP_SERVER - for(i = 0; i < FD_SETSIZE; i++){ - if (FD_ISSET (i, &read_fd_set)){ - int sock = i; - int new; - size = sizeof (clientname); - new = accept (sock, - (struct sockaddr *) &clientname, - &size); - if (new < 0){ - logwrite(LOG_ALERT, "accept: (ignoring): %s\n", - strerror(errno)); - }else - accept_connect(sock, new, &clientname); - } - } -#else - ; -#endif - }else{ - /* If select returns 0, the interval time has elapsed. - We start a new queue runner process */ - int pid; - signal(SIGCHLD, sigchld_handler); - if((pid = fork()) == 0){ - queue_run(); - - _exit(EXIT_SUCCESS); - } - else if(pid < 0){ - logwrite(LOG_ALERT, "could not fork for queue run"); - } - } - } } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/local.c --- a/src/local.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/local.c Mon Oct 27 16:23:10 2008 +0100 @@ -20,347 +20,333 @@ #include "peopen.h" #include -static -void message_stream(FILE *out, message *msg, GList *hdr_list, guint flags) +static void +message_stream(FILE * out, message * msg, GList * hdr_list, guint flags) { - time_t now = time(NULL); - GList *node; - - if(flags & MSGSTR_FROMLINE){ - fprintf(out, "From <%s@%s> %s", msg->return_path->local_part, - msg->return_path->domain, ctime(&now)); - } - - foreach(hdr_list, node){ - header *hdr = (header *)(node->data); - fputs(hdr->header, out); - } - putc('\n', out); - foreach(msg->data_list, node){ - /* From hack: */ - if(flags & MSGSTR_FROMHACK){ - if(strncmp(node->data, "From ", 5) == 0) - putc('>', out); - } - fputs(node->data, out); - } - putc('\n', out); + time_t now = time(NULL); + GList *node; + + if (flags & MSGSTR_FROMLINE) { + fprintf(out, "From <%s@%s> %s", msg->return_path->local_part, msg->return_path->domain, ctime(&now)); + } + + foreach(hdr_list, node) { + header *hdr = (header *) (node->data); + fputs(hdr->header, out); + } + putc('\n', out); + foreach(msg->data_list, node) { + /* From hack: */ + if (flags & MSGSTR_FROMHACK) { + if (strncmp(node->data, "From ", 5) == 0) + putc('>', out); + } + fputs(node->data, out); + } + putc('\n', out); } -gboolean append_file(message *msg, GList *hdr_list, gchar *user) +gboolean +append_file(message * msg, GList * hdr_list, gchar * user) { - struct passwd *pw; - gboolean ok = FALSE; - - /* headers may be special for a local delivery */ - if(hdr_list == NULL) - hdr_list = msg->hdr_list; + struct passwd *pw; + gboolean ok = FALSE; - if((pw = getpwnam(user))){ - uid_t saved_uid = geteuid(); - gid_t saved_gid = getegid(); - gboolean uid_ok = TRUE, gid_ok = TRUE; + /* headers may be special for a local delivery */ + if (hdr_list == NULL) + hdr_list = msg->hdr_list; - if(!conf.run_as_user){ - uid_ok = (seteuid(0) == 0); - if(uid_ok){ - gid_ok = (setegid(conf.mail_gid) == 0); - uid_ok = (seteuid(pw->pw_uid) == 0); - } - } + if ((pw = getpwnam(user))) { + uid_t saved_uid = geteuid(); + gid_t saved_gid = getegid(); + gboolean uid_ok = TRUE, gid_ok = TRUE; - DEBUG(5) debugf("running as euid %d\n", geteuid()); - DEBUG(5) debugf("running as egid %d\n", getegid()); + if (!conf.run_as_user) { + uid_ok = (seteuid(0) == 0); + if (uid_ok) { + gid_ok = (setegid(conf.mail_gid) == 0); + uid_ok = (seteuid(pw->pw_uid) == 0); + } + } - if(uid_ok && gid_ok){ - gchar *filename; - FILE *out; + DEBUG(5) debugf("running as euid %d\n", geteuid()); + DEBUG(5) debugf("running as egid %d\n", getegid()); - filename = g_strdup_printf("%s/%s", conf.mail_dir, user); - if((out = fopen(filename, "a"))){ + if (uid_ok && gid_ok) { + gchar *filename; + FILE *out; + + filename = g_strdup_printf("%s/%s", conf.mail_dir, user); + if ((out = fopen(filename, "a"))) { #ifdef USE_LIBLOCKFILE - gint err; - /* lock file using liblockfile */ - err = maillock(user,3); - if(err == 0){ + gint err; + /* lock file using liblockfile */ + err = maillock(user, 3); + if (err == 0) { #else - /* lock file: */ - struct flock lock; - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_END; - lock.l_start = lock.l_len = 0; - if(fcntl(fileno(out), F_SETLK, &lock) != -1){ + /* lock file: */ + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_END; + lock.l_start = lock.l_len = 0; + if (fcntl(fileno(out), F_SETLK, &lock) != -1) { #endif - fchmod(fileno(out), 0600); - - message_stream(out, msg, hdr_list, MSGSTR_FROMLINE|MSGSTR_FROMHACK); + fchmod(fileno(out), 0600); - ok = TRUE; - - /* close when still user */ - fclose(out); + message_stream(out, msg, hdr_list, MSGSTR_FROMLINE | MSGSTR_FROMHACK); + + ok = TRUE; + + /* close when still user */ + fclose(out); #ifdef USE_LIBLOCKFILE - mailunlock(); + mailunlock(); #endif - }else{ - fclose(out); + } else { + fclose(out); #ifdef USE_LIBLOCKFILE - DEBUG(3) debugf("could not lock file %s: error %d\n", - filename, err); - } /* XEmacs indenting convenience... */ + DEBUG(3) debugf("could not lock file %s: error %d\n", filename, err); + } /* XEmacs indenting convenience... */ #else - DEBUG(3) debugf("could not lock file %s: %s\n", - filename, strerror(errno)); + DEBUG(3) debugf("could not lock file %s: %s\n", filename, strerror(errno)); + } +#endif + } else { + logwrite(LOG_ALERT, "could not open file %s: %s\n", filename, strerror(errno)); + } + g_free(filename); + + if (!conf.run_as_user) { + uid_ok = (seteuid(0) == 0); + if (uid_ok) { + gid_ok = (setegid(saved_gid) == 0); + uid_ok = (seteuid(saved_uid) == 0); + } + } + + if (!uid_ok || !gid_ok) { + /* FIXME: if this fails we HAVE to exit, because we shall not run + with some users id. But we do not return, and so this message + will not be finished, so the user will get the message again + next time a delivery is attempted... */ + logwrite(LOG_ALERT, "could not set back uid or gid after local delivery: %s\n", strerror(errno)); + logwrite(LOG_ALERT, "uid=%d, gid=%d, euid=%d, egid=%d, want = %d, %d\n", + getuid(), getgid(), geteuid(), getegid(), saved_uid, saved_gid); + exit(EXIT_FAILURE); + } + } else { + logwrite(LOG_ALERT, "could not set uid or gid for local delivery, uid = %d: %s\n", pw->pw_uid, strerror(errno)); + } + } else { + logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); + errno = ENOENT; /* getpwnam does not set errno correctly */ } -#endif - }else{ - logwrite(LOG_ALERT, "could not open file %s: %s\n", - filename, strerror(errno)); - } - g_free(filename); - if(!conf.run_as_user){ - uid_ok = (seteuid(0) == 0); - if(uid_ok){ - gid_ok = (setegid(saved_gid) == 0); - uid_ok = (seteuid(saved_uid) == 0); - } - } - - if(!uid_ok || !gid_ok){ - /* FIXME: if this fails we HAVE to exit, because we shall not run - with some users id. But we do not return, and so this message - will not be finished, so the user will get the message again - next time a delivery is attempted... */ - logwrite(LOG_ALERT, - "could not set back uid or gid after local delivery: %s\n", - strerror(errno)); - logwrite(LOG_ALERT, - "uid=%d, gid=%d, euid=%d, egid=%d, want = %d, %d\n", - getuid(), getgid(), geteuid(), getegid(), saved_uid, saved_gid); - exit(EXIT_FAILURE); - } - }else{ - logwrite(LOG_ALERT, - "could not set uid or gid for local delivery, uid = %d: %s\n", - pw->pw_uid, strerror(errno)); - } - }else{ - logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); - errno = ENOENT; /* getpwnam does not set errno correctly */ - } - - return ok; + return ok; } #ifdef ENABLE_MAILDIR -gboolean maildir_out(message *msg, GList *hdr_list, gchar *user, guint flags) +gboolean +maildir_out(message * msg, GList * hdr_list, gchar * user, guint flags) { - struct passwd *pw; - gboolean ok = FALSE; - - /* headers may be special for a local delivery */ - if(hdr_list == NULL) - hdr_list = msg->hdr_list; + struct passwd *pw; + gboolean ok = FALSE; - if((pw = getpwnam(user))){ - uid_t saved_uid = geteuid(); - gid_t saved_gid = getegid(); - gboolean uid_ok = TRUE, gid_ok = TRUE; + /* headers may be special for a local delivery */ + if (hdr_list == NULL) + hdr_list = msg->hdr_list; - if(!conf.run_as_user){ - uid_ok = (seteuid(0) == 0); - if(uid_ok){ - gid_ok = (setegid(conf.mail_gid) == 0); - uid_ok = (seteuid(pw->pw_uid) == 0); - } - } + if ((pw = getpwnam(user))) { + uid_t saved_uid = geteuid(); + gid_t saved_gid = getegid(); + gboolean uid_ok = TRUE, gid_ok = TRUE; - DEBUG(5) debugf("running as euid %d\n", geteuid()); - DEBUG(5) debugf("running as egid %d\n", getegid()); - - if(uid_ok && gid_ok){ - char *path = g_strdup_printf("%s/Maildir", pw->pw_dir); - struct stat statbuf; - int ret; + if (!conf.run_as_user) { + uid_ok = (seteuid(0) == 0); + if (uid_ok) { + gid_ok = (setegid(conf.mail_gid) == 0); + uid_ok = (seteuid(pw->pw_uid) == 0); + } + } - DEBUG(5) debugf("path = %s\n", path); + DEBUG(5) debugf("running as euid %d\n", geteuid()); + DEBUG(5) debugf("running as egid %d\n", getegid()); - ok = TRUE; - ret = stat(path, &statbuf); - if(ret != 0){ - ok = FALSE; - if(errno == ENOENT){ - logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path); - if(mkdir(path, 0700) == 0) - ok = TRUE; - }else - logwrite(LOG_ALERT, "stat of %s failed: %s\n", path, strerror(errno)); - } - if(ok){ - ok = FALSE; - ret = stat(path, &statbuf); - if(S_ISDIR(statbuf.st_mode)){ - gchar *subdirs[] = {"tmp", "new", "cur"}; - int i; - for(i = 0; i < 3; i++){ - char *path1 = g_strdup_printf("%s/%s", path, subdirs[i]); - ret = stat(path1, &statbuf); - if(ret != 0){ - if(errno == ENOENT){ - logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path1); - if(mkdir(path1, 0700) != 0) break; - } - } - g_free(path1); - } - if(i == 3){ - FILE *out; - mode_t saved_mode = umask(066); - /* the qmail style unique works only if delivering - with different process. We do not fork for each delivery, - so our uid is more unique. Hope it is compatible with all - MUAs. - */ - gchar *filename = g_strdup_printf("%s/tmp/%s.%s", path, msg->uid, conf.host_name); + if (uid_ok && gid_ok) { + char *path = g_strdup_printf("%s/Maildir", pw->pw_dir); + struct stat statbuf; + int ret; - DEBUG(5) debugf("filename = %s\n", filename); - - if((out = fopen(filename, "w"))){ - gchar *newname = - g_strdup_printf("%s/new/%s.%s", path, msg->uid, conf.host_name); - message_stream(out, msg, hdr_list, flags); - ok = TRUE; - if(fflush(out) == EOF) ok = FALSE; - else if(fdatasync(fileno(out)) != 0){ - if(errno != EINVAL) /* some fs do not support this.. - I hope this also means that it is not necessary */ - ok = FALSE; - } - fclose(out); - if(rename(filename, newname) != 0){ - ok = FALSE; - logwrite(LOG_ALERT, "moving %s to %s failed: %s", - filename, newname, strerror(errno)); - } - g_free(newname); - } - umask(saved_mode); - g_free(filename); - } - }else{ - logwrite(LOG_ALERT, "%s is not a directory\n", path); - errno = ENOTDIR; + DEBUG(5) debugf("path = %s\n", path); + + ok = TRUE; + ret = stat(path, &statbuf); + if (ret != 0) { + ok = FALSE; + if (errno == ENOENT) { + logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path); + if (mkdir(path, 0700) == 0) + ok = TRUE; + } else + logwrite(LOG_ALERT, "stat of %s failed: %s\n", path, strerror(errno)); + } + if (ok) { + ok = FALSE; + ret = stat(path, &statbuf); + if (S_ISDIR(statbuf.st_mode)) { + gchar *subdirs[] = { "tmp", "new", "cur" }; + int i; + for (i = 0; i < 3; i++) { + char *path1 = g_strdup_printf("%s/%s", path, subdirs[i]); + ret = stat(path1, &statbuf); + if (ret != 0) { + if (errno == ENOENT) { + logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path1); + if (mkdir(path1, 0700) != 0) + break; + } + } + g_free(path1); + } + if (i == 3) { + FILE *out; + mode_t saved_mode = umask(066); + /* the qmail style unique works only if delivering + with different process. We do not fork for each delivery, + so our uid is more unique. Hope it is compatible with all + MUAs. + */ + gchar *filename = g_strdup_printf("%s/tmp/%s.%s", path, msg->uid, conf.host_name); + + DEBUG(5) debugf("filename = %s\n", filename); + + if ((out = fopen(filename, "w"))) { + gchar *newname = g_strdup_printf("%s/new/%s.%s", path, msg->uid, conf.host_name); + message_stream(out, msg, hdr_list, flags); + ok = TRUE; + if (fflush(out) == EOF) + ok = FALSE; + else if (fdatasync(fileno(out)) != 0) { + if (errno != EINVAL) /* some fs do not support this.. I hope this also means that it is not necessary */ + ok = FALSE; + } + fclose(out); + if (rename(filename, newname) != 0) { + ok = FALSE; + logwrite(LOG_ALERT, "moving %s to %s failed: %s", filename, newname, strerror(errno)); + } + g_free(newname); + } + umask(saved_mode); + g_free(filename); + } + } else { + logwrite(LOG_ALERT, "%s is not a directory\n", path); + errno = ENOTDIR; + } + } + if (!conf.run_as_user) { + uid_ok = (seteuid(0) == 0); + if (uid_ok) { + gid_ok = (setegid(saved_gid) == 0); + uid_ok = (seteuid(saved_uid) == 0); + } + } + if (!uid_ok || !gid_ok) { + /* FIXME: if this fails we HAVE to exit, because we shall not run + with some users id. But we do not return, and so this message + will not be finished, so the user will get the message again + next time a delivery is attempted... */ + logwrite(LOG_ALERT, "could not set back uid or gid after local delivery: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + g_free(path); + } else { + logwrite(LOG_ALERT, "could not set uid or gid for local delivery, uid = %d: %s\n", pw->pw_uid, strerror(errno)); + } + } else { + logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); + errno = ENOENT; /* getpwnam does not set errno correctly */ } - } - if(!conf.run_as_user){ - uid_ok = (seteuid(0) == 0); - if(uid_ok){ - gid_ok = (setegid(saved_gid) == 0); - uid_ok = (seteuid(saved_uid) == 0); - } - } - if(!uid_ok || !gid_ok){ - /* FIXME: if this fails we HAVE to exit, because we shall not run - with some users id. But we do not return, and so this message - will not be finished, so the user will get the message again - next time a delivery is attempted... */ - logwrite(LOG_ALERT, - "could not set back uid or gid after local delivery: %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - g_free(path); - }else{ - logwrite(LOG_ALERT, - "could not set uid or gid for local delivery, uid = %d: %s\n", - pw->pw_uid, strerror(errno)); - } - }else{ - logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); - errno = ENOENT; /* getpwnam does not set errno correctly */ - } - return ok; + return ok; } #endif gboolean -pipe_out(message *msg, GList *hdr_list, address *rcpt, gchar *cmd, guint flags) +pipe_out(message * msg, GList * hdr_list, address * rcpt, gchar * cmd, guint flags) { - gchar *envp[40]; - FILE *out; - uid_t saved_uid = geteuid(); - gid_t saved_gid = getegid(); - gboolean ok = FALSE; - gint i, n; - pid_t pid; - void (*old_signal)(int); - int status; + gchar *envp[40]; + FILE *out; + uid_t saved_uid = geteuid(); + gid_t saved_gid = getegid(); + gboolean ok = FALSE; + gint i, n; + pid_t pid; + void (*old_signal) (int); + int status; - /* set uid and gid to the mail ids */ - if(!conf.run_as_user){ - set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); - } + /* set uid and gid to the mail ids */ + if (!conf.run_as_user) { + set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); + } - /* set environment */ - { - gint i = 0; - address *ancestor = addr_find_ancestor(rcpt); + /* set environment */ + { + gint i = 0; + address *ancestor = addr_find_ancestor(rcpt); - envp[i++] = g_strdup_printf("SENDER=%s@%s", msg->return_path->local_part, msg->return_path->domain); - envp[i++] = g_strdup_printf("SENDER_DOMAIN=%s", msg->return_path->domain); - envp[i++] = g_strdup_printf("SENDER_LOCAL=%s", msg->return_path->local_part); - envp[i++] = g_strdup_printf("RECEIVED_HOST=%s", msg->received_host ? msg->received_host : ""); + envp[i++] = g_strdup_printf("SENDER=%s@%s", msg->return_path->local_part, msg->return_path->domain); + envp[i++] = g_strdup_printf("SENDER_DOMAIN=%s", msg->return_path->domain); + envp[i++] = g_strdup_printf("SENDER_LOCAL=%s", msg->return_path->local_part); + envp[i++] = g_strdup_printf("RECEIVED_HOST=%s", msg->received_host ? msg->received_host : ""); - envp[i++] = g_strdup_printf("RETURN_PATH=%s@%s", - msg->return_path->local_part, msg->return_path->domain); - envp[i++] = g_strdup_printf("DOMAIN=%s", ancestor->domain); + envp[i++] = g_strdup_printf("RETURN_PATH=%s@%s", msg->return_path->local_part, msg->return_path->domain); + envp[i++] = g_strdup_printf("DOMAIN=%s", ancestor->domain); - envp[i++] = g_strdup_printf("LOCAL_PART=%s", ancestor->local_part); - envp[i++] = g_strdup_printf("USER=%s", ancestor->local_part); - envp[i++] = g_strdup_printf("LOGNAME=%s", ancestor->local_part); + envp[i++] = g_strdup_printf("LOCAL_PART=%s", ancestor->local_part); + envp[i++] = g_strdup_printf("USER=%s", ancestor->local_part); + envp[i++] = g_strdup_printf("LOGNAME=%s", ancestor->local_part); - envp[i++] = g_strdup_printf("MESSAGE_ID=%s", msg->uid); - envp[i++] = g_strdup_printf("QUALIFY_DOMAIN=%s", conf.host_name); + envp[i++] = g_strdup_printf("MESSAGE_ID=%s", msg->uid); + envp[i++] = g_strdup_printf("QUALIFY_DOMAIN=%s", conf.host_name); - envp[i] = NULL; - n = i; - } + envp[i] = NULL; + n = i; + } - old_signal = signal(SIGCHLD, SIG_DFL); + old_signal = signal(SIGCHLD, SIG_DFL); - out = peidopen(cmd, "w", envp, &pid, conf.mail_uid, conf.mail_gid); - if(out != NULL){ - message_stream(out, msg, hdr_list, flags); + out = peidopen(cmd, "w", envp, &pid, conf.mail_uid, conf.mail_gid); + if (out != NULL) { + message_stream(out, msg, hdr_list, flags); - fclose(out); + fclose(out); - waitpid(pid, &status, 0); + waitpid(pid, &status, 0); - if(WEXITSTATUS(status) != 0){ - int exstat = WEXITSTATUS(status); - logwrite(LOG_ALERT, "process returned %d (%s)\n", exstat, ext_strerror(1024 + exstat)); - errno = 1024 + exstat; - }else if(WIFSIGNALED(status)){ - logwrite(LOG_ALERT, "process got signal %d\n", WTERMSIG(status)); - }else - ok = TRUE; + if (WEXITSTATUS(status) != 0) { + int exstat = WEXITSTATUS(status); + logwrite(LOG_ALERT, "process returned %d (%s)\n", exstat, ext_strerror(1024 + exstat)); + errno = 1024 + exstat; + } else if (WIFSIGNALED(status)) { + logwrite(LOG_ALERT, "process got signal %d\n", WTERMSIG(status)); + } else + ok = TRUE; - }else - logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", cmd, strerror(errno)); + } else + logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", cmd, strerror(errno)); - signal(SIGCHLD, old_signal); + signal(SIGCHLD, old_signal); - /* free environment */ - for(i = 0; i < n; i++){ - g_free(envp[i]); - } + /* free environment */ + for (i = 0; i < n; i++) { + g_free(envp[i]); + } - /* set uid and gid back */ - if(!conf.run_as_user){ - set_euidgid(saved_uid, saved_gid, NULL, NULL); - } + /* set uid and gid back */ + if (!conf.run_as_user) { + set_euidgid(saved_uid, saved_gid, NULL, NULL); + } - return ok; + return ok; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/log.c --- a/src/log.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/log.c Mon Oct 27 16:23:10 2008 +0100 @@ -21,191 +21,201 @@ #include "sysexits.h" static char *_sysexit_strings[] = { - "command line usage error", - "data format error", - "cannot open input", - "addressee unknown", - "host name unknown", - "service unavailable", - "internal software error", - "system error (e.g., can't fork)", - "critical OS file missing", - "can't create (user) output file", - "input/output error", - "temp failure; user is invited to retry", - "remote error in protocol", - "permission denied", - "configuration error" + "command line usage error", + "data format error", + "cannot open input", + "addressee unknown", + "host name unknown", + "service unavailable", + "internal software error", + "system error (e.g., can't fork)", + "critical OS file missing", + "can't create (user) output file", + "input/output error", + "temp failure; user is invited to retry", + "remote error in protocol", + "permission denied", + "configuration error" }; -gchar *ext_strerror(int err) +gchar* +ext_strerror(int err) { - if(err < 1024) - return strerror(err); - else - if(err > 1024 + EX__BASE && - (err - 1024 - EX__BASE < sizeof(_sysexit_strings)/sizeof(_sysexit_strings[0]))) - return _sysexit_strings[err - 1024 - EX__BASE]; + if (err < 1024) + return strerror(err); + else if (err > 1024 + EX__BASE + && (err - 1024 - EX__BASE < sizeof(_sysexit_strings) / sizeof(_sysexit_strings[0]))) + return _sysexit_strings[err - 1024 - EX__BASE]; - return "unknown error"; + return "unknown error"; } static FILE *logfile = NULL; static FILE *debugfile = NULL; -gboolean logopen() +gboolean +logopen() { - gchar *filename; - mode_t saved_mode = umask(066); + gchar *filename; + mode_t saved_mode = umask(066); - if(conf.use_syslog){ - openlog(PACKAGE, LOG_PID, LOG_MAIL); - }else{ - uid_t saved_uid; - gid_t saved_gid; - - saved_gid = setegid(conf.mail_gid); - saved_uid = seteuid(conf.mail_uid); + if (conf.use_syslog) { + openlog(PACKAGE, LOG_PID, LOG_MAIL); + } else { + uid_t saved_uid; + gid_t saved_gid; - filename = g_strdup_printf("%s/masqmail.log", conf.log_dir); - logfile = fopen(filename, "a"); - if(!logfile){ - fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno)); - return FALSE; - } - g_free(filename); + saved_gid = setegid(conf.mail_gid); + saved_uid = seteuid(conf.mail_uid); - seteuid(saved_uid); - setegid(saved_gid); - } + filename = g_strdup_printf("%s/masqmail.log", conf.log_dir); + logfile = fopen(filename, "a"); + if (!logfile) { + fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno)); + return FALSE; + } + g_free(filename); + + seteuid(saved_uid); + setegid(saved_gid); + } #ifdef ENABLE_DEBUG - if(conf.debug_level > 0){ - filename = g_strdup_printf("%s/debug.log", conf.log_dir); - debugfile = fopen(filename, "a"); - if(!debugfile){ - fprintf(stderr, "could not open debug log '%s'\n", filename); - return FALSE; - } - g_free(filename); - } + if (conf.debug_level > 0) { + filename = g_strdup_printf("%s/debug.log", conf.log_dir); + debugfile = fopen(filename, "a"); + if (!debugfile) { + fprintf(stderr, "could not open debug log '%s'\n", filename); + return FALSE; + } + g_free(filename); + } #endif - umask(saved_mode); - return TRUE; + umask(saved_mode); + return TRUE; } -void logclose() +void +logclose() { - if(conf.use_syslog) - closelog(); - else - if(logfile) fclose(logfile); - if(debugfile) fclose(debugfile); + if (conf.use_syslog) + closelog(); + else if (logfile) + fclose(logfile); + if (debugfile) + fclose(debugfile); } -void vlogwrite(int pri, const char *fmt, va_list args) +void +vlogwrite(int pri, const char *fmt, va_list args) { - if((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) || (pri == LOG_WARNING)){ - va_list args_copy; - va_copy(args_copy, args); - vfprintf(stdout, fmt, args_copy); - va_end(args_copy); - fflush(stdout); /* is this necessary? */ - } + if ((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) + || (pri == LOG_WARNING)) { + va_list args_copy; + va_copy(args_copy, args); + vfprintf(stdout, fmt, args_copy); + va_end(args_copy); + fflush(stdout); /* is this necessary? */ + } - pri &= ~LOG_VERBOSE; - if(pri){ + pri &= ~LOG_VERBOSE; + if (pri) { - if(conf.use_syslog) - vsyslog(pri, fmt, args); - else{ - if(pri <= conf.log_max_pri){ - FILE *file = logfile ? logfile : stderr; + if (conf.use_syslog) + vsyslog(pri, fmt, args); + else { + if (pri <= conf.log_max_pri) { + FILE *file = logfile ? logfile : stderr; + time_t now = time(NULL); + struct tm *t = localtime(&now); + gchar buf[24]; + uid_t saved_uid; + gid_t saved_gid; + + saved_gid = setegid(conf.mail_gid); + saved_uid = seteuid(conf.mail_uid); + + strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); + fprintf(file, "%s [%d] ", buf, getpid()); + + vfprintf(file, fmt, args); + fflush(file); + + seteuid(saved_uid); + setegid(saved_gid); + } + } + } +} + +#ifdef ENABLE_DEBUG +void +vdebugwrite(int pri, const char *fmt, va_list args) +{ time_t now = time(NULL); struct tm *t = localtime(&now); gchar buf[24]; - uid_t saved_uid; - gid_t saved_gid; + strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); - saved_gid = setegid(conf.mail_gid); - saved_uid = seteuid(conf.mail_uid); + if (debugfile) { + fprintf(debugfile, "%s [%d] ", buf, getpid()); - strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); - fprintf(file, "%s [%d] ", buf, getpid()); - - vfprintf(file, fmt, args); - fflush(file); - - seteuid(saved_uid); - setegid(saved_gid); - } - } - } -} - -#ifdef ENABLE_DEBUG -void vdebugwrite(int pri, const char *fmt, va_list args) -{ - time_t now = time(NULL); - struct tm *t = localtime(&now); - gchar buf[24]; - strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); - - if(debugfile){ - fprintf(debugfile, "%s [%d] ", buf, getpid()); - - vfprintf(debugfile, fmt, args); - fflush(debugfile); - }else{ - fprintf(stderr, "no debug file, msg was:\n"); - vfprintf(stderr, fmt, args); - } + vfprintf(debugfile, fmt, args); + fflush(debugfile); + } else { + fprintf(stderr, "no debug file, msg was:\n"); + vfprintf(stderr, fmt, args); + } } #endif -void logwrite(int pri, const char *fmt, ...) +void +logwrite(int pri, const char *fmt, ...) { - va_list args, args_copy; - int saved_errno = errno; /* somewhere this is changed to EBADF */ + va_list args, args_copy; + int saved_errno = errno; /* somewhere this is changed to EBADF */ - va_start(args, fmt); + va_start(args, fmt); #ifdef ENABLE_DEBUG - va_copy(args_copy, args); + va_copy(args_copy, args); #endif - vlogwrite(pri, fmt, args); + vlogwrite(pri, fmt, args); #ifdef ENABLE_DEBUG - if(debugfile) - vdebugwrite(pri, fmt, args_copy); - va_end(args_copy); + if (debugfile) + vdebugwrite(pri, fmt, args_copy); + va_end(args_copy); #endif - va_end(args); + va_end(args); - errno = saved_errno; + errno = saved_errno; } #ifdef ENABLE_DEBUG -void debugf(const char *fmt, ...) +void +debugf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - vdebugwrite(LOG_DEBUG, fmt, args); + vdebugwrite(LOG_DEBUG, fmt, args); - va_end(args); + va_end(args); } -void vdebugf(const char *fmt, va_list args) +void +vdebugf(const char *fmt, va_list args) { - vdebugwrite(LOG_DEBUG, fmt, args); + vdebugwrite(LOG_DEBUG, fmt, args); } #endif -void maillog(const char *fmt, ...) +void +maillog(const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - vlogwrite(LOG_NOTICE, fmt, args); + vlogwrite(LOG_NOTICE, fmt, args); - va_end(args); + va_end(args); } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/lookup.c --- a/src/lookup.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/lookup.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 @@ -33,8 +33,8 @@ #ifdef ENABLE_RESOLVER static union { - HEADER hdr; - unsigned char buf[PACKETSZ]; + HEADER hdr; + unsigned char buf[PACKETSZ]; } response; static unsigned char *resp_end; static unsigned char *resp_pos; @@ -45,139 +45,143 @@ unsigned short rr_type; unsigned short rr_dlen; -static -unsigned short getshort(unsigned char *c) +static unsigned short +getshort(unsigned char *c) { - unsigned short u; - u = c[0]; - return (u << 8) + c[1]; + unsigned short u; + u = c[0]; + return (u << 8) + c[1]; } -static -int dns_resolve(char *domain, int type, gboolean do_search) +static int +dns_resolve(char *domain, int type, gboolean do_search) { - int n; - int i; + int n; + int i; - int resp_len; - /*errno = 0;*/ + int resp_len; + /*errno = 0; */ - /* - if (!stralloc_copy(&glue,domain)) return DNS_MEM; - if (!stralloc_0(&glue)) return DNS_MEM; - */ + /* + if (!stralloc_copy(&glue,domain)) return DNS_MEM; + if (!stralloc_0(&glue)) return DNS_MEM; + */ - // resp_len = res_query(domain, C_IN, type, response.buf, sizeof(response)); - DEBUG(5) debugf("DNS: before res_search()\n"); - if(do_search) - resp_len = res_search(domain, C_IN, type, response.buf, sizeof(response)); - else - resp_len = res_query(domain, C_IN, type, response.buf, sizeof(response)); - DEBUG(5) debugf("DBG: after res_search()\n"); + // resp_len = res_query(domain, C_IN, type, response.buf, sizeof(response)); + DEBUG(5) debugf("DNS: before res_search()\n"); + if (do_search) + resp_len = res_search(domain, C_IN, type, response.buf, sizeof(response)); + else + resp_len = res_query(domain, C_IN, type, response.buf, sizeof(response)); + DEBUG(5) debugf("DBG: after res_search()\n"); - if (resp_len <= 0){ - /* - if (errno == ECONNREFUSED) return DNS_SOFT; - if (h_errno == TRY_AGAIN) return DNS_SOFT; - return DNS_HARD; - */ - return -1; - } - if (resp_len >= sizeof(response)) - resp_len = sizeof(response); + if (resp_len <= 0) { + /* + if (errno == ECONNREFUSED) return DNS_SOFT; + if (h_errno == TRY_AGAIN) return DNS_SOFT; + return DNS_HARD; + */ + return -1; + } + if (resp_len >= sizeof(response)) + resp_len = sizeof(response); - resp_end = response.buf + resp_len; - resp_pos = response.buf + sizeof(HEADER); - n = ntohs(response.hdr.qdcount); + resp_end = response.buf + resp_len; + resp_pos = response.buf + sizeof(HEADER); + n = ntohs(response.hdr.qdcount); - while (n-- > 0){ - i = dn_expand(response.buf, resp_end, resp_pos, name, MAX_DNSNAME); - if (i < 0) - return -1; - DEBUG(5) debugf("DBG: resolve name = %s\n", name); - resp_pos += i; - i = resp_end - resp_pos; - if (i < QFIXEDSZ) - return -1; - resp_pos += QFIXEDSZ; - } - num_answers = ntohs(response.hdr.ancount); + while (n-- > 0) { + i = dn_expand(response.buf, resp_end, resp_pos, name, MAX_DNSNAME); + if (i < 0) + return -1; + DEBUG(5) debugf("DBG: resolve name = %s\n", name); + resp_pos += i; + i = resp_end - resp_pos; + if (i < QFIXEDSZ) + return -1; + resp_pos += QFIXEDSZ; + } + num_answers = ntohs(response.hdr.ancount); - return 0; + return 0; } -static int dns_next() +static int +dns_next() { - int i; + int i; - if (num_answers <= 0) return 2; - num_answers--; + if (num_answers <= 0) + return 2; + num_answers--; - if (resp_pos == resp_end) - return -1 /* soft */; + if (resp_pos == resp_end) + return -1; /* soft */ - i = dn_expand(response.buf, resp_end, resp_pos, name, 256); - if (i < 0) - return -1; /* soft */ - resp_pos += i; + i = dn_expand(response.buf, resp_end, resp_pos, name, 256); + if (i < 0) + return -1; /* soft */ + resp_pos += i; - i = resp_end - resp_pos; - if (i < 4 + 3 * 2) - return -1; /* soft */ - - rr_type = getshort(resp_pos); - rr_dlen = getshort(resp_pos + 8); - resp_pos += 10; + i = resp_end - resp_pos; + if (i < 4 + 3 * 2) + return -1; /* soft */ - return 0; + rr_type = getshort(resp_pos); + rr_dlen = getshort(resp_pos + 8); + resp_pos += 10; + + return 0; } -static -int dns_getip(guint32 *ip) +static int +dns_getip(guint32 * ip) { - int ret; + int ret; - if((ret = dns_next())) return ret; + if ((ret = dns_next())) + return ret; - if (rr_type == T_A){ - if (rr_dlen < 4) - return -1; /* soft */ - *ip = *(guint32 *)(resp_pos); - DEBUG(5) debugf("DNS: dns_getip(): ip = %s\n", inet_ntoa(*(struct in_addr*)ip)); - resp_pos += rr_dlen; + if (rr_type == T_A) { + if (rr_dlen < 4) + return -1; /* soft */ + *ip = *(guint32 *) (resp_pos); + DEBUG(5) debugf("DNS: dns_getip(): ip = %s\n", inet_ntoa(*(struct in_addr *) ip)); + resp_pos += rr_dlen; - return 1; - } - resp_pos += rr_dlen; - return 0; + return 1; + } + resp_pos += rr_dlen; + return 0; } -static -int dns_getmx(int *pref) +static int +dns_getmx(int *pref) { - int ret; + int ret; - if((ret = dns_next())) return ret; + if ((ret = dns_next())) + return ret; - if (rr_type == T_MX){ - if (rr_dlen < 3) - return -1; /* soft */ + if (rr_type == T_MX) { + if (rr_dlen < 3) + return -1; /* soft */ - *pref = (resp_pos[0] << 8) + resp_pos[1]; - if (dn_expand(response.buf, resp_end, resp_pos + 2, name, MAX_DNSNAME) < 0) - return -1; - - resp_pos += rr_dlen; + *pref = (resp_pos[0] << 8) + resp_pos[1]; + if (dn_expand(response.buf, resp_end, resp_pos + 2, name, MAX_DNSNAME) < 0) + return -1; - return 1; - } - resp_pos += rr_dlen; - return 0; + resp_pos += rr_dlen; + + return 1; + } + resp_pos += rr_dlen; + return 0; } /* -static -int dns_getname(int type) +static int +dns_getname(int type) { int ret; @@ -186,7 +190,7 @@ if (rr_type == type){ if (dn_expand(response.buf, resp_end, resp_pos, name, MAX_DNSNAME) < 0) return -1; - + resp_pos += rr_dlen; return 1; @@ -196,181 +200,177 @@ } */ -static -int dns_look_ip(gchar *domain, guint32 *ip) +static int +dns_look_ip(gchar * domain, guint32 * ip) { - gchar *n = domain; + gchar *n = domain; - while(TRUE){ - if(dns_resolve(n, T_A, FALSE) == 0){ - dns_next(); - if(rr_type == T_A){ - if (rr_dlen < 4) - return -1; /* soft */ - *ip = *(guint32 *)(resp_pos); - - DEBUG(5) debugf("DNS: dns_look_ip(): ip = %s\n", - inet_ntoa(*(struct in_addr*)ip)); - - resp_pos += rr_dlen; - return 0; - }else if(rr_type == T_CNAME){ - if (dn_expand(response.buf, resp_end, resp_pos, name, MAX_DNSNAME) < 0) - return -1; + while (TRUE) { + if (dns_resolve(n, T_A, FALSE) == 0) { + dns_next(); + if (rr_type == T_A) { + if (rr_dlen < 4) + return -1; /* soft */ + *ip = *(guint32 *) (resp_pos); - DEBUG(5) debugf("DNS: (CNAME) dns_look_ip(): name = %s\n", name); - - resp_pos += rr_dlen; - n = name; - }else - return -1; - }else - return -1; - } + DEBUG(5) debugf("DNS: dns_look_ip(): ip = %s\n", inet_ntoa(*(struct in_addr *) ip)); + + resp_pos += rr_dlen; + return 0; + } else if (rr_type == T_CNAME) { + if (dn_expand(response.buf, resp_end, resp_pos, name, MAX_DNSNAME) < 0) + return -1; + + DEBUG(5) debugf("DNS: (CNAME) dns_look_ip(): name = %s\n", name); + + resp_pos += rr_dlen; + n = name; + } else + return -1; + } else + return -1; + } } -GList *resolve_dns_a(GList *list, gchar *domain) +GList* +resolve_dns_a(GList * list, gchar * domain) { - int ret; + int ret; - DEBUG(5) debugf("DNS: resolve_dns_a entered\n"); + DEBUG(5) debugf("DNS: resolve_dns_a entered\n"); - if(dns_resolve(domain, T_A, TRUE) == 0){ - mxip_addr mxip; - while((ret = dns_getip(&(mxip.ip))) != 2){ - if(ret == 1){ - mxip.name = g_strdup(name); - mxip.pref = 0; - list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); - } - } - } - return list; + if (dns_resolve(domain, T_A, TRUE) == 0) { + mxip_addr mxip; + while ((ret = dns_getip(&(mxip.ip))) != 2) { + if (ret == 1) { + mxip.name = g_strdup(name); + mxip.pref = 0; + list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); + } + } + } + return list; } -static -gint _mx_sort_func(gconstpointer aa, gconstpointer bb) +static gint +_mx_sort_func(gconstpointer aa, gconstpointer bb) { - const mxip_addr *a = (mxip_addr *)aa; - const mxip_addr *b = (mxip_addr *)bb; + const mxip_addr *a = (mxip_addr *) aa; + const mxip_addr *b = (mxip_addr *) bb; - if(a->pref == b->pref) - return a->ip - b->ip; - else - return a->pref - b->pref; + if (a->pref == b->pref) + return a->ip - b->ip; + else + return a->pref - b->pref; } -GList *resolve_dns_mx(GList *list, gchar *domain) +GList* +resolve_dns_mx(GList * list, gchar * domain) { - GList *node; - int ret; - int cnt = 0; + GList *node; + int ret; + int cnt = 0; - DEBUG(5) debugf("DNS: resolve_dns_mx entered\n"); + DEBUG(5) debugf("DNS: resolve_dns_mx entered\n"); - if(dns_resolve(domain, T_MX, TRUE) == 0){ - GList *node_next; - mxip_addr mxip; - while((ret = dns_getmx(&(mxip.pref))) != 2){ - if(ret == 1){ - mxip.name = g_strdup(name); - mxip.ip = rand(); - list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); - cnt++; - } - } + if (dns_resolve(domain, T_MX, TRUE) == 0) { + GList *node_next; + mxip_addr mxip; + while ((ret = dns_getmx(&(mxip.pref))) != 2) { + if (ret == 1) { + mxip.name = g_strdup(name); + mxip.ip = rand(); + list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); + cnt++; + } + } - DEBUG(5) debugf("DNS: found %d mx records\n", cnt); + DEBUG(5) debugf("DNS: found %d mx records\n", cnt); - /* to randomize sequences with equal pref values, - we temporarily 'misused' the ip field and - put a random number in it as a secondary sort key. - */ - list = g_list_sort(list, _mx_sort_func); + /* to randomize sequences with equal pref values, + we temporarily 'misused' the ip field and + put a random number in it as a secondary sort key. + */ + list = g_list_sort(list, _mx_sort_func); - /* CNAME resolving has to be added as well. */ + /* CNAME resolving has to be added as well. */ - for(node = g_list_first(list); - node != NULL; - node = node_next){ + for (node = g_list_first(list); node != NULL; node = node_next) { - mxip_addr *p_mxip = (mxip_addr *)(node->data); - node_next = g_list_next(node); + mxip_addr *p_mxip = (mxip_addr *) (node->data); + node_next = g_list_next(node); - if(dns_look_ip(p_mxip->name, &(p_mxip->ip)) != 0){ - DEBUG(1) debugf("DNS: could not resolve target of mx %s\n", p_mxip->name); - list = g_list_remove_link(list, node); - g_free(node->data); - g_list_free_1(node); - } - } - } - return list; + if (dns_look_ip(p_mxip->name, &(p_mxip->ip)) != 0) { + DEBUG(1) debugf("DNS: could not resolve target of mx %s\n", p_mxip->name); + list = g_list_remove_link(list, node); + g_free(node->data); + g_list_free_1(node); + } + } + } + return list; } #endif /* now something completely different... */ -GList *resolve_byname(GList *list, gchar *domain) +GList* +resolve_byname(GList * list, gchar * domain) { - struct hostent *hent; + struct hostent *hent; - DEBUG(5) debugf("DNS: resolve_byname entered\n"); + DEBUG(5) debugf("DNS: resolve_byname entered\n"); - if((hent = gethostbyname(domain))){ - char *haddr; - int i = 0; - while((haddr = hent->h_addr_list[i++])){ - mxip_addr mxip; - mxip.ip = *(guint32 *)(haddr); - mxip.pref = 0; - mxip.name = g_strdup(hent->h_name); - list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); - } - } - return list; + if ((hent = gethostbyname(domain))) { + char *haddr; + int i = 0; + while ((haddr = hent->h_addr_list[i++])) { + mxip_addr mxip; + mxip.ip = *(guint32 *) (haddr); + mxip.pref = 0; + mxip.name = g_strdup(hent->h_name); + list = g_list_append(list, g_memdup(&mxip, sizeof(mxip))); + } + } + return list; } #ifdef RESOLV_TEST -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - GList *addr_list = NULL, *node; + GList *addr_list = NULL, *node; - g_print("starting res_init()\n"); + g_print("starting res_init()\n"); - g_print("retrans = %d, retry = %d\n", _res.retrans, _res.retry); + g_print("retrans = %d, retry = %d\n", _res.retrans, _res.retry); - if(res_init() == 0){ - - addr_list = resolve_dns_a(NULL, argv[1]); - g_print("A:\n"); + if (res_init() == 0) { - foreach(addr_list, node){ - mxip_addr *p_mxip = (mxip_addr *)(node->data); - - printf("name = %s\n IP = %s\n", - p_mxip->name, - inet_ntoa(*(struct in_addr *)&(p_mxip->ip))); - } - addr_list = resolve_dns_mx(NULL, argv[1]); - g_print("MX:\n"); + addr_list = resolve_dns_a(NULL, argv[1]); + g_print("A:\n"); - foreach(addr_list, node){ - mxip_addr *p_mxip = (mxip_addr *)(node->data); - - printf("name = %s\n IP = %s pref = %d\n", - p_mxip->name, - inet_ntoa(*(struct in_addr *)&(p_mxip->ip)), - p_mxip->pref); - } - { - guint32 ip; - dns_look_ip(argv[1], &ip); - printf("dns_look_ip: %s\n", inet_ntoa(*((struct in_addr *)(&ip)))); - } - }else - printf("res_init() failed.\n"); - + foreach(addr_list, node) { + mxip_addr *p_mxip = (mxip_addr *) (node->data); + + printf("name = %s\n IP = %s\n", p_mxip->name, inet_ntoa(*(struct in_addr *) &(p_mxip->ip))); + } + addr_list = resolve_dns_mx(NULL, argv[1]); + g_print("MX:\n"); + + foreach(addr_list, node) { + mxip_addr *p_mxip = (mxip_addr *) (node->data); + + printf("name = %s\n IP = %s pref = %d\n", p_mxip->name, inet_ntoa(*(struct in_addr *) &(p_mxip->ip)), p_mxip->pref); + } + { + guint32 ip; + dns_look_ip(argv[1], &ip); + printf("dns_look_ip: %s\n", inet_ntoa(*((struct in_addr *) (&ip)))); + } + } else + printf("res_init() failed.\n"); + } #endif diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/lookup.h --- a/src/lookup.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/lookup.h Mon Oct 27 16:23:10 2008 +0100 @@ -5,7 +5,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 @@ -18,16 +18,15 @@ #define MAX_DNSNAME MAXDNAME -typedef -struct{ - guint32 ip; - int pref; - guchar *name; +typedef struct { + guint32 ip; + int pref; + guchar *name; } mxip_addr; -typedef GList *(*resolve_func)(GList *, gchar *); +typedef GList *(*resolve_func) (GList *, gchar *); -GList *resolve_dns_a(GList *list, gchar *domain); -GList *resolve_dns_mx(GList *list, gchar *domain); -GList *resolve_byname(GList *list, gchar *domain); +GList *resolve_dns_a(GList * list, gchar * domain); +GList *resolve_dns_mx(GList * list, gchar * domain); +GList *resolve_byname(GList * list, gchar * domain); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/masqmail.c --- a/src/masqmail.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/masqmail.c Mon Oct 27 16:23:10 2008 +0100 @@ -37,792 +37,783 @@ nor a 'queue daemon' mode. These, as well as the distinction beween the two (non exclusive) daemon (queue and listen) modes are handled by flags.*/ -typedef enum _mta_mode -{ - MODE_ACCEPT = 0, /* accept message on stdin */ - MODE_DAEMON, /* run as daemon */ - MODE_RUNQUEUE, /* single queue run, online or offline */ - MODE_GET_DAEMON, /* run as get (retrieve) daemon */ - MODE_SMTP, /* accept SMTP on stdin */ - MODE_LIST, /* list queue */ - MODE_MCMD, /* do queue manipulation */ - MODE_VERSION, /* show version */ - MODE_BI, /* fake ;-) */ - MODE_NONE /* to prevent default MODE_ACCEPT */ -}mta_mode; +typedef enum _mta_mode { + MODE_ACCEPT = 0, /* accept message on stdin */ + MODE_DAEMON, /* run as daemon */ + MODE_RUNQUEUE, /* single queue run, online or offline */ + MODE_GET_DAEMON, /* run as get (retrieve) daemon */ + MODE_SMTP, /* accept SMTP on stdin */ + MODE_LIST, /* list queue */ + MODE_MCMD, /* do queue manipulation */ + MODE_VERSION, /* show version */ + MODE_BI, /* fake ;-) */ + MODE_NONE /* to prevent default MODE_ACCEPT */ +} mta_mode; char *pidfile = NULL; volatile int sigterm_in_progress = 0; -static -void sigterm_handler(int sig) +static void +sigterm_handler(int sig) { - if(sigterm_in_progress) - raise(sig); - sigterm_in_progress = 1; + if (sigterm_in_progress) + raise(sig); + sigterm_in_progress = 1; - if(pidfile){ - uid_t uid; - uid = seteuid(0); - if(unlink(pidfile) != 0) - logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", - pidfile, strerror(errno)); - seteuid(uid); /* we exit anyway after this, just to be sure */ - } + if (pidfile) { + uid_t uid; + uid = seteuid(0); + if (unlink(pidfile) != 0) + logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", pidfile, strerror(errno)); + seteuid(uid); /* we exit anyway after this, just to be sure */ + } - signal(sig, SIG_DFL); - raise(sig); + signal(sig, SIG_DFL); + raise(sig); } -#ifdef ENABLE_IDENT /* so far used for that only */ -static -gboolean is_in_netlist(gchar *host, GList *netlist) +#ifdef ENABLE_IDENT /* so far used for that only */ +static gboolean +is_in_netlist(gchar * host, GList * netlist) { - guint hostip = inet_addr(host); - struct in_addr addr; + guint hostip = inet_addr(host); + struct in_addr addr; - addr.s_addr = hostip; - if(addr.s_addr != INADDR_NONE){ - GList *node; - foreach(netlist, node){ - struct in_addr *net = (struct in_addr *)(node->data); - if((addr.s_addr & net->s_addr) == net->s_addr) - return TRUE; - } - } - return FALSE; + addr.s_addr = hostip; + if (addr.s_addr != INADDR_NONE) { + GList *node; + foreach(netlist, node) { + struct in_addr *net = (struct in_addr *) (node->data); + if ((addr.s_addr & net->s_addr) == net->s_addr) + return TRUE; + } + } + return FALSE; } #endif -gchar *get_optarg(char *argv[], gint argc, gint *argp, gint *pos) +gchar* +get_optarg(char *argv[], gint argc, gint * argp, gint * pos) { - if(argv[*argp][*pos]) - return &(argv[*argp][*pos]); - else{ - if(*argp+1 < argc){ - if(argv[(*argp)+1][0] != '-'){ - (*argp)++; - *pos = 0; - return &(argv[*argp][*pos]); - } - } - } - return NULL; -} - -gchar *get_progname(gchar *arg0) -{ - gchar *p = arg0 + strlen(arg0) - 1; - while(p > arg0){ - if(*p == '/') - return p+1; - p--; - } - return p; + if (argv[*argp][*pos]) + return &(argv[*argp][*pos]); + else { + if (*argp + 1 < argc) { + if (argv[(*argp) + 1][0] != '-') { + (*argp)++; + *pos = 0; + return &(argv[*argp][*pos]); + } + } + } + return NULL; } -gboolean write_pidfile(gchar *name) +gchar* +get_progname(gchar * arg0) { - FILE *fptr; - - if((fptr = fopen(name, "wt"))){ - fprintf(fptr, "%d\n", getpid()); - fclose(fptr); - pidfile = strdup(name); - return TRUE; - } - logwrite(LOG_WARNING, "could not write pid file: %s\n", strerror(errno)); - return FALSE; + gchar *p = arg0 + strlen(arg0) - 1; + while (p > arg0) { + if (*p == '/') + return p + 1; + p--; + } + return p; } -static -void mode_daemon(gboolean do_listen, gint queue_interval, char *argv[]) +gboolean +write_pidfile(gchar * name) { - guint pid; + FILE *fptr; - /* daemon */ - if(!conf.run_as_user){ - if((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)){ - fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER); - exit(EXIT_FAILURE); - } - } + if ((fptr = fopen(name, "wt"))) { + fprintf(fptr, "%d\n", getpid()); + fclose(fptr); + pidfile = strdup(name); + return TRUE; + } + logwrite(LOG_WARNING, "could not write pid file: %s\n", strerror(errno)); + return FALSE; +} - if((pid = fork()) > 0){ - exit(EXIT_SUCCESS); - }else if(pid < 0){ - logwrite(LOG_ALERT, "could not fork!"); - exit(EXIT_FAILURE); - } +static void +mode_daemon(gboolean do_listen, gint queue_interval, char *argv[]) +{ + guint pid; - signal(SIGTERM, sigterm_handler); - write_pidfile(PIDFILEDIR"/masqmail.pid"); + /* daemon */ + if (!conf.run_as_user) { + if ((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)) { + fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER); + exit(EXIT_FAILURE); + } + } - conf.do_verbose = FALSE; + if ((pid = fork()) > 0) { + exit(EXIT_SUCCESS); + } else if (pid < 0) { + logwrite(LOG_ALERT, "could not fork!"); + exit(EXIT_FAILURE); + } - fclose(stdin); - fclose(stdout); - fclose(stderr); + signal(SIGTERM, sigterm_handler); + write_pidfile(PIDFILEDIR "/masqmail.pid"); - listen_port(do_listen ? conf.listen_addresses : NULL, - queue_interval, argv); + conf.do_verbose = FALSE; + + fclose(stdin); + fclose(stdout); + fclose(stderr); + + listen_port(do_listen ? conf.listen_addresses : NULL, queue_interval, argv); } #ifdef ENABLE_POP3 -static -void mode_get_daemon(gint get_interval, char *argv[]) +static void +mode_get_daemon(gint get_interval, char *argv[]) { - guint pid; + guint pid; - /* daemon */ - if(!conf.run_as_user){ - if((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)){ - fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER); - exit(EXIT_FAILURE); - } - } + /* daemon */ + if (!conf.run_as_user) { + if ((conf.orig_uid != 0) && (conf.orig_uid != conf.mail_uid)) { + fprintf(stderr, "must be root or %s for daemon.\n", DEF_MAIL_USER); + exit(EXIT_FAILURE); + } + } - if((pid = fork()) > 0){ - exit(EXIT_SUCCESS); - }else if(pid < 0){ - logwrite(LOG_ALERT, "could not fork!"); - exit(EXIT_FAILURE); - } + if ((pid = fork()) > 0) { + exit(EXIT_SUCCESS); + } else if (pid < 0) { + logwrite(LOG_ALERT, "could not fork!"); + exit(EXIT_FAILURE); + } - signal(SIGTERM, sigterm_handler); - write_pidfile(PIDFILEDIR"/masqmail-get.pid"); + signal(SIGTERM, sigterm_handler); + write_pidfile(PIDFILEDIR "/masqmail-get.pid"); - conf.do_verbose = FALSE; + conf.do_verbose = FALSE; - fclose(stdin); - fclose(stdout); - fclose(stderr); + fclose(stdin); + fclose(stdout); + fclose(stderr); - get_daemon(get_interval, argv); + get_daemon(get_interval, argv); } #endif #ifdef ENABLE_SMTP_SERVER -static void mode_smtp() +static void +mode_smtp() { - /* accept smtp message on stdin */ - /* write responses to stderr. */ + /* accept smtp message on stdin */ + /* write responses to stderr. */ - struct sockaddr_in saddr; - gchar *peername = NULL; - int dummy = sizeof(saddr); + struct sockaddr_in saddr; + gchar *peername = NULL; + int dummy = sizeof(saddr); #ifdef ENABLE_IDENT - gchar *ident = NULL; + gchar *ident = NULL; #endif - conf.do_verbose = FALSE; + conf.do_verbose = FALSE; - if(!conf.run_as_user){ - seteuid(conf.orig_uid); - setegid(conf.orig_gid); - } + if (!conf.run_as_user) { + seteuid(conf.orig_uid); + setegid(conf.orig_gid); + } - DEBUG(5) debugf("accepting smtp message on stdin\n"); + DEBUG(5) debugf("accepting smtp message on stdin\n"); - if(getpeername(0, (struct sockaddr *)(&saddr), &dummy) == 0){ - peername = g_strdup(inet_ntoa(saddr.sin_addr)); + if (getpeername(0, (struct sockaddr *) (&saddr), &dummy) == 0) { + peername = g_strdup(inet_ntoa(saddr.sin_addr)); #ifdef ENABLE_IDENT - { - gchar *id = NULL; - if((id = (gchar *)ident_id(0, 60))){ - ident = g_strdup(id); - } - } + { + gchar *id = NULL; + if ((id = (gchar *) ident_id(0, 60))) { + ident = g_strdup(id); + } + } #endif - }else if(errno != ENOTSOCK) - exit(EXIT_FAILURE); + } else if (errno != ENOTSOCK) + exit(EXIT_FAILURE); - //smtp_in(stdin, stdout, peername); - smtp_in(stdin, stderr, peername, NULL); + //smtp_in(stdin, stdout, peername); + smtp_in(stdin, stderr, peername, NULL); #ifdef ENABLE_IDENT - if(ident) g_free(ident); + if (ident) + g_free(ident); #endif } #endif -static void mode_accept(address *return_path, gchar *full_sender_name, - guint accept_flags, char **addresses, int addr_cnt) +static void +mode_accept(address * return_path, gchar * full_sender_name, guint accept_flags, char **addresses, int addr_cnt) { - /* accept message on stdin */ - accept_error err; - message *msg = create_message(); - gint i; + /* accept message on stdin */ + accept_error err; + message *msg = create_message(); + gint i; - if(return_path != NULL){ - if((conf.orig_uid != 0) && - (conf.orig_uid != conf.mail_uid) && - (!is_ingroup(conf.orig_uid, conf.mail_gid))){ - fprintf(stderr, - "must be in root, %s or in group %s for setting return path.\n", - DEF_MAIL_USER, DEF_MAIL_GROUP); - exit(EXIT_FAILURE); - } - } + if (return_path != NULL) { + if ((conf.orig_uid != 0) + && (conf.orig_uid != conf.mail_uid) + && (!is_ingroup(conf.orig_uid, conf.mail_gid))) { + fprintf(stderr, "must be in root, %s or in group %s for setting return path.\n", DEF_MAIL_USER, DEF_MAIL_GROUP); + exit(EXIT_FAILURE); + } + } - if(!conf.run_as_user){ - seteuid(conf.orig_uid); - setegid(conf.orig_gid); - } + if (!conf.run_as_user) { + seteuid(conf.orig_uid); + setegid(conf.orig_gid); + } - DEBUG(5) debugf("accepting message on stdin\n"); + DEBUG(5) debugf("accepting message on stdin\n"); - msg->received_prot = PROT_LOCAL; - for(i = 0; i < addr_cnt; i++){ - if(addresses[i][0] != '|') - msg->rcpt_list = - g_list_append(msg->rcpt_list, - create_address_qualified(addresses[i], TRUE, conf.host_name)); - else{ - logwrite(LOG_ALERT, "no pipe allowed as recipient address: %s\n", addresses[i]); - exit(EXIT_FAILURE); - } - } + msg->received_prot = PROT_LOCAL; + for (i = 0; i < addr_cnt; i++) { + if (addresses[i][0] != '|') + msg->rcpt_list = g_list_append(msg->rcpt_list, create_address_qualified(addresses[i], TRUE, conf.host_name)); + else { + logwrite(LOG_ALERT, "no pipe allowed as recipient address: %s\n", addresses[i]); + exit(EXIT_FAILURE); + } + } - /* -f option */ - msg->return_path = return_path; + /* -f option */ + msg->return_path = return_path; - /* -F option */ - msg->full_sender_name = full_sender_name; - - if((err = accept_message(stdin, msg, accept_flags)) == AERR_OK){ - if(spool_write(msg, TRUE)){ - pid_t pid; - logwrite(LOG_NOTICE, "%s <= %s with %s\n", - msg->uid, addr_string(msg->return_path), - prot_names[PROT_LOCAL]); + /* -F option */ + msg->full_sender_name = full_sender_name; - if(!conf.do_queue){ + if ((err = accept_message(stdin, msg, accept_flags)) == AERR_OK) { + if (spool_write(msg, TRUE)) { + pid_t pid; + logwrite(LOG_NOTICE, "%s <= %s with %s\n", msg->uid, addr_string(msg->return_path), prot_names[PROT_LOCAL]); - if((pid = fork()) == 0){ - - conf.do_verbose = FALSE; - - fclose(stdin); - fclose(stdout); - fclose(stderr); - - if(deliver(msg)){ - exit(EXIT_SUCCESS); - }else - exit(EXIT_FAILURE); - }else if(pid < 0){ - logwrite(LOG_ALERT, "could not fork for delivery, id = %s", - msg->uid); + if (!conf.do_queue) { + if ((pid = fork()) == 0) { + conf.do_verbose = FALSE; + fclose(stdin); + fclose(stdout); + fclose(stderr); + if (deliver(msg)) { + exit(EXIT_SUCCESS); + } else + exit(EXIT_FAILURE); + } else if (pid < 0) { + logwrite(LOG_ALERT, "could not fork for delivery, id = %s", msg->uid); + } + } + } else { + fprintf(stderr, "Could not write spool file\n"); + exit(EXIT_FAILURE); + } + } else { + switch (err) { + case AERR_EOF: + fprintf(stderr, "unexpected EOF.\n"); + exit(EXIT_FAILURE); + case AERR_NORCPT: + fprintf(stderr, "no recipients.\n"); + exit(EXIT_FAILURE); + default: + /* should never happen: */ + fprintf(stderr, "Unknown error (%d)\r\n", err); + exit(EXIT_FAILURE); + } + exit(EXIT_FAILURE); } - } - }else{ - fprintf(stderr, "Could not write spool file\n"); - exit(EXIT_FAILURE); - } - }else{ - switch(err){ - case AERR_EOF: - fprintf(stderr, "unexpected EOF.\n"); - exit(EXIT_FAILURE); - case AERR_NORCPT: - fprintf(stderr, "no recipients.\n"); - exit(EXIT_FAILURE); - default: - /* should never happen: */ - fprintf(stderr, "Unknown error (%d)\r\n", err); - exit(EXIT_FAILURE); - } - exit(EXIT_FAILURE); - } } int main(int argc, char *argv[]) { - /* cmd line flags */ - gchar *conf_file = CONF_FILE; - gint arg = 1; - gboolean do_get = FALSE; - gboolean do_get_online = FALSE; + /* cmd line flags */ + gchar *conf_file = CONF_FILE; + gint arg = 1; + gboolean do_get = FALSE; + gboolean do_get_online = FALSE; - gboolean do_listen = FALSE; - gboolean do_runq = FALSE; - gboolean do_runq_online = FALSE; + gboolean do_listen = FALSE; + gboolean do_runq = FALSE; + gboolean do_runq_online = FALSE; - gboolean do_queue = FALSE; + gboolean do_queue = FALSE; - gboolean do_verbose = FALSE; - gint debug_level = -1; + gboolean do_verbose = FALSE; + gint debug_level = -1; - mta_mode mta_mode = MODE_ACCEPT; + mta_mode mta_mode = MODE_ACCEPT; - gint queue_interval = 0; - gint get_interval = 0; - gboolean opt_t = FALSE; - gboolean opt_i = FALSE; - gboolean opt_odb = FALSE; - gboolean opt_oem = FALSE; - gboolean exit_failure = FALSE; + gint queue_interval = 0; + gint get_interval = 0; + gboolean opt_t = FALSE; + gboolean opt_i = FALSE; + gboolean opt_odb = FALSE; + gboolean opt_oem = FALSE; + gboolean exit_failure = FALSE; - gchar *M_cmd = NULL; + gchar *M_cmd = NULL; - gint exit_code = EXIT_SUCCESS; - gchar *route_name = NULL; - gchar *get_name = NULL; - gchar *progname; - gchar *f_address = NULL; - gchar *full_sender_name = NULL; - address *return_path = NULL; /* may be changed by -f option */ + gint exit_code = EXIT_SUCCESS; + gchar *route_name = NULL; + gchar *get_name = NULL; + gchar *progname; + gchar *f_address = NULL; + gchar *full_sender_name = NULL; + address *return_path = NULL; /* may be changed by -f option */ - progname = get_progname(argv[0]); + progname = get_progname(argv[0]); - if(strcmp(progname, "mailq") == 0) - { mta_mode = MODE_LIST; } - else if(strcmp(progname, "mailrm") == 0) - { mta_mode = MODE_MCMD; M_cmd = "rm"; } - else if(strcmp(progname, "runq") == 0) - { mta_mode = MODE_RUNQUEUE; do_runq = TRUE; } - else if(strcmp(progname, "rmail") == 0) - { mta_mode = MODE_ACCEPT; opt_i = TRUE; } - else if(strcmp(progname, "smtpd") == 0 || strcmp(progname, "in.smtpd") == 0) - { mta_mode = MODE_SMTP; } + if (strcmp(progname, "mailq") == 0) { + mta_mode = MODE_LIST; + } else if (strcmp(progname, "mailrm") == 0) { + mta_mode = MODE_MCMD; + M_cmd = "rm"; + } else if (strcmp(progname, "runq") == 0) { + mta_mode = MODE_RUNQUEUE; + do_runq = TRUE; + } else if (strcmp(progname, "rmail") == 0) { + mta_mode = MODE_ACCEPT; + opt_i = TRUE; + } else if (strcmp(progname, "smtpd") == 0 || strcmp(progname, "in.smtpd") == 0) { + mta_mode = MODE_SMTP; + } - /* parse cmd line */ - while(arg < argc){ - gint pos = 0; - if((argv[arg][pos] == '-') && (argv[arg][pos+1] != '-')){ - pos++; - switch(argv[arg][pos++]){ - case 'b': - switch(argv[arg][pos++]){ - case 'd': - do_listen = TRUE; - mta_mode = MODE_DAEMON; - break; - case 'i': - /* ignored */ - mta_mode = MODE_BI; - break; - case 's': - mta_mode = MODE_SMTP; - break; - case 'p': - mta_mode = MODE_LIST; - break; - case 'V': - mta_mode = MODE_VERSION; - break; - default: - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); + /* parse cmd line */ + while (arg < argc) { + gint pos = 0; + if ((argv[arg][pos] == '-') && (argv[arg][pos + 1] != '-')) { + pos++; + switch (argv[arg][pos++]) { + case 'b': + switch (argv[arg][pos++]) { + case 'd': + do_listen = TRUE; + mta_mode = MODE_DAEMON; + break; + case 'i': + /* ignored */ + mta_mode = MODE_BI; + break; + case 's': + mta_mode = MODE_SMTP; + break; + case 'p': + mta_mode = MODE_LIST; + break; + case 'V': + mta_mode = MODE_VERSION; + break; + default: + fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); + exit(EXIT_FAILURE); + } + break; + case 'B': + /* we ignore this and throw the argument away */ + get_optarg(argv, argc, &arg, &pos); + break; + case 'C': + if (!(conf_file = get_optarg(argv, argc, &arg, &pos))) { + fprintf(stderr, "-C requires a filename as argument.\n"); + exit(EXIT_FAILURE); + } + break; + case 'F': + { + full_sender_name = get_optarg(argv, argc, &arg, &pos); + if (!full_sender_name) { + fprintf(stderr, "-F requires a name as an argument\n"); + exit(EXIT_FAILURE); + } + } + break; + case 'd': + if (getuid() == 0) { + char *lvl = get_optarg(argv, argc, &arg, &pos); + if (lvl) + debug_level = atoi(lvl); + else { + fprintf(stderr, "-d requires a number as an argument.\n"); + exit(EXIT_FAILURE); + } + } else { + fprintf(stderr, "only root may set the debug level.\n"); + exit(EXIT_FAILURE); + } + break; + case 'f': + /* set return path */ + { + gchar *address; + address = get_optarg(argv, argc, &arg, &pos); + if (address) { + f_address = g_strdup(address); + } else { + fprintf(stderr, "-f requires an address as an argument\n"); + exit(EXIT_FAILURE); + } + } + break; + case 'g': + do_get = TRUE; + if (!mta_mode) + mta_mode = MODE_NONE; /* to prevent default MODE_ACCEPT */ + if (argv[arg][pos] == 'o') { + pos++; + do_get_online = TRUE; + /* can be NULL, then we use online detection method */ + route_name = get_optarg(argv, argc, &arg, &pos); + + if (route_name != NULL) { + if (isdigit(route_name[0])) { + get_interval = time_interval(route_name, &pos); + route_name = get_optarg(argv, argc, &arg, &pos); + mta_mode = MODE_GET_DAEMON; + do_get = FALSE; + } + } + } else { + if ((optarg = get_optarg(argv, argc, &arg, &pos))) { + get_name = get_optarg(argv, argc, &arg, &pos); + } + } + break; + case 'i': + if (argv[arg][pos] == 0) { + opt_i = TRUE; + exit_failure = FALSE; /* may override -oem */ + } else { + fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); + exit(EXIT_FAILURE); + } + break; + case 'M': + { + mta_mode = MODE_MCMD; + M_cmd = g_strdup(&(argv[arg][pos])); + } + break; + case 'o': + switch (argv[arg][pos++]) { + case 'e': + if (argv[arg][pos++] == 'm') /* -oem */ + if (!opt_i) + exit_failure = TRUE; + opt_oem = TRUE; + break; + case 'd': + if (argv[arg][pos] == 'b') /* -odb */ + opt_odb = TRUE; + else if (argv[arg][pos] == 'q') /* -odq */ + do_queue = TRUE; + break; + case 'i': + opt_i = TRUE; + exit_failure = FALSE; /* may override -oem */ + break; + } + break; + + case 'q': + { + gchar *optarg; + + do_runq = TRUE; + mta_mode = MODE_RUNQUEUE; + if (argv[arg][pos] == 'o') { + pos++; + do_runq = FALSE; + do_runq_online = TRUE; + /* can be NULL, then we use online detection method */ + route_name = get_optarg(argv, argc, &arg, &pos); + } else + if ((optarg = get_optarg(argv, argc, &arg, &pos))) { + mta_mode = MODE_DAEMON; + queue_interval = time_interval(optarg, &pos); + } + } + break; + case 't': + if (argv[arg][pos] == 0) { + opt_t = TRUE; + } else { + fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); + exit(EXIT_FAILURE); + } + break; + case 'v': + do_verbose = TRUE; + break; + default: + fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); + exit(EXIT_FAILURE); + } + } else { + if (argv[arg][pos + 1] == '-') { + if (argv[arg][pos + 2] != '\0') { + fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); + exit(EXIT_FAILURE); + } + arg++; + } + break; + } + arg++; } - break; - case 'B': - /* we ignore this and throw the argument away */ - get_optarg(argv, argc, &arg, &pos); - break; - case 'C': - if(!(conf_file = get_optarg(argv, argc, &arg, &pos))){ - fprintf(stderr, "-C requires a filename as argument.\n"); - exit(EXIT_FAILURE); - } - break; - case 'F': - { - full_sender_name = get_optarg(argv, argc, &arg, &pos); - if(!full_sender_name){ - fprintf(stderr, "-F requires a name as an argument\n"); - exit(EXIT_FAILURE); - } - } - break; - case 'd': - if(getuid() == 0){ - char *lvl = get_optarg(argv, argc, &arg, &pos); - if(lvl) - debug_level = atoi(lvl); - else{ - fprintf(stderr, "-d requires a number as an argument.\n"); - exit(EXIT_FAILURE); - } - }else{ - fprintf(stderr, "only root may set the debug level.\n"); - exit(EXIT_FAILURE); - } - break; - case 'f': - /* set return path */ - { - gchar *address; - address = get_optarg(argv, argc, &arg, &pos); - if(address){ - f_address = g_strdup(address); - }else{ - fprintf(stderr, "-f requires an address as an argument\n"); - exit(EXIT_FAILURE); - } - } - break; - case 'g': - do_get = TRUE; - if(!mta_mode) mta_mode = MODE_NONE; /* to prevent default MODE_ACCEPT */ - if(argv[arg][pos] == 'o'){ - pos++; - do_get_online = TRUE; - /* can be NULL, then we use online detection method */ - route_name = get_optarg(argv, argc, &arg, &pos); - if(route_name != NULL){ - if(isdigit(route_name[0])){ - get_interval = time_interval(route_name, &pos); - route_name = get_optarg(argv, argc, &arg, &pos); - mta_mode = MODE_GET_DAEMON; - do_get = FALSE; - } - } - }else{ - if((optarg = get_optarg(argv, argc, &arg, &pos))){ - get_name = get_optarg(argv, argc, &arg, &pos); - } - } - break; - case 'i': - if(argv[arg][pos] == 0){ - opt_i = TRUE; - exit_failure = FALSE; /* may override -oem */ - }else{ - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); - } - break; - case 'M': - { - mta_mode = MODE_MCMD; - M_cmd = g_strdup(&(argv[arg][pos])); - } - break; - case 'o': - switch(argv[arg][pos++]){ - case 'e': - if(argv[arg][pos++] == 'm') /* -oem */ - if(!opt_i) exit_failure = TRUE; - opt_oem = TRUE; - break; - case 'd': - if(argv[arg][pos] == 'b') /* -odb */ - opt_odb = TRUE; - else if(argv[arg][pos] == 'q') /* -odq */ - do_queue = TRUE; - break; - case 'i': - opt_i = TRUE; - exit_failure = FALSE; /* may override -oem */ - break; - } - break; + if (mta_mode == MODE_VERSION) { + gchar *with_resolver = "", *with_smtp_server = "", *with_pop3 = "", + *with_auth = "", *with_maildir = "", *with_ident = "", *with_mserver = ""; - case 'q': - { - gchar *optarg; - - do_runq = TRUE; - mta_mode = MODE_RUNQUEUE; - if(argv[arg][pos] == 'o'){ - pos++; - do_runq = FALSE; - do_runq_online = TRUE; - /* can be NULL, then we use online detection method */ - route_name = get_optarg(argv, argc, &arg, &pos); - }else if((optarg = get_optarg(argv, argc, &arg, &pos))){ - mta_mode = MODE_DAEMON; - queue_interval = time_interval(optarg, &pos); - } - } - break; - case 't': - if(argv[arg][pos] == 0){ - opt_t = TRUE; - }else{ - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); - } - break; - case 'v': - do_verbose = TRUE; - break; - default: - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); - } - }else{ - if(argv[arg][pos+1] == '-'){ - if(argv[arg][pos+2] != '\0'){ - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); - } - arg++; - } - break; - } - arg++; - } - - if(mta_mode == MODE_VERSION){ - gchar *with_resolver = "", *with_smtp_server = "", *with_pop3 = "", *with_auth = "", - *with_maildir = "", *with_ident = "", *with_mserver = ""; - #ifdef ENABLE_RESOLVER - with_resolver = " +resolver"; + with_resolver = " +resolver"; #endif #ifdef ENABLE_SMTP_SERVER - with_smtp_server = " +smtp-server"; + with_smtp_server = " +smtp-server"; #endif #ifdef ENABLE_POP3 - with_pop3 = " +pop3"; + with_pop3 = " +pop3"; #endif #ifdef ENABLE_AUTH - with_auth = " +auth"; + with_auth = " +auth"; #endif #ifdef ENABLE_MAILDIR - with_maildir = " +maildir"; + with_maildir = " +maildir"; #endif #ifdef ENABLE_IDENT - with_ident = " +ident"; + with_ident = " +ident"; #endif #ifdef ENABLE_MSERVER - with_mserver = " +mserver"; + with_mserver = " +mserver"; #endif - printf("%s %s%s%s%s%s%s%s%s\n", PACKAGE, VERSION, - with_resolver, with_smtp_server, with_pop3, with_auth, - with_maildir, with_ident, with_mserver); - - exit(EXIT_SUCCESS); - } + printf("%s %s%s%s%s%s%s%s%s\n", PACKAGE, VERSION, with_resolver, with_smtp_server, + with_pop3, with_auth, with_maildir, with_ident, with_mserver); - /* initialize random generator */ - srand(time(NULL)); - /* ignore SIGPIPE signal */ - signal(SIGPIPE, SIG_IGN); + exit(EXIT_SUCCESS); + } - /* close all possibly open file descriptors */ - { - int i, max_fd = sysconf(_SC_OPEN_MAX); + /* initialize random generator */ + srand(time(NULL)); + /* ignore SIGPIPE signal */ + signal(SIGPIPE, SIG_IGN); - if(max_fd <= 0) max_fd = 64; - for(i = 3; i < max_fd; i++) - close(i); - } + /* close all possibly open file descriptors */ + { + int i, max_fd = sysconf(_SC_OPEN_MAX); - init_conf(); + if (max_fd <= 0) + max_fd = 64; + for (i = 3; i < max_fd; i++) + close(i); + } - /* if we are not privileged, and the config file was changed we - implicetely set the the run_as_user flag and give up all - privileges. + init_conf(); - So it is possible for a user to run his own daemon without - breaking security. - */ - if(strcmp(conf_file, CONF_FILE) != 0){ - if(conf.orig_uid != 0){ - conf.run_as_user = TRUE; - seteuid(conf.orig_uid); - setegid(conf.orig_gid); - setuid(conf.orig_uid); - setgid(conf.orig_gid); - } - } + /* if we are not privileged, and the config file was changed we + implicetely set the the run_as_user flag and give up all + privileges. - read_conf(conf_file); + So it is possible for a user to run his own daemon without + breaking security. + */ + if (strcmp(conf_file, CONF_FILE) != 0) { + if (conf.orig_uid != 0) { + conf.run_as_user = TRUE; + seteuid(conf.orig_uid); + setegid(conf.orig_gid); + setuid(conf.orig_uid); + setgid(conf.orig_gid); + } + } - if(do_queue) conf.do_queue = TRUE; - if(do_verbose) conf.do_verbose = TRUE; - if(debug_level >= 0) /* if >= 0, it was given by argument */ - conf.debug_level = debug_level; + read_conf(conf_file); - chdir("/"); + if (do_queue) + conf.do_queue = TRUE; + if (do_verbose) + conf.do_verbose = TRUE; + if (debug_level >= 0) /* if >= 0, it was given by argument */ + conf.debug_level = debug_level; - if(!conf.run_as_user){ - if(setgid(0) != 0){ - fprintf(stderr, - "could not set gid to 0. Is the setuid bit set? : %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - if(setuid(0) != 0){ - fprintf(stderr, - "could not gain root privileges. Is the setuid bit set? : %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - } + chdir("/"); - if(!logopen()){ - fprintf(stderr, "could not open log file\n"); - exit(EXIT_FAILURE); - } + if (!conf.run_as_user) { + if (setgid(0) != 0) { + fprintf(stderr, "could not set gid to 0. Is the setuid bit set? : %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + if (setuid(0) != 0) { + fprintf(stderr, "could not gain root privileges. Is the setuid bit set? : %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } - DEBUG(1) debugf("masqmail %s starting\n", VERSION); + if (!logopen()) { + fprintf(stderr, "could not open log file\n"); + exit(EXIT_FAILURE); + } - DEBUG(5){ - gchar **str = argv; - debugf("args: \n"); - while(*str){ - debugf("%s \n", *str); - str++; - } - } - DEBUG(5) debugf("queue_interval = %d\n", queue_interval); + DEBUG(1) debugf("masqmail %s starting\n", VERSION); - if(f_address){ - return_path = create_address_qualified(f_address, TRUE, conf.host_name); - g_free(f_address); - if(!return_path){ - fprintf(stderr, "invalid RFC821 address: %s\n", f_address); - exit(EXIT_FAILURE); - } - } + DEBUG(5) { + gchar **str = argv; + debugf("args: \n"); + while (*str) { + debugf("%s \n", *str); + str++; + } + } + DEBUG(5) debugf("queue_interval = %d\n", queue_interval); - if(do_get){ + if (f_address) { + return_path = create_address_qualified(f_address, TRUE, conf.host_name); + g_free(f_address); + if (!return_path) { + fprintf(stderr, "invalid RFC821 address: %s\n", f_address); + exit(EXIT_FAILURE); + } + } + + if (do_get) { #ifdef ENABLE_POP3 - if((mta_mode == MODE_NONE) || (mta_mode == MODE_RUNQUEUE)){ + if ((mta_mode == MODE_NONE) || (mta_mode == MODE_RUNQUEUE)) { + set_identity(conf.orig_uid, "getting mail"); + if (do_get_online) { + if (route_name != NULL) { + conf.online_detect = g_strdup("argument"); + set_online_name(route_name); + } + get_online(); + } else { + if (get_name) + get_from_name(get_name); + else + get_all(); + } + } else { + logwrite(LOG_ALERT, "get (-g) only allowed alone or together with queue run (-q)\n"); + } +#else + fprintf(stderr, "get (pop) support not compiled in\n"); +#endif + } - set_identity(conf.orig_uid, "getting mail"); + switch (mta_mode) { + case MODE_DAEMON: + mode_daemon(do_listen, queue_interval, argv); + break; + case MODE_RUNQUEUE: + { + /* queue runs */ + set_identity(conf.orig_uid, "queue run"); - if(do_get_online){ - if(route_name != NULL){ - conf.online_detect = g_strdup("argument"); - set_online_name(route_name); + if (do_runq) + exit_code = queue_run() ? EXIT_SUCCESS : EXIT_FAILURE; + + if (do_runq_online) { + if (route_name != NULL) { + conf.online_detect = g_strdup("argument"); + set_online_name(route_name); + } + exit_code = + queue_run_online() ? EXIT_SUCCESS : EXIT_FAILURE; + } + } + break; + case MODE_GET_DAEMON: +#ifdef ENABLE_POP3 + if (route_name != NULL) { + conf.online_detect = g_strdup("argument"); + set_online_name(route_name); + } + mode_get_daemon(get_interval, argv); +#endif + break; + + case MODE_SMTP: +#ifdef ENABLE_SMTP_SERVER + mode_smtp(); +#else + fprintf(stderr, "smtp server support not compiled in\n"); +#endif + break; + + case MODE_LIST: + queue_list(); + break; + + case MODE_BI: + exit(EXIT_SUCCESS); + break; /* well... */ + + case MODE_MCMD: + if (strcmp(M_cmd, "rm") == 0) { + gboolean ok = FALSE; + + set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL); + + if (is_privileged_user(conf.orig_uid)) { + for (; arg < argc; arg++) { + if (queue_delete(argv[arg])) + ok = TRUE; + } + } else { + struct passwd *pw = getpwuid(conf.orig_uid); + if (pw) { + for (; arg < argc; arg++) { + message *msg = msg_spool_read(argv[arg], FALSE); +#ifdef ENABLE_IDENT + if (((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)) + || is_in_netlist(msg->received_host, conf.ident_trusted_nets)) { +#else + if ((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)) { +#endif + if (msg->ident) { + if (strcmp(pw->pw_name, msg->ident) == 0) { + if (queue_delete(argv[arg])) + ok = TRUE; + } else { + fprintf(stderr, "you do not own message id %s\n", argv[arg]); + } + } else + fprintf(stderr, "message %s does not have an ident.\n", argv[arg]); + } else { + fprintf(stderr, "message %s was not received locally or from a trusted network.\n", argv[arg]); + } + } + } else { + fprintf(stderr, "could not find a passwd entry for uid %d: %s\n", conf.orig_uid, strerror(errno)); + } + } + exit(ok ? EXIT_SUCCESS : EXIT_FAILURE); + } else { + fprintf(stderr, "unknown command %s\n", M_cmd); + exit(EXIT_FAILURE); + } + break; + + case MODE_ACCEPT: + { + guint accept_flags = (opt_t ? ACC_DEL_RCPTS | ACC_DEL_BCC | ACC_RCPT_FROM_HEAD : ACC_HEAD_FROM_RCPT) + | (opt_i ? ACC_NODOT_TERM : ACC_NODOT_RELAX); + mode_accept(return_path, full_sender_name, accept_flags, &(argv[arg]), argc - arg); + exit(exit_failure ? EXIT_FAILURE : EXIT_SUCCESS); + } + break; + case MODE_NONE: + break; + default: + fprintf(stderr, "unknown mode: %d\n", mta_mode); + break; } - get_online(); - }else{ - if(get_name) - get_from_name(get_name); - else - get_all(); - } - }else{ - logwrite(LOG_ALERT, "get (-g) only allowed alone or together with queue run (-q)\n"); - } -#else - fprintf(stderr, "get (pop) support not compiled in\n"); -#endif - } - switch(mta_mode){ - case MODE_DAEMON: - mode_daemon(do_listen, queue_interval, argv); - break; - case MODE_RUNQUEUE: - { - /* queue runs */ - set_identity(conf.orig_uid, "queue run"); + logclose(); - if(do_runq) - exit_code = queue_run() ? EXIT_SUCCESS : EXIT_FAILURE; - - if(do_runq_online){ - if(route_name != NULL){ - conf.online_detect = g_strdup("argument"); - set_online_name(route_name); - } - exit_code = queue_run_online() ? EXIT_SUCCESS : EXIT_FAILURE; - } - } - break; - case MODE_GET_DAEMON: -#ifdef ENABLE_POP3 - if(route_name != NULL){ - conf.online_detect = g_strdup("argument"); - set_online_name(route_name); - } - mode_get_daemon(get_interval, argv); -#endif - break; - - case MODE_SMTP: -#ifdef ENABLE_SMTP_SERVER - mode_smtp(); -#else - fprintf(stderr, "smtp server support not compiled in\n"); -#endif - break; - case MODE_LIST: - - queue_list(); - break; - - case MODE_BI: - - exit(EXIT_SUCCESS); - break; /* well... */ - - case MODE_MCMD: - if(strcmp(M_cmd, "rm") == 0){ - gboolean ok = FALSE; - - set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL); - - if(is_privileged_user(conf.orig_uid)){ - for(; arg < argc; arg++){ - if(queue_delete(argv[arg])) - ok = TRUE; - } - }else{ - struct passwd *pw = getpwuid(conf.orig_uid); - if(pw){ - for(; arg < argc; arg++){ - message *msg = msg_spool_read(argv[arg], FALSE); -#ifdef ENABLE_IDENT - if(((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)) || - is_in_netlist(msg->received_host, conf.ident_trusted_nets)){ -#else - if((msg->received_host == NULL) && (msg->received_prot == PROT_LOCAL)){ -#endif - if(msg->ident){ - if(strcmp(pw->pw_name, msg->ident) == 0){ - if(queue_delete(argv[arg])) - ok = TRUE; - }else{ - fprintf(stderr, "you do not own message id %s\n", argv[arg]); - } - }else - fprintf(stderr, "message %s does not have an ident.\n", argv[arg]); - }else{ - fprintf(stderr, "message %s was not received locally or from a trusted network.\n", argv[arg]); - } - } - }else{ - fprintf(stderr, "could not find a passwd entry for uid %d: %s\n", conf.orig_uid, strerror(errno)); - } - } - exit(ok ? EXIT_SUCCESS : EXIT_FAILURE); - }else{ - fprintf(stderr, "unknown command %s\n", M_cmd); - exit(EXIT_FAILURE); - } - break; - - case MODE_ACCEPT: - { - guint accept_flags = - (opt_t ? ACC_DEL_RCPTS|ACC_DEL_BCC|ACC_RCPT_FROM_HEAD : ACC_HEAD_FROM_RCPT) | - (opt_i ? ACC_NODOT_TERM : ACC_NODOT_RELAX); - - mode_accept(return_path, full_sender_name, accept_flags, &(argv[arg]), argc - arg); - - exit(exit_failure ? EXIT_FAILURE : EXIT_SUCCESS); - } - break; - case MODE_NONE: - break; - default: - fprintf(stderr, "unknown mode: %d\n", mta_mode); - break; - } - - logclose(); - - exit(exit_code); + exit(exit_code); } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/masqmail.h --- a/src/masqmail.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/masqmail.h Mon Oct 27 16:23:10 2008 +0100 @@ -45,11 +45,9 @@ #include "lookup.h" -typedef -struct _interface -{ - gchar *address; - gint port; +typedef struct _interface { + gchar *address; + gint port; } interface; #define ADDR_FLAG_DELIVERED 0x01 @@ -58,14 +56,13 @@ #define ADDR_FLAG_LAST_ROUTE 0x40 #define ADDR_FLAG_NOEXPAND 0x80 -typedef struct _address -{ - gchar *address; - gchar *local_part; - gchar *domain; - gint flags; - GList *children; - struct _address *parent; +typedef struct _address { + gchar *address; + gchar *local_part; + gchar *domain; + gint flags; + GList *children; + struct _address *parent; } address; #define addr_mark_delivered(addr) { addr->flags |= ADDR_FLAG_DELIVERED; } @@ -80,269 +77,247 @@ #define addr_unmark_failed(addr) { addr->flags &= ~ADDR_FLAG_FAILED; } #define addr_is_failed(addr) ((addr->flags & ADDR_FLAG_FAILED) != 0 ) -typedef -struct _connect_route -{ - gchar *name; - gchar *filename; +typedef struct _connect_route { + gchar *name; + gchar *filename; - gchar *protocol; + gchar *protocol; - gboolean is_local_net; - gboolean last_route; + gboolean is_local_net; + gboolean last_route; - GList *allowed_return_paths; - GList *not_allowed_return_paths; - GList *allowed_mail_locals; - GList *not_allowed_mail_locals; - GList *allowed_rcpt_domains; - GList *not_allowed_rcpt_domains; + GList *allowed_return_paths; + GList *not_allowed_return_paths; + GList *allowed_mail_locals; + GList *not_allowed_mail_locals; + GList *allowed_rcpt_domains; + GList *not_allowed_rcpt_domains; - interface *mail_host; - gchar *wrapper; - gboolean connect_error_fail; + interface *mail_host; + gchar *wrapper; + gboolean connect_error_fail; - gchar *helo_name; - gboolean do_correct_helo; - gboolean do_pipelining; + gchar *helo_name; + gboolean do_correct_helo; + gboolean do_pipelining; - gchar *set_h_from_domain; - gchar *set_h_reply_to_domain; - gchar *set_return_path_domain; + gchar *set_h_from_domain; + gchar *set_h_reply_to_domain; + gchar *set_return_path_domain; - GList *map_h_from_addresses; - GList *map_h_reply_to_addresses; - GList *map_h_mail_followup_to_addresses; - GList *map_return_path_addresses; + GList *map_h_from_addresses; + GList *map_h_reply_to_addresses; + GList *map_h_mail_followup_to_addresses; + GList *map_return_path_addresses; - gboolean expand_h_sender_domain; - gboolean expand_h_sender_address; + gboolean expand_h_sender_domain; + gboolean expand_h_sender_address; - GList *resolve_list; + GList *resolve_list; - gchar *auth_name; - gchar *auth_login; - gchar *auth_secret; + gchar *auth_name; + gchar *auth_login; + gchar *auth_secret; - gchar *pop3_login; + gchar *pop3_login; - gchar *pipe; - - gboolean pipe_fromline; - gboolean pipe_fromhack; + gchar *pipe; + + gboolean pipe_fromline; + gboolean pipe_fromhack; } connect_route; -typedef struct _get_conf -{ - gchar *protocol; - gchar *server_name; - guint server_port; - gchar *wrapper; - gchar *login_user; - gchar *login_pass; - address *address; - address *return_path; - gboolean do_keep; - gboolean do_uidl; - gboolean do_uidl_dele; - gint max_size; - gboolean max_size_delete; - gint max_count; +typedef struct _get_conf { + gchar *protocol; + gchar *server_name; + guint server_port; + gchar *wrapper; + gchar *login_user; + gchar *login_pass; + address *address; + address *return_path; + gboolean do_keep; + gboolean do_uidl; + gboolean do_uidl_dele; + gint max_size; + gboolean max_size_delete; + gint max_count; - GList *resolve_list; + GList *resolve_list; } get_conf; -typedef -struct _masqmail_conf -{ - gint mail_uid; - gint mail_gid; +typedef struct _masqmail_conf { + gint mail_uid; + gint mail_gid; - gint orig_uid; - gint orig_gid; + gint orig_uid; + gint orig_gid; - gboolean run_as_user; + gboolean run_as_user; - gchar *mail_dir; - gchar *lock_dir; - gchar *spool_dir; - gchar *log_dir; + gchar *mail_dir; + gchar *lock_dir; + gchar *spool_dir; + gchar *log_dir; - gint debug_level; - gboolean use_syslog; - guint log_max_pri; + gint debug_level; + gboolean use_syslog; + guint log_max_pri; - gchar *host_name; - GList *local_hosts; - GList *local_addresses; - GList *not_local_addresses; - GList *local_nets; - GList *listen_addresses; + gchar *host_name; + GList *local_hosts; + GList *local_addresses; + GList *not_local_addresses; + GList *local_nets; + GList *listen_addresses; - guint remote_port; + guint remote_port; - gboolean do_save_envelope_to; + gboolean do_save_envelope_to; - gboolean defer_all; - gboolean do_relay; + gboolean defer_all; + gboolean do_relay; - GList *ident_trusted_nets; + GList *ident_trusted_nets; - gboolean do_queue; + gboolean do_queue; - gboolean do_verbose; + gboolean do_verbose; - gchar *mbox_default; - GList *mbox_users; - GList *mda_users; - GList *maildir_users; + gchar *mbox_default; + GList *mbox_users; + GList *mda_users; + GList *maildir_users; - gchar *mda; - gboolean mda_fromline; - gboolean mda_fromhack; + gchar *mda; + gboolean mda_fromline; + gboolean mda_fromhack; - gboolean pipe_fromline; - gboolean pipe_fromhack; + gboolean pipe_fromline; + gboolean pipe_fromhack; - gchar *alias_file; - int (*alias_local_cmp)(const char *, const char *); + gchar *alias_file; + int (*alias_local_cmp) (const char *, const char *); - GList *local_net_routes; - GList *connect_routes; /* list of pairs which point to lists */ + GList *local_net_routes; + GList *connect_routes; /* list of pairs which point to lists */ - gchar *online_detect; - gchar *online_file; - gchar *online_pipe; - interface *mserver_iface; + gchar *online_detect; + gchar *online_file; + gchar *online_pipe; + interface *mserver_iface; - GList *get_names; - GList *online_gets; /* list of pairs which point to lists */ + GList *get_names; + GList *online_gets; /* list of pairs which point to lists */ - gchar *errmsg_file; - gchar *warnmsg_file; - GList *warn_intervals; - gint max_defer_time; + gchar *errmsg_file; + gchar *warnmsg_file; + GList *warn_intervals; + gint max_defer_time; - gchar *log_user; + gchar *log_user; } masqmail_conf; extern masqmail_conf conf; -typedef -struct _table_pair -{ - gchar *key; - gpointer *value; +typedef struct _table_pair { + gchar *key; + gpointer *value; } table_pair; -typedef -enum _prot_id -{ - PROT_LOCAL = 0, - PROT_BSMTP, - PROT_SMTP, - PROT_ESMTP, - PROT_POP3, - PROT_APOP, - PROT_NUM -}prot_id; +typedef enum _prot_id { + PROT_LOCAL = 0, + PROT_BSMTP, + PROT_SMTP, + PROT_ESMTP, + PROT_POP3, + PROT_APOP, + PROT_NUM +} prot_id; extern gchar *prot_names[]; -typedef -enum _header_id -{ - HEAD_FROM = 0, - HEAD_SENDER, - HEAD_TO, - HEAD_CC, - HEAD_BCC, - HEAD_DATE, - HEAD_MESSAGE_ID, - HEAD_REPLY_TO, - HEAD_SUBJECT, - HEAD_RETURN_PATH, - HEAD_ENVELOPE_TO, - HEAD_RECEIVED, - HEAD_NUM_IDS, - HEAD_STATUS, - HEAD_UNKNOWN = HEAD_NUM_IDS, - HEAD_NONE = -1, -}header_id; +typedef enum _header_id { + HEAD_FROM = 0, + HEAD_SENDER, + HEAD_TO, + HEAD_CC, + HEAD_BCC, + HEAD_DATE, + HEAD_MESSAGE_ID, + HEAD_REPLY_TO, + HEAD_SUBJECT, + HEAD_RETURN_PATH, + HEAD_ENVELOPE_TO, + HEAD_RECEIVED, + HEAD_NUM_IDS, + HEAD_STATUS, + HEAD_UNKNOWN = HEAD_NUM_IDS, + HEAD_NONE = -1, +} header_id; -typedef -struct _header_name -{ - gchar *header; - header_id id; -}header_name; +typedef struct _header_name { + gchar *header; + header_id id; +} header_name; -typedef -struct _header -{ - header_id id; - gchar *header; - gchar *value; -}header; +typedef struct _header { + header_id id; + gchar *header; + gchar *value; +} header; -typedef -struct _message -{ - gchar *uid; +typedef struct _message { + gchar *uid; - gchar *received_host; - prot_id received_prot; - gchar *ident; - gint transfer_id; /* for multiple messages per transfer */ + gchar *received_host; + prot_id received_prot; + gchar *ident; + gint transfer_id; /* for multiple messages per transfer */ - address *return_path; - GList *rcpt_list; - GList *non_rcpt_list; + address *return_path; + GList *rcpt_list; + GList *non_rcpt_list; - GList *hdr_list; - GList *data_list; + GList *hdr_list; + GList *data_list; - gint data_size; - time_t received_time; - time_t warned_time; + gint data_size; + time_t received_time; + time_t warned_time; - gchar *full_sender_name; -}message; + gchar *full_sender_name; +} message; -typedef -struct _msg_out -{ - message *msg; - - address *return_path; - GList *rcpt_list; +typedef struct _msg_out { + message *msg; - GList *hdr_list; - GList *xtra_hdr_list; -}msg_out; + address *return_path; + GList *rcpt_list; -typedef -struct _msgout_perhost -{ - gchar *host; - GList *msgout_list; + GList *hdr_list; + GList *xtra_hdr_list; +} msg_out; + +typedef struct _msgout_perhost { + gchar *host; + GList *msgout_list; } msgout_perhost; /* flags for accept() */ /*#define ACC_LOCAL 0x01 (we better use received_host == NULL) */ -#define ACC_HEAD_FROM_RCPT 0x01 /* create To: Header from rcpt_list (cmd line) */ -#define ACC_DEL_RCPTS 0x02 /* -t option, delete rcpts */ -#define ACC_DEL_BCC 0x04 /* -t option, delete Bcc header */ -#define ACC_RCPT_FROM_HEAD 0x08 /* -t option, get rcpts from headers */ -#define ACC_NODOT_TERM 0x10 /* a dot on a line itself does not end - the message (-oi option) */ -#define ACC_NO_RECVD_HDR 0x20 /* do not create a Received: header */ -#define ACC_MAIL_FROM_HEAD 0x40 /* get return path from header */ -#define ACC_NODOT_RELAX 0x80 /* do not be picky if message ist not terminated by a dot on a line */ -#define ACC_SAVE_ENVELOPE_TO 0x0100 /* save an existent Envelope-to header as X-Orig-Envelope-to */ +#define ACC_HEAD_FROM_RCPT 0x01 /* create To: Header from rcpt_list (cmd line) */ +#define ACC_DEL_RCPTS 0x02 /* -t option, delete rcpts */ +#define ACC_DEL_BCC 0x04 /* -t option, delete Bcc header */ +#define ACC_RCPT_FROM_HEAD 0x08 /* -t option, get rcpts from headers */ +#define ACC_NODOT_TERM 0x10 /* a dot on a line itself does not end the message (-oi option) */ +#define ACC_NO_RECVD_HDR 0x20 /* do not create a Received: header */ +#define ACC_MAIL_FROM_HEAD 0x40 /* get return path from header */ +#define ACC_NODOT_RELAX 0x80 /* do not be picky if message ist not terminated by a dot on a line */ +#define ACC_SAVE_ENVELOPE_TO 0x0100 /* save an existent Envelope-to header as X-Orig-Envelope-to */ #define DLVR_LOCAL 0x01 #define DLVR_LAN 0x02 @@ -353,192 +328,171 @@ #define MSGSTR_FROMLINE 0x01 #define MSGSTR_FROMHACK 0x02 -typedef -enum _accept_error -{ - AERR_OK = 0, - AERR_TIMEOUT, - AERR_EOF, - AERR_OVERFLOW, - AERR_SYNTAX, - AERR_NOSPOOL, - AERR_NORCPT, - AERR_UNKNOWN -}accept_error; +typedef enum _accept_error { + AERR_OK = 0, + AERR_TIMEOUT, + AERR_EOF, + AERR_OVERFLOW, + AERR_SYNTAX, + AERR_NOSPOOL, + AERR_NORCPT, + AERR_UNKNOWN +} accept_error; #define BUF_LEN 1024 #define MAX_ADDRESS 256 #define MAX_DATALINE 4096 -typedef -enum _smtp_cmd_id -{ - SMTP_HELO = 0, - SMTP_EHLO, - SMTP_MAIL_FROM, - SMTP_RCPT_TO, - SMTP_DATA, - SMTP_QUIT, - SMTP_RSET, - SMTP_NOOP, - SMTP_HELP, - SMTP_NUM_IDS, - SMTP_EOF = -1, - SMTP_ERROR = -2, +typedef enum _smtp_cmd_id { + SMTP_HELO = 0, + SMTP_EHLO, + SMTP_MAIL_FROM, + SMTP_RCPT_TO, + SMTP_DATA, + SMTP_QUIT, + SMTP_RSET, + SMTP_NOOP, + SMTP_HELP, + SMTP_NUM_IDS, + SMTP_EOF = -1, + SMTP_ERROR = -2, } smtp_cmd_id; -typedef -struct _smtp_cmd -{ - smtp_cmd_id id; - gchar *cmd; +typedef struct _smtp_cmd { + smtp_cmd_id id; + gchar *cmd; } smtp_cmd; -typedef -struct _smtp_connection -{ - gchar *remote_host; +typedef struct _smtp_connection { + gchar *remote_host; - prot_id prot; - gint next_id; - - gboolean helo_seen; - gboolean from_seen; - gboolean rcpt_seen; + prot_id prot; + gint next_id; - message *msg; -}smtp_connection; + gboolean helo_seen; + gboolean from_seen; + gboolean rcpt_seen; + + message *msg; +} smtp_connection; /* alias.c*/ -gboolean addr_is_local(address *addr); -GList *alias_expand(GList *alias_table, GList *rcpt_list, GList *non_rcpt_list); +gboolean addr_is_local(address * addr); +GList *alias_expand(GList * alias_table, GList * rcpt_list, GList * non_rcpt_list); /* child.c */ int child(const char *command); /* conf.c */ void init_conf(); -gboolean read_conf(gchar *filename); -connect_route *read_route(gchar *filename, gboolean is_local_net); -GList *read_route_list(GList *rf_list, gboolean is_local_net); -void destroy_route(connect_route *r); -void destroy_route_list(GList *list); -get_conf *read_get_conf(gchar *filename); -void destroy_get_conf(get_conf *gc); +gboolean read_conf(gchar * filename); +connect_route *read_route(gchar * filename, gboolean is_local_net); +GList *read_route_list(GList * rf_list, gboolean is_local_net); +void destroy_route(connect_route * r); +void destroy_route_list(GList * list); +get_conf *read_get_conf(gchar * filename); +void destroy_get_conf(get_conf * gc); connect_route *create_local_route(); /* expand.c */ -GList *var_table_rcpt(GList *var_table, address *rcpt); -GList *var_table_msg(GList *var_table, message *msg); -GList *var_table_conf(GList *var_table); -gint expand(GList *var_list, gchar *format, gchar *result, gint result_len); +GList *var_table_rcpt(GList * var_table, address * rcpt); +GList *var_table_msg(GList * var_table, message * msg); +GList *var_table_conf(GList * var_table); +gint expand(GList * var_list, gchar * format, gchar * result, gint result_len); /* message.c */ message *create_message(void); -void destroy_message(message *msg); -void destroy_msg_list(GList *msg_list); -void msg_free_data(message *msg); -gint msg_calc_size(message *msg, gboolean is_smtp); +void destroy_message(message * msg); +void destroy_msg_list(GList * msg_list); +void msg_free_data(message * msg); +gint msg_calc_size(message * msg, gboolean is_smtp); -msg_out *create_msg_out(message *msg); -msg_out *clone_msg_out(msg_out *msgout_orig); -GList *create_msg_out_list(GList *msg_list); -void destroy_msg_out(msg_out *msgout); -void destroy_msg_out_list(GList *msgout_list); +msg_out *create_msg_out(message * msg); +msg_out *clone_msg_out(msg_out * msgout_orig); +GList *create_msg_out_list(GList * msg_list); +void destroy_msg_out(msg_out * msgout); +void destroy_msg_out_list(GList * msgout_list); /* address.c */ -address *create_address(gchar *path, gboolean is_rfc821); -address *create_address_qualified(gchar *path, gboolean is_rfc821, - gchar *domain); -address *create_address_pipe(gchar *path); -void destroy_address(address *addr); -address *copy_modify_address(const address *orig, gchar *l_part, gchar *dom); +address *create_address(gchar * path, gboolean is_rfc821); +address *create_address_qualified(gchar * path, gboolean is_rfc821, gchar * domain); +address *create_address_pipe(gchar * path); +void destroy_address(address * addr); +address *copy_modify_address(const address * orig, gchar * l_part, gchar * dom); #define copy_address(addr) copy_modify_address(addr, NULL, NULL) -gboolean addr_isequal(address *addr1, address *addr2); -gboolean addr_isequal_parent(address *addr1, address *addr2); -address *addr_find_ancestor(address *addr); -gboolean addr_is_delivered_children(address *addr); -gboolean addr_is_finished_children(address *addr); -gchar *addr_string(address *addr); -gint addr_match(address *addr1, address *addr2); +gboolean addr_isequal(address * addr1, address * addr2); +gboolean addr_isequal_parent(address * addr1, address * addr2); +address *addr_find_ancestor(address * addr); +gboolean addr_is_delivered_children(address * addr); +gboolean addr_is_finished_children(address * addr); +gchar *addr_string(address * addr); +gint addr_match(address * addr1, address * addr2); /* accept.c */ -accept_error accept_message(FILE *in, message *msg, - guint flags); -accept_error accept_message_prepare(message *msg, guint flags); +accept_error accept_message(FILE * in, message * msg, guint flags); +accept_error accept_message_prepare(message * msg, guint flags); /* header.c */ gchar *rec_timestamp(); -GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str); -void header_unfold(header *hdr); -void header_fold(header *hdr); -header *create_header(header_id id, gchar *fmt, ...); -void destroy_header(header *hdr); -header *copy_header(header *hdr); -header *get_header(gchar *line); +GList *find_header(GList * hdr_list, header_id id, gchar * hdr_str); +void header_unfold(header * hdr); +void header_fold(header * hdr); +header *create_header(header_id id, gchar * fmt, ...); +void destroy_header(header * hdr); +header *copy_header(header * hdr); +header *get_header(gchar * line); /* smtp_in.c */ -void smtp_in(FILE *in, FILE *out, gchar *remote_host, gchar *ident); +void smtp_in(FILE * in, FILE * out, gchar * remote_host, gchar * ident); /* listen.c */ -void listen_port(GList *addr_list, gint qival, char *argv[]); +void listen_port(GList * addr_list, gint qival, char *argv[]); /* parse.c */ -gboolean split_address(const gchar *path, gchar **local_part, gchar **domain, - gboolean is_rfc821); -gboolean parse_address_rfc822(gchar *string, - gchar **local_begin, gchar **local_end, - gchar **domain_begin, gchar **domain_end, - gchar **address_end); -gboolean parse_address_rfc821(gchar *string, - gchar **local_begin, gchar **local_end, - gchar **domain_begin, gchar **domain_end, - gchar **address_end); -address *_create_address(gchar *string, gchar **end, gboolean is_rfc821); -address *create_address_rfc821(gchar *string, gchar **end); -address *create_address_rfc822(gchar *string, gchar **end); -GList *addr_list_append_rfc822(GList *addr_list, gchar *string, gchar *domain); -gboolean addr_isequal(address *addr1, address *addr2); +gboolean split_address(const gchar * path, gchar ** local_part, gchar ** domain, gboolean is_rfc821); +gboolean parse_address_rfc822(gchar * string, gchar ** local_begin, gchar ** local_end, gchar ** domain_begin, gchar ** domain_end, gchar ** address_end); +gboolean parse_address_rfc821(gchar * string, gchar ** local_begin, gchar ** local_end, gchar ** domain_begin, gchar ** domain_end, gchar ** address_end); +address *_create_address(gchar * string, gchar ** end, gboolean is_rfc821); +address *create_address_rfc821(gchar * string, gchar ** end); +address *create_address_rfc822(gchar * string, gchar ** end); +GList *addr_list_append_rfc822(GList * addr_list, gchar * string, gchar * domain); +gboolean addr_isequal(address * addr1, address * addr2); /* connect.c */ -mxip_addr *connect_hostlist(int *psockfd, gchar *host, guint port, - GList *addr_list); -mxip_addr *connect_resolvelist(int *psockfd, gchar *host, guint port, - GList *res_funcs); +mxip_addr *connect_hostlist(int *psockfd, gchar * host, guint port, GList * addr_list); +mxip_addr *connect_resolvelist(int *psockfd, gchar * host, guint port, GList * res_funcs); /* deliver.c */ -void msg_rcptlist_local(GList *rcpt_list, GList **, GList **); -gboolean deliver_local(msg_out *msgout); -gboolean deliver_msglist_host(connect_route *route, GList *msg_list, gchar *host, GList *res_list); -gboolean deliver_route_msgout_list(connect_route *route, GList *msgout_list); -gboolean deliver_route_msg_list(connect_route *route, GList *msgout_list); -gboolean deliver_finish(msg_out *msgout); -gboolean deliver_finish_list(GList *msgout_list); -gboolean deliver_msg_list(GList *msg_list, guint flags); -gboolean deliver(message *msg); +void msg_rcptlist_local(GList * rcpt_list, GList **, GList **); +gboolean deliver_local(msg_out * msgout); +gboolean deliver_msglist_host(connect_route * route, GList * msg_list, gchar * host, GList * res_list); +gboolean deliver_route_msgout_list(connect_route * route, GList * msgout_list); +gboolean deliver_route_msg_list(connect_route * route, GList * msgout_list); +gboolean deliver_finish(msg_out * msgout); +gboolean deliver_finish_list(GList * msgout_list); +gboolean deliver_msg_list(GList * msg_list, guint flags); +gboolean deliver(message * msg); /* fail_msg.c */ -gboolean fail_msg(message *msg, gchar *template, - GList *failed_rcpts, gchar *err_fmt, va_list args); -gboolean warn_msg(message *msg, gchar *template, - GList *failed_rcpts, gchar *err_fmt, va_list args); +gboolean fail_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args); +gboolean warn_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args); /* get.c */ -gboolean get_from_file(gchar *fname); -gboolean get_from_name(gchar *name); +gboolean get_from_file(gchar * fname); +gboolean get_from_name(gchar * name); gboolean get_all(void); void get_online(void); void get_daemon(gint gival, char *argv[]); -gboolean pop_before_smtp(gchar *fname); +gboolean pop_before_smtp(gchar * fname); /* interface.c */ -gboolean init_sockaddr(struct sockaddr_in *name, interface *iface); -int make_server_socket(interface *iface); +gboolean init_sockaddr(struct sockaddr_in *name, interface * iface); +int make_server_socket(interface * iface); /* local.c */ -gboolean append_file(message *msg, GList *hdr_list, gchar *user); -gboolean maildir_out(message *msg, GList *hdr_list, gchar *user, guint flags); -gboolean pipe_out(message *msg, GList *hdr_list, address *rcpt, gchar *cmd, guint flags); +gboolean append_file(message * msg, GList * hdr_list, gchar * user); +gboolean maildir_out(message * msg, GList * hdr_list, gchar * user, guint flags); +gboolean pipe_out(message * msg, GList * hdr_list, address * rcpt, gchar * cmd, guint flags); /* log.c */ gchar *ext_strerror(int err); @@ -551,63 +505,60 @@ void maillog(const char *fmt, ...); /* spool.c */ -gboolean spool_read_data(message *msg); -gboolean spool_read_data(message *msg); -message *msg_spool_read(gchar *uid, gboolean do_readdata); -gboolean spool_write(message *msg, gboolean do_writedata); -gboolean spool_lock(gchar *uid); -gboolean spool_unlock(gchar *uid); -gboolean spool_delete_all(message *msg); +gboolean spool_read_data(message * msg); +gboolean spool_read_data(message * msg); +message *msg_spool_read(gchar * uid, gboolean do_readdata); +gboolean spool_write(message * msg, gboolean do_writedata); +gboolean spool_lock(gchar * uid); +gboolean spool_unlock(gchar * uid); +gboolean spool_delete_all(message * msg); /* queue.c */ GList *read_queue(gboolean do_readdata); gboolean queue_run(void); gboolean queue_run_online(void); void queue_list(void); -gboolean queue_delete(gchar *uid); +gboolean queue_delete(gchar * uid); /* online.c */ gchar *detect_online(); -void set_online_name(gchar *name); +void set_online_name(gchar * name); /* permissions.c */ gboolean is_ingroup(uid_t uid, gid_t gid); -void set_euidgid(gint uid, gint gid, uid_t *old_uid, gid_t *old_gid); -void set_identity(uid_t old_uid, gchar *task_name); +void set_euidgid(gint uid, gint gid, uid_t * old_uid, gid_t * old_gid); +void set_identity(uid_t old_uid, gchar * task_name); /* rewrite.c */ -gboolean set_address_header_domain(header *hdr, gchar *domain); -gboolean map_address_header(header *hdr, GList *table); +gboolean set_address_header_domain(header * hdr, gchar * domain); +gboolean map_address_header(header * hdr, GList * table); /* route.c */ -msgout_perhost *create_msgout_perhost(gchar *host); -void destroy_msgout_perhost(msgout_perhost *mo_ph); -void rewrite_headers(msg_out *msgout, connect_route *route); -void rcptlist_with_one_of_hostlist(GList *rcpt_list, GList *host_list, - GList **, GList **); -void rcptlist_with_addr_is_local(GList *rcpt_list, - GList **p_rcpt_list, GList **p_non_rcpt_list); -gboolean route_strip_msgout(connect_route *route, msg_out *msgout); -msg_out *route_prepare_msgout(connect_route *route, msg_out *msgout); -GList *route_msgout_list(connect_route *route, GList *msgout_list); -gboolean route_is_allowed_return_path(connect_route *route, address *ret_path); -gboolean route_is_allowed_mail_local(connect_route *route, address *ret_path); -void msg_rcptlist_route(connect_route *route, GList *rcpt_list, - GList **p_rcpt_list, GList **p_non_rcpt_list); +msgout_perhost *create_msgout_perhost(gchar * host); +void destroy_msgout_perhost(msgout_perhost * mo_ph); +void rewrite_headers(msg_out * msgout, connect_route * route); +void rcptlist_with_one_of_hostlist(GList * rcpt_list, GList * host_list, GList **, GList **); +void rcptlist_with_addr_is_local(GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list); +gboolean route_strip_msgout(connect_route * route, msg_out * msgout); +msg_out *route_prepare_msgout(connect_route * route, msg_out * msgout); +GList *route_msgout_list(connect_route * route, GList * msgout_list); +gboolean route_is_allowed_return_path(connect_route * route, address * ret_path); +gboolean route_is_allowed_mail_local(connect_route * route, address * ret_path); +void msg_rcptlist_route(connect_route * route, GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list); /* tables.c */ -table_pair *create_pair(gchar *key, gpointer value); -table_pair *create_pair_string(gchar *key, gpointer value); -table_pair *parse_table_pair(gchar *line, char delim); -gpointer *table_find_func(GList *table_list, gchar *key, int (*cmp_func)(const char *, const char *)); -gpointer *table_find(GList *table_list, gchar *key); -gpointer *table_find_case(GList *table_list, gchar *key); -gpointer *table_find_fnmatch(GList *table_list, gchar *key); -GList *table_read(gchar *fname, gchar delim); -void destroy_table(GList *table); +table_pair *create_pair(gchar * key, gpointer value); +table_pair *create_pair_string(gchar * key, gpointer value); +table_pair *parse_table_pair(gchar * line, char delim); +gpointer *table_find_func(GList * table_list, gchar * key, int (*cmp_func) (const char *, const char *)); +gpointer *table_find(GList * table_list, gchar * key); +gpointer *table_find_case(GList * table_list, gchar * key); +gpointer *table_find_fnmatch(GList * table_list, gchar * key); +GList *table_read(gchar * fname, gchar delim); +void destroy_table(GList * table); /* timeival.c */ -gint time_interval(gchar *str, gint *pos); +gint time_interval(gchar * str, gint * pos); /* permissions.c */ gboolean is_privileged_user(uid_t uid); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/md5/hmac_md5.c --- a/src/md5/hmac_md5.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/md5/hmac_md5.c Mon Oct 27 16:23:10 2008 +0100 @@ -7,74 +7,66 @@ #include "md5.h" #include "hmac_md5.h" -void hmac_md5(unsigned char *text, int text_len, - unsigned char* key, int key_len, unsigned char *digest) - /* text; pointer to data stream */ - /* text_len; length of data stream */ - /* key; pointer to authentication key */ - /* key_len; length of authentication key */ - /* digest; caller digest to be filled in */ +void +hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest) + /* text; pointer to data stream */ + /* text_len; length of data stream */ + /* key; pointer to authentication key */ + /* key_len; length of authentication key */ + /* digest; caller digest to be filled in */ +{ + MD5_CTX context; + unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ + unsigned char k_opad[65]; /* outer padding - key XORd with opad */ + unsigned char tk[16]; + int i; + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { -{ - MD5_CTX context; - unsigned char k_ipad[65]; /* inner padding - - * key XORd with ipad - */ - unsigned char k_opad[65]; /* outer padding - - * key XORd with opad - */ - unsigned char tk[16]; - int i; - /* if key is longer than 64 bytes reset it to key=MD5(key) */ - if (key_len > 64) { + MD5_CTX tctx; - MD5_CTX tctx; + MD5Init(&tctx); + MD5Update(&tctx, key, key_len); + MD5Final(tk, &tctx); - MD5Init(&tctx); - MD5Update(&tctx, key, key_len); - MD5Final(tk, &tctx); + key = tk; + key_len = 16; + } - key = tk; - key_len = 16; - } + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ - /* - * the HMAC_MD5 transform looks like: - * - * MD5(K XOR opad, MD5(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ + /* start out by storing key in pads */ + bzero(k_ipad, sizeof k_ipad); + bzero(k_opad, sizeof k_opad); + bcopy(key, k_ipad, key_len); + bcopy(key, k_opad, key_len); - /* start out by storing key in pads */ - bzero( k_ipad, sizeof k_ipad); - bzero( k_opad, sizeof k_opad); - bcopy( key, k_ipad, key_len); - bcopy( key, k_opad, key_len); - - /* XOR key with ipad and opad values */ - for (i=0; i<64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - /* - * perform inner MD5 - */ - MD5Init(&context); /* init context for 1st - * pass */ - MD5Update(&context, k_ipad, 64); /* start with inner pad */ - MD5Update(&context, text, text_len); /* then text of datagram */ - MD5Final(digest, &context); /* finish up 1st pass */ - /* - * perform outer MD5 - */ - MD5Init(&context); /* init context for 2nd - * pass */ - MD5Update(&context, k_opad, 64); /* start with outer pad */ - MD5Update(&context, digest, 16); /* then results of 1st - * hash */ - MD5Final(digest, &context); /* finish up 2nd pass */ + /* XOR key with ipad and opad values */ + for (i = 0; i < 64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + /* + * perform inner MD5 + */ + MD5Init(&context); /* init context for 1st pass */ + MD5Update(&context, k_ipad, 64); /* start with inner pad */ + MD5Update(&context, text, text_len); /* then text of datagram */ + MD5Final(digest, &context); /* finish up 1st pass */ + /* + * perform outer MD5 + */ + MD5Init(&context); /* init context for 2nd pass */ + MD5Update(&context, k_opad, 64); /* start with outer pad */ + MD5Update(&context, digest, 16); /* then results of 1st hash */ + MD5Final(digest, &context); /* finish up 2nd pass */ } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/md5/hmac_md5.h --- a/src/md5/hmac_md5.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/md5/hmac_md5.h Mon Oct 27 16:23:10 2008 +0100 @@ -1,7 +1,7 @@ -void hmac_md5(unsigned char *text, int text_len, - unsigned char* key, int key_len, unsigned char *digest); - /* text; pointer to data stream */ - /* text_len; length of data stream */ - /* key; pointer to authentication key */ - /* key_len; length of authentication key */ - /* digest; caller digest to be filled in */ +void +hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest); + /* text; pointer to data stream */ + /* text_len; length of data stream */ + /* key; pointer to authentication key */ + /* key_len; length of authentication key */ + /* digest; caller digest to be filled in */ diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/md5/hmactest.c --- a/src/md5/hmactest.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/md5/hmactest.c Mon Oct 27 16:23:10 2008 +0100 @@ -6,41 +6,44 @@ #include "md5.h" #include "hmac_md5.h" -static -void pad0_copy(char *d, char *s, int sz) +static void +pad0_copy(char *d, char *s, int sz) { - int i = 0; - while(*s && (i < sz)) { *(d++) = *(s++); i++; } - while(i <= sz) { *(d++) = 0; i++; } + int i = 0; + while (*s && (i < sz)) { + *(d++) = *(s++); + i++; + } + while (i <= sz) { + *(d++) = 0; + i++; + } } -int main() +int +main() { - int i; - // unsigned char digest[16]; - char digest[16]; - char *msgid = "<1896.697170952@postoffice.reston.mci.net>"; - char secret[65]; + int i; + // unsigned char digest[16]; + char digest[16]; + char *msgid = "<1896.697170952@postoffice.reston.mci.net>"; + char secret[65]; - hmac_md5("<48157.953508124@mail.class-c.net>", 34, - "no!SpamAtAll", 12, digest); - for(i = 0; i < 16; i++) - printf("%x", (unsigned int)digest[i]); - printf("\n"); + hmac_md5("<48157.953508124@mail.class-c.net>", 34, "no!SpamAtAll", 12, digest); + for (i = 0; i < 16; i++) + printf("%x", (unsigned int) digest[i]); + printf("\n"); - hmac_md5(msgid, strlen(msgid), - "tanstaaftanstaaf", 16, digest); - for(i = 0; i < 16; i++) - printf("%x", (unsigned int)digest[i]); - printf("\n"); + hmac_md5(msgid, strlen(msgid), "tanstaaftanstaaf", 16, digest); + for (i = 0; i < 16; i++) + printf("%x", (unsigned int) digest[i]); + printf("\n"); - pad0_copy(secret, "tanstaaftanstaaf", 64); - hmac_md5(msgid, strlen(msgid), - secret, 64, digest); - for(i = 0; i < 16; i++) - printf("%x", (unsigned int)digest[i]); - printf("\n"); + pad0_copy(secret, "tanstaaftanstaaf", 64); + hmac_md5(msgid, strlen(msgid), secret, 64, digest); + for (i = 0; i < 16; i++) + printf("%x", (unsigned int) digest[i]); + printf("\n"); - exit(0); + exit(0); } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/md5/md5.h --- a/src/md5/md5.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/md5/md5.h Mon Oct 27 16:23:10 2008 +0100 @@ -25,12 +25,11 @@ /* MD5 context. */ typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ } MD5_CTX; -void MD5Init PROTO_LIST ((MD5_CTX *)); -void MD5Update PROTO_LIST - ((MD5_CTX *, unsigned char *, unsigned int)); -void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); +void MD5Init PROTO_LIST((MD5_CTX *)); +void MD5Update PROTO_LIST((MD5_CTX *, unsigned char *, unsigned int)); +void MD5Final PROTO_LIST((unsigned char[16], MD5_CTX *)); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/md5/md5c.c --- a/src/md5/md5c.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/md5/md5c.c Mon Oct 27 16:23:10 2008 +0100 @@ -45,18 +45,16 @@ #define S43 15 #define S44 21 -static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); -static void Encode PROTO_LIST - ((unsigned char *, UINT4 *, unsigned int)); -static void Decode PROTO_LIST - ((UINT4 *, unsigned char *, unsigned int)); -static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); -static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); +static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64])); +static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int)); +static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int)); +static void MD5_memset PROTO_LIST((POINTER, int, unsigned int)); static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. @@ -96,239 +94,239 @@ /* MD5 initialization. Begins an MD5 operation, writing a new context. */ -void MD5Init (context) -MD5_CTX *context; /* context */ +void +MD5Init(context) +MD5_CTX *context; /* context */ { - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ -void MD5Update (context, input, inputLen) -MD5_CTX *context; /* context */ -unsigned char *input; /* input block */ -unsigned int inputLen; /* length of input block */ +void +MD5Update(context, input, inputLen) +MD5_CTX *context; /* context */ +unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ { - unsigned int i, index, partLen; + unsigned int i, index, partLen; - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); + /* Compute number of bytes mod 64 */ + index = (unsigned int) ((context->count[0] >> 3) & 0x3F); - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); + /* Update number of bits */ + if ((context->count[0] += ((UINT4) inputLen << 3)) < ((UINT4) inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4) inputLen >> 29); - partLen = 64 - index; + partLen = 64 - index; - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)input, partLen); - MD5Transform (context->state, context->buffer); + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + MD5_memcpy((POINTER) & context->buffer[index], (POINTER) input, partLen); + MD5Transform(context->state, context->buffer); - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform(context->state, &input[i]); - index = 0; - } - else - i = 0; + index = 0; + } else + i = 0; - /* Buffer remaining input */ - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)&input[i], - inputLen-i); + /* Buffer remaining input */ + MD5_memcpy((POINTER) & context->buffer[index], (POINTER) & input[i], inputLen - i); } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ -void MD5Final (digest, context) -unsigned char digest[16]; /* message digest */ -MD5_CTX *context; /* context */ +void +MD5Final(digest, context) +unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ { - unsigned char bits[8]; - unsigned int index, padLen; + unsigned char bits[8]; + unsigned int index, padLen; - /* Save number of bits */ - Encode (bits, context->count, 8); + /* Save number of bits */ + Encode(bits, context->count, 8); - /* Pad out to 56 mod 64. -*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); + /* Pad out to 56 mod 64. + */ + index = (unsigned int) ((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update(context, PADDING, padLen); - /* Append length (before padding) */ - MD5Update (context, bits, 8); + /* Append length (before padding) */ + MD5Update(context, bits, 8); - /* Store state in digest */ - Encode (digest, context->state, 16); + /* Store state in digest */ + Encode(digest, context->state, 16); - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)context, 0, sizeof (*context)); + /* Zeroize sensitive information. + */ + MD5_memset((POINTER) context, 0, sizeof(*context)); } /* MD5 basic transformation. Transforms state based on block. */ -static void MD5Transform (state, block) +static void +MD5Transform(state, block) UINT4 state[4]; unsigned char block[64]; { - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - Decode (x, block, 64); + Decode(x, block, 64); - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + /* Round 1 */ + FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ + FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ + FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ + FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ + FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ + FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ + FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ + FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ + FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ + FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ + FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + /* Round 2 */ + GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ + GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ + GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ + GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ + GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ + GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ + GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ + GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ + GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ + GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ + GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + /* Round 3 */ + HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ + HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ + HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ + HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ + HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ + HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ + HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ + HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ + HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ + HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + /* Round 4 */ + II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ + II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ + II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ + II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ + II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ + II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ + II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ + II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ + II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ + II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)x, 0, sizeof (x)); + /* Zeroize sensitive information. */ + MD5_memset((POINTER) x, 0, sizeof(x)); } /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ -static void Encode (output, input, len) +static void +Encode(output, input, len) unsigned char *output; UINT4 *input; unsigned int len; { - unsigned int i, j; + unsigned int i, j; - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char) (input[i] & 0xff); + output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); + output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); + output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); + } } /* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ -static void Decode (output, input, len) +static void +Decode(output, input, len) UINT4 *output; unsigned char *input; unsigned int len; { - unsigned int i, j; + unsigned int i, j; - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) | (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24); } /* Note: Replace "for loop" with standard memcpy if possible. */ -static void MD5_memcpy (output, input, len) +static void +MD5_memcpy(output, input, len) POINTER output; POINTER input; unsigned int len; { - unsigned int i; + unsigned int i; - for (i = 0; i < len; i++) - output[i] = input[i]; + for (i = 0; i < len; i++) + output[i] = input[i]; } /* Note: Replace "for loop" with standard memset if possible. */ -static void MD5_memset (output, value, len) +static void +MD5_memset(output, value, len) POINTER output; int value; unsigned int len; { - unsigned int i; + unsigned int i; - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; + for (i = 0; i < len; i++) + ((char *) output)[i] = (char) value; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/message.c --- a/src/message.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/message.c Mon Oct 27 16:23:10 2008 +0100 @@ -18,193 +18,208 @@ #include "masqmail.h" -message *create_message() +message* +create_message() { - message *msg = (message *)g_malloc(sizeof(message)); - if(msg){ - memset(msg, 0, sizeof(message)); - msg->data_size = -1; - } - return msg; + message *msg = (message *) g_malloc(sizeof(message)); + if (msg) { + memset(msg, 0, sizeof(message)); + msg->data_size = -1; + } + return msg; } -gint msg_calc_size(message *msg, gboolean is_smtp) +gint +msg_calc_size(message * msg, gboolean is_smtp) { - GList *node; - gint l_cnt = 0, c_cnt = 0; + GList *node; + gint l_cnt = 0, c_cnt = 0; - /* header size */ - if(msg->hdr_list){ - for(node = g_list_first(msg->hdr_list); node; node = g_list_next(node)){ - if(node->data){ - header *hdr = (header *)(node->data); - if(hdr->header){ - char *p = hdr->header; - while(*p){ - if(*p++ == '\n') l_cnt++; - c_cnt++; - } + /* header size */ + if (msg->hdr_list) { + for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) { + if (node->data) { + header *hdr = (header *) (node->data); + if (hdr->header) { + char *p = hdr->header; + while (*p) { + if (*p++ == '\n') + l_cnt++; + c_cnt++; + } + } + } + } } - } - } - } - /* empty line separating headers from data: */ - c_cnt++; - l_cnt++; + /* empty line separating headers from data: */ + c_cnt++; + l_cnt++; - /* data size */ - if(msg->data_list){ - for(node = g_list_first(msg->data_list); node; node = g_list_next(node)){ - if(node->data){ - char *p = node->data; - while(*p){ - if(*p++ == '\n') l_cnt++; - c_cnt++; + /* data size */ + if (msg->data_list) { + for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) { + if (node->data) { + char *p = node->data; + while (*p) { + if (*p++ == '\n') + l_cnt++; + c_cnt++; + } + } + } } - } - } - } - return is_smtp ? c_cnt + l_cnt : c_cnt; + return is_smtp ? c_cnt + l_cnt : c_cnt; } -void msg_free_data(message *msg) +void +msg_free_data(message * msg) { - GList *node; + GList *node; - if(msg->data_list){ - for(node = g_list_first(msg->data_list); node; node = g_list_next(node)){ - if(node->data) - g_free(node->data); - } - g_list_free(msg->data_list); - msg->data_list = NULL; - } + if (msg->data_list) { + for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) { + if (node->data) + g_free(node->data); + } + g_list_free(msg->data_list); + msg->data_list = NULL; + } } -void destroy_message(message *msg) +void +destroy_message(message * msg) { - GList *node; + GList *node; - if(msg->uid) g_free(msg->uid); - if(msg->ident) g_free(msg->ident); - if(msg->return_path) g_free(msg->return_path); + if (msg->uid) + g_free(msg->uid); + if (msg->ident) + g_free(msg->ident); + if (msg->return_path) + g_free(msg->return_path); - if(msg->rcpt_list){ - for(node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)){ - if(node->data) - g_free(node->data); - } - g_list_free(msg->rcpt_list); - } - if(msg->hdr_list){ - for(node = g_list_first(msg->hdr_list); node; node = g_list_next(node)){ - if(node->data){ - header *hdr = (header *)(node->data); - if(hdr->header) - g_free(hdr->header); - g_free(node->data); - } - } - g_list_free(msg->hdr_list); - } + if (msg->rcpt_list) { + for (node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)) { + if (node->data) + g_free(node->data); + } + g_list_free(msg->rcpt_list); + } + if (msg->hdr_list) { + for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) { + if (node->data) { + header *hdr = (header *) (node->data); + if (hdr->header) + g_free(hdr->header); + g_free(node->data); + } + } + g_list_free(msg->hdr_list); + } - if(msg->full_sender_name) - g_free(msg->full_sender_name); + if (msg->full_sender_name) + g_free(msg->full_sender_name); - msg_free_data(msg); + msg_free_data(msg); - g_free(msg); + g_free(msg); } -void destroy_msg_list(GList *msg_list) +void +destroy_msg_list(GList * msg_list) { - GList *msg_node; + GList *msg_node; - foreach(msg_list, msg_node){ - message *msg = (message *)(msg_node->data); - destroy_message(msg); - } - g_list_free(msg_list); + foreach(msg_list, msg_node) { + message *msg = (message *) (msg_node->data); + destroy_message(msg); + } + g_list_free(msg_list); } -msg_out *create_msg_out(message *msg) +msg_out* +create_msg_out(message * msg) { - msg_out *msgout = NULL; + msg_out *msgout = NULL; - msgout = g_malloc(sizeof(msg_out)); - if(msgout){ - msgout->msg = msg; - msgout->return_path = NULL; - msgout->rcpt_list = NULL; - - msgout->hdr_list = NULL; - msgout->xtra_hdr_list = NULL; - } - return msgout; + msgout = g_malloc(sizeof(msg_out)); + if (msgout) { + msgout->msg = msg; + msgout->return_path = NULL; + msgout->rcpt_list = NULL; + + msgout->hdr_list = NULL; + msgout->xtra_hdr_list = NULL; + } + return msgout; } -msg_out *clone_msg_out(msg_out *msgout_orig) +msg_out* +clone_msg_out(msg_out * msgout_orig) { - if(msgout_orig){ - msg_out *msgout = create_msg_out(msgout_orig->msg); - if(msgout){ - msgout->msg = msgout_orig->msg; - if(msgout_orig->return_path) - msgout->return_path = copy_address(msgout_orig->return_path); - if(msgout_orig->hdr_list) - msgout->hdr_list = g_list_copy(msgout_orig->hdr_list); - /* FIXME: if this lives longer than the original - and we access one of the xtra hdrs, we will segfault - or cause some weird bugs: */ - msgout->xtra_hdr_list = NULL; - if(msgout_orig->rcpt_list) - msgout->rcpt_list = g_list_copy(msgout_orig->rcpt_list); - } - return msgout; - } - return NULL; + if (msgout_orig) { + msg_out *msgout = create_msg_out(msgout_orig->msg); + if (msgout) { + msgout->msg = msgout_orig->msg; + if (msgout_orig->return_path) + msgout->return_path = copy_address(msgout_orig->return_path); + if (msgout_orig->hdr_list) + msgout->hdr_list = g_list_copy(msgout_orig->hdr_list); + /* FIXME: if this lives longer than the original + and we access one of the xtra hdrs, we will segfault + or cause some weird bugs: */ + msgout->xtra_hdr_list = NULL; + if (msgout_orig->rcpt_list) + msgout->rcpt_list = g_list_copy(msgout_orig->rcpt_list); + } + return msgout; + } + return NULL; } -GList *create_msg_out_list(GList *msg_list) +GList* +create_msg_out_list(GList * msg_list) { - GList *msgout_list = NULL; - GList *msg_node; + GList *msgout_list = NULL; + GList *msg_node; - foreach(msg_list, msg_node){ - message *msg = (message *)(msg_node->data); - msgout_list = g_list_append(msgout_list, create_msg_out(msg)); - } - return msgout_list; + foreach(msg_list, msg_node) { + message *msg = (message *) (msg_node->data); + msgout_list = g_list_append(msgout_list, create_msg_out(msg)); + } + return msgout_list; } -void destroy_msg_out(msg_out *msgout) +void +destroy_msg_out(msg_out * msgout) { - if(msgout){ - if(msgout->return_path) - destroy_address(msgout->return_path); - if(msgout->hdr_list) - g_list_free(msgout->hdr_list); - if(msgout->xtra_hdr_list){ - GList *hdr_node; - foreach(msgout->xtra_hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - destroy_header(hdr); - } - g_list_free(msgout->xtra_hdr_list); - } - g_free(msgout); - } + if (msgout) { + if (msgout->return_path) + destroy_address(msgout->return_path); + if (msgout->hdr_list) + g_list_free(msgout->hdr_list); + if (msgout->xtra_hdr_list) { + GList *hdr_node; + foreach(msgout->xtra_hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + destroy_header(hdr); + } + g_list_free(msgout->xtra_hdr_list); + } + g_free(msgout); + } } -void destroy_msg_out_list(GList *msgout_list) +void +destroy_msg_out_list(GList * msgout_list) { - GList *msgout_node; + GList *msgout_node; - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - destroy_msg_out(msgout); - } - g_list_free(msgout_list); + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + destroy_msg_out(msgout); + } + g_list_free(msgout_list); } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/mservdetect.c --- a/src/mservdetect.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/mservdetect.c Mon Oct 27 16:23:10 2008 +0100 @@ -32,45 +32,47 @@ #include "masqmail.h" #include "readsock.h" #include "mserver.h" -#endif /* ENABLE_MSERVER */ +#endif /* ENABLE_MSERVER */ -void logwrite(int pri, const char *fmt, ...) +void +logwrite(int pri, const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - vfprintf(stdout, fmt, args); + vfprintf(stdout, fmt, args); - va_end(args); + va_end(args); } -void debugf(const char *fmt, ...) +void +debugf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - vfprintf(stdout, fmt, args); + vfprintf(stdout, fmt, args); - va_end(args); + va_end(args); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - if(argc == 3){ - interface iface; - gchar *name; + if (argc == 3) { + interface iface; + gchar *name; - iface.address = g_strdup(argv[1]); - iface.port = atoi(argv[2]); + iface.address = g_strdup(argv[1]); + iface.port = atoi(argv[2]); - name = mserver_detect_online(&iface); + name = mserver_detect_online(&iface); - printf("%s\n", name); + printf("%s\n", name); - exit(EXIT_SUCCESS); - }else{ - fprintf(stderr, "usage %s \n", argv[0]); - exit(EXIT_FAILURE); - } + exit(EXIT_SUCCESS); + } else { + fprintf(stderr, "usage %s \n", argv[0]); + exit(EXIT_FAILURE); + } } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/mserver.c --- a/src/mserver.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/mserver.c Mon Oct 27 16:23:10 2008 +0100 @@ -22,57 +22,57 @@ #ifdef ENABLE_MSERVER -gchar *mserver_detect_online(interface *iface) +gchar* +mserver_detect_online(interface * iface) { - struct sockaddr_in saddr; - gchar *ret = NULL; + struct sockaddr_in saddr; + gchar *ret = NULL; - if(init_sockaddr(&saddr, iface)){ - int sock = socket(PF_INET, SOCK_STREAM, 0); - int dup_sock; - if(connect(sock, (struct sockaddr *)(&saddr), sizeof(saddr)) == 0){ - FILE *in, *out; - char buf[256]; + if (init_sockaddr(&saddr, iface)) { + int sock = socket(PF_INET, SOCK_STREAM, 0); + int dup_sock; + if (connect(sock, (struct sockaddr *) (&saddr), sizeof(saddr)) == 0) { + FILE *in, *out; + char buf[256]; - dup_sock = dup(sock); - out = fdopen(sock, "w"); - in = fdopen(dup_sock, "r"); + dup_sock = dup(sock); + out = fdopen(sock, "w"); + in = fdopen(dup_sock, "r"); - if(read_sockline(in, buf, 256, 15, READSOCKL_CHUG)){ - if(strncmp(buf, "READY", 5) == 0){ - fprintf(out, "STAT\n"); fflush(out); - if(read_sockline(in, buf, 256, 15, READSOCKL_CHUG)){ - if(strncmp(buf, "DOWN", 4) == 0){ - ret = NULL; - }else if(strncmp(buf, "UP", 2) == 0){ - gchar *p = buf+3; - while((*p != ':') && *p) p++; - if(*p){ - *p = 0; - p++; - if((atoi(p) >= 0) && *p) - ret = g_strdup(buf+3); - }else - logwrite(LOG_ALERT, - "unexpected response from mserver after STAT cmd: %s", - buf); - }else{ - logwrite(LOG_ALERT, - "unexpected response from mserver after STAT cmd: %s", - buf); - } - } + if (read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) { + if (strncmp(buf, "READY", 5) == 0) { + fprintf(out, "STAT\n"); + fflush(out); + if (read_sockline(in, buf, 256, 15, READSOCKL_CHUG)) { + if (strncmp(buf, "DOWN", 4) == 0) { + ret = NULL; + } else if (strncmp(buf, "UP", 2) == 0) { + gchar *p = buf + 3; + while ((*p != ':') && *p) + p++; + if (*p) { + *p = 0; + p++; + if ((atoi(p) >= 0) && *p) + ret = g_strdup(buf + 3); + } else + logwrite(LOG_ALERT, "unexpected response from mserver after STAT cmd: %s", buf); + } else { + logwrite(LOG_ALERT, "unexpected response from mserver after STAT cmd: %s", buf); + } + } + } + fprintf(out, "QUIT"); + fflush(out); + + close(sock); + close(dup_sock); + fclose(in); + fclose(out); + } + } } - fprintf(out, "QUIT"); fflush(out); - - close(sock); - close(dup_sock); - fclose(in); - fclose(out); - } - } - } - return ret; + return ret; } #endif diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/mserver.h --- a/src/mserver.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/mserver.h Mon Oct 27 16:23:10 2008 +0100 @@ -16,4 +16,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -gchar *mserver_detect_online(interface *iface); +gchar *mserver_detect_online(interface * iface); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/online.c --- a/src/online.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/online.c Mon Oct 27 16:23:10 2008 +0100 @@ -24,96 +24,91 @@ gchar *connection_name; -void set_online_name(gchar *name) +void +set_online_name(gchar * name) { - connection_name = g_strdup(name); + connection_name = g_strdup(name); } -static -gchar *detect_online_pipe(const gchar *pipe) +static gchar* +detect_online_pipe(const gchar * pipe) { - pid_t pid; - void (*old_signal)(int); - int status; - FILE *in; - gchar *name = NULL; + pid_t pid; + void (*old_signal) (int); + int status; + FILE *in; + gchar *name = NULL; - old_signal = signal(SIGCHLD, SIG_DFL); + old_signal = signal(SIGCHLD, SIG_DFL); - in = peopen(pipe, "r", environ, &pid); - if(in != NULL){ - gchar output[256]; - if(fgets(output, 255, in)){ - g_strchomp(output); - name = g_strdup(output); - } - fclose(in); - waitpid(pid, &status, 0); - if(WEXITSTATUS(status) != EXIT_SUCCESS){ - g_free(name); - name = NULL; - } - }else - logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", pipe, strerror(errno)); + in = peopen(pipe, "r", environ, &pid); + if (in != NULL) { + gchar output[256]; + if (fgets(output, 255, in)) { + g_strchomp(output); + name = g_strdup(output); + } + fclose(in); + waitpid(pid, &status, 0); + if (WEXITSTATUS(status) != EXIT_SUCCESS) { + g_free(name); + name = NULL; + } + } else + logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", pipe, strerror(errno)); - signal(SIGCHLD, old_signal); + signal(SIGCHLD, old_signal); - return name; + return name; } -gchar *detect_online() +gchar* +detect_online() { - if(conf.online_detect != NULL){ - if(strcmp(conf.online_detect, "file") == 0){ - DEBUG(3) debugf("online detection method 'file'\n"); - if(conf.online_file != NULL){ - struct stat st; - if(stat(conf.online_file, &st) == 0){ - FILE *fptr = fopen(conf.online_file, "r"); - if(fptr){ - char buf[256]; - fgets(buf, 256, fptr); - g_strchomp(buf); - fclose(fptr); - return g_strdup(buf); - }else{ - logwrite(LOG_ALERT, "opening of %s failed: %s\n", - conf.online_file, strerror(errno)); - return NULL; - } + if (conf.online_detect != NULL) { + if (strcmp(conf.online_detect, "file") == 0) { + DEBUG(3) debugf("online detection method 'file'\n"); + if (conf.online_file != NULL) { + struct stat st; + if (stat(conf.online_file, &st) == 0) { + FILE *fptr = fopen(conf.online_file, "r"); + if (fptr) { + char buf[256]; + fgets(buf, 256, fptr); + g_strchomp(buf); + fclose(fptr); + return g_strdup(buf); + } else { + logwrite(LOG_ALERT, "opening of %s failed: %s\n", conf.online_file, strerror(errno)); + return NULL; + } + } else if (errno == ENOENT) { + logwrite(LOG_NOTICE, "not online.\n"); + return NULL; + } else { + logwrite(LOG_ALERT, "stat of %s failed: %s", conf.online_file, strerror(errno)); + return NULL; + } + } else + logwrite(LOG_ALERT, "online detection mode is 'file', but online_file is undefined\n"); +#ifdef ENABLE_MSERVER + } else if (strcmp(conf.online_detect, "mserver") == 0) { + DEBUG(3) debugf("connection method 'mserver'\n"); + return mserver_detect_online(conf.mserver_iface); +#endif + } else if (strcmp(conf.online_detect, "pipe") == 0) { + DEBUG(3) debugf("connection method 'pipe'\n"); + if (conf.online_pipe) + return detect_online_pipe(conf.online_pipe); + else { + logwrite(LOG_ALERT, "online detection mode is 'pipe', but online_pipe is undefined\n"); + return NULL; + } + } else if (strcmp(conf.online_detect, "argument") == 0) { + return connection_name; + } else { + DEBUG(3) debugf("no connection method selected\n"); + } } - else if(errno == ENOENT){ - logwrite(LOG_NOTICE, "not online.\n"); - return NULL; - }else{ - logwrite(LOG_ALERT, "stat of %s failed: %s", - conf.online_file, strerror(errno)); - return NULL; - } - }else - logwrite(LOG_ALERT, - "online detection mode is 'file', " - "but online_file is undefined\n"); -#ifdef ENABLE_MSERVER - }else if(strcmp(conf.online_detect, "mserver") == 0){ - DEBUG(3) debugf("connection method 'mserver'\n"); - return mserver_detect_online(conf.mserver_iface); -#endif - }else if(strcmp(conf.online_detect, "pipe") == 0){ - DEBUG(3) debugf("connection method 'pipe'\n"); - if(conf.online_pipe) - return detect_online_pipe(conf.online_pipe); - else{ - logwrite(LOG_ALERT, - "online detection mode is 'pipe', " - "but online_pipe is undefined\n"); return NULL; - } - }else if(strcmp(conf.online_detect, "argument") == 0){ - return connection_name; - }else{ - DEBUG(3) debugf("no connection method selected\n"); - } - } - return NULL; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/parse.c --- a/src/parse.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/parse.c Mon Oct 27 16:23:10 2008 +0100 @@ -33,320 +33,315 @@ char *parse_error = NULL; -static -gchar *skip_comment(gchar *p) +static gchar* +skip_comment(gchar * p) { #ifdef PARSE_TEST - g_print("skip_comment: %s\n", p); + g_print("skip_comment: %s\n", p); #endif - p++; - while(*p && *p != ')'){ - p++; - if(*p == '(') - p = skip_comment(p); - } - p++; + p++; + while (*p && *p != ')') { + p++; + if (*p == '(') + p = skip_comment(p); + } + p++; - return p; + return p; } -static -gboolean read_word(gchar *p, gchar **b, gchar **e) +static gboolean +read_word(gchar * p, gchar ** b, gchar ** e) { #ifdef PARSE_TEST - g_print("read_word: %s\n", p); + g_print("read_word: %s\n", p); #endif - /* eat leading spaces */ - while(*p && isspace(*p)) p++; - - *b = p; - /* b = &p;*/ - if(*p == '\"'){ - /* quoted-string */ - p++; - while(*p && (*p != '\"')) p++; - p++; - }else{ - /* atom */ - while(*p && !strchr(specials, *p) && !iscntrl(*p) && !isspace(*p)) - p++; - } - *e = p; - return TRUE; + /* eat leading spaces */ + while (*p && isspace(*p)) + p++; + + *b = p; + /* b = &p; */ + if (*p == '\"') { + /* quoted-string */ + p++; + while (*p && (*p != '\"')) + p++; + p++; + } else { + /* atom */ + while (*p && !strchr(specials, *p) && !iscntrl(*p) && !isspace(*p)) + p++; + } + *e = p; + return TRUE; } -static -gboolean read_word_with_dots(gchar *p, gchar **b, gchar **e) +static gboolean +read_word_with_dots(gchar * p, gchar ** b, gchar ** e) { - gchar *b0 = p; + gchar *b0 = p; #ifdef PARSE_TEST - g_print("read_word_with_dots: %s\n", p); + g_print("read_word_with_dots: %s\n", p); #endif - while(TRUE){ - if(!read_word(p, b, e)) - return FALSE; - p = *e; - if(*p != '.') break; - p++; - } - *b = b0; - *e = p; - return TRUE; + while (TRUE) { + if (!read_word(p, b, e)) + return FALSE; + p = *e; + if (*p != '.') + break; + p++; + } + *b = b0; + *e = p; + return TRUE; } -static -gboolean read_domain(gchar *p, gchar **b, gchar **e) +static gboolean +read_domain(gchar * p, gchar ** b, gchar ** e) { #ifdef PARSE_TEST - g_print("read_domain: %s\n", p); + g_print("read_domain: %s\n", p); #endif - *b = p; - if(*p != '['){ - while(isalnum(*p) || (*p == '-') || (*p == '.')) - p++; - }else{ - p++; - while(isalpha(*p) || (*p == '.')) - p++; - if(*p != ']'){ - parse_error = - g_strdup_printf("']' expected at end of literal address %s", *b); - return FALSE; - } - p++; - } - *e = p; - return TRUE; + *b = p; + if (*p != '[') { + while (isalnum(*p) || (*p == '-') || (*p == '.')) + p++; + } else { + p++; + while (isalpha(*p) || (*p == '.')) + p++; + if (*p != ']') { + parse_error = g_strdup_printf("']' expected at end of literal address %s", *b); + return FALSE; + } + p++; + } + *e = p; + return TRUE; } -gboolean parse_address_rfc822(gchar *string, - gchar **local_begin, gchar **local_end, - gchar **domain_begin, gchar **domain_end, - gchar **address_end) +gboolean +parse_address_rfc822(gchar* string, gchar** local_begin, gchar** local_end, gchar** domain_begin, gchar** domain_end, gchar** address_end) { - gint angle_brackets = 0; + gint angle_brackets = 0; - gchar *p = string; - gchar *b, *e; + gchar *p = string; + gchar *b, *e; - *local_begin = *local_end = NULL; - *domain_begin = *domain_end = NULL; + *local_begin = *local_end = NULL; + *domain_begin = *domain_end = NULL; - /* might be some memory left from previous call: */ - if(parse_error != NULL){ - g_free(parse_error); - parse_error = NULL; - } + /* might be some memory left from previous call: */ + if (parse_error != NULL) { + g_free(parse_error); + parse_error = NULL; + } - /* leading spaces and angle brackets */ - while(*p && (isspace(*p) || (*p == '<'))){ - if(*p == '<') - angle_brackets++; - p++; - } - - if(*p){ - while(TRUE){ - if(read_word_with_dots(p, &b, &e)){ - p = e; + /* leading spaces and angle brackets */ + while (*p && (isspace(*p) || (*p == '<'))) { + if (*p == '<') + angle_brackets++; + p++; + } + + if (*p) { + while (TRUE) { + if (read_word_with_dots(p, &b, &e)) { + p = e; #ifdef PARSE_TEST - g_print("after read_word_with_dots: %s\n", p); + g_print("after read_word_with_dots: %s\n", p); #endif - /* eat white spaces and comments */ - while((*p && (isspace(*p))) || (*p == '(')){ - if(*p == '('){ - if(!(p = skip_comment(p))){ - parse_error = - g_strdup("missing right bracket ')'"); - return FALSE; - } - }else - p++; + /* eat white spaces and comments */ + while ((*p && (isspace(*p))) || (*p == '(')) { + if (*p == '(') { + if (!(p = skip_comment(p))) { + parse_error = g_strdup("missing right bracket ')'"); + return FALSE; + } + } else + p++; + } + /* we now have a non-space char that is not + the beginning of a comment */ + + if (*p == '@') { + /* the last word was the local_part + of an addr-spec */ + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); +#endif + if (*p == '@') { + p++; /* skip @ */ + /* now the domain */ + if (read_domain(p, &b, &e)) { + p = e; + *domain_begin = b; + *domain_end = e; + } else + return FALSE; + } else { + /* unqualified? */ + *domain_begin = *domain_end = NULL; + } + break; + } else if (*p == '<') { + /* addr-spec follows */ + while (isspace(*p) || (*p == '<')) { + if (*p == '<') + angle_brackets++; + p++; + } + if (read_word_with_dots(p, &b, &e)) { + p = e; + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); +#endif + } else + return FALSE; + if (*p == '@') { + p++; + if (read_domain(p, &b, &e)) { + p = e; + *domain_begin = b; + *domain_end = e; + } else + return FALSE; + } else { + /* may be unqualified address */ + *domain_begin = *domain_end = NULL; + } + break; + } else if (!*p || *p == '>') { + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); +#endif + *domain_begin = *domain_end = NULL; + break; + } else if (strchr(specials, *p) || iscntrl(*p) || isspace(*p)) { + parse_error = g_strdup_printf("unexpected character: %c", *p); + return FALSE; + } + } else + return FALSE; + } + /* trailing spaces and angle brackets */ +#ifdef PARSE_TEST + g_print("down counting trailing '>'\n"); +#endif + while (*p && (isspace(*p) || (*p == '>'))) { + if (*p == '>') + angle_brackets--; + p++; + } + + *address_end = p; + + if (angle_brackets != 0) { + if (angle_brackets > 0) + parse_error = g_strdup("missing '>' at end of string"); + else + parse_error = g_strdup("superfluous '>' at end of string"); + return FALSE; + } else { + /* we successfully parsed the address */ + return TRUE; + } + /* we never get here */ } - /* we now have a non-space char that is not - the beginning of a comment */ - - if(*p == '@'){ - /* the last word was the local_part - of an addr-spec */ - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); -#endif - if(*p == '@'){ - p++; /* skip @ */ - /* now the domain */ - if(read_domain(p, &b, &e)){ - p = e; - *domain_begin = b; - *domain_end = e; - } - else - return FALSE; - }else{ - /* unqualified? */ - *domain_begin = *domain_end = NULL; - } - break; - }else if(*p == '<'){ - /* addr-spec follows */ - while(isspace(*p) || (*p == '<')){ - if(*p == '<') - angle_brackets++; - p++; - } - if(read_word_with_dots(p, &b, &e)){ - p = e; - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); -#endif - }else - return FALSE; - if(*p == '@'){ - p++; - if(read_domain(p, &b, &e)){ - p = e; - *domain_begin = b; - *domain_end = e; - }else - return FALSE; - }else{ - /* may be unqualified address */ - *domain_begin = *domain_end = NULL; - } - break; - }else if(!*p || *p == '>'){ - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); -#endif - *domain_begin = *domain_end = NULL; - break; - }else if(strchr(specials, *p) || iscntrl(*p) || isspace(*p)){ - parse_error = g_strdup_printf("unexpected character: %c", *p); - return FALSE; - } - }else return FALSE; - } - /* trailing spaces and angle brackets */ -#ifdef PARSE_TEST - g_print("down counting trailing '>'\n"); -#endif - while(*p && (isspace(*p) || (*p == '>'))){ - if(*p == '>') - angle_brackets--; - p++; - } - - *address_end = p; - - if(angle_brackets != 0){ - if(angle_brackets > 0) - parse_error = g_strdup("missing '>' at end of string"); - else - parse_error = g_strdup("superfluous '>' at end of string"); - return FALSE; - }else{ - /* we successfully parsed the address */ - return TRUE; - } - /* we never get here */ - } - return FALSE; } -gboolean parse_address_rfc821(gchar *string, - gchar **local_begin, gchar **local_end, - gchar **domain_begin, gchar **domain_end, - gchar **address_end) +gboolean +parse_address_rfc821(gchar* string, gchar** local_begin, gchar** local_end, gchar** domain_begin, gchar** domain_end, gchar** address_end) { - gint angle_brackets = 0; + gint angle_brackets = 0; - gchar *p = string; - gchar *b, *e; + gchar *p = string; + gchar *b, *e; - *local_begin = *local_end = NULL; - *domain_begin = *domain_end = NULL; + *local_begin = *local_end = NULL; + *domain_begin = *domain_end = NULL; - /* might be some memory left from previous call: */ - if(parse_error != NULL){ - g_free(parse_error); - parse_error = NULL; - } + /* might be some memory left from previous call: */ + if (parse_error != NULL) { + g_free(parse_error); + parse_error = NULL; + } - /* leading spaces and angle brackets */ - while(*p && (isspace(*p) || (*p == '<'))){ - if(*p == '<') - angle_brackets++; - p++; - } - - if(*p){ - while(TRUE){ - if(read_word_with_dots(p, &b, &e)){ - p = e; + /* leading spaces and angle brackets */ + while (*p && (isspace(*p) || (*p == '<'))) { + if (*p == '<') + angle_brackets++; + p++; + } + + if (*p) { + while (TRUE) { + if (read_word_with_dots(p, &b, &e)) { + p = e; #ifdef PARSE_TEST - g_print("after read_word_with_dots: %s\n", p); + g_print("after read_word_with_dots: %s\n", p); #endif - *local_begin = b; - *local_end = e; + *local_begin = b; + *local_end = e; #ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); - g_print("local_end = %s\n", *local_end); + g_print("found local part: %s\n", *local_begin); + g_print("local_end = %s\n", *local_end); #endif - if(!(*p) || isspace(*p) || (*p == '>')){ - /* unqualified ?*/ - domain_begin = domain_end = NULL; - break; - }else if(*p == '@'){ - p++; - if(read_domain(p, &b, &e)){ - p = e; - *domain_begin = b; - *domain_end = e; - } - break; - }else{ - parse_error = - g_strdup_printf("unexpected character after local part '%c'",*p); - return FALSE; + if (!(*p) || isspace(*p) || (*p == '>')) { + /* unqualified ? */ + domain_begin = domain_end = NULL; + break; + } else if (*p == '@') { + p++; + if (read_domain(p, &b, &e)) { + p = e; + *domain_begin = b; + *domain_end = e; + } + break; + } else { + parse_error = g_strdup_printf ("unexpected character after local part '%c'", *p); + return FALSE; + } + } else + return FALSE; + } + + /* trailing spaces and angle brackets */ +#ifdef PARSE_TEST + g_print("down counting trailing '>'\n"); +#endif + while (*p && (isspace(*p) || (*p == '>'))) { + if (*p == '>') + angle_brackets--; + p++; + } + *address_end = p; + + if (angle_brackets != 0) { + if (angle_brackets > 0) + parse_error = g_strdup("missing '>' at end of string"); + else + parse_error = g_strdup("superfluous '>' at end of string"); + return FALSE; + } else { + /* we successfully parsed the address */ + return TRUE; + } + /* we never get here */ } - } else - return FALSE; - } - - /* trailing spaces and angle brackets */ -#ifdef PARSE_TEST - g_print("down counting trailing '>'\n"); -#endif - while(*p && (isspace(*p) || (*p == '>'))){ - if(*p == '>') - angle_brackets--; - p++; - } - *address_end = p; - - if(angle_brackets != 0){ - if(angle_brackets > 0) - parse_error = g_strdup("missing '>' at end of string"); - else - parse_error = g_strdup("superfluous '>' at end of string"); - return FALSE; - }else{ - /* we successfully parsed the address */ - return TRUE; - } - /* we never get here */ - } - return FALSE; + return FALSE; } /* @@ -358,93 +353,98 @@ parses both rfc 821 and rfc 822 addresses, depending on flag is_rfc821 */ -address *_create_address(gchar *string, gchar **end, gboolean is_rfc821) +address* +_create_address(gchar * string, gchar ** end, gboolean is_rfc821) { - gchar *loc_beg, *loc_end; - gchar *dom_beg, *dom_end; - gchar *addr_end; + gchar *loc_beg, *loc_end; + gchar *dom_beg, *dom_end; + gchar *addr_end; - if (string && (string[0] == 0)) { - address *addr = g_malloc(sizeof(address)); - addr->address = g_strdup(""); - addr->local_part = g_strdup(""); - addr->domain = g_strdup(""); /* 'NULL' address (failure notice), - "" makes sure it will not be qualified with a hostname */ - return addr; - } + if (string && (string[0] == 0)) { + address *addr = g_malloc(sizeof(address)); + addr->address = g_strdup(""); + addr->local_part = g_strdup(""); + addr->domain = g_strdup(""); /* 'NULL' address (failure notice), "" makes sure it will not be qualified with a hostname */ + return addr; + } - if(is_rfc821 ? - parse_address_rfc821(string, - &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end) : - parse_address_rfc822(string, - &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end)){ - address *addr = g_malloc(sizeof(address)); - gchar *p = addr_end; - + if (is_rfc821 + ? parse_address_rfc821(string, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end) + : parse_address_rfc822(string, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end)) + { + address *addr = g_malloc(sizeof(address)); + gchar *p = addr_end; - memset(addr, 0, sizeof(address)); - if(loc_beg[0] == '|'){ - parse_error = g_strdup("no pipe allowed for RFC 822/821 address"); - return NULL; - } + memset(addr, 0, sizeof(address)); - while(*p && (*p != ',')) p++; - addr->address = g_strndup(string, p - string); + if (loc_beg[0] == '|') { + parse_error = g_strdup("no pipe allowed for RFC 822/821 address"); + return NULL; + } - addr->local_part = g_strndup(loc_beg, loc_end - loc_beg); + while (*p && (*p != ',')) + p++; + addr->address = g_strndup(string, p - string); + + addr->local_part = g_strndup(loc_beg, loc_end - loc_beg); #ifdef PARSE_TEST - g_print("addr->local_part = %s\n", addr->local_part); + g_print("addr->local_part = %s\n", addr->local_part); #endif - if(dom_beg != NULL){ - addr->domain = g_strndup(dom_beg, dom_end - dom_beg); - }else{ - if(addr->local_part[0] == 0) - addr->domain = g_strdup(""); /* 'NULL' address (failure notice), - "" makes sure it will not be qualified with a hostname */ - else - addr->domain = NULL; - } + if (dom_beg != NULL) { + addr->domain = g_strndup(dom_beg, dom_end - dom_beg); + } else { + if (addr->local_part[0] == 0) + addr->domain = g_strdup(""); /* 'NULL' address (failure notice), "" makes sure it will not be qualified with a hostname */ + else + addr->domain = NULL; + } - if(end != NULL) - *end = p; + if (end != NULL) + *end = p; #ifndef PARSE_TEST - addr_unmark_delivered(addr); + addr_unmark_delivered(addr); #endif - return addr; - } - return NULL; + return addr; + } + return NULL; } -address *create_address_rfc822(gchar *string, gchar **end){ - return _create_address(string, end, FALSE); +address* +create_address_rfc822(gchar * string, gchar ** end) +{ + return _create_address(string, end, FALSE); } -address *create_address_rfc821(gchar *string, gchar **end){ - return _create_address(string, end, TRUE); +address* +create_address_rfc821(gchar * string, gchar ** end) +{ + return _create_address(string, end, TRUE); } -GList *addr_list_append_rfc822(GList *addr_list, gchar *string, gchar *domain) +GList* +addr_list_append_rfc822(GList * addr_list, gchar * string, gchar * domain) { - gchar *p = string; - gchar *end; + gchar *p = string; + gchar *end; - while(*p){ - address *addr = _create_address(p, &end, FALSE); - if(addr){ - if(domain) - if(addr->domain == NULL) - addr->domain = g_strdup(domain); + while (*p) { + address *addr = _create_address(p, &end, FALSE); + if (addr) { + if (domain) + if (addr->domain == NULL) + addr->domain = g_strdup(domain); - addr_list = g_list_append(addr_list, addr); - p = end; - }else - break; - while(*p == ',' || isspace(*p)) p++; - } - return addr_list; + addr_list = g_list_append(addr_list, addr); + p = end; + } else + break; + while (*p == ',' || isspace(*p)) + p++; + } + return addr_list; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/peopen.c --- a/src/peopen.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/peopen.c Mon Oct 27 16:23:10 2008 +0100 @@ -13,124 +13,123 @@ #include "masqmail.h" -static -void destroy_argv(char **arr) +static void +destroy_argv(char **arr) { - char *p = arr[0]; - int i = 0; + char *p = arr[0]; + int i = 0; - while(p){ - free(p); - p = arr[i++]; - } - free(arr); + while (p) { + free(p); + p = arr[i++]; + } + free(arr); } -static -char **create_argv(const char *cmd, int count) +static char** +create_argv(const char *cmd, int count) { - char buf[strlen(cmd)+1]; - char **arr, *q; - const char *p; - int i = 0; + char buf[strlen(cmd) + 1]; + char **arr, *q; + const char *p; + int i = 0; - arr = (char **)malloc(sizeof(char *) * count); - - p = cmd; - while(*p && i < (count-1)){ - while(*p && isspace(*p)) p++; - q = buf; - while(*p && !isspace(*p)) *q++ = *p++; - *q = 0; - arr[i++] = strdup(buf); - while(*p && isspace(*p)) p++; - } - arr[i] = NULL; + arr = (char **) malloc(sizeof(char *) * count); - return arr; + p = cmd; + while (*p && i < (count - 1)) { + while (*p && isspace(*p)) + p++; + q = buf; + while (*p && !isspace(*p)) + *q++ = *p++; + *q = 0; + arr[i++] = strdup(buf); + while (*p && isspace(*p)) + p++; + } + arr[i] = NULL; + + return arr; } -FILE* peidopen(const char *command, - const char *type, - char *const envp [], - int *ret_pid, - uid_t uid, gid_t gid - ) +FILE* +peidopen(const char *command, const char *type, char *const envp[], int *ret_pid, uid_t uid, gid_t gid) { - enum { Read, Write } mode; - int pipe_fd [2]; - pid_t pid; - - if (command == NULL || type == NULL) { - errno = EINVAL; - return NULL; - } + enum { Read, Write } mode; + int pipe_fd[2]; + pid_t pid; - if (strcmp (type, "r")) { - if (strcmp (type, "w")) { - errno = EINVAL; - return NULL; - } else - mode = Write; - } else - mode = Read; + if (command == NULL || type == NULL) { + errno = EINVAL; + return NULL; + } - if (pipe (pipe_fd) == -1) - return NULL; + if (strcmp(type, "r")) { + if (strcmp(type, "w")) { + errno = EINVAL; + return NULL; + } else + mode = Write; + } else + mode = Read; - switch (pid = fork ()) { - case 0: /* child thread */ + if (pipe(pipe_fd) == -1) + return NULL; - { - int i, max_fd = sysconf(_SC_OPEN_MAX); - - if(max_fd <= 0) max_fd = 64; - for(i = 0; i < max_fd; i++) - if((i != pipe_fd[0]) && (i != pipe_fd[1])) close(i); - } - if (close (pipe_fd [mode == Read ? 0 : 1]) != -1 && - dup2 (pipe_fd [mode == Read ? 1 : 0], mode == Read ? STDOUT_FILENO : STDIN_FILENO) != -1) { - // char *argv [] = { "/bin/sh", "-c", (char*) command, NULL }; - char **argv = create_argv(command, 10); - int ret; + switch (pid = fork()) { + case 0: /* child thread */ - if(uid != (uid_t)-1){ - if((ret = seteuid(0)) != 0){ - exit(EX_NOPERM); + { + int i, max_fd = sysconf(_SC_OPEN_MAX); + + if (max_fd <= 0) + max_fd = 64; + for (i = 0; i < max_fd; i++) + if ((i != pipe_fd[0]) && (i != pipe_fd[1])) + close(i); + } + if (close(pipe_fd[mode == Read ? 0 : 1]) != -1 && + dup2(pipe_fd[mode == Read ? 1 : 0], + mode == Read ? STDOUT_FILENO : STDIN_FILENO) != -1) { + // char *argv [] = { "/bin/sh", "-c", (char*) command, NULL }; + char **argv = create_argv(command, 10); + int ret; + + if (uid != (uid_t) - 1) { + if ((ret = seteuid(0)) != 0) { + exit(EX_NOPERM); + } + } + if (gid != (gid_t) - 1) { + if ((ret = setgid(gid)) != 0) { + exit(EX_NOPERM); + } + } + if (uid != (uid_t) - 1) { + if ((ret = setuid(uid)) != 0) { + exit(EX_NOPERM); + } + } + execve(*argv, argv, envp); + } + + _exit(errno); + + default: /* parent thread */ + *ret_pid = pid; + close(pipe_fd[mode == Read ? 1 : 0]); + return fdopen(pipe_fd[mode == Read ? 0 : 1], type); + + case -1: + close(pipe_fd[0]); + close(pipe_fd[1]); + return NULL; } - } - if(gid != (gid_t)-1){ - if((ret = setgid(gid)) != 0){ - exit(EX_NOPERM); - } - } - if(uid != (uid_t)-1){ - if((ret = setuid(uid)) != 0){ - exit(EX_NOPERM); - } - } - execve (*argv, argv, envp); - } - - _exit (errno); - - default: /* parent thread */ - *ret_pid = pid; - close (pipe_fd [mode == Read ? 1 : 0]); - return fdopen (pipe_fd [mode == Read ? 0 : 1], type); - - case -1: - close (pipe_fd [0]); - close (pipe_fd [1]); - return NULL; - } } -FILE* peopen(const char *command, - const char *type, - char *const envp [], - int *ret_pid - ) +FILE* +peopen(const char *command, const char *type, char *const envp[], int *ret_pid) { - return peidopen(command, type, envp, ret_pid, -1 ,-1); + return peidopen(command, type, envp, ret_pid, -1, -1); } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/peopen.h --- a/src/peopen.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/peopen.h Mon Oct 27 16:23:10 2008 +0100 @@ -1,13 +1,3 @@ -FILE* peopen(const char *command, - const char *type, - char *const envp [], - int *ret_pid -); +FILE *peopen(const char *command, const char *type, char *const envp[], int *ret_pid); -FILE* peidopen(const char *command, - const char *type, - char *const envp [], - int *ret_pid, - uid_t uid, gid_t gid -); - +FILE *peidopen(const char *command, const char *type, char *const envp[], int *ret_pid, uid_t uid, gid_t gid); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/permissions.c --- a/src/permissions.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/permissions.c Mon Oct 27 16:23:10 2008 +0100 @@ -21,58 +21,60 @@ #include /* is there really no function in libc for this? */ -gboolean is_ingroup(uid_t uid, gid_t gid) +gboolean +is_ingroup(uid_t uid, gid_t gid) { - struct group *grent = getgrgid(gid); + struct group *grent = getgrgid(gid); - if(grent){ - struct passwd *pwent = getpwuid(uid); - if(pwent){ - char *entry; - int i = 0; - while((entry = grent->gr_mem[i++])){ - if(strcmp(pwent->pw_name, entry) == 0) - return TRUE; - } - } - } - return FALSE; + if (grent) { + struct passwd *pwent = getpwuid(uid); + if (pwent) { + char *entry; + int i = 0; + while ((entry = grent->gr_mem[i++])) { + if (strcmp(pwent->pw_name, entry) == 0) + return TRUE; + } + } + } + return FALSE; } -gboolean is_privileged_user(uid_t uid) +gboolean +is_privileged_user(uid_t uid) { - return (uid == 0) || (uid == conf.mail_uid) || (is_ingroup(uid, conf.mail_gid)); + return (uid == 0) || (uid == conf.mail_uid) || (is_ingroup(uid, conf.mail_gid)); } -void set_euidgid(gint uid, gint gid, uid_t *old_uid, gid_t *old_gid) +void +set_euidgid(gint uid, gint gid, uid_t * old_uid, gid_t * old_gid) { - if(old_uid) *old_uid = geteuid(); - if(old_gid) *old_gid = getegid(); + if (old_uid) + *old_uid = geteuid(); + if (old_gid) + *old_gid = getegid(); - seteuid(0); + seteuid(0); - if(setegid(gid) != 0){ - logwrite(LOG_ALERT, "could not change gid to %d: %s\n", - gid, strerror(errno)); - exit(EXIT_FAILURE); - } - if(seteuid(uid) != 0){ - logwrite(LOG_ALERT, "could not change uid to %d: %s\n", - uid, strerror(errno)); - exit(EXIT_FAILURE); - } + if (setegid(gid) != 0) { + logwrite(LOG_ALERT, "could not change gid to %d: %s\n", gid, strerror(errno)); + exit(EXIT_FAILURE); + } + if (seteuid(uid) != 0) { + logwrite(LOG_ALERT, "could not change uid to %d: %s\n", uid, strerror(errno)); + exit(EXIT_FAILURE); + } } -void set_identity(uid_t old_uid, gchar *task_name) +void +set_identity(uid_t old_uid, gchar * task_name) { - if(!conf.run_as_user){ - if(!is_privileged_user(old_uid)){ - fprintf(stderr, - "must be root, %s or in group %s for %s.\n", - DEF_MAIL_USER, DEF_MAIL_GROUP, task_name); - exit(EXIT_FAILURE); - } + if (!conf.run_as_user) { + if (!is_privileged_user(old_uid)) { + fprintf(stderr, "must be root, %s or in group %s for %s.\n", DEF_MAIL_USER, DEF_MAIL_GROUP, task_name); + exit(EXIT_FAILURE); + } - set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL); - } + set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL); + } } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/pop3_in.c --- a/src/pop3_in.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/pop3_in.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 @@ -36,785 +36,774 @@ /* experimental feature */ #define DO_WRITE_UIDL_EARLY 1 -static -gchar *MD5String (char *string) +static gchar* +MD5String(char *string) { - MD5_CTX context; - unsigned char digest[16]; - char str_digest[33]; - int i; + MD5_CTX context; + unsigned char digest[16]; + char str_digest[33]; + int i; #ifdef USE_LIB_CRYPTO - MD5(string, strlen(string), digest); + MD5(string, strlen(string), digest); #else - MD5Init(&context); - MD5Update(&context, string, strlen(string)); - MD5Final(digest, &context); + MD5Init(&context); + MD5Update(&context, string, strlen(string)); + MD5Final(digest, &context); #endif - for (i = 0; i < 16; i++) - sprintf(str_digest+2*i, "%02x", digest[i]); + for (i = 0; i < 16; i++) + sprintf(str_digest + 2 * i, "%02x", digest[i]); - return g_strdup(str_digest); + return g_strdup(str_digest); } -static -pop3_base *create_pop3base(gint sock, guint flags) +static pop3_base* +create_pop3base(gint sock, guint flags) { - gint dup_sock; + gint dup_sock; - pop3_base *popb = (pop3_base *)g_malloc(sizeof(pop3_base)); - if(popb){ - memset(popb, 0, sizeof(pop3_base)); + pop3_base *popb = (pop3_base *) g_malloc(sizeof(pop3_base)); + if (popb) { + memset(popb, 0, sizeof(pop3_base)); - popb->error = pop3_ok; + popb->error = pop3_ok; - popb->buffer = (gchar *)g_malloc(POP3_BUF_LEN); + popb->buffer = (gchar *) g_malloc(POP3_BUF_LEN); - dup_sock = dup(sock); - popb->out = fdopen(sock, "w"); - popb->in = fdopen(dup_sock, "r"); - - popb->flags = flags; - } - return popb; + dup_sock = dup(sock); + popb->out = fdopen(sock, "w"); + popb->in = fdopen(dup_sock, "r"); + + popb->flags = flags; + } + return popb; } -static -void pop3_printf(FILE *out, gchar *fmt, ...) +static void +pop3_printf(FILE * out, gchar * fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - DEBUG(4){ - gchar buf[256]; - va_list args_copy; + DEBUG(4) { + gchar buf[256]; + va_list args_copy; - va_copy(args_copy, args); - vsnprintf(buf, 255, fmt, args_copy); - va_end(args_copy); + va_copy(args_copy, args); + vsnprintf(buf, 255, fmt, args_copy); + va_end(args_copy); - debugf(">>>%s", buf); - } + debugf(">>>%s", buf); + } - vfprintf(out, fmt, args); fflush(out); + vfprintf(out, fmt, args); + fflush(out); - va_end(args); + va_end(args); } -static -gboolean find_uid(pop3_base *popb, gchar *str) +static gboolean +find_uid(pop3_base * popb, gchar * str) { - GList *node, *node_next; + GList *node, *node_next; - for(node = popb->list_uid_old; node; node=node_next){ - gchar *uid = (gchar *)(node->data); - node_next = node->next; - if(strcmp(uid, str) == 0){ + for (node = popb->list_uid_old; node; node = node_next) { + gchar *uid = (gchar *) (node->data); + node_next = node->next; + if (strcmp(uid, str) == 0) { #if 1 - popb->list_uid_old = g_list_remove_link(popb->list_uid_old, node); - g_list_free_1(node); - g_free(uid); + popb->list_uid_old = g_list_remove_link(popb->list_uid_old, node); + g_list_free_1(node); + g_free(uid); #endif - return TRUE; - } - } - return FALSE; + return TRUE; + } + } + return FALSE; } -static -gboolean write_uidl(pop3_base *popb, gchar *user) +static gboolean +write_uidl(pop3_base * popb, gchar * user) { - gboolean ok = FALSE; - GList *node; - gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", - conf.spool_dir, - user, popb->remote_host); - gchar *tmpname = g_strdup_printf("%s.tmp", filename); - FILE *fptr = fopen(tmpname, "wt"); + gboolean ok = FALSE; + GList *node; + gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", conf.spool_dir, user, popb->remote_host); + gchar *tmpname = g_strdup_printf("%s.tmp", filename); + FILE *fptr = fopen(tmpname, "wt"); - if(fptr){ - foreach(popb->drop_list, node){ - msg_info *info = (msg_info *)(node->data); - if(info->is_fetched || info->is_in_uidl) - fprintf(fptr, "%s\n", info->uid); - } - fclose(fptr); - ok = (rename(tmpname, filename) != -1); - } - - g_free(tmpname); - g_free(filename); - return ok; + if (fptr) { + foreach(popb->drop_list, node) { + msg_info *info = (msg_info *) (node->data); + if (info->is_fetched || info->is_in_uidl) + fprintf(fptr, "%s\n", info->uid); + } + fclose(fptr); + ok = (rename(tmpname, filename) != -1); + } + + g_free(tmpname); + g_free(filename); + return ok; } -static -gboolean read_uidl_fname(pop3_base *popb, gchar *filename) +static gboolean +read_uidl_fname(pop3_base * popb, gchar * filename) { - gboolean ok = FALSE; - FILE *fptr = fopen(filename, "rt"); - gchar buf[256]; + gboolean ok = FALSE; + FILE *fptr = fopen(filename, "rt"); + gchar buf[256]; - if(fptr){ - popb->list_uid_old = NULL; - while(fgets(buf, 255, fptr)){ - if(buf[strlen(buf)-1] == '\n'){ - g_strchomp(buf); - popb->list_uid_old = - g_list_append(popb->list_uid_old, g_strdup(buf)); - }else{ - logwrite(LOG_ALERT, "broken uid: %s\n", buf); - break; - } - } - fclose(fptr); - ok = TRUE; - }else - logwrite(LOG_ALERT, "opening of %s failed: %s", filename, strerror(errno)); - return ok; + if (fptr) { + popb->list_uid_old = NULL; + while (fgets(buf, 255, fptr)) { + if (buf[strlen(buf) - 1] == '\n') { + g_strchomp(buf); + popb->list_uid_old = g_list_append(popb->list_uid_old, g_strdup(buf)); + } else { + logwrite(LOG_ALERT, "broken uid: %s\n", buf); + break; + } + } + fclose(fptr); + ok = TRUE; + } else + logwrite(LOG_ALERT, "opening of %s failed: %s", filename, strerror(errno)); + return ok; } -static -gboolean read_uidl(pop3_base *popb, gchar *user) +static gboolean +read_uidl(pop3_base * popb, gchar * user) { - gboolean ok = FALSE; - struct stat statbuf; - gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", - conf.spool_dir, - user, popb->remote_host); + gboolean ok = FALSE; + struct stat statbuf; + gchar *filename = g_strdup_printf("%s/popuidl/%s@%s", conf.spool_dir, user, popb->remote_host); - if(stat(filename, &statbuf) == 0){ - ok = read_uidl_fname(popb, filename); - if(ok){ - GList *drop_node; - foreach(popb->drop_list, drop_node){ - msg_info *info = (msg_info *)(drop_node->data); - if(find_uid(popb, info->uid)){ - DEBUG(5) debugf("msg with uid '%s' already known\n", info->uid); - info->is_in_uidl = TRUE; - popb->uidl_known_cnt++; - }else - DEBUG(5) debugf("msg with uid '%s' not known\n", info->uid); - } - } - }else{ - logwrite(LOG_DEBUG, "no uidl file '%s' found\n", filename); - ok = TRUE; - } + if (stat(filename, &statbuf) == 0) { + ok = read_uidl_fname(popb, filename); + if (ok) { + GList *drop_node; + foreach(popb->drop_list, drop_node) { + msg_info *info = (msg_info *) (drop_node->data); + if (find_uid(popb, info->uid)) { + DEBUG(5) debugf("msg with uid '%s' already known\n", info->uid); + info->is_in_uidl = TRUE; + popb->uidl_known_cnt++; + } else + DEBUG(5) debugf("msg with uid '%s' not known\n", info->uid); + } + } + } else { + logwrite(LOG_DEBUG, "no uidl file '%s' found\n", filename); + ok = TRUE; + } - g_free(filename); - return ok; /* return code is irrelevant, do not check... */ + g_free(filename); + return ok; /* return code is irrelevant, do not check... */ } -static -gboolean read_response(pop3_base *popb, int timeout) +static gboolean +read_response(pop3_base * popb, int timeout) { - gint len; + gint len; - len = read_sockline(popb->in, popb->buffer, POP3_BUF_LEN, timeout, READSOCKL_CHUG); + len = read_sockline(popb->in, popb->buffer, POP3_BUF_LEN, timeout, READSOCKL_CHUG); - if(len == -3){ - popb->error = pop3_timeout; - return FALSE; - } - else if(len == -2){ - popb->error = pop3_syntax; - return FALSE; - } - else if(len == -1){ - popb->error = pop3_eof; - return FALSE; - } - - return TRUE; + if (len == -3) { + popb->error = pop3_timeout; + return FALSE; + } else if (len == -2) { + popb->error = pop3_syntax; + return FALSE; + } else if (len == -1) { + popb->error = pop3_eof; + return FALSE; + } + + return TRUE; } -static -gboolean check_response(pop3_base *popb) +static gboolean +check_response(pop3_base * popb) { - char c = popb->buffer[0]; + char c = popb->buffer[0]; - if(c == '+'){ - popb->error = pop3_ok; - return TRUE; - }else if(c == '-') - popb->error = pop3_fail; - else - popb->error = pop3_syntax; - return FALSE; + if (c == '+') { + popb->error = pop3_ok; + return TRUE; + } else if (c == '-') + popb->error = pop3_fail; + else + popb->error = pop3_syntax; + return FALSE; } -static -gboolean strtoi(gchar *p, gchar **pend, gint *val) +static gboolean +strtoi(gchar * p, gchar ** pend, gint * val) { - gchar buf[12]; - gint i = 0; + gchar buf[12]; + gint i = 0; - while(*p && isspace(*p)) p++; - if(*p){ - while((i < 11) && isdigit(*p)) - buf[i++] = *(p++); - buf[i] = 0; - *val = atoi(buf); - *pend = p; - return TRUE; - } - return FALSE; + while (*p && isspace(*p)) + p++; + if (*p) { + while ((i < 11) && isdigit(*p)) + buf[i++] = *(p++); + buf[i] = 0; + *val = atoi(buf); + *pend = p; + return TRUE; + } + return FALSE; } -static -gboolean check_response_int_int(pop3_base *popb, gint *arg0, gint *arg1) +static gboolean +check_response_int_int(pop3_base * popb, gint * arg0, gint * arg1) { - if(check_response(popb)){ - gchar *p = &(popb->buffer[3]); - gchar *pe; + if (check_response(popb)) { + gchar *p = &(popb->buffer[3]); + gchar *pe; - if(strtoi(p, &pe, arg0)){ - DEBUG(5) debugf("arg0 = %d\n", *arg0); - p = pe; - if(strtoi(p, &pe, arg1)) - DEBUG(5) debugf("arg1 = %d\n", *arg1); - return TRUE; - } - popb->error = pop3_syntax; - } - return FALSE; + if (strtoi(p, &pe, arg0)) { + DEBUG(5) debugf("arg0 = %d\n", *arg0); + p = pe; + if (strtoi(p, &pe, arg1)) + DEBUG(5) debugf("arg1 = %d\n", *arg1); + return TRUE; + } + popb->error = pop3_syntax; + } + return FALSE; } -static -gboolean get_drop_listing(pop3_base *popb) +static gboolean +get_drop_listing(pop3_base * popb) { - gchar buf[64]; + gchar buf[64]; - DEBUG(5) debugf("get_drop_listing() entered\n"); + DEBUG(5) debugf("get_drop_listing() entered\n"); - while(1){ - gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG); - if(len > 0){ - if(buf[0] == '.') - return TRUE; - else{ - gint number, msg_size; - gchar *p = buf, *pe; - if(strtoi(p, &pe, &number)){ - p = pe; - if(strtoi(p, &pe, &msg_size)){ - msg_info *info = g_malloc(sizeof(msg_info)); - info->number = number; - info->size = msg_size; + while (1) { + gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG); + if (len > 0) { + if (buf[0] == '.') + return TRUE; + else { + gint number, msg_size; + gchar *p = buf, *pe; + if (strtoi(p, &pe, &number)) { + p = pe; + if (strtoi(p, &pe, &msg_size)) { + msg_info *info = g_malloc(sizeof(msg_info)); + info->number = number; + info->size = msg_size; - DEBUG(5) debugf("get_drop_listing(), number = %d, msg_size = %d\n", number, msg_size); + DEBUG(5) debugf ("get_drop_listing(), number = %d, msg_size = %d\n", number, msg_size); - info->uid = NULL; - info->is_fetched = FALSE; - info->is_in_uidl = FALSE; - popb->drop_list = g_list_append(popb->drop_list, info); - }else{ - popb->error = pop3_syntax; - break; - } - }else{ - popb->error = pop3_syntax; - break; + info->uid = NULL; + info->is_fetched = FALSE; + info->is_in_uidl = FALSE; + popb->drop_list = g_list_append(popb->drop_list, info); + } else { + popb->error = pop3_syntax; + break; + } + } else { + popb->error = pop3_syntax; + break; + } + } + } else { + popb->error = (len == -1) ? pop3_eof : pop3_timeout; + return FALSE; + } } - } - }else{ - popb->error = (len == -1) ? pop3_eof : pop3_timeout; - return FALSE; - } - } - return FALSE; + return FALSE; } -static -gboolean get_uid_listing(pop3_base *popb) +static gboolean +get_uid_listing(pop3_base * popb) { - gchar buf[64]; + gchar buf[64]; - while(1){ - gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG); - if(len > 0){ - if(buf[0] == '.') - return TRUE; - else{ - gint number; - gchar *p = buf, *pe; - if(strtoi(p, &pe, &number)){ - msg_info *info = NULL; - GList *drop_node; + while (1) { + gint len = read_sockline(popb->in, buf, 64, POP3_CMD_TIMEOUT, READSOCKL_CHUG); + if (len > 0) { + if (buf[0] == '.') + return TRUE; + else { + gint number; + gchar *p = buf, *pe; + if (strtoi(p, &pe, &number)) { + msg_info *info = NULL; + GList *drop_node; - p = pe; - while(*p && isspace(*p)) p++; + p = pe; + while (*p && isspace(*p)) + p++; - foreach(popb->drop_list, drop_node){ - msg_info *curr_info = (msg_info *)(drop_node->data); - if(curr_info->number == number){ - info = curr_info; - break; - } - } - if(info){ - info->uid = g_strdup(p); - g_strchomp(info->uid); - } + foreach(popb->drop_list, drop_node) { + msg_info *curr_info = (msg_info *) (drop_node->data); + if (curr_info->number == number) { + info = curr_info; + break; + } + } + if (info) { + info->uid = g_strdup(p); + g_strchomp(info->uid); + } - }else{ - popb->error = pop3_syntax; - break; + } else { + popb->error = pop3_syntax; + break; + } + } + } } - } - } - } - return FALSE; + return FALSE; } -static -gboolean check_init_response(pop3_base *popb) +static gboolean +check_init_response(pop3_base * popb) { - if(check_response(popb)){ - gchar buf[256]; - gchar *p = popb->buffer; - gint i = 0; - if(*p){ - while(*p && (*p != '<')) p++; - while(*p && (*p != '>') && (i < 254)) - buf[i++] = *(p++); - buf[i++] = '>'; - buf[i] = 0; + if (check_response(popb)) { + gchar buf[256]; + gchar *p = popb->buffer; + gint i = 0; + if (*p) { + while (*p && (*p != '<')) + p++; + while (*p && (*p != '>') && (i < 254)) + buf[i++] = *(p++); + buf[i++] = '>'; + buf[i] = 0; - popb->timestamp = g_strdup(buf); + popb->timestamp = g_strdup(buf); - return TRUE; - } - } - return FALSE; + return TRUE; + } + } + return FALSE; } -void pop3_in_close(pop3_base *popb) +void +pop3_in_close(pop3_base * popb) { - GList *node; + GList *node; - fclose(popb->in); - fclose(popb->out); + fclose(popb->in); + fclose(popb->out); - close(popb->sock); + close(popb->sock); - foreach(popb->list_uid_old, node){ - gchar *uid = (gchar *)(node->data); - g_free(uid); - } - g_list_free(popb->list_uid_old); + foreach(popb->list_uid_old, node) { + gchar *uid = (gchar *) (node->data); + g_free(uid); + } + g_list_free(popb->list_uid_old); - foreach(popb->drop_list, node){ - msg_info *info = (msg_info *)(node->data); - if(info->uid) g_free(info->uid); - g_free(info); - } - g_list_free(popb->drop_list); + foreach(popb->drop_list, node) { + msg_info *info = (msg_info *) (node->data); + if (info->uid) + g_free(info->uid); + g_free(info); + } + g_list_free(popb->drop_list); - if(popb->buffer) g_free(popb->buffer); - if(popb->timestamp) g_free(popb->timestamp); + if (popb->buffer) + g_free(popb->buffer); + if (popb->timestamp) + g_free(popb->timestamp); } -pop3_base *pop3_in_open(gchar *host, gint port, GList *resolve_list, guint flags) +pop3_base* +pop3_in_open(gchar * host, gint port, GList * resolve_list, guint flags) { - pop3_base *popb; - gint sock; - mxip_addr *addr; + pop3_base *popb; + gint sock; + mxip_addr *addr; - DEBUG(5) debugf("pop3_in_open entered, host = %s\n", host); + DEBUG(5) debugf("pop3_in_open entered, host = %s\n", host); - if((addr = connect_resolvelist(&sock, host, port, resolve_list))){ - /* create structure to hold status data: */ - popb = create_pop3base(sock, flags); - popb->remote_host = addr->name; + if ((addr = connect_resolvelist(&sock, host, port, resolve_list))) { + /* create structure to hold status data: */ + popb = create_pop3base(sock, flags); + popb->remote_host = addr->name; - DEBUG(5){ - struct sockaddr_in name; - int len; - getsockname(sock, (struct sockaddr *)(&name), &len); - debugf("socket: name.sin_addr = %s\n", inet_ntoa(name.sin_addr)); - } - return popb; - } - return NULL; + DEBUG(5) { + struct sockaddr_in name; + int len; + getsockname(sock, (struct sockaddr *) (&name), &len); + debugf("socket: name.sin_addr = %s\n", inet_ntoa(name.sin_addr)); + } + return popb; + } + return NULL; } -pop3_base *pop3_in_open_child(gchar *cmd, guint flags) +pop3_base* +pop3_in_open_child(gchar * cmd, guint flags) { - pop3_base *popb; - gint sock; + pop3_base *popb; + gint sock; - DEBUG(5) debugf("pop3_in_open_child entered, cmd = %s\n", cmd); + DEBUG(5) debugf("pop3_in_open_child entered, cmd = %s\n", cmd); - sock = child(cmd); + sock = child(cmd); - if(sock > 0){ + if (sock > 0) { - popb = create_pop3base(sock, flags); - popb->remote_host = NULL; + popb = create_pop3base(sock, flags); + popb->remote_host = NULL; - return popb; - } - logwrite(LOG_ALERT, "child failed (sock = %d): %s\n", sock, strerror(errno)); + return popb; + } + logwrite(LOG_ALERT, "child failed (sock = %d): %s\n", sock, strerror(errno)); - return NULL; + return NULL; } -gboolean pop3_in_init(pop3_base *popb) +gboolean +pop3_in_init(pop3_base * popb) { - gboolean ok; + gboolean ok; - if((ok = read_response(popb, POP3_INITIAL_TIMEOUT))){ - ok = check_init_response(popb); - } - if(!ok) - /* pop3_in_log_failure(popb, NULL);*/ - logwrite(LOG_ALERT, "pop3 failed\n"); - return ok; + if ((ok = read_response(popb, POP3_INITIAL_TIMEOUT))) { + ok = check_init_response(popb); + } + if (!ok) + /* pop3_in_log_failure(popb, NULL); */ + logwrite(LOG_ALERT, "pop3 failed\n"); + return ok; } -gboolean pop3_in_login(pop3_base *popb, gchar *user, gchar *pass) +gboolean +pop3_in_login(pop3_base * popb, gchar * user, gchar * pass) { - if(popb->flags & POP3_FLAG_APOP){ + if (popb->flags & POP3_FLAG_APOP) { - gchar *string = g_strdup_printf("%s%s", popb->timestamp, pass); - gchar *digest = MD5String(string); - pop3_printf(popb->out, "APOP %s %s\r\n", user, digest); - g_free(string); - g_free(digest); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - if(check_response(popb)) - return TRUE; - else - popb->error = pop3_login_failure; - } + gchar *string = g_strdup_printf("%s%s", popb->timestamp, pass); + gchar *digest = MD5String(string); + pop3_printf(popb->out, "APOP %s %s\r\n", user, digest); + g_free(string); + g_free(digest); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + if (check_response(popb)) + return TRUE; + else + popb->error = pop3_login_failure; + } - }else{ + } else { - pop3_printf(popb->out, "USER %s\r\n", user); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - if(check_response(popb)){ - pop3_printf(popb->out, "PASS %s\r\n", pass); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - if(check_response(popb)) - return TRUE; - else - popb->error = pop3_login_failure; + pop3_printf(popb->out, "USER %s\r\n", user); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + if (check_response(popb)) { + pop3_printf(popb->out, "PASS %s\r\n", pass); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + if (check_response(popb)) + return TRUE; + else + popb->error = pop3_login_failure; + } + } else { + popb->error = pop3_login_failure; + } + } } - }else{ - popb->error = pop3_login_failure; - } - } - } - return FALSE; + return FALSE; } -gboolean pop3_in_stat(pop3_base *popb) +gboolean +pop3_in_stat(pop3_base * popb) { - pop3_printf(popb->out, "STAT\r\n"); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - gint msg_cnt, mbox_size; - if(check_response_int_int(popb, &msg_cnt, &mbox_size)){ - popb->msg_cnt = msg_cnt; - popb->mbox_size = mbox_size; + pop3_printf(popb->out, "STAT\r\n"); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + gint msg_cnt, mbox_size; + if (check_response_int_int(popb, &msg_cnt, &mbox_size)) { + popb->msg_cnt = msg_cnt; + popb->mbox_size = mbox_size; - return TRUE; - } - } - return FALSE; + return TRUE; + } + } + return FALSE; } -gboolean pop3_in_list(pop3_base *popb) +gboolean +pop3_in_list(pop3_base * popb) { - pop3_printf(popb->out, "LIST\r\n"); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - if(get_drop_listing(popb)){ - return TRUE; - } - } - return FALSE; + pop3_printf(popb->out, "LIST\r\n"); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + if (get_drop_listing(popb)) { + return TRUE; + } + } + return FALSE; } -gboolean pop3_in_dele(pop3_base *popb, gint number) +gboolean +pop3_in_dele(pop3_base * popb, gint number) { - pop3_printf(popb->out, "DELE %d\r\n", number); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - return TRUE; - } - return FALSE; + pop3_printf(popb->out, "DELE %d\r\n", number); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + return TRUE; + } + return FALSE; } -message *pop3_in_retr(pop3_base *popb, gint number, address *rcpt) +message* +pop3_in_retr(pop3_base * popb, gint number, address * rcpt) { - accept_error err; + accept_error err; - pop3_printf(popb->out, "RETR %d\r\n", number); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - message *msg = create_message(); - msg->received_host = popb->remote_host; - msg->received_prot = (popb->flags & POP3_FLAG_APOP) ? PROT_APOP : PROT_POP3; - msg->transfer_id = (popb->next_id)++; - msg->rcpt_list = g_list_append(NULL, copy_address(rcpt)); + pop3_printf(popb->out, "RETR %d\r\n", number); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + message *msg = create_message(); + msg->received_host = popb->remote_host; + msg->received_prot = (popb->flags & POP3_FLAG_APOP) ? PROT_APOP : PROT_POP3; + msg->transfer_id = (popb->next_id)++; + msg->rcpt_list = g_list_append(NULL, copy_address(rcpt)); - if((err = accept_message(popb->in, msg, - ACC_MAIL_FROM_HEAD|(conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0))) - == AERR_OK) - return msg; + if ((err = accept_message(popb->in, msg, ACC_MAIL_FROM_HEAD + | (conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0))) + == AERR_OK) + return msg; - destroy_message(msg); - } - return NULL; -} - -gboolean pop3_in_uidl(pop3_base *popb) -{ - pop3_printf(popb->out, "UIDL\r\n"); - if(read_response(popb, POP3_CMD_TIMEOUT)){ - if(get_uid_listing(popb)){ - return TRUE; - } - } - return FALSE; + destroy_message(msg); + } + return NULL; } -gboolean pop3_in_quit(pop3_base *popb) +gboolean +pop3_in_uidl(pop3_base * popb) { - pop3_printf(popb->out, "QUIT\r\n"); - - DEBUG(4) debugf("QUIT\n"); + pop3_printf(popb->out, "UIDL\r\n"); + if (read_response(popb, POP3_CMD_TIMEOUT)) { + if (get_uid_listing(popb)) { + return TRUE; + } + } + return FALSE; +} - signal(SIGALRM, SIG_DFL); +gboolean +pop3_in_quit(pop3_base * popb) +{ + pop3_printf(popb->out, "QUIT\r\n"); - return TRUE; + DEBUG(4) debugf("QUIT\n"); + + signal(SIGALRM, SIG_DFL); + + return TRUE; } /* Send a DELE command for each message in (the old) uid listing. This is to prevent mail from to be kept on server, if a previous transaction was interupted. */ -gboolean pop3_in_uidl_dele(pop3_base *popb) +gboolean +pop3_in_uidl_dele(pop3_base * popb) { - GList *drop_node; + GList *drop_node; - foreach(popb->drop_list, drop_node){ - msg_info *info = (msg_info *)(drop_node->data); - /* if(find_uid(popb, info->uid)){*/ - if(info->is_in_uidl){ - if(!pop3_in_dele(popb, info->number)) - return FALSE; - /* TODO: it probably makes sense to also - delete this uid from the listing */ - } - } - return TRUE; + foreach(popb->drop_list, drop_node) { + msg_info *info = (msg_info *) (drop_node->data); + /* if(find_uid(popb, info->uid)){ */ + if (info->is_in_uidl) { + if (!pop3_in_dele(popb, info->number)) + return FALSE; + /* TODO: it probably makes sense to also delete this uid from the listing */ + } + } + return TRUE; } -gboolean pop3_get(pop3_base *popb, - gchar *user, gchar *pass, address *rcpt, address *return_path, - gint max_count, gint max_size, gboolean max_size_delete) +gboolean +pop3_get(pop3_base * popb, gchar * user, gchar * pass, address * rcpt, address * return_path, gint max_count, gint max_size, gboolean max_size_delete) { - gboolean ok = FALSE; - gint num_children = 0; - - DEBUG(5) debugf("rcpt = %s@%s\n", rcpt->local_part, rcpt->domain); + gboolean ok = FALSE; + gint num_children = 0; - signal(SIGCHLD, SIG_DFL); + DEBUG(5) debugf("rcpt = %s@%s\n", rcpt->local_part, rcpt->domain); - if(pop3_in_init(popb)){ - if(pop3_in_login(popb, user, pass)){ - if(pop3_in_stat(popb)){ - if(popb->msg_cnt > 0){ + signal(SIGCHLD, SIG_DFL); - logwrite(LOG_NOTICE|LOG_VERBOSE, "%d message(s) for user %s at %s\n", - popb->msg_cnt, user, popb->remote_host); + if (pop3_in_init(popb)) { + if (pop3_in_login(popb, user, pass)) { + if (pop3_in_stat(popb)) { + if (popb->msg_cnt > 0) { - if(pop3_in_list(popb)){ - gboolean do_get = !(popb->flags & POP3_FLAG_UIDL); - if(!do_get) do_get = pop3_in_uidl(popb); - if(do_get){ - gint count = 0; - GList *drop_node; + logwrite(LOG_NOTICE | LOG_VERBOSE, "%d message(s) for user %s at %s\n", popb->msg_cnt, user, popb->remote_host); - if(popb->flags & POP3_FLAG_UIDL){ - read_uidl(popb, user); - logwrite(LOG_VERBOSE|LOG_NOTICE, "%d message(s) already in uidl.\n", - popb->uidl_known_cnt); - } - if((popb->flags & POP3_FLAG_UIDL) && (popb->flags & POP3_FLAG_UIDL_DELE)) - pop3_in_uidl_dele(popb); + if (pop3_in_list(popb)) { + gboolean do_get = !(popb->flags & POP3_FLAG_UIDL); + if (!do_get) + do_get = pop3_in_uidl(popb); + if (do_get) { + gint count = 0; + GList *drop_node; - foreach(popb->drop_list, drop_node){ + if (popb->flags & POP3_FLAG_UIDL) { + read_uidl(popb, user); + logwrite(LOG_VERBOSE | LOG_NOTICE, "%d message(s) already in uidl.\n", popb->uidl_known_cnt); + } + if ((popb->flags & POP3_FLAG_UIDL) && (popb->flags & POP3_FLAG_UIDL_DELE)) + pop3_in_uidl_dele(popb); - msg_info *info = (msg_info *)(drop_node->data); - gboolean do_get_this = !(popb->flags & POP3_FLAG_UIDL); - /* if(!do_get_this) do_get_this = !find_uid(popb, info->uid);*/ - if(!do_get_this) do_get_this = !(info->is_in_uidl); - if(do_get_this){ + foreach(popb->drop_list, drop_node) { - if((info->size < max_size) || (max_size == 0)){ - message *msg; + msg_info *info = (msg_info *) (drop_node->data); + gboolean do_get_this = !(popb->flags & POP3_FLAG_UIDL); + /* if(!do_get_this) do_get_this = !find_uid(popb, info->uid); */ + if (!do_get_this) + do_get_this = !(info->is_in_uidl); + if (do_get_this) { - logwrite(LOG_VERBOSE|LOG_NOTICE, "receiving message %d\n", info->number); - msg = pop3_in_retr(popb, info->number, rcpt); + if ((info->size < max_size) || (max_size == 0)) { + message *msg; - if(msg){ - if(return_path) - msg->return_path = copy_address(return_path); - if(spool_write(msg, TRUE)){ - pid_t pid; - logwrite(LOG_NOTICE, "%s <= %s host=%s with %s\n", - msg->uid, - addr_string(msg->return_path), - popb->remote_host, - (popb->flags & POP3_FLAG_APOP) ? - prot_names[PROT_APOP] : prot_names[PROT_POP3] - ); - info->is_fetched = TRUE; - count++; + logwrite(LOG_VERBOSE | LOG_NOTICE, "receiving message %d\n", info->number); + msg = pop3_in_retr(popb, info->number, rcpt); + + if (msg) { + if (return_path) + msg->return_path = copy_address(return_path); + if (spool_write(msg, TRUE)) { + pid_t pid; + logwrite(LOG_NOTICE, "%s <= %s host=%s with %s\n", msg->uid, + addr_string(msg->return_path), popb->remote_host, + (popb->flags & POP3_FLAG_APOP) ? prot_names [PROT_APOP] : prot_names [PROT_POP3]); + info->is_fetched = TRUE; + count++; #if DO_WRITE_UIDL_EARLY - if(popb->flags & POP3_FLAG_UIDL) write_uidl(popb, user); + if (popb->flags & POP3_FLAG_UIDL) + write_uidl(popb, user); #endif - if(!conf.do_queue){ + if (!conf.do_queue) { - /* wait for child processes. If there are too many, - we wait blocking, before we fork another one */ - while(num_children > 0){ - int status, options = WNOHANG; - pid_t pid; + /* wait for child processes. If there are too many, we wait blocking, before we fork another one */ + while (num_children > 0) { + int status, options = WNOHANG; + pid_t pid; - if(num_children >= POP3_MAX_CHILDREN){ - logwrite(LOG_NOTICE, "too many children - waiting\n"); - options = 0; - } - if((pid = waitpid(0, &status, options)) > 0){ - num_children--; - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, - "delivery process with pid %d returned %d\n", - pid, WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, - "delivery process with pid %d got signal: %d\n", - pid, WTERMSIG(status)); - }else if(pid < 0){ - logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno)); - } - } + if (num_children >= POP3_MAX_CHILDREN) { + logwrite(LOG_NOTICE, "too many children - waiting\n"); + options = 0; + } + if ((pid = waitpid(0, &status, options)) > 0) { + num_children--; + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "delivery process with pid %d returned %d\n", pid, WEXITSTATUS (status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "delivery process with pid %d got signal: %d\n", pid, WTERMSIG (status)); + } else if (pid < 0) { + logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno)); + } + } - if((pid = fork()) == 0){ - deliver(msg); - _exit(EXIT_SUCCESS); - }else if(pid < 0){ - logwrite(LOG_ALERT|LOG_VERBOSE, - "could not fork for delivery, id = %s: %s\n", - msg->uid, strerror(errno)); - }else - num_children++; - }else{ - DEBUG(1) debugf("queuing forced by configuration or option.\n"); - } - if(popb->flags & POP3_FLAG_DELETE) - pop3_in_dele(popb, info->number); + if ((pid = fork()) == 0) { + deliver(msg); + _exit(EXIT_SUCCESS); + } else if (pid < 0) { + logwrite(LOG_ALERT | LOG_VERBOSE, "could not fork for delivery, id = %s: %s\n", msg->uid, strerror(errno)); + } else + num_children++; + } else { + DEBUG(1) debugf("queuing forced by configuration or option.\n"); + } + if (popb->flags & POP3_FLAG_DELETE) + pop3_in_dele(popb, info->number); - destroy_message(msg); - }/* if(spool_write(msg, TRUE)) */ - }else{ - logwrite(LOG_ALERT, - "retrieving of message %d failed: %d\n", - info->number, popb->error); - } - }/* if((info->size > max_size) ... */ - else{ - logwrite(LOG_NOTICE|LOG_VERBOSE, "size of message #%d (%d) > max_size (%d)\n", - info->number, info->size, max_size); - if(max_size_delete) - if(popb->flags & POP3_FLAG_DELETE) - pop3_in_dele(popb, info->number); - } - }/* if(do_get_this) ... */ - else{ - if(popb->flags & POP3_FLAG_UIDL){ - info->is_fetched = TRUE; /* obsolete? */ - logwrite(LOG_VERBOSE, "message %d already known\n", - info->number); - DEBUG(1) debugf("message %d (uid = %s) not fetched\n", - info->number, info->uid); + destroy_message(msg); + } /* if(spool_write(msg, TRUE)) */ + } else { + logwrite(LOG_ALERT, "retrieving of message %d failed: %d\n", info->number, popb->error); + } + } /* if((info->size > max_size) ... */ + else { + logwrite(LOG_NOTICE | LOG_VERBOSE, "size of message #%d (%d) > max_size (%d)\n", info->number, info->size, max_size); + if (max_size_delete) + if (popb->flags & POP3_FLAG_DELETE) + pop3_in_dele(popb, info->number); + } + } /* if(do_get_this) ... */ + else { + if (popb->flags & POP3_FLAG_UIDL) { + info->is_fetched = TRUE; /* obsolete? */ + logwrite(LOG_VERBOSE, "message %d already known\n", info->number); + DEBUG(1) debugf("message %d (uid = %s) not fetched\n", info->number, info->uid); #if 0 #if DO_WRITE_UIDL_EARLY - write_uidl(popb, user); /* obsolete? */ + write_uidl(popb, user); /* obsolete? */ #endif #endif - } - } - if((max_count != 0) && (count >= max_count)) - break; - }/* foreach() */ + } + } + if ((max_count != 0) && (count >= max_count)) + break; + } /* foreach() */ #if DO_WRITE_UIDL_EARLY #else - if(popb->flags & POP3_FLAG_UIDL) write_uidl(popb, user); + if (popb->flags & POP3_FLAG_UIDL) + write_uidl(popb, user); #endif - }/* if(pop3_in_uidl(popb) ... */ - }/* if(pop3_in_list(popb)) */ - }/* if(popb->msg_cnt > 0) */ - else{ - logwrite(LOG_NOTICE|LOG_VERBOSE, - "no messages for user %s at %s\n", user, popb->remote_host); + } /* if(pop3_in_uidl(popb) ... */ + } /* if(pop3_in_list(popb)) */ + } /* if(popb->msg_cnt > 0) */ + else { + logwrite(LOG_NOTICE | LOG_VERBOSE, "no messages for user %s at %s\n", user, popb->remote_host); + } + ok = TRUE; + } + pop3_in_quit(popb); + } else { + logwrite(LOG_ALERT | LOG_VERBOSE, "pop3 login failed for user %s, host = %s\n", user, popb->remote_host); + } } - ok = TRUE; - } - pop3_in_quit(popb); - }else{ - logwrite(LOG_ALERT|LOG_VERBOSE, - "pop3 login failed for user %s, host = %s\n", user, popb->remote_host); - } - } - if(!ok){ - logwrite(LOG_ALERT|LOG_VERBOSE, "pop3 failed, error = %d\n", popb->error); - } + if (!ok) { + logwrite(LOG_ALERT | LOG_VERBOSE, "pop3 failed, error = %d\n", popb->error); + } - while(num_children > 0){ - int status; - pid_t pid; - if((pid = wait(&status)) > 0){ - num_children--; - if(WEXITSTATUS(status) != EXIT_SUCCESS) - logwrite(LOG_WARNING, - "delivery process with pid %d returned %d\n", - pid, WEXITSTATUS(status)); - if(WIFSIGNALED(status)) - logwrite(LOG_WARNING, - "delivery process with pid %d got signal: %d\n", - pid, WTERMSIG(status)); - }else{ - logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno)); - } - } + while (num_children > 0) { + int status; + pid_t pid; + if ((pid = wait(&status)) > 0) { + num_children--; + if (WEXITSTATUS(status) != EXIT_SUCCESS) + logwrite(LOG_WARNING, "delivery process with pid %d returned %d\n", pid, WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + logwrite(LOG_WARNING, "delivery process with pid %d got signal: %d\n", pid, WTERMSIG(status)); + } else { + logwrite(LOG_WARNING, "wait got error: %s\n", strerror(errno)); + } + } - return ok; + return ok; } /* function just to log into a pop server, for pop_before_smtp (or is it smtp_after_pop?) */ -gboolean pop3_login(gchar *host, gint port, GList *resolve_list, - gchar *user, gchar *pass, guint flags) +gboolean +pop3_login(gchar * host, gint port, GList * resolve_list, gchar * user, gchar * pass, guint flags) { - gboolean ok = FALSE; - pop3_base *popb; + gboolean ok = FALSE; + pop3_base *popb; - signal(SIGCHLD, SIG_IGN); + signal(SIGCHLD, SIG_IGN); - if((popb = pop3_in_open(host, port, resolve_list, flags))){ - if(pop3_in_init(popb)){ - if(pop3_in_login(popb, user, pass)) - ok = TRUE; - else - logwrite(LOG_ALERT|LOG_VERBOSE, - "pop3 login failed for user %s, host = %s\n", user, host); - } - pop3_in_close(popb); - } - return ok; + if ((popb = pop3_in_open(host, port, resolve_list, flags))) { + if (pop3_in_init(popb)) { + if (pop3_in_login(popb, user, pass)) + ok = TRUE; + else + logwrite(LOG_ALERT | LOG_VERBOSE, "pop3 login failed for user %s, host = %s\n", user, host); + } + pop3_in_close(popb); + } + return ok; } #endif diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/pop3_in.h --- a/src/pop3_in.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/pop3_in.h 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 @@ -31,56 +31,52 @@ #define POP3_MAX_CHILDREN 2 -typedef -enum _pop3_error{ - pop3_ok = 0, - pop3_fail, - pop3_eof, - pop3_timeout, - pop3_login_failure, - pop3_syntax +typedef enum _pop3_error { + pop3_ok = 0, + pop3_fail, + pop3_eof, + pop3_timeout, + pop3_login_failure, + pop3_syntax } pop3_error; -typedef struct pop3_base{ - FILE *in; - FILE *out; - gint sock; - gint dup_sock; +typedef struct pop3_base { + FILE *in; + FILE *out; + gint sock; + gint dup_sock; - gchar *remote_host; - gchar *buffer; + gchar *remote_host; + gchar *buffer; - gint next_id; - gint msg_cnt; - gint uidl_known_cnt; - gint mbox_size; + gint next_id; + gint msg_cnt; + gint uidl_known_cnt; + gint mbox_size; - GList *list_uid_old; - GList *drop_list; + GList *list_uid_old; + GList *drop_list; - gchar* timestamp; + gchar *timestamp; - guint flags; + guint flags; - pop3_error error; + pop3_error error; } pop3_base; -typedef struct _msg_info{ - gint number; - gint size; - gchar *uid; - gboolean is_fetched; - gboolean is_in_uidl; +typedef struct _msg_info { + gint number; + gint size; + gchar *uid; + gboolean is_fetched; + gboolean is_in_uidl; } msg_info; -pop3_base *pop3_in_open(gchar *host, gint port, GList *resolve_list, guint flags); -pop3_base *pop3_in_open_child(gchar *cmd, guint flags); -void pop3_in_close(pop3_base *popb); -gboolean pop3_get(pop3_base *popb, - gchar *user, gchar *pass, address *rcpt, address *return_path, - gint max_count, gint max_size, gboolean max_size_delete); -gboolean pop3_login(gchar *host, gint port, GList *resolve_list, - gchar *user, gchar *pass, guint flags); +pop3_base *pop3_in_open(gchar * host, gint port, GList * resolve_list, guint flags); +pop3_base *pop3_in_open_child(gchar * cmd, guint flags); +void pop3_in_close(pop3_base * popb); +gboolean pop3_get(pop3_base * popb, gchar * user, gchar * pass, address * rcpt, address * return_path, gint max_count, gint max_size, gboolean max_size_delete); +gboolean pop3_login(gchar * host, gint port, GList * resolve_list, gchar * user, gchar * pass, guint flags); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/queue.c --- a/src/queue.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/queue.c Mon Oct 27 16:23:10 2008 +0100 @@ -21,204 +21,205 @@ #include #include -static -void mix_arr(int *buf, int len) +static void +mix_arr(int *buf, int len) { - int i; + int i; - for(i = 0; i < len; i++) - buf[i] = i; - for(i = 0; i < len-1; i++){ - int j = (int)((float)(len-i) * ((float)rand())/(RAND_MAX + 1.0)); - int tmp; + for (i = 0; i < len; i++) + buf[i] = i; + for (i = 0; i < len - 1; i++) { + int j = (int) ((float) (len - i) * ((float) rand()) / (RAND_MAX + 1.0)); + int tmp; - if(i != j){ - tmp = buf[i]; buf[i] = buf[j]; buf[j] = tmp; - } - } + if (i != j) { + tmp = buf[i]; + buf[i] = buf[j]; + buf[j] = tmp; + } + } } -GList *read_queue(gboolean do_readdata) +GList* +read_queue(gboolean do_readdata) { - GList *msg_list = NULL; - glob_t gl; - gchar *pattern; - int i, *idx_arr; + GList *msg_list = NULL; + glob_t gl; + gchar *pattern; + int i, *idx_arr; - pattern = g_strdup_printf("%s/input/??????-???-??-H", conf.spool_dir); - gl.gl_offs = 0; - glob(pattern, 0, NULL, &gl); + pattern = g_strdup_printf("%s/input/??????-???-??-H", conf.spool_dir); + gl.gl_offs = 0; + glob(pattern, 0, NULL, &gl); - g_free(pattern); + g_free(pattern); - DEBUG(4){ - int i; - for(i = 0; i < gl.gl_pathc; i++){ - debugf("spoolfile: %s\n", gl.gl_pathv[i]); - } - } + DEBUG(4) { + int i; + for (i = 0; i < gl.gl_pathc; i++) { + debugf("spoolfile: %s\n", gl.gl_pathv[i]); + } + } - idx_arr = g_malloc(sizeof(int) * gl.gl_pathc); - mix_arr(idx_arr, gl.gl_pathc); + idx_arr = g_malloc(sizeof(int) * gl.gl_pathc); + mix_arr(idx_arr, gl.gl_pathc); - for(i = 0; i < gl.gl_pathc; i++){ - gchar *uid; + for (i = 0; i < gl.gl_pathc; i++) { + gchar *uid; - /* copy 13 chars, offset spooldir path + 7 chars for /input/ */ - /* uid length = 6 chars + '-' + 3 chars + '-' + 2 = 13 chars */ - uid = g_strndup(&(gl.gl_pathv[idx_arr[i]][strlen(conf.spool_dir) + 7]), 13); + /* copy 13 chars, offset spooldir path + 7 chars for /input/ */ + /* uid length = 6 chars + '-' + 3 chars + '-' + 2 = 13 chars */ + uid = g_strndup(&(gl.gl_pathv[idx_arr[i]][strlen(conf.spool_dir) + 7]), 13); - DEBUG(5) debugf("uid: %s\n", uid); + DEBUG(5) debugf("uid: %s\n", uid); - msg_list = g_list_append(msg_list, msg_spool_read(uid, do_readdata)); + msg_list = g_list_append(msg_list, msg_spool_read(uid, do_readdata)); - DEBUG(5) debugf("after read spool file for %s\n", uid); + DEBUG(5) debugf("after read spool file for %s\n", uid); - g_free(uid); - } - return msg_list; + g_free(uid); + } + return msg_list; } -gboolean queue_run() +gboolean +queue_run() { - GList *msg_list; - gboolean ok = TRUE; + GList *msg_list; + gboolean ok = TRUE; - logwrite(LOG_NOTICE, "Starting queue run.\n"); + logwrite(LOG_NOTICE, "Starting queue run.\n"); - msg_list = read_queue(FALSE); + msg_list = read_queue(FALSE); - if(msg_list != NULL){ - ok = deliver_msg_list(msg_list, DLVR_ALL); - destroy_msg_list(msg_list); - } - logwrite(LOG_NOTICE, "Finished queue run.\n"); + if (msg_list != NULL) { + ok = deliver_msg_list(msg_list, DLVR_ALL); + destroy_msg_list(msg_list); + } + logwrite(LOG_NOTICE, "Finished queue run.\n"); - return ok; + return ok; } -gboolean queue_run_online() +gboolean +queue_run_online() { - GList *msg_list = read_queue(FALSE); - gboolean ok = TRUE; + GList *msg_list = read_queue(FALSE); + gboolean ok = TRUE; - logwrite(LOG_NOTICE, "Starting online queue run.\n"); - if(msg_list != NULL){ - ok = deliver_msg_list(msg_list, DLVR_ONLINE); - destroy_msg_list(msg_list); - } - logwrite(LOG_NOTICE, "Finished online queue run.\n"); + logwrite(LOG_NOTICE, "Starting online queue run.\n"); + if (msg_list != NULL) { + ok = deliver_msg_list(msg_list, DLVR_ONLINE); + destroy_msg_list(msg_list); + } + logwrite(LOG_NOTICE, "Finished online queue run.\n"); - return ok; + return ok; } -static -gchar *format_difftime(double secs) +static gchar* +format_difftime(double secs) { - if(secs > 86400) - return g_strdup_printf("%.1fd", secs/86400); - else if(secs > 3600) - return g_strdup_printf("%.1fh", secs/3600); - else if(secs > 60) - return g_strdup_printf("%.1fm", secs/60); - else - return g_strdup_printf("%.0fs", secs); -} + if (secs > 86400) + return g_strdup_printf("%.1fd", secs / 86400); + else if (secs > 3600) + return g_strdup_printf("%.1fh", secs / 3600); + else if (secs > 60) + return g_strdup_printf("%.1fm", secs / 60); + else + return g_strdup_printf("%.0fs", secs); +} -void queue_list() +void +queue_list() { - GList *msg_list; - GList *msg_node; + GList *msg_list; + GList *msg_node; - msg_list = read_queue(FALSE); + msg_list = read_queue(FALSE); - if(msg_list != NULL){ - foreach(msg_list, msg_node){ - message *msg = (message *)(msg_node->data); - GList *rcpt_node; - gchar *size_str = NULL; - gchar *time_str = NULL; - gchar *host_str = NULL; - gchar *ident_str = NULL; - - if(msg->data_size >= 0) - size_str = g_strdup_printf(" size=%d", msg->data_size); - if(msg->received_time > 0){ - gchar *tmp_str; - time_str = - g_strdup_printf(" age=%s", - tmp_str = format_difftime(difftime(time(NULL), - msg->received_time))); - g_free(tmp_str); - } - if(msg->received_host != NULL) - host_str = g_strdup_printf(" host=%s", msg->received_host); - if(msg->ident != NULL) - ident_str = g_strdup_printf(" ident=%s", msg->ident); + if (msg_list != NULL) { + foreach(msg_list, msg_node) { + message *msg = (message *) (msg_node->data); + GList *rcpt_node; + gchar *size_str = NULL; + gchar *time_str = NULL; + gchar *host_str = NULL; + gchar *ident_str = NULL; - printf("%s <= %s%s%s%s%s\n", msg->uid, - addr_string(msg->return_path), - size_str ? size_str : "", - time_str ? time_str : "", - host_str ? host_str : "", - ident_str ? ident_str : "" - ); + if (msg->data_size >= 0) + size_str = g_strdup_printf(" size=%d", msg->data_size); + if (msg->received_time > 0) { + gchar *tmp_str; + time_str = g_strdup_printf(" age=%s", tmp_str = format_difftime(difftime(time(NULL), msg->received_time))); + g_free(tmp_str); + } + if (msg->received_host != NULL) + host_str = g_strdup_printf(" host=%s", msg->received_host); + if (msg->ident != NULL) + ident_str = g_strdup_printf(" ident=%s", msg->ident); - if(size_str) g_free(size_str); - if(time_str) g_free(time_str); - if(host_str) g_free(host_str); - if(ident_str) g_free(ident_str); + printf("%s <= %s%s%s%s%s\n", msg->uid, addr_string(msg->return_path), size_str ? size_str : "", + time_str ? time_str : "", host_str ? host_str : "", ident_str ? ident_str : ""); - foreach(msg->rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - - printf(" %s %s\n", - addr_is_delivered(rcpt) ? "=>" : (addr_is_failed(rcpt) ? "!=" : "=="), - addr_string(rcpt)); - } - g_free(msg); - } - }else - printf("mail queue is empty.\n"); -} + if (size_str) + g_free(size_str); + if (time_str) + g_free(time_str); + if (host_str) + g_free(host_str); + if (ident_str) + g_free(ident_str); -gboolean queue_delete(gchar *uid) + foreach(msg->rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + + printf(" %s %s\n", addr_is_delivered(rcpt) ? "=>" : (addr_is_failed(rcpt) ? "!=" : "=="), addr_string(rcpt)); + } + g_free(msg); + } + } else + printf("mail queue is empty.\n"); +} + +gboolean +queue_delete(gchar * uid) { - gboolean hdr_ok = TRUE; - gboolean dat_ok = TRUE; - gchar *hdr_name = g_strdup_printf("%s/input/%s-H", conf.spool_dir, uid); - gchar *dat_name = g_strdup_printf("%s/input/%s-D", conf.spool_dir, uid); - struct stat stat_buf; + gboolean hdr_ok = TRUE; + gboolean dat_ok = TRUE; + gchar *hdr_name = g_strdup_printf("%s/input/%s-H", conf.spool_dir, uid); + gchar *dat_name = g_strdup_printf("%s/input/%s-D", conf.spool_dir, uid); + struct stat stat_buf; - if(spool_lock(uid)){ + if (spool_lock(uid)) { - if(stat(hdr_name, &stat_buf) == 0){ - if(unlink(hdr_name) != 0){ - fprintf(stderr, "could not unlink %s: %s\n", hdr_name, strerror(errno)); - hdr_ok = FALSE; - } - }else{ - fprintf(stderr, "could not stat file %s: %s\n", hdr_name, strerror(errno)); - hdr_ok = FALSE; - } - if(stat(dat_name, &stat_buf) == 0){ - if(unlink(dat_name) != 0){ - fprintf(stderr, "could not unlink %s: %s\n", dat_name, strerror(errno)); - dat_ok = FALSE; - } - }else{ - fprintf(stderr, "could not stat file %s: %s\n", dat_name, strerror(errno)); - dat_ok = FALSE; - } - printf("message %s deleted\n", uid); + if (stat(hdr_name, &stat_buf) == 0) { + if (unlink(hdr_name) != 0) { + fprintf(stderr, "could not unlink %s: %s\n", hdr_name, strerror(errno)); + hdr_ok = FALSE; + } + } else { + fprintf(stderr, "could not stat file %s: %s\n", hdr_name, strerror(errno)); + hdr_ok = FALSE; + } + if (stat(dat_name, &stat_buf) == 0) { + if (unlink(dat_name) != 0) { + fprintf(stderr, "could not unlink %s: %s\n", dat_name, strerror(errno)); + dat_ok = FALSE; + } + } else { + fprintf(stderr, "could not stat file %s: %s\n", dat_name, strerror(errno)); + dat_ok = FALSE; + } + printf("message %s deleted\n", uid); - spool_unlock(uid); + spool_unlock(uid); - }else{ + } else { - fprintf(stderr, "message %s is locked.\n", uid); - return FALSE; - } + fprintf(stderr, "message %s is locked.\n", uid); + return FALSE; + } - return (dat_ok && hdr_ok); + return (dat_ok && hdr_ok); } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/readsock.c --- a/src/readsock.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/readsock.c Mon Oct 27 16:23:10 2008 +0100 @@ -27,156 +27,160 @@ jmp_buf jmp_timeout; -static -void sig_timeout_handler(int sig) +static void +sig_timeout_handler(int sig) { - longjmp(jmp_timeout, 1); + longjmp(jmp_timeout, 1); } static struct sigaction old_sa_alrm; -static -void alarm_on(int timeout) +static void +alarm_on(int timeout) { - struct sigaction sa; + struct sigaction sa; - sa.sa_handler = sig_timeout_handler; - sigemptyset(&(sa.sa_mask)); - sa.sa_flags = 0; - sigaction(SIGALRM, &sa, &old_sa_alrm); + sa.sa_handler = sig_timeout_handler; + sigemptyset(&(sa.sa_mask)); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, &old_sa_alrm); - if(timeout > 0) - alarm(timeout); + if (timeout > 0) + alarm(timeout); } -static -void alarm_off() +static void +alarm_off() { - alarm(0); + alarm(0); - sigaction(SIGALRM, &old_sa_alrm, NULL); + sigaction(SIGALRM, &old_sa_alrm, NULL); } -static -void _read_chug(FILE *in) +static void +_read_chug(FILE * in) { - int c = 0; + int c = 0; - c = fgetc(in); - while(isspace(c) && (c != EOF)) c = fgetc(in); - ungetc(c, in); + c = fgetc(in); + while (isspace(c) && (c != EOF)) + c = fgetc(in); + ungetc(c, in); } -static -int _read_line(FILE *in, char *buf, int buf_len, int timeout) +static int +_read_line(FILE * in, char *buf, int buf_len, int timeout) { - int p = 0; - int c = 0; + int p = 0; + int c = 0; - c = fgetc(in); - while((c != '\n') && (c != EOF) && (p < buf_len-1)){ - buf[p++] = c; - c = fgetc(in); - } + c = fgetc(in); + while ((c != '\n') && (c != EOF) && (p < buf_len - 1)) { + buf[p++] = c; + c = fgetc(in); + } - buf[p] = 0; + buf[p] = 0; - if(c == EOF) - return -1; - else if(p >= buf_len){ - ungetc(c, in); - return -2; - } + if (c == EOF) + return -1; + else if (p >= buf_len) { + ungetc(c, in); + return -2; + } - buf[p++] = c; /* \n */ - buf[p] = 0; + buf[p++] = c; /* \n */ + buf[p] = 0; - return p; + return p; } -int read_sockline(FILE *in, char *buf, int buf_len, int timeout, unsigned int flags) +int +read_sockline(FILE * in, char *buf, int buf_len, int timeout, unsigned int flags) { - int p = 0; + int p = 0; - if(setjmp(jmp_timeout) != 0){ - alarm_off(); - return -3; - } + if (setjmp(jmp_timeout) != 0) { + alarm_off(); + return -3; + } - alarm_on(timeout); + alarm_on(timeout); - /* strip leading spaces */ - if(flags & READSOCKL_CHUG){ - _read_chug(in); - } + /* strip leading spaces */ + if (flags & READSOCKL_CHUG) { + _read_chug(in); + } - p = _read_line(in, buf, buf_len, timeout); + p = _read_line(in, buf, buf_len, timeout); - alarm_off(); + alarm_off(); - if(p > 1){ - /* here we are sure that buf[p-1] == '\n' */ - if(flags & READSOCKL_CVT_CRLF){ - if((buf[p-2] == '\r') && (buf[p-1] == '\n')){ - buf[p-2] = '\n'; - buf[p-1] = 0; - p--; - } - } - } - return p; + if (p > 1) { + /* here we are sure that buf[p-1] == '\n' */ + if (flags & READSOCKL_CVT_CRLF) { + if ((buf[p - 2] == '\r') && (buf[p - 1] == '\n')) { + buf[p - 2] = '\n'; + buf[p - 1] = 0; + p--; + } + } + } + return p; } -int read_sockline1(FILE *in, char **pbuf, int *buf_len, int timeout, unsigned int flags) +int +read_sockline1(FILE * in, char **pbuf, int *buf_len, int timeout, unsigned int flags) { - int p = 0, size = *buf_len; - char *buf; + int p = 0, size = *buf_len; + char *buf; - if(setjmp(jmp_timeout) != 0){ - alarm_off(); - return -3; - } + if (setjmp(jmp_timeout) != 0) { + alarm_off(); + return -3; + } - alarm_on(timeout); + alarm_on(timeout); - /* strip leading spaces */ - if(flags & READSOCKL_CHUG){ - _read_chug(in); - } + /* strip leading spaces */ + if (flags & READSOCKL_CHUG) { + _read_chug(in); + } - if(!*pbuf) *pbuf = malloc(size); - buf = *pbuf; - - while(1){ - int pp; + if (!*pbuf) + *pbuf = malloc(size); + buf = *pbuf; - pp = _read_line(in, buf, size, timeout); - if(pp == -2){ - *pbuf = realloc(*pbuf, *buf_len + size); - buf = *pbuf + *buf_len; - *buf_len += size; - p += size; - } - else{ - if(pp > 0) p += pp; - else p = pp; - break; - } - } + while (1) { + int pp; - alarm_off(); + pp = _read_line(in, buf, size, timeout); + if (pp == -2) { + *pbuf = realloc(*pbuf, *buf_len + size); + buf = *pbuf + *buf_len; + *buf_len += size; + p += size; + } else { + if (pp > 0) + p += pp; + else + p = pp; + break; + } + } - if(p > 1){ - buf = *pbuf; - /* here we are sure that buf[p-1] == '\n' */ - if(flags & READSOCKL_CVT_CRLF){ - if((buf[p-2] == '\r') && (buf[p-1] == '\n')){ - buf[p-2] = '\n'; - buf[p-1] = 0; - p--; - } - } - } - return p; + alarm_off(); + + if (p > 1) { + buf = *pbuf; + /* here we are sure that buf[p-1] == '\n' */ + if (flags & READSOCKL_CVT_CRLF) { + if ((buf[p - 2] == '\r') && (buf[p - 1] == '\n')) { + buf[p - 2] = '\n'; + buf[p - 1] = 0; + p--; + } + } + } + return p; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/readsock.h --- a/src/readsock.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/readsock.h Mon Oct 27 16:23:10 2008 +0100 @@ -20,5 +20,5 @@ #define READSOCKL_CVT_CRLF 0x02 -int read_sockline(FILE *in, char *buf, int buf_len, int timeout, unsigned int flags); -int read_sockline1(FILE *in, char **pbuf, int *size, int timeout, unsigned int flags); +int read_sockline(FILE * in, char *buf, int buf_len, int timeout, unsigned int flags); +int read_sockline1(FILE * in, char **pbuf, int *size, int timeout, unsigned int flags); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/readtest.c --- a/src/readtest.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/readtest.c Mon Oct 27 16:23:10 2008 +0100 @@ -2,18 +2,17 @@ #include "masqmail.h" #include "readsock.h" -int main() +int +main() { - char *buf = g_malloc(20); - int size = 20, ret; + char *buf = g_malloc(20); + int size = 20, ret; - ret = read_sockline1(stdin, &buf, &size, 60, READSOCKL_CVT_CRLF); - // ret = read_sockline(stdin, buf, size, 60, READSOCKL_CHUG); + ret = read_sockline1(stdin, &buf, &size, 60, READSOCKL_CVT_CRLF); + // ret = read_sockline(stdin, buf, size, 60, READSOCKL_CHUG); - printf("%s\n", buf); - printf("ret = %d, size = %d, strlen = %d\n", ret, size, strlen(buf)); + printf("%s\n", buf); + printf("ret = %d, size = %d, strlen = %d\n", ret, size, strlen(buf)); - return 0; + return 0; } - - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/rewrite.c --- a/src/rewrite.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/rewrite.c Mon Oct 27 16:23:10 2008 +0100 @@ -20,81 +20,78 @@ #include "masqmail.h" #endif -gboolean set_address_header_domain(header *hdr, gchar *domain) +gboolean +set_address_header_domain(header * hdr, gchar * domain) { - gchar *p = hdr->value; - gchar *new_hdr = g_strndup(hdr->header, hdr->value - hdr->header); - gint tmp; + gchar *p = hdr->value; + gchar *new_hdr = g_strndup(hdr->header, hdr->value - hdr->header); + gint tmp; - while(*p){ - gchar *loc_beg, *loc_end; - gchar *dom_beg, *dom_end; - gchar *addr_end; - gchar *rewr_string; + while (*p) { + gchar *loc_beg, *loc_end; + gchar *dom_beg, *dom_end; + gchar *addr_end; + gchar *rewr_string; - if(parse_address_rfc822(p, - &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end)){ - gchar *left, *right; + if (parse_address_rfc822(p, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end)) { + gchar *left, *right; - if(dom_beg != NULL){ - left = g_strndup(p, dom_beg - p); - right = g_strndup(dom_end, addr_end - dom_end); + if (dom_beg != NULL) { + left = g_strndup(p, dom_beg - p); + right = g_strndup(dom_end, addr_end - dom_end); - rewr_string = g_strconcat(left, domain, right, NULL); - }else{ - left = g_strndup(p, loc_end - p); - right = g_strndup(loc_end, addr_end - loc_end); + rewr_string = g_strconcat(left, domain, right, NULL); + } else { + left = g_strndup(p, loc_end - p); + right = g_strndup(loc_end, addr_end - loc_end); - rewr_string = g_strconcat(left, "@", domain, right, NULL); - } - g_free(left); - g_free(right); + rewr_string = g_strconcat(left, "@", domain, right, NULL); + } + g_free(left); + g_free(right); - p = addr_end; - if(*p == ',') p++; + p = addr_end; + if (*p == ',') + p++; - new_hdr = - g_strconcat(new_hdr, rewr_string, - *p != 0 ? "," : NULL, NULL); + new_hdr = g_strconcat(new_hdr, rewr_string, *p != 0 ? "," : NULL, NULL); - }else - return FALSE; - } - tmp = (hdr->value - hdr->header); - g_free(hdr->header); - hdr->header = new_hdr; - hdr->value = hdr->header + tmp; + } else + return FALSE; + } + tmp = (hdr->value - hdr->header); + g_free(hdr->header); + hdr->header = new_hdr; + hdr->value = hdr->header + tmp; - return TRUE; + return TRUE; } -gboolean map_address_header(header *hdr, GList *table) +gboolean +map_address_header(header * hdr, GList * table) { - GList *addr_list = addr_list_append_rfc822(NULL, hdr->value, conf.host_name); - GList *addr_node; - gchar *new_hdr = g_strndup(hdr->header, hdr->value - hdr->header); - gboolean did_change = FALSE; + GList *addr_list = addr_list_append_rfc822(NULL, hdr->value, conf.host_name); + GList *addr_node; + gchar *new_hdr = g_strndup(hdr->header, hdr->value - hdr->header); + gboolean did_change = FALSE; - foreach(addr_list, addr_node){ - address *addr = (address *)(addr_node->data); - gchar *rewr_string = (gchar *)table_find_fnmatch(table, addr->local_part); + foreach(addr_list, addr_node) { + address *addr = (address *) (addr_node->data); + gchar *rewr_string = (gchar *) table_find_fnmatch(table, addr->local_part); - if(rewr_string == NULL) - rewr_string = addr->address; - else - did_change = TRUE; + if (rewr_string == NULL) + rewr_string = addr->address; + else + did_change = TRUE; - if(rewr_string) - new_hdr = - g_strconcat(new_hdr, rewr_string, - g_list_next(addr_node) ? "," : "\n", NULL); - } - if(did_change){ - g_free(hdr->header); - hdr->header = new_hdr; - }else - g_free(new_hdr); + if (rewr_string) + new_hdr = g_strconcat(new_hdr, rewr_string, g_list_next(addr_node) ? "," : "\n", NULL); + } + if (did_change) { + g_free(hdr->header); + hdr->header = new_hdr; + } else + g_free(new_hdr); - return did_change; + return did_change; } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/route.c --- a/src/route.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/route.c Mon Oct 27 16:23:10 2008 +0100 @@ -19,347 +19,335 @@ #include "masqmail.h" #include -msgout_perhost *create_msgout_perhost(gchar *host) +msgout_perhost* +create_msgout_perhost(gchar * host) { - msgout_perhost *mo_ph = g_malloc(sizeof(msgout_perhost)); - if(mo_ph){ - mo_ph->host = g_strdup(host); - mo_ph->msgout_list = NULL; - } - return mo_ph; + msgout_perhost *mo_ph = g_malloc(sizeof(msgout_perhost)); + if (mo_ph) { + mo_ph->host = g_strdup(host); + mo_ph->msgout_list = NULL; + } + return mo_ph; } -void destroy_msgout_perhost(msgout_perhost *mo_ph) +void +destroy_msgout_perhost(msgout_perhost * mo_ph) { - GList *mo_node; + GList *mo_node; - foreach(mo_ph->msgout_list, mo_node){ - msg_out *mo = (msg_out *)(mo_node->data); - /* the rcpt_list is owned by the msgout's, - but not the rcpt's themselves */ - g_list_free(mo->rcpt_list); - g_free(mo); - } - g_list_free(mo_ph->msgout_list); - g_free(mo_ph); + foreach(mo_ph->msgout_list, mo_node) { + msg_out *mo = (msg_out *) (mo_node->data); + /* the rcpt_list is owned by the msgout's, but not the rcpt's themselves */ + g_list_free(mo->rcpt_list); + g_free(mo); + } + g_list_free(mo_ph->msgout_list); + g_free(mo_ph); } -void rewrite_headers(msg_out *msgout, connect_route *route) +void +rewrite_headers(msg_out * msgout, connect_route * route) { - /* if set_h_from_domain is set, replace domain in all - From: headers. - */ - msgout->hdr_list = g_list_copy(msgout->msg->hdr_list); + /* if set_h_from_domain is set, replace domain in all + From: headers. + */ + msgout->hdr_list = g_list_copy(msgout->msg->hdr_list); - /* map from addresses */ - if(route->map_h_from_addresses != NULL){ - GList *hdr_node; - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(hdr->id == HEAD_FROM){ - header *new_hdr = copy_header(hdr); - if(map_address_header(new_hdr, route->map_h_from_addresses)){ - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - msgout->xtra_hdr_list = - g_list_append(msgout->xtra_hdr_list, new_hdr); - }else - g_free(new_hdr); - } - } - }else{ - /* replace from domain */ - if(route->set_h_from_domain != NULL){ - GList *hdr_node; - - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(hdr->id == HEAD_FROM){ - header *new_hdr = copy_header(hdr); - - DEBUG(5) debugf("setting From: domain to %s\n", - route->set_h_from_domain); - if(set_address_header_domain(new_hdr, route->set_h_from_domain)){ - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - DEBUG(6) debugf("header = %s\n", - new_hdr->header); - msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); - }else{ - logwrite(LOG_ALERT, "error in set_address_header_domain(%s, %s)\n", - new_hdr->value, route->set_h_from_domain); - } + /* map from addresses */ + if (route->map_h_from_addresses != NULL) { + GList *hdr_node; + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (hdr->id == HEAD_FROM) { + header *new_hdr = copy_header(hdr); + if (map_address_header(new_hdr, route->map_h_from_addresses)) { + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } else + g_free(new_hdr); + } + } + } else { + /* replace from domain */ + if (route->set_h_from_domain != NULL) { + GList *hdr_node; + + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (hdr->id == HEAD_FROM) { + header *new_hdr = copy_header(hdr); + + DEBUG(5) debugf("setting From: domain to %s\n", route->set_h_from_domain); + if (set_address_header_domain(new_hdr, route->set_h_from_domain)) { + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + DEBUG(6) debugf("header = %s\n", new_hdr->header); + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } else { + logwrite(LOG_ALERT, "error in set_address_header_domain(%s, %s)\n", new_hdr->value, route->set_h_from_domain); + } + } + } + } } - } - } - } - /* map reply-to addresses */ - if(route->map_h_reply_to_addresses != NULL){ - GList *hdr_node; - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(hdr->id == HEAD_REPLY_TO){ - header *new_hdr = copy_header(hdr); - if(map_address_header(new_hdr, route->map_h_reply_to_addresses)){ - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - msgout->xtra_hdr_list = - g_list_append(msgout->xtra_hdr_list, new_hdr); - }else - g_free(new_hdr); - } - } - }else{ - /* replace Reply-to domain */ - if(route->set_h_reply_to_domain != NULL){ - GList *hdr_node; - - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(hdr->id == HEAD_REPLY_TO){ - header *new_hdr = copy_header(hdr); - - set_address_header_domain(new_hdr, route->set_h_reply_to_domain); - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + /* map reply-to addresses */ + if (route->map_h_reply_to_addresses != NULL) { + GList *hdr_node; + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (hdr->id == HEAD_REPLY_TO) { + header *new_hdr = copy_header(hdr); + if (map_address_header + (new_hdr, route->map_h_reply_to_addresses)) { + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } else + g_free(new_hdr); + } + } + } else { + /* replace Reply-to domain */ + if (route->set_h_reply_to_domain != NULL) { + GList *hdr_node; + + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (hdr->id == HEAD_REPLY_TO) { + header *new_hdr = copy_header(hdr); + + set_address_header_domain(new_hdr, route-> set_h_reply_to_domain); + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } + } + } } - } - } - } - /* map Mail-Followup-To addresses */ - if(route->map_h_mail_followup_to_addresses != NULL){ - GList *hdr_node; - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(strncasecmp(hdr->header, "Mail-Followup-To", 16) == 0){ - header *new_hdr = copy_header(hdr); - if(map_address_header(new_hdr, route->map_h_mail_followup_to_addresses)){ - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - msgout->xtra_hdr_list = - g_list_append(msgout->xtra_hdr_list, new_hdr); - }else - g_free(new_hdr); - } - } - } + /* map Mail-Followup-To addresses */ + if (route->map_h_mail_followup_to_addresses != NULL) { + GList *hdr_node; + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (strncasecmp(hdr->header, "Mail-Followup-To", 16) == 0) { + header *new_hdr = copy_header(hdr); + if (map_address_header(new_hdr, route->map_h_mail_followup_to_addresses)) { + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } else + g_free(new_hdr); + } + } + } - /* set Sender: domain to return_path->domain */ - if(route->expand_h_sender_domain){ - GList *hdr_node; + /* set Sender: domain to return_path->domain */ + if (route->expand_h_sender_domain) { + GList *hdr_node; - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(hdr->id == HEAD_SENDER){ - header *new_hdr = copy_header(hdr); + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (hdr->id == HEAD_SENDER) { + header *new_hdr = copy_header(hdr); - set_address_header_domain(new_hdr, msgout->return_path->domain); - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); - } - } - } + set_address_header_domain(new_hdr, msgout->return_path->domain); + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } + } + } - /* set Sender: domain to return_path->domain */ - if(route->expand_h_sender_address){ - GList *hdr_node; + /* set Sender: domain to return_path->domain */ + if (route->expand_h_sender_address) { + GList *hdr_node; - foreach(msgout->hdr_list, hdr_node){ - header *hdr = (header *)(hdr_node->data); - if(hdr->id == HEAD_SENDER){ - header *new_hdr; + foreach(msgout->hdr_list, hdr_node) { + header *hdr = (header *) (hdr_node->data); + if (hdr->id == HEAD_SENDER) { + header *new_hdr; - new_hdr = - create_header(HEAD_SENDER, "Sender: %s@%s\n", - msgout->return_path->local_part, msgout->return_path->domain); - hdr_node->data = new_hdr; - /* we need this list only to carefully free the extra headers: */ - msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); - } - } - } + new_hdr = create_header(HEAD_SENDER, "Sender: %s@%s\n", msgout->return_path->local_part, msgout->return_path->domain); + hdr_node->data = new_hdr; + /* we need this list only to carefully free the extra headers: */ + msgout->xtra_hdr_list = g_list_append(msgout->xtra_hdr_list, new_hdr); + } + } + } - if(msgout->xtra_hdr_list == NULL){ - /* nothing was changed */ - g_list_free(msgout->hdr_list); - msgout->hdr_list = NULL; - } - DEBUG(5) debugf("rewrite_headers() returning\n"); + if (msgout->xtra_hdr_list == NULL) { + /* nothing was changed */ + g_list_free(msgout->hdr_list); + msgout->hdr_list = NULL; + } + DEBUG(5) debugf("rewrite_headers() returning\n"); } -void rcptlist_with_one_of_hostlist(GList *rcpt_list, GList *host_list, - GList **p_rcpt_list, GList **p_non_rcpt_list) +void +rcptlist_with_one_of_hostlist(GList * rcpt_list, GList * host_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list) { - GList *rcpt_node; + GList *rcpt_node; - if(rcpt_list == NULL) - return; + if (rcpt_list == NULL) + return; - foreach(rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - GList *host_node = NULL; + foreach(rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + GList *host_node = NULL; - foreach(host_list, host_node){ - gchar *host = (gchar *)(host_node->data); - if(fnmatch(host, rcpt->domain, FNM_CASEFOLD) == 0) - break; - } - if(host_node){ - if(p_rcpt_list) - *p_rcpt_list = g_list_append(*p_rcpt_list, rcpt); - }else{ - if(p_non_rcpt_list) - *p_non_rcpt_list = g_list_append(*p_non_rcpt_list, rcpt); - } + foreach(host_list, host_node) { + gchar *host = (gchar *) (host_node->data); + if (fnmatch(host, rcpt->domain, FNM_CASEFOLD) == 0) + break; + } + if (host_node) { + if (p_rcpt_list) + *p_rcpt_list = g_list_append(*p_rcpt_list, rcpt); + } else { + if (p_non_rcpt_list) + *p_non_rcpt_list = g_list_append(*p_non_rcpt_list, rcpt); + } - } + } } -void rcptlist_with_addr_is_local(GList *rcpt_list, - GList **p_rcpt_list, GList **p_non_rcpt_list) +void +rcptlist_with_addr_is_local(GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list) { - GList *rcpt_node; + GList *rcpt_node; - if(rcpt_list == NULL) - return; + if (rcpt_list == NULL) + return; - foreach(rcpt_list, rcpt_node){ - address *rcpt = (address *)(rcpt_node->data); - if(addr_is_local(rcpt)){ - if(p_rcpt_list) - *p_rcpt_list = g_list_append(*p_rcpt_list, rcpt); - }else{ - if(p_non_rcpt_list) - *p_non_rcpt_list = g_list_append(*p_non_rcpt_list, rcpt); - } + foreach(rcpt_list, rcpt_node) { + address *rcpt = (address *) (rcpt_node->data); + if (addr_is_local(rcpt)) { + if (p_rcpt_list) + *p_rcpt_list = g_list_append(*p_rcpt_list, rcpt); + } else { + if (p_non_rcpt_list) + *p_non_rcpt_list = g_list_append(*p_non_rcpt_list, rcpt); + } - } + } } -static gint _g_list_addrcmp(gconstpointer a, gconstpointer b) +static gint +_g_list_addrcmp(gconstpointer a, gconstpointer b) { - return addr_match((address *)a, (address *)b); + return addr_match((address *) a, (address *) b); } -gboolean route_is_allowed_return_path(connect_route *route, address *ret_path) +gboolean +route_is_allowed_return_path(connect_route * route, address * ret_path) { - if(route->not_allowed_return_paths != NULL){ - if(g_list_find_custom(route->not_allowed_return_paths, ret_path, - _g_list_addrcmp) != NULL){ - return FALSE; - } - } - if(route->allowed_return_paths != NULL){ - if(g_list_find_custom(route->allowed_return_paths, ret_path, - _g_list_addrcmp) != NULL){ - return TRUE; - }else{ - return FALSE; - } - } - return TRUE; + if (route->not_allowed_return_paths != NULL) { + if (g_list_find_custom(route->not_allowed_return_paths, ret_path, _g_list_addrcmp) != NULL) { + return FALSE; + } + } + if (route->allowed_return_paths != NULL) { + if (g_list_find_custom(route->allowed_return_paths, ret_path, _g_list_addrcmp) != NULL) { + return TRUE; + } else { + return FALSE; + } + } + return TRUE; } -static gint _g_list_strcmp(gconstpointer a, gconstpointer b) +static gint +_g_list_strcmp(gconstpointer a, gconstpointer b) { - return (gint)strcmp(a, b); + return (gint) strcmp(a, b); } -gboolean route_is_allowed_mail_local(connect_route *route, address *ret_path) +gboolean +route_is_allowed_mail_local(connect_route * route, address * ret_path) { - gchar *loc_part = ret_path->local_part; + gchar *loc_part = ret_path->local_part; - if(route->not_allowed_mail_locals != NULL){ - if(g_list_find_custom(route->not_allowed_mail_locals, loc_part, - _g_list_strcmp) != NULL) - return FALSE; - } - if(route->allowed_mail_locals != NULL){ - if(g_list_find_custom(route->allowed_mail_locals, loc_part, - _g_list_strcmp) != NULL) - return TRUE; - else - return FALSE; - } - return TRUE; + if (route->not_allowed_mail_locals != NULL) { + if (g_list_find_custom(route->not_allowed_mail_locals, loc_part, _g_list_strcmp) != NULL) + return FALSE; + } + if (route->allowed_mail_locals != NULL) { + if (g_list_find_custom(route->allowed_mail_locals, loc_part, _g_list_strcmp) != NULL) + return TRUE; + else + return FALSE; + } + return TRUE; } -/* +/* Make lists of matching/not matching rcpts. Local domains are NOT regared here, these should be sorted out previously */ -void msg_rcptlist_route(connect_route *route, GList *rcpt_list, - GList **p_rcpt_list, GList **p_non_rcpt_list) +void +msg_rcptlist_route(connect_route * route, GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list) { - GList *tmp_list = NULL; - /* sort out those domains that can be sent over this connection: */ - if(route->allowed_rcpt_domains){ - DEBUG(5) debugf("testing for route->allowed_rcpt_domains\n"); - rcptlist_with_one_of_hostlist(rcpt_list, route->allowed_rcpt_domains, &tmp_list, p_non_rcpt_list); - }else{ - DEBUG(5) debugf("route->allowed_rcpt_domains == NULL\n"); - tmp_list = g_list_copy(rcpt_list); - } + GList *tmp_list = NULL; + /* sort out those domains that can be sent over this connection: */ + if (route->allowed_rcpt_domains) { + DEBUG(5) debugf("testing for route->allowed_rcpt_domains\n"); + rcptlist_with_one_of_hostlist(rcpt_list, route->allowed_rcpt_domains, &tmp_list, p_non_rcpt_list); + } else { + DEBUG(5) debugf("route->allowed_rcpt_domains == NULL\n"); + tmp_list = g_list_copy(rcpt_list); + } - /* sort out those domains that cannot be sent over this connection: */ - rcptlist_with_one_of_hostlist(tmp_list, route->not_allowed_rcpt_domains, p_non_rcpt_list, p_rcpt_list); - g_list_free(tmp_list); + /* sort out those domains that cannot be sent over this connection: */ + rcptlist_with_one_of_hostlist(tmp_list, route->not_allowed_rcpt_domains, p_non_rcpt_list, p_rcpt_list); + g_list_free(tmp_list); } -msg_out *route_prepare_msgout(connect_route *route, msg_out *msgout) +msg_out* +route_prepare_msgout(connect_route * route, msg_out * msgout) { - message *msg = msgout->msg; - GList *rcpt_list = msgout->rcpt_list; + message *msg = msgout->msg; + GList *rcpt_list = msgout->rcpt_list; - if(rcpt_list != NULL){ - /* found a few */ - DEBUG(5){ - GList *node; - debugf("rcpts for routed delivery, route = %s, id = %s\n", route->name, msg->uid); - foreach(rcpt_list, node){ - address *rcpt = (address *)(node->data); - debugf("rcpt for routed delivery: <%s@%s>\n", - rcpt->local_part, rcpt->domain); - } - } - - /* rewrite return path - if there is a table, use that - if an address is found and if it has a domain, use that - */ - if(route->map_return_path_addresses){ - address *ret_path = NULL; - DEBUG(5) debugf("looking up %s in map_return_path_addresses\n", - msg->return_path->local_part); - ret_path = - (address *)table_find_fnmatch(route->map_return_path_addresses, - msg->return_path->local_part); - if(ret_path){ - DEBUG(5) debugf("found <%s@%s>\n", - ret_path->local_part, ret_path->domain); - if(ret_path->domain == NULL) - ret_path->domain = - route->set_return_path_domain ? - route->set_return_path_domain : msg->return_path->domain; - msgout->return_path = copy_address(ret_path); - } - } - if(msgout->return_path == NULL){ - DEBUG(5) debugf("setting return path to %s\n", - route->set_return_path_domain); - msgout->return_path = - copy_modify_address(msg->return_path, - NULL, route->set_return_path_domain); - } - rewrite_headers(msgout, route); + if (rcpt_list != NULL) { + /* found a few */ + DEBUG(5) { + GList *node; + debugf("rcpts for routed delivery, route = %s, id = %s\n", route->name, msg->uid); + foreach(rcpt_list, node) { + address *rcpt = (address *) (node->data); + debugf("rcpt for routed delivery: <%s@%s>\n", rcpt->local_part, rcpt->domain); + } + } - return msgout; - } - return NULL; + /* rewrite return path + if there is a table, use that + if an address is found and if it has a domain, use that + */ + if (route->map_return_path_addresses) { + address *ret_path = NULL; + DEBUG(5) debugf("looking up %s in map_return_path_addresses\n", msg->return_path->local_part); + ret_path = (address *) table_find_fnmatch(route->map_return_path_addresses, msg->return_path->local_part); + if (ret_path) { + DEBUG(5) debugf("found <%s@%s>\n", ret_path->local_part, ret_path->domain); + if (ret_path->domain == NULL) + ret_path->domain = route->set_return_path_domain + ? route->set_return_path_domain + : msg->return_path->domain; + msgout->return_path = copy_address(ret_path); + } + } + if (msgout->return_path == NULL) { + DEBUG(5) debugf("setting return path to %s\n", route->set_return_path_domain); + msgout->return_path = copy_modify_address(msg->return_path, NULL, route->set_return_path_domain); + } + rewrite_headers(msgout, route); + + return msgout; + } + return NULL; } /* put msgout's is msgout_list into bins (msgout_perhost structs) for each @@ -367,70 +355,66 @@ route param is not used, we leave it here because that may change. */ -GList *route_msgout_list(connect_route *route, GList *msgout_list) +GList* +route_msgout_list(connect_route * route, GList * msgout_list) { - GList *mo_ph_list = NULL; - GList *msgout_node; + GList *mo_ph_list = NULL; + GList *msgout_node; - foreach(msgout_list, msgout_node){ - msg_out *msgout = (msg_out *)(msgout_node->data); - msg_out *msgout_new; - GList *rcpt_list = msgout->rcpt_list; - GList *rcpt_node; + foreach(msgout_list, msgout_node) { + msg_out *msgout = (msg_out *) (msgout_node->data); + msg_out *msgout_new; + GList *rcpt_list = msgout->rcpt_list; + GList *rcpt_node; - foreach(rcpt_list, rcpt_node){ - address *rcpt = rcpt_node->data; - msgout_perhost *mo_ph = NULL; - GList *mo_ph_node = NULL; + foreach(rcpt_list, rcpt_node) { + address *rcpt = rcpt_node->data; + msgout_perhost *mo_ph = NULL; + GList *mo_ph_node = NULL; - /* search host in mo_ph_list */ - foreach(mo_ph_list, mo_ph_node){ - mo_ph = (msgout_perhost *)(mo_ph_node->data); - if(strcasecmp(mo_ph->host, rcpt->domain) == 0) - break; - } - if(mo_ph_node != NULL){ - /* there is already a rcpt for this host */ - msg_out *msgout_last = - (msg_out *)((g_list_last(mo_ph->msgout_list))->data); - if(msgout_last->msg == msgout->msg){ - /* if it is also the same message, it must be the last one - appended to mo_ph->msgout_list (since outer loop goes through - msgout_list) */ - msgout_last->rcpt_list = - g_list_append(msgout_last->rcpt_list, rcpt); - }else{ - /* if not, we append a new msgout */ - /* make a copy of msgout */ - msgout_new = create_msg_out(msgout->msg); - msgout_new->return_path = msgout->return_path; - msgout_new->hdr_list = msgout->hdr_list; + /* search host in mo_ph_list */ + foreach(mo_ph_list, mo_ph_node) { + mo_ph = (msgout_perhost *) (mo_ph_node->data); + if (strcasecmp(mo_ph->host, rcpt->domain) == 0) + break; + } + if (mo_ph_node != NULL) { + /* there is already a rcpt for this host */ + msg_out *msgout_last = (msg_out *) ((g_list_last(mo_ph->msgout_list))->data); + if (msgout_last->msg == msgout->msg) { + /* if it is also the same message, it must be the last one + appended to mo_ph->msgout_list (since outer loop goes through + msgout_list) */ + msgout_last->rcpt_list = g_list_append(msgout_last->rcpt_list, rcpt); + } else { + /* if not, we append a new msgout */ + /* make a copy of msgout */ + msgout_new = create_msg_out(msgout->msg); + msgout_new->return_path = msgout->return_path; + msgout_new->hdr_list = msgout->hdr_list; - /* append our rcpt to it */ - /* It is the 1st rcpt for this msg to this host, - therefore we safely give NULL */ - msgout_new->rcpt_list = g_list_append(NULL, rcpt); - mo_ph->msgout_list = - g_list_append(mo_ph->msgout_list, msgout_new); - } - }else{ - /* this rcpt to goes to another host */ - mo_ph = create_msgout_perhost(rcpt->domain); - mo_ph_list = g_list_append(mo_ph_list, mo_ph); + /* append our rcpt to it */ + /* It is the 1st rcpt for this msg to this host, therefore we safely give NULL */ + msgout_new->rcpt_list = g_list_append(NULL, rcpt); + mo_ph->msgout_list = g_list_append(mo_ph->msgout_list, msgout_new); + } + } else { + /* this rcpt to goes to another host */ + mo_ph = create_msgout_perhost(rcpt->domain); + mo_ph_list = g_list_append(mo_ph_list, mo_ph); - /* make a copy of msgout */ - msgout_new = create_msg_out(msgout->msg); - msgout_new->return_path = msgout->return_path; - msgout_new->hdr_list = msgout->hdr_list; - - /* append our rcpt to it */ - /* It is the 1st rcpt for this msg to this host, - therefore we safely give NULL */ - msgout_new->rcpt_list = g_list_append(NULL, rcpt); - mo_ph->msgout_list = g_list_append(mo_ph->msgout_list, msgout_new); - }/* if mo_ph != NULL */ - }/* foreach(rcpt_list, ... */ - }/* foreach(msgout_list, ... */ + /* make a copy of msgout */ + msgout_new = create_msg_out(msgout->msg); + msgout_new->return_path = msgout->return_path; + msgout_new->hdr_list = msgout->hdr_list; - return mo_ph_list; + /* append our rcpt to it */ + /* It is the 1st rcpt for this msg to this host, therefore we safely give NULL */ + msgout_new->rcpt_list = g_list_append(NULL, rcpt); + mo_ph->msgout_list = g_list_append(mo_ph->msgout_list, msgout_new); + } /* if mo_ph != NULL */ + } /* foreach(rcpt_list, ... */ + } /* foreach(msgout_list, ... */ + + return mo_ph_list; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/smtp_in.c --- a/src/smtp_in.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/smtp_in.c Mon Oct 27 16:23:10 2008 +0100 @@ -30,329 +30,329 @@ #ifdef ENABLE_SMTP_SERVER -smtp_cmd smtp_cmds[] = -{ - { SMTP_HELO, "HELO", }, - { SMTP_EHLO, "EHLO", }, - { SMTP_MAIL_FROM, "MAIL FROM:", }, - { SMTP_RCPT_TO, "RCPT TO:", }, - { SMTP_DATA, "DATA", }, - { SMTP_QUIT, "QUIT", }, - { SMTP_RSET, "RSET", }, - { SMTP_NOOP, "NOOP", }, - { SMTP_HELP, "HELP" }, +smtp_cmd smtp_cmds[] = { + {SMTP_HELO, "HELO",} + , + {SMTP_EHLO, "EHLO",} + , + {SMTP_MAIL_FROM, "MAIL FROM:",} + , + {SMTP_RCPT_TO, "RCPT TO:",} + , + {SMTP_DATA, "DATA",} + , + {SMTP_QUIT, "QUIT",} + , + {SMTP_RSET, "RSET",} + , + {SMTP_NOOP, "NOOP",} + , + {SMTP_HELP, "HELP"} + , }; -static -smtp_cmd_id get_id(const gchar *line) +static smtp_cmd_id +get_id(const gchar * line) { - gint i; - for(i = 0; i < SMTP_NUM_IDS; i++){ - if(strncasecmp(smtp_cmds[i].cmd, line, strlen(smtp_cmds[i].cmd)) == 0) - return (smtp_cmd_id)i; - } - return SMTP_ERROR; + gint i; + for (i = 0; i < SMTP_NUM_IDS; i++) { + if (strncasecmp(smtp_cmds[i].cmd, line, strlen(smtp_cmds[i].cmd)) == 0) + return (smtp_cmd_id) i; + } + return SMTP_ERROR; } /* this is a quick hack: we expect the address to be syntactically correct and containing the mailbox only: */ -static -gboolean get_address(gchar *line, gchar *addr) +static gboolean +get_address(gchar * line, gchar * addr) { - gchar *p = line, *q = addr; + gchar *p = line, *q = addr; - /* skip MAIL FROM: and RCPT TO: */ - while(*p && (*p != ':')) p++; - p++; + /* skip MAIL FROM: and RCPT TO: */ + while (*p && (*p != ':')) + p++; + p++; - /* skip spaces: */ - while(*p && isspace(*p)) p++; + /* skip spaces: */ + while (*p && isspace(*p)) + p++; - /* get address: */ - while(*p && !isspace(*p) && (q < addr+MAX_ADDRESS-1)) *(q++) = *(p++); - *q = 0; + /* get address: */ + while (*p && !isspace(*p) && (q < addr + MAX_ADDRESS - 1)) + *(q++) = *(p++); + *q = 0; - return TRUE; + return TRUE; } -static -smtp_connection *create_base(gchar *remote_host) +static smtp_connection* +create_base(gchar * remote_host) { - smtp_connection *base = g_malloc(sizeof(smtp_connection)); - if(base){ - base->remote_host = g_strdup(remote_host); + smtp_connection *base = g_malloc(sizeof(smtp_connection)); + if (base) { + base->remote_host = g_strdup(remote_host); - base->prot = PROT_SMTP; - base->next_id = 0; - base->helo_seen = 0; - base->from_seen = 0; - base->rcpt_seen = 0; - base->msg = NULL; + base->prot = PROT_SMTP; + base->next_id = 0; + base->helo_seen = 0; + base->from_seen = 0; + base->rcpt_seen = 0; + base->msg = NULL; - return base; - } - return NULL; + return base; + } + return NULL; } -static -void smtp_printf(FILE *out, gchar *fmt, ...) +static void +smtp_printf(FILE * out, gchar * fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - DEBUG(4){ - gchar buf[256]; - va_list args_copy; + DEBUG(4) { + gchar buf[256]; + va_list args_copy; - va_copy(args_copy, args); - vsnprintf(buf, 255, fmt, args_copy); - va_end(args_copy); + va_copy(args_copy, args); + vsnprintf(buf, 255, fmt, args_copy); + va_end(args_copy); - debugf(">>>%s", buf); - } + debugf(">>>%s", buf); + } - vfprintf(out, fmt, args); fflush(out); + vfprintf(out, fmt, args); + fflush(out); - va_end(args); + va_end(args); } -void smtp_in(FILE *in, FILE *out, gchar *remote_host, gchar *ident) +void +smtp_in(FILE * in, FILE * out, gchar * remote_host, gchar * ident) { - gchar *buffer; - smtp_cmd_id cmd_id; - message *msg = NULL; - smtp_connection *psc; - int len; + gchar *buffer; + smtp_cmd_id cmd_id; + message *msg = NULL; + smtp_connection *psc; + int len; - DEBUG(5) debugf("smtp_in entered, remote_host = %s\n", remote_host); + DEBUG(5) debugf("smtp_in entered, remote_host = %s\n", remote_host); - psc = create_base(remote_host); - psc->msg = msg; + psc = create_base(remote_host); + psc->msg = msg; - buffer = (gchar *)g_malloc(BUF_LEN); - if(buffer){ - /* send greeting string, containing ESMTP: */ - smtp_printf(out, "220 %s MasqMail %s ESMTP\r\n", - conf.host_name, VERSION); - - while((len = read_sockline(in, buffer, BUF_LEN, 5*60, READSOCKL_CHUG)) >= 0){ - cmd_id = get_id(buffer); - - switch(cmd_id){ - case SMTP_EHLO: - psc->prot = PROT_ESMTP; - /* fall through */ - case SMTP_HELO: - psc->helo_seen = TRUE; + buffer = (gchar *) g_malloc(BUF_LEN); + if (buffer) { + /* send greeting string, containing ESMTP: */ + smtp_printf(out, "220 %s MasqMail %s ESMTP\r\n", conf.host_name, VERSION); - if(!conf.defer_all){ /* I need this to debug delivery failures */ - if(psc->prot == PROT_ESMTP){ - smtp_printf(out, "250-%s Nice to meet you with ESMTP\r\n", - conf.host_name); - /* not yet: fprintf(out, "250-SIZE\r\n"); */ - smtp_printf(out, - "250-PIPELINING\r\n" - "250 HELP\r\n"); - }else{ - smtp_printf(out, "250 %s pretty old mailer, huh?\r\n", - conf.host_name); - } - break; - }else{ - smtp_printf(out, "421 %s service temporarily unavailable.\r\n", - conf.host_name); + while ((len = read_sockline(in, buffer, BUF_LEN, 5 * 60, READSOCKL_CHUG)) >= 0) { + cmd_id = get_id(buffer); + + switch (cmd_id) { + case SMTP_EHLO: + psc->prot = PROT_ESMTP; + /* fall through */ + case SMTP_HELO: + psc->helo_seen = TRUE; + + if (!conf.defer_all) { /* I need this to debug delivery failures */ + if (psc->prot == PROT_ESMTP) { + smtp_printf(out, "250-%s Nice to meet you with ESMTP\r\n", conf.host_name); + /* not yet: fprintf(out, "250-SIZE\r\n"); */ + smtp_printf(out, "250-PIPELINING\r\n" "250 HELP\r\n"); + } else { + smtp_printf(out, "250 %s pretty old mailer, huh?\r\n", conf.host_name); + } + break; + } else { + smtp_printf(out, "421 %s service temporarily unavailable.\r\n", conf.host_name); + } + + case SMTP_MAIL_FROM: + if (psc->helo_seen && !psc->from_seen) { + gchar buf[MAX_ADDRESS]; + address *addr; + + msg = create_message(); + msg->received_host = remote_host ? g_strdup(remote_host) : NULL; + msg->received_prot = psc->prot; + msg->ident = ident ? g_strdup(ident) : NULL; + /* get transfer id and increment for next one */ + msg->transfer_id = (psc->next_id)++; + + get_address(buffer, buf); + if ((addr = remote_host + ? create_address(buf, TRUE) + : create_address_qualified(buf, TRUE, conf.host_name))) { + if (addr->domain != NULL) { + psc->from_seen = TRUE; + msg->return_path = addr; + smtp_printf(out, "250 OK %s is a nice guy.\r\n", addr->address); + } else { + smtp_printf(out, "501 return path must be qualified.\r\n", buf); + } + } else { + smtp_printf(out, "501 %s: syntax error.\r\n", buf); + } + } else { + if (!psc->helo_seen) + smtp_printf(out, "503 need HELO or EHLO\r\n"); + else + smtp_printf(out, "503 MAIL FROM: already given.\r\n"); + } + break; + + case SMTP_RCPT_TO: + + if (psc->helo_seen && psc->from_seen) { + char buf[MAX_ADDRESS]; + address *addr; + + get_address(buffer, buf); + if ((addr = remote_host + ? create_address(buf, TRUE) + : create_address_qualified(buf, TRUE, conf.host_name))) { + if (addr->local_part[0] != '|') { + if (addr->domain != NULL) { + gboolean do_relay = conf.do_relay; + if (!do_relay) { + if ((do_relay = addr_is_local(msg->return_path))) { + } + if (!do_relay) { + do_relay = addr_is_local(addr); + } + } + if (do_relay) { + psc->rcpt_seen = TRUE; + msg->rcpt_list = g_list_append(msg->rcpt_list, addr); + smtp_printf(out, "250 OK %s is our friend.\r\n", addr->address); + } else { + smtp_printf(out, "550 relaying to %s denied.\r\n", addr_string(addr)); + } + } else { + smtp_printf(out, "501 recipient address must be qualified.\r\n", buf); + } + } else + smtp_printf(out, "501 %s: no pipe allowed for SMTP connections\r\n", buf); + } else { + smtp_printf(out, "501 %s: syntax error in address.\r\n", buf); + } + } else { + + if (!psc->helo_seen) + smtp_printf(out, "503 need HELO or EHLO.\r\n"); + else + smtp_printf(out, "503 need MAIL FROM: before RCPT TO:\r\n"); + } + break; + + case SMTP_DATA: + if (psc->helo_seen && psc->rcpt_seen) { + accept_error err; + + smtp_printf(out, "354 okay, and do not forget the dot\r\n"); + + if ((err = accept_message(in, msg, conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0)) == AERR_OK) { + if (spool_write(msg, TRUE)) { + pid_t pid; + smtp_printf(out, "250 OK id=%s\r\n", msg->uid); + + if (remote_host != NULL) + logwrite(LOG_NOTICE, "%s <= <%s@%s> host=%s with %s\n", msg->uid, msg->return_path->local_part, + msg->return_path->domain, remote_host, prot_names[psc->prot]); + else + logwrite(LOG_NOTICE, "%s <= <%s@%s> with %s\n", msg->uid, msg->return_path->local_part, + msg->return_path->domain, prot_names[psc->prot]); + + if (!conf.do_queue) { + if ((pid = fork()) == 0) { + + if (deliver(msg)) + _exit(EXIT_SUCCESS); + else + _exit(EXIT_FAILURE); + + } else if (pid < 0) { + logwrite(LOG_ALERT, "could not fork for delivery, id = %s", msg->uid); + } + } else { + DEBUG(1) debugf("queuing forced by configuration or option.\n"); + } + } else { + smtp_printf(out, "451 Could not write spool file\r\n"); + return; + } + } else { + switch (err) { + case AERR_TIMEOUT: + return; + case AERR_EOF: + return; + default: + /* should never happen: */ + smtp_printf(out, "451 Unknown error\r\n"); + return; + } + } + psc->rcpt_seen = psc->from_seen = FALSE; + destroy_message(msg); + msg = NULL; + } else { + if (!psc->helo_seen) + smtp_printf(out, "503 need HELO or EHLO.\r\n"); + else + smtp_printf(out, "503 need RCPT TO: before DATA\r\n"); + } + break; + case SMTP_QUIT: + smtp_printf(out, "221 goodbye\r\n"); + if (msg != NULL) + destroy_message(msg); + return; + case SMTP_RSET: + psc->from_seen = psc->rcpt_seen = FALSE; + if (msg != NULL) + destroy_message(msg); + msg = NULL; + smtp_printf(out, "250 OK\r\n"); + break; + case SMTP_NOOP: + smtp_printf(out, "250 OK\r\n"); + break; + case SMTP_HELP: + { + int i; + + smtp_printf(out, "214-supported commands:\r\n"); + for (i = 0; i < SMTP_NUM_IDS - 1; i++) { + smtp_printf(out, "214-%s\r\n", smtp_cmds[i].cmd); + } + smtp_printf(out, "214 %s\r\n", smtp_cmds[i].cmd); + } + break; + default: + smtp_printf(out, "501 command not recognized\r\n"); + DEBUG(1) debugf("command not recognized, was '%s'\n", buffer); + break; + } + } + switch (len) { + case -3: + logwrite(LOG_NOTICE, "connection timed out\n"); + break; + case -2: + logwrite(LOG_NOTICE, "line overflow\n"); + break; + case -1: + logwrite(LOG_NOTICE, "received EOF\n"); + break; + default: + break; + } } - - case SMTP_MAIL_FROM: - if(psc->helo_seen && !psc->from_seen){ - gchar buf[MAX_ADDRESS]; - address *addr; - - msg = create_message(); - msg->received_host = remote_host ? g_strdup(remote_host) : NULL; - msg->received_prot = psc->prot; - msg->ident = ident ? g_strdup(ident) : NULL; - /* get transfer id and increment for next one */ - msg->transfer_id = (psc->next_id)++; - - get_address(buffer, buf); - if((addr = remote_host ? - create_address(buf, TRUE) : - create_address_qualified(buf, TRUE, conf.host_name))){ - if(addr->domain != NULL){ - psc->from_seen = TRUE; - msg->return_path = addr; - smtp_printf(out, "250 OK %s is a nice guy.\r\n", addr->address); - }else{ - smtp_printf(out, - "501 return path must be qualified.\r\n", buf); - } - }else{ - smtp_printf(out, "501 %s: syntax error.\r\n", buf); - } - }else{ - if(!psc->helo_seen) - smtp_printf(out, "503 need HELO or EHLO\r\n"); - else - smtp_printf(out, "503 MAIL FROM: already given.\r\n"); - } - break; - - case SMTP_RCPT_TO: - - if(psc->helo_seen && psc->from_seen){ - char buf[MAX_ADDRESS]; - address *addr; - - get_address(buffer, buf); - if((addr = remote_host ? - create_address(buf, TRUE) : - create_address_qualified(buf, TRUE, conf.host_name))){ - if(addr->local_part[0] != '|'){ - if(addr->domain != NULL){ - gboolean do_relay = conf.do_relay; - if(!do_relay){ - if((do_relay = addr_is_local(msg->return_path))); - if(!do_relay){ - do_relay = addr_is_local(addr); - } - } - if(do_relay){ - psc->rcpt_seen = TRUE; - msg->rcpt_list = g_list_append(msg->rcpt_list, addr); - smtp_printf(out, "250 OK %s is our friend.\r\n", addr->address); - }else{ - smtp_printf(out, "550 relaying to %s denied.\r\n", - addr_string(addr)); - } - }else{ - smtp_printf(out, - "501 recipient address must be qualified.\r\n", buf); - } - }else - smtp_printf(out, "501 %s: no pipe allowed for SMTP connections\r\n", buf); - }else{ - smtp_printf(out, "501 %s: syntax error in address.\r\n", buf); - } - }else{ - - if(!psc->helo_seen) - smtp_printf(out, "503 need HELO or EHLO.\r\n"); - else - smtp_printf(out, "503 need MAIL FROM: before RCPT TO:\r\n"); - } - break; - - case SMTP_DATA: - if(psc->helo_seen && psc->rcpt_seen){ - accept_error err; - - smtp_printf(out, "354 okay, and do not forget the dot\r\n"); - - if((err = accept_message(in, msg, conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0)) - == AERR_OK){ - if(spool_write(msg, TRUE)){ - pid_t pid; - smtp_printf(out, "250 OK id=%s\r\n", msg->uid); - - if(remote_host != NULL) - logwrite(LOG_NOTICE, "%s <= <%s@%s> host=%s with %s\n", - msg->uid, msg->return_path->local_part, - msg->return_path->domain, remote_host, - prot_names[psc->prot]); - else - logwrite(LOG_NOTICE, "%s <= <%s@%s> with %s\n", - msg->uid, msg->return_path->local_part, - msg->return_path->domain, - prot_names[psc->prot]); - - if(!conf.do_queue){ - if((pid = fork()) == 0){ - - if(deliver(msg)) - _exit(EXIT_SUCCESS); - else - _exit(EXIT_FAILURE); - - }else if(pid < 0){ - logwrite(LOG_ALERT, "could not fork for delivery, id = %s", - msg->uid); - } - }else{ - DEBUG(1) debugf("queuing forced by configuration or option.\n"); - } - }else{ - smtp_printf(out, "451 Could not write spool file\r\n"); - return; - } - }else{ - switch(err){ - case AERR_TIMEOUT: - return; - case AERR_EOF: - return; - default: - /* should never happen: */ - smtp_printf(out, "451 Unknown error\r\n"); - return; - } - } - psc->rcpt_seen = psc->from_seen = FALSE; - destroy_message(msg); - msg = NULL; - }else{ - if(!psc->helo_seen) - smtp_printf(out, "503 need HELO or EHLO.\r\n"); - else - smtp_printf(out, "503 need RCPT TO: before DATA\r\n"); - } - break; - case SMTP_QUIT: - smtp_printf(out, "221 goodbye\r\n"); - if(msg != NULL) destroy_message(msg); - return; - case SMTP_RSET: - psc->from_seen = psc->rcpt_seen = FALSE; - if(msg != NULL) - destroy_message(msg); - msg = NULL; - smtp_printf(out, "250 OK\r\n"); - break; - case SMTP_NOOP: - smtp_printf(out, "250 OK\r\n"); - break; - case SMTP_HELP: - { - int i; - - smtp_printf(out, "214-supported commands:\r\n"); - for(i = 0; i < SMTP_NUM_IDS-1; i++){ - smtp_printf(out, "214-%s\r\n", smtp_cmds[i].cmd); - } - smtp_printf(out, "214 %s\r\n", smtp_cmds[i].cmd); - } - break; - default: - smtp_printf(out, "501 command not recognized\r\n"); - DEBUG(1) debugf("command not recognized, was '%s'\n", buffer); - break; - } - } - switch(len){ - case -3: - logwrite(LOG_NOTICE, "connection timed out\n"); - break; - case -2: - logwrite(LOG_NOTICE, "line overflow\n"); - break; - case -1: - logwrite(LOG_NOTICE, "received EOF\n"); - break; - default: - break; - } - } } #endif diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/smtp_out.c --- 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); + 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); + DEBUG(4) debugf("EHLO %s\r\n", helo); - }else{ - fprintf(psb->out, "HELO %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("HELO %s\r\n", helo); - } - - 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; + 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); + 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; + 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){ - 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)); - } + 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; + 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); + DEBUG(5) debugf("smtp_out_open_child entered, cmd = %s\n", cmd); - sock = child(cmd); + sock = child(cmd); - if(sock > 0){ - psb = create_smtpbase(sock); - psb->remote_host = NULL; + if (sock > 0) { + psb = create_smtpbase(sock); + psb->remote_host = NULL; - return psb; - } + return psb; + } - return NULL; + 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 + } + } } -#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(!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 (ok) { + smtp_cmd_mailfrom(psb, return_path, psb->use_size ? size + SMTP_SIZE_ADD : 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; - } - } + 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; - /* 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){ + 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; + } + } - fprintf(psb->out, "DATA\r\n"); fflush(psb->out); + /* 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) { - 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))){ + fprintf(psb->out, "DATA\r\n"); + fflush(psb->out); - /* 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); + 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))) { + + /* 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{ - /* 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); - } - } + } + + 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{ - 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"); + } 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); } - } /* 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); - } - - 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; + 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; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/smtp_out.h --- a/src/smtp_out.h Mon Oct 27 16:21:27 2008 +0100 +++ b/src/smtp_out.h 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 @@ -30,62 +30,55 @@ #define SMTP_DATA_TIMEOUT 5*60 #define SMTP_FINAL_TIMEOUT 10*60 -typedef -enum _smtp_error{ - smtp_ok = 0, /* mail was delivered to at least one recpient */ - smtp_trylater, /* server responded with 4xx */ - smtp_fail, /* server responded with 5xx */ - smtp_timeout, /* connection timed out */ - smtp_eof, /* got unexpected EOF */ - smtp_syntax, /* unexpected response */ - smtp_cancel /* we gave up (eg. size) */ +typedef enum _smtp_error { + smtp_ok = 0, /* mail was delivered to at least one recpient */ + smtp_trylater, /* server responded with 4xx */ + smtp_fail, /* server responded with 5xx */ + smtp_timeout, /* connection timed out */ + smtp_eof, /* got unexpected EOF */ + smtp_syntax, /* unexpected response */ + smtp_cancel /* we gave up (eg. size) */ } smtp_error; -typedef -struct _smtp_base{ - FILE *in; - FILE *out; +typedef struct _smtp_base { + FILE *in; + FILE *out; - gint sock; - gint dup_sock; + gint sock; + gint dup_sock; - gchar *remote_host; - gchar *helo_name; + gchar *remote_host; + gchar *helo_name; - gchar *buffer; - gint last_code; + gchar *buffer; + gint last_code; - gboolean use_esmtp; - gboolean use_size; - gboolean use_pipelining; - gboolean use_auth; - - gint max_size; + gboolean use_esmtp; + gboolean use_size; + gboolean use_pipelining; + gboolean use_auth; - gchar **auth_names; + gint max_size; - gchar *auth_name; - gchar *auth_login; - gchar *auth_secret; + gchar **auth_names; - smtp_error error; + gchar *auth_name; + gchar *auth_login; + gchar *auth_secret; + + smtp_error error; } smtp_base; -gchar *set_heloname(smtp_base *psb, gchar *default_name, gboolean do_correct); -gboolean set_auth(smtp_base *psb, gchar *name, gchar *login, gchar *secret); -void destroy_smtpbase(smtp_base *psb); -smtp_base *smtp_out_open(gchar *host, gint port, GList *resolve_list); -smtp_base *smtp_out_open_child(gchar *cmd); -gboolean smtp_out_rset(smtp_base *psb); -gboolean smtp_out_init(smtp_base *psb); -gint smtp_out_msg(smtp_base *psb, - message *msg, address *return_path, - GList *rcpt_list, GList *hdr_list); -gboolean smtp_out_quit(smtp_base *psb); +gchar *set_heloname(smtp_base * psb, gchar * default_name, gboolean do_correct); +gboolean set_auth(smtp_base * psb, gchar * name, gchar * login, gchar * secret); +void destroy_smtpbase(smtp_base * psb); +smtp_base *smtp_out_open(gchar * host, gint port, GList * resolve_list); +smtp_base *smtp_out_open_child(gchar * cmd); +gboolean smtp_out_rset(smtp_base * psb); +gboolean smtp_out_init(smtp_base * psb); +gint smtp_out_msg(smtp_base * psb, message * msg, address * return_path, GList * rcpt_list, GList * hdr_list); +gboolean smtp_out_quit(smtp_base * psb); -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); diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/smtpsend.c --- a/src/smtpsend.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/smtpsend.c Mon Oct 27 16:23:10 2008 +0100 @@ -32,83 +32,83 @@ extern char *optarg; extern int optind, opterr, optopt; -void logwrite(int pri, const char *fmt, ...) +void +logwrite(int pri, const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - vfprintf(stdout, fmt, args); + vfprintf(stdout, fmt, args); - va_end(args); + va_end(args); } -void debugf(const char *fmt, ...) +void +debugf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - vfprintf(stdout, fmt, args); + vfprintf(stdout, fmt, args); - va_end(args); + va_end(args); } int main(int argc, char *argv[]) { - gchar *helo_name = g_malloc(64); - gchar *server_name = g_strdup("localhost"); - gint server_port = 25; - GList *resolve_list = g_list_append(NULL, resolve_byname); + gchar *helo_name = g_malloc(64); + gchar *server_name = g_strdup("localhost"); + gint server_port = 25; + GList *resolve_list = g_list_append(NULL, resolve_byname); - gethostname(helo_name, 63); + gethostname(helo_name, 63); - conf.host_name = g_strdup(helo_name); + conf.host_name = g_strdup(helo_name); - while(1){ - int c; - c = getopt(argc, argv, "d:p:s:H:"); - if(c == -1) - break; - switch(c){ - case 'd': - conf.debug_level = atoi(optarg); - break; - case 'p': - server_port = atoi(optarg); - break; - case 's': - g_free(server_name); - server_name = g_strdup(optarg); - break; - case 'H': - g_free(helo_name); - helo_name = g_strdup(optarg); - break; - default: - break; - } - } + while (1) { + int c; + c = getopt(argc, argv, "d:p:s:H:"); + if (c == -1) + break; + switch (c) { + case 'd': + conf.debug_level = atoi(optarg); + break; + case 'p': + server_port = atoi(optarg); + break; + case 's': + g_free(server_name); + server_name = g_strdup(optarg); + break; + case 'H': + g_free(helo_name); + helo_name = g_strdup(optarg); + break; + default: + break; + } + } - if (optind < argc){ - gint ret; - message *msg = create_message(); + if (optind < argc) { + gint ret; + message *msg = create_message(); - while (optind < argc){ - msg->rcpt_list = - g_list_append(msg->rcpt_list, - create_address_qualified(argv[optind++], TRUE, conf.host_name)); - } - - if((ret = accept_message(stdin, msg, ACC_NODOT_TERM|ACC_HEAD_FROM_RCPT)) == AERR_OK){ - if((ret = smtp_deliver(server_name, server_port, resolve_list, msg, NULL, NULL)) == smtp_ok){ - exit(EXIT_SUCCESS); - } - fprintf(stderr, "deliver failed: %d\n", ret); - } - fprintf(stderr, "accept failed: %d\n", ret); - exit(ret); - }else{ - fprintf(stderr, "no recipients given.\n"); - exit(-1); - } + while (optind < argc) { + msg->rcpt_list = g_list_append(msg->rcpt_list, create_address_qualified(argv[optind++], TRUE, conf.host_name)); + } + + if ((ret = accept_message(stdin, msg, ACC_NODOT_TERM | ACC_HEAD_FROM_RCPT)) == AERR_OK) { + if ((ret = smtp_deliver(server_name, server_port, resolve_list, msg, NULL, NULL)) == smtp_ok) { + exit(EXIT_SUCCESS); + } + fprintf(stderr, "deliver failed: %d\n", ret); + } + fprintf(stderr, "accept failed: %d\n", ret); + exit(ret); + } else { + fprintf(stderr, "no recipients given.\n"); + exit(-1); + } } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/spool.c --- a/src/spool.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/spool.c Mon Oct 27 16:23:10 2008 +0100 @@ -20,418 +20,416 @@ #include #include "dotlock.h" -static -gint read_line(FILE *in, gchar *buf, gint buf_len) +static gint +read_line(FILE * in, gchar * buf, gint buf_len) { - gint p = 0; - gint c; + gint p = 0; + gint c; - while((c = getc(in)) != '\n' && (c != EOF)){ - if(p >= buf_len-1) { return 0; } - buf[p++] = c; - } + while ((c = getc(in)) != '\n' && (c != EOF)) { + if (p >= buf_len - 1) { + return 0; + } + buf[p++] = c; + } - if(c == EOF){ - return -1; - } - if((p > 0) && (buf[p-1] == '\r')) - p--; - buf[p++] = '\n'; - buf[p] = 0; + if (c == EOF) { + return -1; + } + if ((p > 0) && (buf[p - 1] == '\r')) + p--; + buf[p++] = '\n'; + buf[p] = 0; - return p; + return p; } -static -void spool_write_rcpt(FILE *out, address *rcpt) +static void +spool_write_rcpt(FILE * out, address * rcpt) { - gchar dlvrd_char = addr_is_delivered(rcpt) ? 'X' : (addr_is_failed(rcpt) ? 'F' : ' '); + gchar dlvrd_char = addr_is_delivered(rcpt) ? 'X' : (addr_is_failed(rcpt) ? 'F' : ' '); - if(rcpt->local_part[0] != '|'){ - /* this is a paranoid check, in case it slipped through: */ - /* if this happens, it is a bug */ - if(rcpt->domain == NULL){ - logwrite(LOG_WARNING, "BUG: null domain for address %s, setting to %s\n", - rcpt->local_part, conf.host_name); - logwrite(LOG_WARNING, "please report this bug.\n"); - rcpt->domain = g_strdup(conf.host_name); - } - fprintf(out, "RT:%c%s\n", dlvrd_char, addr_string(rcpt)); - }else{ - fprintf(out, "RT:%c%s\n", dlvrd_char, rcpt->local_part); - } + if (rcpt->local_part[0] != '|') { + /* this is a paranoid check, in case it slipped through: */ + /* if this happens, it is a bug */ + if (rcpt->domain == NULL) { + logwrite(LOG_WARNING, "BUG: null domain for address %s, setting to %s\n", rcpt->local_part, conf.host_name); + logwrite(LOG_WARNING, "please report this bug.\n"); + rcpt->domain = g_strdup(conf.host_name); + } + fprintf(out, "RT:%c%s\n", dlvrd_char, addr_string(rcpt)); + } else { + fprintf(out, "RT:%c%s\n", dlvrd_char, rcpt->local_part); + } } -static -address *spool_scan_rcpt(gchar *line) +static address* +spool_scan_rcpt(gchar * line) { - address *rcpt = NULL; + address *rcpt = NULL; - if(line[3] != 0){ - if(line[4] != '|'){ - rcpt = create_address(&(line[4]), TRUE); - }else{ - rcpt = create_address_pipe(&(line[4])); - } - if(line[3] == 'X'){ - addr_mark_delivered(rcpt); - }else if(line[3] == 'F'){ - addr_mark_failed(rcpt); - } - } - return rcpt; + if (line[3] != 0) { + if (line[4] != '|') { + rcpt = create_address(&(line[4]), TRUE); + } else { + rcpt = create_address_pipe(&(line[4])); + } + if (line[3] == 'X') { + addr_mark_delivered(rcpt); + } else if (line[3] == 'F') { + addr_mark_failed(rcpt); + } + } + return rcpt; } -gboolean spool_read_data(message *msg) +gboolean +spool_read_data(message * msg) { - FILE *in; - gboolean ok = FALSE; - gchar *spool_file; + FILE *in; + gboolean ok = FALSE; + gchar *spool_file; - DEBUG(5) debugf("spool_read_data entered\n"); - spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); - DEBUG(5) debugf("reading data spool file '%s'\n", spool_file); - if((in = fopen(spool_file, "r"))){ - char buf[MAX_DATALINE]; - int len; - - /* msg uid */ - read_line(in, buf, MAX_DATALINE); - - /* data */ - msg->data_list = NULL; - while((len = read_line(in, buf, MAX_DATALINE)) > 0){ - msg->data_list = g_list_prepend(msg->data_list, g_strdup(buf)); - } - msg->data_list = g_list_reverse(msg->data_list); - fclose(in); - ok = TRUE; - }else - logwrite(LOG_ALERT, "could not open spool data file %s: %s\n", - spool_file, strerror(errno)); - return ok; + DEBUG(5) debugf("spool_read_data entered\n"); + spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); + DEBUG(5) debugf("reading data spool file '%s'\n", spool_file); + if ((in = fopen(spool_file, "r"))) { + char buf[MAX_DATALINE]; + int len; + + /* msg uid */ + read_line(in, buf, MAX_DATALINE); + + /* data */ + msg->data_list = NULL; + while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { + msg->data_list = g_list_prepend(msg->data_list, g_strdup(buf)); + } + msg->data_list = g_list_reverse(msg->data_list); + fclose(in); + ok = TRUE; + } else + logwrite(LOG_ALERT, "could not open spool data file %s: %s\n", spool_file, strerror(errno)); + return ok; } -gboolean spool_read_header(message *msg) +gboolean +spool_read_header(message * msg) { - FILE *in; - gboolean ok = FALSE; - gchar *spool_file; + FILE *in; + gboolean ok = FALSE; + gchar *spool_file; - /* header spool: */ - spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); - if((in = fopen(spool_file, "r"))){ - header *hdr = NULL; - char buf[MAX_DATALINE]; - int len; + /* header spool: */ + spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); + if ((in = fopen(spool_file, "r"))) { + header *hdr = NULL; + char buf[MAX_DATALINE]; + int len; - /* msg uid */ - read_line(in, buf, MAX_DATALINE); - - /* envelope header */ - while((len = read_line(in, buf, MAX_DATALINE)) > 0){ - if(buf[0] == '\n') - break; - else if(strncasecmp(buf, "MF:", 3) == 0){ - msg->return_path = create_address(&(buf[3]), TRUE); - DEBUG(3) debugf("spool_read: MAIL FROM: %s", - msg->return_path->address); - }else if(strncasecmp(buf, "RT:", 3) == 0){ - address *addr; - addr = spool_scan_rcpt(buf); - if(!addr_is_delivered(addr) && !addr_is_failed(addr)){ - msg->rcpt_list = g_list_append(msg->rcpt_list, addr); - }else{ - msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, addr); - } - }else if(strncasecmp(buf, "PR:", 3) == 0){ - prot_id i; - for(i = 0; i < PROT_NUM; i++){ - if(strncasecmp(prot_names[i], &(buf[3]), - strlen(prot_names[i])) == 0){ - break; - } - } - msg->received_prot = i; - }else if(strncasecmp(buf, "RH:", 3) == 0){ - g_strchomp(buf); - msg->received_host = g_strdup(&(buf[3])); - }else if(strncasecmp(buf, "ID:", 3) == 0){ - g_strchomp(buf); - msg->ident = g_strdup(&(buf[3])); - }else if(strncasecmp(buf, "DS:", 3) == 0){ - msg->data_size = atoi(&(buf[3])); - }else if(strncasecmp(buf, "TR:", 3) == 0){ - msg->received_time = (time_t)(atoi(&(buf[3]))); - }else if(strncasecmp(buf, "TW:", 3) == 0){ - msg->warned_time = (time_t)(atoi(&(buf[3]))); - } - /* so far ignore other tags */ - } - - /* mail headers */ - while((len = read_line(in, buf, MAX_DATALINE)) > 0){ - if(strncasecmp(buf, "HD:", 3) == 0){ - hdr = get_header(&(buf[3])); - msg->hdr_list = g_list_append(msg->hdr_list, hdr); - }else if((buf[0] == ' ' || buf[0] == '\t') && hdr){ - char *tmp = hdr->header; - /* header continuation */ - hdr->header = g_strconcat(hdr->header, buf, NULL); - hdr->value = hdr->header + (hdr->value - tmp); - }else - break; - } - fclose(in); - ok = TRUE; - }else - logwrite(LOG_ALERT, "could not open spool header file %s: %s\n", - spool_file, strerror(errno)); - return ok; + /* msg uid */ + read_line(in, buf, MAX_DATALINE); + + /* envelope header */ + while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { + if (buf[0] == '\n') + break; + else if (strncasecmp(buf, "MF:", 3) == 0) { + msg->return_path = create_address(&(buf[3]), TRUE); + DEBUG(3) debugf("spool_read: MAIL FROM: %s", msg->return_path->address); + } else if (strncasecmp(buf, "RT:", 3) == 0) { + address *addr; + addr = spool_scan_rcpt(buf); + if (!addr_is_delivered(addr) && !addr_is_failed(addr)) { + msg->rcpt_list = g_list_append(msg->rcpt_list, addr); + } else { + msg->non_rcpt_list = g_list_append(msg->non_rcpt_list, addr); + } + } else if (strncasecmp(buf, "PR:", 3) == 0) { + prot_id i; + for (i = 0; i < PROT_NUM; i++) { + if (strncasecmp(prot_names[i], &(buf[3]), strlen(prot_names[i])) == 0) { + break; + } + } + msg->received_prot = i; + } else if (strncasecmp(buf, "RH:", 3) == 0) { + g_strchomp(buf); + msg->received_host = g_strdup(&(buf[3])); + } else if (strncasecmp(buf, "ID:", 3) == 0) { + g_strchomp(buf); + msg->ident = g_strdup(&(buf[3])); + } else if (strncasecmp(buf, "DS:", 3) == 0) { + msg->data_size = atoi(&(buf[3])); + } else if (strncasecmp(buf, "TR:", 3) == 0) { + msg->received_time = (time_t) (atoi(&(buf[3]))); + } else if (strncasecmp(buf, "TW:", 3) == 0) { + msg->warned_time = (time_t) (atoi(&(buf[3]))); + } + /* so far ignore other tags */ + } + + /* mail headers */ + while ((len = read_line(in, buf, MAX_DATALINE)) > 0) { + if (strncasecmp(buf, "HD:", 3) == 0) { + hdr = get_header(&(buf[3])); + msg->hdr_list = g_list_append(msg->hdr_list, hdr); + } else if ((buf[0] == ' ' || buf[0] == '\t') && hdr) { + char *tmp = hdr->header; + /* header continuation */ + hdr->header = g_strconcat(hdr->header, buf, NULL); + hdr->value = hdr->header + (hdr->value - tmp); + } else + break; + } + fclose(in); + ok = TRUE; + } else + logwrite(LOG_ALERT, "could not open spool header file %s: %s\n", spool_file, strerror(errno)); + return ok; } -message *msg_spool_read(gchar *uid, gboolean do_readdata) +message* +msg_spool_read(gchar * uid, gboolean do_readdata) { - message *msg; - gboolean ok = FALSE; - - msg = create_message(); - msg->uid = g_strdup(uid); + message *msg; + gboolean ok = FALSE; - /* header spool: */ - ok = spool_read_header(msg); - if(ok && do_readdata){ - /* data spool: */ - ok = spool_read_data(msg); - } - return msg; + msg = create_message(); + msg->uid = g_strdup(uid); + + /* header spool: */ + ok = spool_read_header(msg); + if (ok && do_readdata) { + /* data spool: */ + ok = spool_read_data(msg); + } + return msg; } /* write header. uid and gid should already be set to the mail ids. Better call spool_write(msg, FALSE). */ -static -gboolean spool_write_header(message *msg) +static gboolean +spool_write_header(message * msg) { - GList *node; - gchar *spool_file, *tmp_file; - FILE *out; - gboolean ok = TRUE; + GList *node; + gchar *spool_file, *tmp_file; + FILE *out; + gboolean ok = TRUE; - /* header spool: */ - tmp_file = g_strdup_printf("%s/input/%d-H.tmp", conf.spool_dir, getpid()); - DEBUG(4) debugf("tmp_file = %s\n", tmp_file); + /* header spool: */ + tmp_file = g_strdup_printf("%s/input/%d-H.tmp", conf.spool_dir, getpid()); + DEBUG(4) debugf("tmp_file = %s\n", tmp_file); - if((out = fopen(tmp_file, "w"))){ - DEBUG(6) debugf("opened tmp_file %s\n", tmp_file); + if ((out = fopen(tmp_file, "w"))) { + DEBUG(6) debugf("opened tmp_file %s\n", tmp_file); - fprintf(out, "%s\n", msg->uid); - fprintf(out, "MF:%s\n", addr_string(msg->return_path)); + fprintf(out, "%s\n", msg->uid); + fprintf(out, "MF:%s\n", addr_string(msg->return_path)); - DEBUG(6) debugf("after MF\n"); - foreach(msg->rcpt_list, node){ - address *rcpt = (address *)(node->data); - spool_write_rcpt(out, rcpt); - } - foreach(msg->non_rcpt_list, node){ - address *rcpt = (address *)(node->data); - spool_write_rcpt(out, rcpt); - } - DEBUG(6) debugf("after RT\n"); - fprintf(out, "PR:%s\n", prot_names[msg->received_prot]); - if(msg->received_host != NULL) - fprintf(out, "RH:%s\n", msg->received_host); + DEBUG(6) debugf("after MF\n"); + foreach(msg->rcpt_list, node) { + address *rcpt = (address *) (node->data); + spool_write_rcpt(out, rcpt); + } + foreach(msg->non_rcpt_list, node) { + address *rcpt = (address *) (node->data); + spool_write_rcpt(out, rcpt); + } + DEBUG(6) debugf("after RT\n"); + fprintf(out, "PR:%s\n", prot_names[msg->received_prot]); + if (msg->received_host != NULL) + fprintf(out, "RH:%s\n", msg->received_host); - if(msg->ident != NULL) - fprintf(out, "ID:%s\n", msg->ident); + if (msg->ident != NULL) + fprintf(out, "ID:%s\n", msg->ident); - if(msg->data_size >= 0) - fprintf(out, "DS: %d\n", msg->data_size); + if (msg->data_size >= 0) + fprintf(out, "DS: %d\n", msg->data_size); - if(msg->received_time > 0) - fprintf(out, "TR: %u\n", (int)(msg->received_time)); + if (msg->received_time > 0) + fprintf(out, "TR: %u\n", (int) (msg->received_time)); - if(msg->warned_time > 0) - fprintf(out, "TW: %u\n", (int)(msg->warned_time)); + if (msg->warned_time > 0) + fprintf(out, "TW: %u\n", (int) (msg->warned_time)); - DEBUG(6) debugf("after RH\n"); - fprintf(out, "\n"); + DEBUG(6) debugf("after RH\n"); + fprintf(out, "\n"); - foreach(msg->hdr_list, node){ - header *hdr = (header *)(node->data); - fprintf(out, "HD:%s", hdr->header); - } - if(fflush(out) == EOF) ok = FALSE; - else if(fdatasync(fileno(out)) != 0){ - if(errno != EINVAL) /* some fs do not support this.. - I hope this also means that it is not necessary */ - ok = FALSE; - } - fclose(out); - if(ok){ - spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); - DEBUG(4) debugf("spool_file = %s\n", spool_file); - ok = (rename(tmp_file, spool_file) != -1); - g_free(spool_file); - } - }else{ - logwrite(LOG_ALERT, "could not open temporary header spool file '%s': %s\n", tmp_file, strerror(errno)); - DEBUG(1) debugf("euid = %d, egid = %d\n", geteuid(), getegid()); - ok = FALSE; - } + foreach(msg->hdr_list, node) { + header *hdr = (header *) (node->data); + fprintf(out, "HD:%s", hdr->header); + } + if (fflush(out) == EOF) + ok = FALSE; + else if (fdatasync(fileno(out)) != 0) { + if (errno != EINVAL) /* some fs do not support this.. I hope this also means that it is not necessary */ + ok = FALSE; + } + fclose(out); + if (ok) { + spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); + DEBUG(4) debugf("spool_file = %s\n", spool_file); + ok = (rename(tmp_file, spool_file) != -1); + g_free(spool_file); + } + } else { + logwrite(LOG_ALERT, "could not open temporary header spool file '%s': %s\n", tmp_file, strerror(errno)); + DEBUG(1) debugf("euid = %d, egid = %d\n", geteuid(), getegid()); + ok = FALSE; + } - g_free(tmp_file); + g_free(tmp_file); - return ok; + return ok; } -gboolean spool_write(message *msg, gboolean do_write_data) +gboolean +spool_write(message * msg, gboolean do_write_data) { - GList *list; - gchar *spool_file, *tmp_file; - FILE *out; - gboolean ok = TRUE; - uid_t saved_uid, saved_gid; - /* user can read/write, group can read, others cannot do anything: */ - mode_t saved_mode = saved_mode = umask(026); + GList *list; + gchar *spool_file, *tmp_file; + FILE *out; + gboolean ok = TRUE; + uid_t saved_uid, saved_gid; + /* user can read/write, group can read, others cannot do anything: */ + mode_t saved_mode = saved_mode = umask(026); - /* set uid and gid to the mail ids */ - if(!conf.run_as_user){ - set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); - } - - /* header spool: */ - ok = spool_write_header(msg); - - if(ok){ - - if(do_write_data){ - /* data spool: */ - tmp_file = g_strdup_printf("%s/input/%d-D.tmp", - conf.spool_dir, getpid()); - DEBUG(4) debugf("tmp_file = %s\n", tmp_file); - - if((out = fopen(tmp_file, "w"))){ - fprintf(out, "%s\n", msg->uid); - for(list = g_list_first(msg->data_list); - list != NULL; - list = g_list_next(list)){ - fprintf(out, "%s", (gchar *)(list->data)); + /* set uid and gid to the mail ids */ + if (!conf.run_as_user) { + set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); } - /* possibly paranoid ;-) */ - if(fflush(out) == EOF) ok = FALSE; - else if(fdatasync(fileno(out)) != 0){ - if(errno != EINVAL) /* some fs do not support this.. - I hope this also means that it is not necessary */ - ok = FALSE; + /* header spool: */ + ok = spool_write_header(msg); + + if (ok) { + + if (do_write_data) { + /* data spool: */ + tmp_file = g_strdup_printf("%s/input/%d-D.tmp", conf.spool_dir, getpid()); + DEBUG(4) debugf("tmp_file = %s\n", tmp_file); + + if ((out = fopen(tmp_file, "w"))) { + fprintf(out, "%s\n", msg->uid); + for (list = g_list_first(msg->data_list); list != NULL; list = g_list_next(list)) { + fprintf(out, "%s", (gchar *) (list->data)); + } + + /* possibly paranoid ;-) */ + if (fflush(out) == EOF) + ok = FALSE; + else if (fdatasync(fileno(out)) != 0) { + if (errno != EINVAL) /* some fs do not support this.. I hope this also means that it is not necessary */ + ok = FALSE; + } + fclose(out); + if (ok) { + spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); + DEBUG(4) debugf("spool_file = %s\n", spool_file); + ok = (rename(tmp_file, spool_file) != -1); + g_free(spool_file); + } + } else { + logwrite(LOG_ALERT, "could not open temporary data spool file: %s\n", strerror(errno)); + ok = FALSE; + } + g_free(tmp_file); + } } - fclose(out); - if(ok){ - spool_file = g_strdup_printf("%s/input/%s-D", - conf.spool_dir, msg->uid); - DEBUG(4) debugf("spool_file = %s\n", spool_file); - ok = (rename(tmp_file, spool_file) != -1); - g_free(spool_file); + + /* set uid and gid back */ + if (!conf.run_as_user) { + set_euidgid(saved_uid, saved_gid, NULL, NULL); } - }else{ - logwrite(LOG_ALERT, "could not open temporary data spool file: %s\n", - strerror(errno)); - ok = FALSE; - } - g_free(tmp_file); - } - } - /* set uid and gid back */ - if(!conf.run_as_user){ - set_euidgid(saved_uid, saved_gid, NULL, NULL); - } + umask(saved_mode); - umask(saved_mode); - - return ok; + return ok; } #define MAX_LOCKAGE 300 -gboolean spool_lock(gchar *uid) +gboolean +spool_lock(gchar * uid) { - uid_t saved_uid, saved_gid; - gchar *hitch_name; - gchar *lock_name; - gboolean ok = FALSE; + uid_t saved_uid, saved_gid; + gchar *hitch_name; + gchar *lock_name; + gboolean ok = FALSE; - hitch_name = g_strdup_printf("%s/%s-%d.lock", conf.lock_dir, uid, getpid()); - lock_name = g_strdup_printf("%s/%s.lock", conf.lock_dir, uid); + hitch_name = g_strdup_printf("%s/%s-%d.lock", conf.lock_dir, uid, getpid()); + lock_name = g_strdup_printf("%s/%s.lock", conf.lock_dir, uid); - /* set uid and gid to the mail ids */ - if(!conf.run_as_user){ - set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); - } + /* set uid and gid to the mail ids */ + if (!conf.run_as_user) { + set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); + } - ok = dot_lock(lock_name, hitch_name); - if(!ok) logwrite(LOG_WARNING, "spool file %s is locked\n", uid); + ok = dot_lock(lock_name, hitch_name); + if (!ok) + logwrite(LOG_WARNING, "spool file %s is locked\n", uid); - /* set uid and gid back */ - if(!conf.run_as_user){ - set_euidgid(saved_uid, saved_gid, NULL, NULL); - } + /* set uid and gid back */ + if (!conf.run_as_user) { + set_euidgid(saved_uid, saved_gid, NULL, NULL); + } - g_free(lock_name); - g_free(hitch_name); + g_free(lock_name); + g_free(hitch_name); - return ok; + return ok; } -gboolean spool_unlock(gchar *uid) +gboolean +spool_unlock(gchar * uid) { - uid_t saved_uid, saved_gid; - gchar *lock_name; + uid_t saved_uid, saved_gid; + gchar *lock_name; - /* set uid and gid to the mail ids */ - if(!conf.run_as_user){ - set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); - } + /* set uid and gid to the mail ids */ + if (!conf.run_as_user) { + set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); + } - lock_name = g_strdup_printf("%s/%s.lock", conf.lock_dir, uid); - dot_unlock(lock_name); - g_free(lock_name); + lock_name = g_strdup_printf("%s/%s.lock", conf.lock_dir, uid); + dot_unlock(lock_name); + g_free(lock_name); - /* set uid and gid back */ - if(!conf.run_as_user){ - set_euidgid(saved_uid, saved_gid, NULL, NULL); - } - return TRUE; + /* set uid and gid back */ + if (!conf.run_as_user) { + set_euidgid(saved_uid, saved_gid, NULL, NULL); + } + return TRUE; } -gboolean spool_delete_all(message *msg) +gboolean +spool_delete_all(message * msg) { - uid_t saved_uid, saved_gid; - gchar *spool_file; + uid_t saved_uid, saved_gid; + gchar *spool_file; - /* set uid and gid to the mail ids */ - if(!conf.run_as_user){ - set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); - } + /* set uid and gid to the mail ids */ + if (!conf.run_as_user) { + set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); + } - /* header spool: */ - spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); - if(unlink(spool_file) != 0) - logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", - spool_file, strerror(errno)); - g_free(spool_file); + /* header spool: */ + spool_file = g_strdup_printf("%s/input/%s-H", conf.spool_dir, msg->uid); + if (unlink(spool_file) != 0) + logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", spool_file, strerror(errno)); + g_free(spool_file); - /* data spool: */ - spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); - if(unlink(spool_file) != 0) - logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", - spool_file, strerror(errno)); - g_free(spool_file); + /* data spool: */ + spool_file = g_strdup_printf("%s/input/%s-D", conf.spool_dir, msg->uid); + if (unlink(spool_file) != 0) + logwrite(LOG_ALERT, "could not delete spool file %s: %s\n", spool_file, strerror(errno)); + g_free(spool_file); - /* set uid and gid back */ - if(!conf.run_as_user){ - set_euidgid(saved_uid, saved_gid, NULL, NULL); - } - return TRUE; + /* set uid and gid back */ + if (!conf.run_as_user) { + set_euidgid(saved_uid, saved_gid, NULL, NULL); + } + return TRUE; } diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/tables.c --- a/src/tables.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/tables.c Mon Oct 27 16:23:10 2008 +0100 @@ -19,120 +19,128 @@ #include "masqmail.h" #include -table_pair *create_pair(gchar *key, gpointer value) +table_pair* +create_pair(gchar * key, gpointer value) { - table_pair *pair; - - pair = g_malloc(sizeof(table_pair)); - pair->key = g_strdup(key); - pair->value = value; + table_pair *pair; - return pair; + pair = g_malloc(sizeof(table_pair)); + pair->key = g_strdup(key); + pair->value = value; + + return pair; } -table_pair *create_pair_string(gchar *key, gpointer value) +table_pair* +create_pair_string(gchar * key, gpointer value) { - table_pair *pair; - - pair = g_malloc(sizeof(table_pair)); - pair->key = g_strdup(key); - pair->value = (gpointer)(g_strdup(value)); + table_pair *pair; - return pair; + pair = g_malloc(sizeof(table_pair)); + pair->key = g_strdup(key); + pair->value = (gpointer) (g_strdup(value)); + + return pair; } -table_pair *parse_table_pair(gchar *line, char delim) +table_pair* +parse_table_pair(gchar * line, char delim) { - gchar buf[256]; - gchar *p, *q; - table_pair *pair; + gchar buf[256]; + gchar *p, *q; + table_pair *pair; - p = line; - q = buf; - while((*p != 0) && (*p != delim) && q < buf+255) - *(q++) = *(p++); - *q = 0; + p = line; + q = buf; + while ((*p != 0) && (*p != delim) && q < buf + 255) + *(q++) = *(p++); + *q = 0; - pair = g_malloc(sizeof(table_pair)); - pair->key = g_strdup(g_strstrip(buf)); + pair = g_malloc(sizeof(table_pair)); + pair->key = g_strdup(g_strstrip(buf)); - if(*p){ - p++; - /* while(isspace(*p)) p++; */ - pair->value = (gpointer *)(g_strdup(g_strstrip(p))); - }else - pair->value = (gpointer *)g_strdup(""); + if (*p) { + p++; + /* while(isspace(*p)) p++; */ + pair->value = (gpointer *) (g_strdup(g_strstrip(p))); + } else + pair->value = (gpointer *) g_strdup(""); - return pair; + return pair; } -gpointer *table_find_func(GList *table_list, gchar *key, int (*cmp_func)(const char *, const char *)) +gpointer* +table_find_func(GList * table_list, gchar * key, int (*cmp_func) (const char *, const char *)) { - GList *node; + GList *node; - foreach(table_list, node){ - table_pair *pair = (table_pair *)(node->data); - if(cmp_func(pair->key, key) == 0) - return pair->value; - } - return NULL; + foreach(table_list, node) { + table_pair *pair = (table_pair *) (node->data); + if (cmp_func(pair->key, key) == 0) + return pair->value; + } + return NULL; } -gpointer *table_find(GList *table_list, gchar *key) +gpointer* +table_find(GList * table_list, gchar * key) { - return table_find_func(table_list, key, strcmp); + return table_find_func(table_list, key, strcmp); } -gpointer *table_find_case(GList *table_list, gchar *key) +gpointer* +table_find_case(GList * table_list, gchar * key) { - return table_find_func(table_list, key, strcasecmp); + return table_find_func(table_list, key, strcasecmp); } -static -int fnmatch0(const char *pattern, const char *string) +static int +fnmatch0(const char *pattern, const char *string) { - return fnmatch(pattern, string, 0); + return fnmatch(pattern, string, 0); } -gpointer *table_find_fnmatch(GList *table_list, gchar *key) +gpointer* +table_find_fnmatch(GList * table_list, gchar * key) { - return table_find_func(table_list, key, fnmatch0); + return table_find_func(table_list, key, fnmatch0); } -GList *table_read(gchar *fname, gchar delim) +GList* +table_read(gchar * fname, gchar delim) { - GList *list = NULL; - FILE *fptr; + GList *list = NULL; + FILE *fptr; - if((fptr = fopen(fname, "rt"))){ - gchar buf[256]; + if ((fptr = fopen(fname, "rt"))) { + gchar buf[256]; - while(fgets(buf, 255, fptr)){ - if(buf[0] && (buf[0] != '#') && (buf[0] != '\n')){ - table_pair *pair; - g_strchomp(buf); - pair = parse_table_pair(buf, delim); - list = g_list_append(list, pair); - } - } - fclose(fptr); - return list; - } - logwrite(LOG_ALERT, "could not open table file %s: %s\n", fname, strerror(errno)); + while (fgets(buf, 255, fptr)) { + if (buf[0] && (buf[0] != '#') && (buf[0] != '\n')) { + table_pair *pair; + g_strchomp(buf); + pair = parse_table_pair(buf, delim); + list = g_list_append(list, pair); + } + } + fclose(fptr); + return list; + } + logwrite(LOG_ALERT, "could not open table file %s: %s\n", fname, strerror(errno)); - return NULL; + return NULL; } -void destroy_table(GList *table) +void +destroy_table(GList * table) { - GList *node; + GList *node; - foreach(table, node){ - table_pair *p = (table_pair *)(node->data); - g_free(p->key); - g_free(p->value); - g_free(p); - } - g_list_free(table); + foreach(table, node) { + table_pair *p = (table_pair *) (node->data); + g_free(p->key); + g_free(p->value); + g_free(p); + } + g_list_free(table); } - diff -r 31cc8a89cb74 -r 26e34ae9a3e3 src/timeival.c --- a/src/timeival.c Mon Oct 27 16:21:27 2008 +0100 +++ b/src/timeival.c Mon Oct 27 16:23:10 2008 +0100 @@ -21,34 +21,35 @@ #include "masqmail.h" -gint time_interval(gchar *str, gint *pos) +gint +time_interval(gchar * str, gint * pos) { - gchar buf[16]; - gchar *p = str, *q = buf; - gint factor = 1, val; + gchar buf[16]; + gchar *p = str, *q = buf; + gint factor = 1, val; - while(*p && isdigit(*p) && (q < buf+15)){ - *(q++) = *(p++); - (*pos)++; - } - (*pos)++; - *q = 0; - val = atoi(buf); - - /* fall through: */ - switch(*p){ - case 'w': - factor *= 7; - case 'd': - factor *= 24; - case 'h': - factor *= 60; - case 'm': - factor *= 60; - case 's': - break; - default: - return -1; - } - return val * factor; + while (*p && isdigit(*p) && (q < buf + 15)) { + *(q++) = *(p++); + (*pos)++; + } + (*pos)++; + *q = 0; + val = atoi(buf); + + /* fall through: */ + switch (*p) { + case 'w': + factor *= 7; + case 'd': + factor *= 24; + case 'h': + factor *= 60; + case 'm': + factor *= 60; + case 's': + break; + default: + return -1; + } + return val * factor; }