meillo@0: /* MasqMail meillo@0: Copyright (C) 1999-2001 Oliver Kurth meillo@174: Copyright (C) 2010 markus schnalke meillo@0: meillo@0: This program is free software; you can redistribute it and/or modify meillo@0: it under the terms of the GNU General Public License as published by meillo@0: the Free Software Foundation; either version 2 of the License, or meillo@0: (at your option) any later version. meillo@0: meillo@0: This program is distributed in the hope that it will be useful, meillo@0: but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@0: GNU General Public License for more details. meillo@0: meillo@0: You should have received a copy of the GNU General Public License meillo@0: along with this program; if not, write to the Free Software meillo@0: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: meillo@0: #include "masqmail.h" meillo@0: meillo@10: message* meillo@10: create_message() meillo@0: { meillo@10: message *msg = (message *) g_malloc(sizeof(message)); meillo@10: if (msg) { meillo@10: memset(msg, 0, sizeof(message)); meillo@10: msg->data_size = -1; meillo@10: } meillo@10: return msg; meillo@0: } meillo@0: meillo@118: /* meillo@118: This function is currently (0.2.24) only used for client side SMTP meillo@118: SIZE support (RFC 1870). The flag is_smtp is always true therefore. meillo@118: meillo@118: Their definition of the message size in RFC 1870 is: meillo@118: meillo@118: The message size is defined as the number of octets, including meillo@118: CR-LF pairs, but not the SMTP DATA command's terminating dot meillo@118: or doubled quoting dots, to be transmitted by the SMTP client meillo@118: after receiving reply code 354 to the DATA command. meillo@118: meillo@118: l_cnt (line count) covers '\r' characters which are not present in meillo@118: masqmail's internal format. Dots are also not stuffed in the meillo@118: internal format. Dot-stuffing is ignored in the size. meillo@118: */ meillo@10: gint meillo@10: msg_calc_size(message * msg, gboolean is_smtp) meillo@0: { meillo@10: GList *node; meillo@118: gint l_cnt = 0; /* line count (we need to add so many '\r' for SMTP) */ meillo@118: gint c_cnt = 0; /* character count */ meillo@0: meillo@118: /* message header size */ meillo@10: if (msg->hdr_list) { meillo@10: for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) { meillo@10: if (node->data) { meillo@10: header *hdr = (header *) (node->data); meillo@10: if (hdr->header) { meillo@10: char *p = hdr->header; meillo@10: while (*p) { meillo@10: if (*p++ == '\n') meillo@10: l_cnt++; meillo@10: c_cnt++; meillo@10: } meillo@10: } meillo@10: } meillo@10: } meillo@0: } meillo@0: meillo@10: /* empty line separating headers from data: */ meillo@10: c_cnt++; meillo@10: l_cnt++; meillo@0: meillo@118: /* message data size */ meillo@10: if (msg->data_list) { meillo@10: for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) { meillo@10: if (node->data) { meillo@10: char *p = node->data; meillo@10: while (*p) { meillo@10: if (*p++ == '\n') meillo@10: l_cnt++; meillo@10: c_cnt++; meillo@10: } meillo@10: } meillo@10: } meillo@0: } meillo@0: meillo@10: return is_smtp ? c_cnt + l_cnt : c_cnt; meillo@0: } meillo@0: meillo@10: void meillo@10: msg_free_data(message * msg) meillo@0: { meillo@10: GList *node; meillo@0: meillo@10: if (msg->data_list) { meillo@10: for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) { meillo@10: if (node->data) meillo@10: g_free(node->data); meillo@10: } meillo@10: g_list_free(msg->data_list); meillo@10: msg->data_list = NULL; meillo@10: } meillo@0: } meillo@0: meillo@10: void meillo@10: destroy_message(message * msg) meillo@0: { meillo@10: GList *node; meillo@0: meillo@81: if (!msg) { meillo@81: return; meillo@81: } meillo@81: meillo@10: if (msg->uid) meillo@10: g_free(msg->uid); meillo@10: if (msg->ident) meillo@10: g_free(msg->ident); meillo@10: if (msg->return_path) meillo@10: g_free(msg->return_path); meillo@0: meillo@10: if (msg->rcpt_list) { meillo@10: for (node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)) { meillo@10: if (node->data) meillo@10: g_free(node->data); meillo@10: } meillo@10: g_list_free(msg->rcpt_list); meillo@10: } meillo@10: if (msg->hdr_list) { meillo@10: for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) { meillo@10: if (node->data) { meillo@10: header *hdr = (header *) (node->data); meillo@10: if (hdr->header) meillo@10: g_free(hdr->header); meillo@10: g_free(node->data); meillo@10: } meillo@10: } meillo@10: g_list_free(msg->hdr_list); meillo@10: } meillo@0: meillo@10: if (msg->full_sender_name) meillo@10: g_free(msg->full_sender_name); meillo@0: meillo@10: msg_free_data(msg); meillo@0: meillo@10: g_free(msg); meillo@0: } meillo@0: meillo@10: void meillo@10: destroy_msg_list(GList * msg_list) meillo@0: { meillo@10: GList *msg_node; meillo@0: meillo@10: foreach(msg_list, msg_node) { meillo@10: message *msg = (message *) (msg_node->data); meillo@10: destroy_message(msg); meillo@10: } meillo@10: g_list_free(msg_list); meillo@0: } meillo@0: meillo@10: msg_out* meillo@10: create_msg_out(message * msg) meillo@0: { meillo@10: msg_out *msgout = NULL; meillo@0: meillo@10: msgout = g_malloc(sizeof(msg_out)); meillo@10: if (msgout) { meillo@10: msgout->msg = msg; meillo@10: msgout->return_path = NULL; meillo@10: msgout->rcpt_list = NULL; meillo@10: meillo@10: msgout->hdr_list = NULL; meillo@10: msgout->xtra_hdr_list = NULL; meillo@10: } meillo@10: return msgout; meillo@0: } meillo@0: meillo@10: msg_out* meillo@10: clone_msg_out(msg_out * msgout_orig) meillo@0: { meillo@10: if (msgout_orig) { meillo@10: msg_out *msgout = create_msg_out(msgout_orig->msg); meillo@10: if (msgout) { meillo@10: msgout->msg = msgout_orig->msg; meillo@10: if (msgout_orig->return_path) meillo@10: msgout->return_path = copy_address(msgout_orig->return_path); meillo@10: if (msgout_orig->hdr_list) meillo@10: msgout->hdr_list = g_list_copy(msgout_orig->hdr_list); meillo@10: /* FIXME: if this lives longer than the original meillo@10: and we access one of the xtra hdrs, we will segfault meillo@10: or cause some weird bugs: */ meillo@10: msgout->xtra_hdr_list = NULL; meillo@10: if (msgout_orig->rcpt_list) meillo@10: msgout->rcpt_list = g_list_copy(msgout_orig->rcpt_list); meillo@10: } meillo@10: return msgout; meillo@10: } meillo@10: return NULL; meillo@0: } meillo@0: meillo@10: GList* meillo@10: create_msg_out_list(GList * msg_list) meillo@0: { meillo@10: GList *msgout_list = NULL; meillo@10: GList *msg_node; meillo@0: meillo@10: foreach(msg_list, msg_node) { meillo@10: message *msg = (message *) (msg_node->data); meillo@10: msgout_list = g_list_append(msgout_list, create_msg_out(msg)); meillo@10: } meillo@10: return msgout_list; meillo@0: } meillo@0: meillo@10: void meillo@10: destroy_msg_out(msg_out * msgout) meillo@0: { meillo@10: if (msgout) { meillo@10: if (msgout->return_path) meillo@10: destroy_address(msgout->return_path); meillo@10: if (msgout->hdr_list) meillo@10: g_list_free(msgout->hdr_list); meillo@10: if (msgout->xtra_hdr_list) { meillo@10: GList *hdr_node; meillo@10: foreach(msgout->xtra_hdr_list, hdr_node) { meillo@10: header *hdr = (header *) (hdr_node->data); meillo@10: destroy_header(hdr); meillo@10: } meillo@10: g_list_free(msgout->xtra_hdr_list); meillo@10: } meillo@10: g_free(msgout); meillo@10: } meillo@0: } meillo@0: meillo@10: void meillo@10: destroy_msg_out_list(GList * msgout_list) meillo@0: { meillo@10: GList *msgout_node; meillo@0: meillo@10: foreach(msgout_list, msgout_node) { meillo@10: msg_out *msgout = (msg_out *) (msgout_node->data); meillo@10: destroy_msg_out(msgout); meillo@10: } meillo@10: g_list_free(msgout_list); meillo@0: }