masqmail-0.2

view src/message.c @ 158:014b9e01ce25

do *not* use the openssl option -crlf in a wrapper command see masqmail.route(5) for details
author meillo@marmaro.de
date Wed, 14 Jul 2010 21:52:20 +0200
parents 71ce3a1568e9
children 087e99c7702a
line source
1 /* MasqMail
2 Copyright (C) 1999-2001 Oliver Kurth
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
19 #include "masqmail.h"
21 message*
22 create_message()
23 {
24 message *msg = (message *) g_malloc(sizeof(message));
25 if (msg) {
26 memset(msg, 0, sizeof(message));
27 msg->data_size = -1;
28 }
29 return msg;
30 }
32 /*
33 This function is currently (0.2.24) only used for client side SMTP
34 SIZE support (RFC 1870). The flag is_smtp is always true therefore.
36 Their definition of the message size in RFC 1870 is:
38 The message size is defined as the number of octets, including
39 CR-LF pairs, but not the SMTP DATA command's terminating dot
40 or doubled quoting dots, to be transmitted by the SMTP client
41 after receiving reply code 354 to the DATA command.
43 l_cnt (line count) covers '\r' characters which are not present in
44 masqmail's internal format. Dots are also not stuffed in the
45 internal format. Dot-stuffing is ignored in the size.
46 */
47 gint
48 msg_calc_size(message * msg, gboolean is_smtp)
49 {
50 GList *node;
51 gint l_cnt = 0; /* line count (we need to add so many '\r' for SMTP) */
52 gint c_cnt = 0; /* character count */
54 /* message header size */
55 if (msg->hdr_list) {
56 for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) {
57 if (node->data) {
58 header *hdr = (header *) (node->data);
59 if (hdr->header) {
60 char *p = hdr->header;
61 while (*p) {
62 if (*p++ == '\n')
63 l_cnt++;
64 c_cnt++;
65 }
66 }
67 }
68 }
69 }
71 /* empty line separating headers from data: */
72 c_cnt++;
73 l_cnt++;
75 /* message data size */
76 if (msg->data_list) {
77 for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) {
78 if (node->data) {
79 char *p = node->data;
80 while (*p) {
81 if (*p++ == '\n')
82 l_cnt++;
83 c_cnt++;
84 }
85 }
86 }
87 }
89 return is_smtp ? c_cnt + l_cnt : c_cnt;
90 }
92 void
93 msg_free_data(message * msg)
94 {
95 GList *node;
97 if (msg->data_list) {
98 for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) {
99 if (node->data)
100 g_free(node->data);
101 }
102 g_list_free(msg->data_list);
103 msg->data_list = NULL;
104 }
105 }
107 void
108 destroy_message(message * msg)
109 {
110 GList *node;
112 if (!msg) {
113 return;
114 }
116 if (msg->uid)
117 g_free(msg->uid);
118 if (msg->ident)
119 g_free(msg->ident);
120 if (msg->return_path)
121 g_free(msg->return_path);
123 if (msg->rcpt_list) {
124 for (node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)) {
125 if (node->data)
126 g_free(node->data);
127 }
128 g_list_free(msg->rcpt_list);
129 }
130 if (msg->hdr_list) {
131 for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) {
132 if (node->data) {
133 header *hdr = (header *) (node->data);
134 if (hdr->header)
135 g_free(hdr->header);
136 g_free(node->data);
137 }
138 }
139 g_list_free(msg->hdr_list);
140 }
142 if (msg->full_sender_name)
143 g_free(msg->full_sender_name);
145 msg_free_data(msg);
147 g_free(msg);
148 }
150 void
151 destroy_msg_list(GList * msg_list)
152 {
153 GList *msg_node;
155 foreach(msg_list, msg_node) {
156 message *msg = (message *) (msg_node->data);
157 destroy_message(msg);
158 }
159 g_list_free(msg_list);
160 }
162 msg_out*
163 create_msg_out(message * msg)
164 {
165 msg_out *msgout = NULL;
167 msgout = g_malloc(sizeof(msg_out));
168 if (msgout) {
169 msgout->msg = msg;
170 msgout->return_path = NULL;
171 msgout->rcpt_list = NULL;
173 msgout->hdr_list = NULL;
174 msgout->xtra_hdr_list = NULL;
175 }
176 return msgout;
177 }
179 msg_out*
180 clone_msg_out(msg_out * msgout_orig)
181 {
182 if (msgout_orig) {
183 msg_out *msgout = create_msg_out(msgout_orig->msg);
184 if (msgout) {
185 msgout->msg = msgout_orig->msg;
186 if (msgout_orig->return_path)
187 msgout->return_path = copy_address(msgout_orig->return_path);
188 if (msgout_orig->hdr_list)
189 msgout->hdr_list = g_list_copy(msgout_orig->hdr_list);
190 /* FIXME: if this lives longer than the original
191 and we access one of the xtra hdrs, we will segfault
192 or cause some weird bugs: */
193 msgout->xtra_hdr_list = NULL;
194 if (msgout_orig->rcpt_list)
195 msgout->rcpt_list = g_list_copy(msgout_orig->rcpt_list);
196 }
197 return msgout;
198 }
199 return NULL;
200 }
202 GList*
203 create_msg_out_list(GList * msg_list)
204 {
205 GList *msgout_list = NULL;
206 GList *msg_node;
208 foreach(msg_list, msg_node) {
209 message *msg = (message *) (msg_node->data);
210 msgout_list = g_list_append(msgout_list, create_msg_out(msg));
211 }
212 return msgout_list;
213 }
215 void
216 destroy_msg_out(msg_out * msgout)
217 {
218 if (msgout) {
219 if (msgout->return_path)
220 destroy_address(msgout->return_path);
221 if (msgout->hdr_list)
222 g_list_free(msgout->hdr_list);
223 if (msgout->xtra_hdr_list) {
224 GList *hdr_node;
225 foreach(msgout->xtra_hdr_list, hdr_node) {
226 header *hdr = (header *) (hdr_node->data);
227 destroy_header(hdr);
228 }
229 g_list_free(msgout->xtra_hdr_list);
230 }
231 g_free(msgout);
232 }
233 }
235 void
236 destroy_msg_out_list(GList * msgout_list)
237 {
238 GList *msgout_node;
240 foreach(msgout_list, msgout_node) {
241 msg_out *msgout = (msg_out *) (msgout_node->data);
242 destroy_msg_out(msgout);
243 }
244 g_list_free(msgout_list);
245 }