masqmail-0.2

view src/queue.c @ 75:257a9e6d1a8e

fixed correct processing of mails with data lines longer 4096 chars Mail messages with lines longer than 4096 chars were already read correctly, i.e. the spool files were correct. This commit fixes the reading of spool files with long lines. The old behavior was that the message body was truncated right before the first line longer 4096 chars. The number comes from MAX_DATALINE.
author meillo@marmaro.de
date Wed, 16 Jun 2010 19:06:34 +0200
parents f671821d8222
children 83a182793503
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 <sys/stat.h>
20 #include <glob.h>
22 #include "masqmail.h"
24 static void
25 mix_arr(int *buf, int len)
26 {
27 int i;
29 for (i = 0; i < len; i++)
30 buf[i] = i;
31 for (i = 0; i < len - 1; i++) {
32 int j = (int) ((float) (len - i) * ((float) rand()) / (RAND_MAX + 1.0));
33 int tmp;
35 if (i != j) {
36 tmp = buf[i];
37 buf[i] = buf[j];
38 buf[j] = tmp;
39 }
40 }
41 }
43 GList*
44 read_queue(gboolean do_readdata)
45 {
46 GList *msg_list = NULL;
47 glob_t gl;
48 gchar *pattern;
49 int i, *idx_arr;
51 /* Escaping the question marks prevents them from being
52 interpreted as trigraphs */
53 pattern = g_strdup_printf("%s/input/?????\?-??\?-?\?-H", conf.spool_dir);
54 gl.gl_offs = 0;
55 glob(pattern, 0, NULL, &gl);
57 g_free(pattern);
59 DEBUG(4) {
60 int i;
61 for (i = 0; i < gl.gl_pathc; i++) {
62 debugf("spoolfile: %s\n", gl.gl_pathv[i]);
63 }
64 }
66 idx_arr = g_malloc(sizeof(int) * gl.gl_pathc);
67 mix_arr(idx_arr, gl.gl_pathc);
69 for (i = 0; i < gl.gl_pathc; i++) {
70 gchar *uid;
72 /* copy 13 chars, offset spooldir path + 7 chars for /input/ */
73 /* uid length = 6 chars + '-' + 3 chars + '-' + 2 = 13 chars */
74 uid = g_strndup(&(gl.gl_pathv[idx_arr[i]][strlen(conf.spool_dir) + 7]), 13);
76 DEBUG(5) debugf("uid: %s\n", uid);
78 msg_list = g_list_append(msg_list, msg_spool_read(uid, do_readdata));
80 DEBUG(5) debugf("after read spool file for %s\n", uid);
82 g_free(uid);
83 }
84 return msg_list;
85 }
87 gboolean
88 queue_run()
89 {
90 GList *msg_list;
91 gboolean ok = TRUE;
93 logwrite(LOG_NOTICE, "Starting queue run.\n");
95 msg_list = read_queue(FALSE);
97 if (msg_list != NULL) {
98 ok = deliver_msg_list(msg_list, DLVR_ALL);
99 destroy_msg_list(msg_list);
100 }
101 logwrite(LOG_NOTICE, "Finished queue run.\n");
103 return ok;
104 }
106 gboolean
107 queue_run_online()
108 {
109 GList *msg_list = read_queue(FALSE);
110 gboolean ok = TRUE;
112 logwrite(LOG_NOTICE, "Starting online queue run.\n");
113 if (msg_list != NULL) {
114 ok = deliver_msg_list(msg_list, DLVR_ONLINE);
115 destroy_msg_list(msg_list);
116 }
117 logwrite(LOG_NOTICE, "Finished online queue run.\n");
119 return ok;
120 }
122 static gchar*
123 format_difftime(double secs)
124 {
125 if (secs > 86400)
126 return g_strdup_printf("%.1fd", secs / 86400);
127 else if (secs > 3600)
128 return g_strdup_printf("%.1fh", secs / 3600);
129 else if (secs > 60)
130 return g_strdup_printf("%.1fm", secs / 60);
131 else
132 return g_strdup_printf("%.0fs", secs);
133 }
135 void
136 queue_list()
137 {
138 GList *msg_list;
139 GList *msg_node;
141 msg_list = read_queue(FALSE);
143 if (msg_list != NULL) {
144 foreach(msg_list, msg_node) {
145 message *msg = (message *) (msg_node->data);
146 GList *rcpt_node;
147 gchar *size_str = NULL;
148 gchar *time_str = NULL;
149 gchar *host_str = NULL;
150 gchar *ident_str = NULL;
152 if (msg->data_size >= 0)
153 size_str = g_strdup_printf(" size=%d", msg->data_size);
154 if (msg->received_time > 0) {
155 gchar *tmp_str;
156 time_str = g_strdup_printf(" age=%s", tmp_str = format_difftime(difftime(time(NULL), msg->received_time)));
157 g_free(tmp_str);
158 }
159 if (msg->received_host != NULL)
160 host_str = g_strdup_printf(" host=%s", msg->received_host);
161 if (msg->ident != NULL)
162 ident_str = g_strdup_printf(" ident=%s", msg->ident);
164 printf("%s <= %s%s%s%s%s\n", msg->uid, addr_string(msg->return_path), size_str ? size_str : "",
165 time_str ? time_str : "", host_str ? host_str : "", ident_str ? ident_str : "");
167 if (size_str)
168 g_free(size_str);
169 if (time_str)
170 g_free(time_str);
171 if (host_str)
172 g_free(host_str);
173 if (ident_str)
174 g_free(ident_str);
176 foreach(msg->rcpt_list, rcpt_node) {
177 address *rcpt = (address *) (rcpt_node->data);
179 printf(" %s %s\n", addr_is_delivered(rcpt) ? "=>" : (addr_is_failed(rcpt) ? "!=" : "=="), addr_string(rcpt));
180 }
181 g_free(msg);
182 }
183 } else
184 printf("mail queue is empty.\n");
185 }
187 gboolean
188 queue_delete(gchar * uid)
189 {
190 gboolean hdr_ok = TRUE;
191 gboolean dat_ok = TRUE;
192 gchar *hdr_name = g_strdup_printf("%s/input/%s-H", conf.spool_dir, uid);
193 gchar *dat_name = g_strdup_printf("%s/input/%s-D", conf.spool_dir, uid);
194 struct stat stat_buf;
196 if (spool_lock(uid)) {
198 if (stat(hdr_name, &stat_buf) == 0) {
199 if (unlink(hdr_name) != 0) {
200 fprintf(stderr, "could not unlink %s: %s\n", hdr_name, strerror(errno));
201 hdr_ok = FALSE;
202 }
203 } else {
204 fprintf(stderr, "could not stat file %s: %s\n", hdr_name, strerror(errno));
205 hdr_ok = FALSE;
206 }
207 if (stat(dat_name, &stat_buf) == 0) {
208 if (unlink(dat_name) != 0) {
209 fprintf(stderr, "could not unlink %s: %s\n", dat_name, strerror(errno));
210 dat_ok = FALSE;
211 }
212 } else {
213 fprintf(stderr, "could not stat file %s: %s\n", dat_name, strerror(errno));
214 dat_ok = FALSE;
215 }
216 printf("message %s deleted\n", uid);
218 spool_unlock(uid);
220 } else {
222 fprintf(stderr, "message %s is locked.\n", uid);
223 return FALSE;
224 }
226 return (dat_ok && hdr_ok);
227 }