Mercurial > masqmail
annotate src/queue.c @ 323:29de6a1c4538
Fixed an important bug with folded headers!
g_strconcat() returns a *copy* of the string, but hdr->value still
pointed to the old header (which probably was a memory leak, too).
If the folded part had been quite small it was likely that the new
string was at the same position as the old one, thus making everything
go well. But if pretty long headers were folded several times it was
likely that the new string was allocated somewhere else in memory,
thus breaking things. In result mails to lots of recipients (folded
header) were frequently only sent to the ones in the first line. Sorry
for the inconvenience.
author | meillo@marmaro.de |
---|---|
date | Fri, 03 Jun 2011 09:47:27 +0200 |
parents | 5f559921391a |
children | a7a387253b2f |
rev | line source |
---|---|
0 | 1 /* MasqMail |
2 Copyright (C) 1999-2001 Oliver Kurth | |
224 | 3 Copyright (C) 2010 markus schnalke <meillo@marmaro.de> |
0 | 4 |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2 of the License, or | |
8 (at your option) any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; if not, write to the Free Software | |
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 */ | |
19 | |
20 #include <sys/stat.h> | |
21 #include <glob.h> | |
22 | |
15 | 23 #include "masqmail.h" |
24 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
25 static void |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
26 mix_arr(int *buf, int len) |
0 | 27 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
28 int i; |
0 | 29 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
30 for (i = 0; i < len; i++) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
31 buf[i] = i; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
32 for (i = 0; i < len - 1; i++) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
33 int j = (int) ((float) (len - i) * ((float) rand()) / (RAND_MAX + 1.0)); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
34 int tmp; |
0 | 35 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
36 if (i != j) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
37 tmp = buf[i]; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
38 buf[i] = buf[j]; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
39 buf[j] = tmp; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
40 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
41 } |
0 | 42 } |
43 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
44 GList* |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
45 read_queue(gboolean do_readdata) |
0 | 46 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
47 GList *msg_list = NULL; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
48 glob_t gl; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
49 gchar *pattern; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
50 int i, *idx_arr; |
0 | 51 |
38 | 52 /* Escaping the question marks prevents them from being |
53 interpreted as trigraphs */ | |
54 pattern = g_strdup_printf("%s/input/?????\?-??\?-?\?-H", conf.spool_dir); | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
55 gl.gl_offs = 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
56 glob(pattern, 0, NULL, &gl); |
0 | 57 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
58 g_free(pattern); |
0 | 59 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
60 DEBUG(4) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
61 int i; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
62 for (i = 0; i < gl.gl_pathc; i++) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
63 debugf("spoolfile: %s\n", gl.gl_pathv[i]); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
64 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
65 } |
0 | 66 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
67 idx_arr = g_malloc(sizeof(int) * gl.gl_pathc); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
68 mix_arr(idx_arr, gl.gl_pathc); |
0 | 69 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
70 for (i = 0; i < gl.gl_pathc; i++) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
71 gchar *uid; |
0 | 72 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
73 /* copy 13 chars, offset spooldir path + 7 chars for /input/ */ |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
74 /* uid length = 6 chars + '-' + 3 chars + '-' + 2 = 13 chars */ |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
75 uid = g_strndup(&(gl.gl_pathv[idx_arr[i]][strlen(conf.spool_dir) + 7]), 13); |
0 | 76 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
77 DEBUG(5) debugf("uid: %s\n", uid); |
0 | 78 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
79 msg_list = g_list_append(msg_list, msg_spool_read(uid, do_readdata)); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
80 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
81 DEBUG(5) debugf("after read spool file for %s\n", uid); |
0 | 82 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
83 g_free(uid); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
84 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
85 return msg_list; |
0 | 86 } |
87 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
88 gboolean |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
89 queue_run() |
0 | 90 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
91 GList *msg_list; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
92 gboolean ok = TRUE; |
0 | 93 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
94 logwrite(LOG_NOTICE, "Starting queue run.\n"); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
95 msg_list = read_queue(FALSE); |
277
5f559921391a
minor refactorings and cleanups
markus schnalke <meillo@marmaro.de>
parents:
236
diff
changeset
|
96 if (msg_list) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
97 ok = deliver_msg_list(msg_list, DLVR_ALL); |
277
5f559921391a
minor refactorings and cleanups
markus schnalke <meillo@marmaro.de>
parents:
236
diff
changeset
|
98 DEBUG(5) debugf(" deliver_msg_list() returned: %d\n", ok); |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
99 destroy_msg_list(msg_list); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
100 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
101 logwrite(LOG_NOTICE, "Finished queue run.\n"); |
0 | 102 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
103 return ok; |
0 | 104 } |
105 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
106 gboolean |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
107 queue_run_online() |
0 | 108 { |
277
5f559921391a
minor refactorings and cleanups
markus schnalke <meillo@marmaro.de>
parents:
236
diff
changeset
|
109 GList *msg_list; |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
110 gboolean ok = TRUE; |
0 | 111 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
112 logwrite(LOG_NOTICE, "Starting online queue run.\n"); |
277
5f559921391a
minor refactorings and cleanups
markus schnalke <meillo@marmaro.de>
parents:
236
diff
changeset
|
113 msg_list = read_queue(FALSE); |
5f559921391a
minor refactorings and cleanups
markus schnalke <meillo@marmaro.de>
parents:
236
diff
changeset
|
114 if (msg_list) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
115 ok = deliver_msg_list(msg_list, DLVR_ONLINE); |
277
5f559921391a
minor refactorings and cleanups
markus schnalke <meillo@marmaro.de>
parents:
236
diff
changeset
|
116 DEBUG(5) debugf(" deliver_msg_list() returned: %d\n", ok); |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
117 destroy_msg_list(msg_list); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
118 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
119 logwrite(LOG_NOTICE, "Finished online queue run.\n"); |
0 | 120 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
121 return ok; |
0 | 122 } |
123 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
124 static gchar* |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
125 format_difftime(double secs) |
0 | 126 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
127 if (secs > 86400) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
128 return g_strdup_printf("%.1fd", secs / 86400); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
129 else if (secs > 3600) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
130 return g_strdup_printf("%.1fh", secs / 3600); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
131 else if (secs > 60) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
132 return g_strdup_printf("%.1fm", secs / 60); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
133 else |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
134 return g_strdup_printf("%.0fs", secs); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
135 } |
0 | 136 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
137 void |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
138 queue_list() |
0 | 139 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
140 GList *msg_list; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
141 GList *msg_node; |
0 | 142 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
143 msg_list = read_queue(FALSE); |
0 | 144 |
82 | 145 if (msg_list == NULL) { |
146 printf("mail queue is empty.\n"); | |
147 return; | |
148 } | |
0 | 149 |
82 | 150 foreach(msg_list, msg_node) { |
151 message *msg = (message *) (msg_node->data); | |
152 GList *rcpt_node; | |
153 gchar *size_str = NULL; | |
154 gchar *time_str = NULL; | |
155 gchar *host_str = NULL; | |
156 gchar *ident_str = NULL; | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
157 |
82 | 158 if (msg->data_size >= 0) |
159 size_str = g_strdup_printf(" size=%d", msg->data_size); | |
160 if (msg->received_time > 0) { | |
161 gchar *tmp_str; | |
162 time_str = g_strdup_printf(" age=%s", tmp_str = format_difftime(difftime(time(NULL), msg->received_time))); | |
163 g_free(tmp_str); | |
164 } | |
165 if (msg->received_host != NULL) | |
166 host_str = g_strdup_printf(" host=%s", msg->received_host); | |
167 if (msg->ident != NULL) | |
168 ident_str = g_strdup_printf(" ident=%s", msg->ident); | |
169 | |
170 printf("%s <= %s%s%s%s%s\n", msg->uid, addr_string(msg->return_path), size_str ? size_str : "", | |
171 time_str ? time_str : "", host_str ? host_str : "", ident_str ? ident_str : ""); | |
0 | 172 |
82 | 173 if (size_str) |
174 g_free(size_str); | |
175 if (time_str) | |
176 g_free(time_str); | |
177 if (host_str) | |
178 g_free(host_str); | |
179 if (ident_str) | |
180 g_free(ident_str); | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
181 |
82 | 182 foreach(msg->rcpt_list, rcpt_node) { |
183 address *rcpt = (address *) (rcpt_node->data); | |
0 | 184 |
82 | 185 printf(" %s %s\n", addr_is_delivered(rcpt) ? "=>" : (addr_is_failed(rcpt) ? "!=" : "=="), addr_string(rcpt)); |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
186 } |
82 | 187 g_free(msg); |
188 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
189 } |
0 | 190 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
191 gboolean |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
192 queue_delete(gchar * uid) |
0 | 193 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
194 gboolean hdr_ok = TRUE; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
195 gboolean dat_ok = TRUE; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
196 gchar *hdr_name = g_strdup_printf("%s/input/%s-H", conf.spool_dir, uid); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
197 gchar *dat_name = g_strdup_printf("%s/input/%s-D", conf.spool_dir, uid); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
198 struct stat stat_buf; |
0 | 199 |
82 | 200 if (!spool_lock(uid)) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
201 fprintf(stderr, "message %s is locked.\n", uid); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
202 return FALSE; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
203 } |
0 | 204 |
82 | 205 if (stat(hdr_name, &stat_buf) == 0) { |
206 if (unlink(hdr_name) != 0) { | |
207 fprintf(stderr, "could not unlink %s: %s\n", hdr_name, strerror(errno)); | |
208 hdr_ok = FALSE; | |
209 } | |
210 } else { | |
211 fprintf(stderr, "could not stat file %s: %s\n", hdr_name, strerror(errno)); | |
212 hdr_ok = FALSE; | |
213 } | |
214 if (stat(dat_name, &stat_buf) == 0) { | |
215 if (unlink(dat_name) != 0) { | |
216 fprintf(stderr, "could not unlink %s: %s\n", dat_name, strerror(errno)); | |
217 dat_ok = FALSE; | |
218 } | |
219 } else { | |
220 fprintf(stderr, "could not stat file %s: %s\n", dat_name, strerror(errno)); | |
221 dat_ok = FALSE; | |
222 } | |
223 printf("message %s deleted\n", uid); | |
224 | |
225 spool_unlock(uid); | |
226 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
227 return (dat_ok && hdr_ok); |
0 | 228 } |