src/mn-mh-mailbox-backend.gob (6940B) - raw
1 /*
2 * Mail Notification
3 * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
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 3 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 %headertop{
21 #include "mn-vfs-mailbox-backend.h"
22 %}
23
24 %{
25 #include <glib/gi18n.h>
26 #include "mn-mailbox-private.h"
27 #include "mn-reentrant-mailbox-private.h"
28 #include "mn-vfs-mailbox-backend-private.h"
29 #include "mn-vfs.h"
30 #include "mn-util.h"
31 #include "mn-message-mime.h"
32
33 #define SEQUENCES_FILE ".mh_sequences"
34 #define XMH_CACHE_FILE ".xmhcache"
35 %}
36
37 class MN:MH:Mailbox:Backend from MN:VFS:Mailbox:Backend
38 {
39 class_init (class)
40 {
41 MN_VFS_MAILBOX_BACKEND_CLASS(class)->format = "MH";
42 }
43
44 constructor (self)
45 {
46 MNVFSMailboxBackend *backend = MN_VFS_MAILBOX_BACKEND(self);
47
48 /*
49 * There is no standard way of locking a MH mailbox, so avoid race
50 * conditions by setting a check latency of 3 seconds.
51 */
52
53 backend->check_latency = 3000;
54 }
55
56 override (MN:VFS:Mailbox:Backend) void
57 monitor_cb (MNVFSMailboxBackend *backend,
58 const char *info_uri,
59 GnomeVFSMonitorEventType event_type)
60 {
61 if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED
62 || event_type == GNOME_VFS_MONITOR_EVENT_DELETED
63 || event_type == GNOME_VFS_MONITOR_EVENT_CREATED)
64 {
65 char *filename;
66
67 filename = mn_vfs_uri_extract_short_name(info_uri);
68 if (filename)
69 {
70 if (! strcmp(filename, SEQUENCES_FILE) || mn_str_isnumeric(filename))
71 mn_vfs_mailbox_backend_queue_check(backend);
72
73 g_free(filename);
74 }
75 }
76 }
77
78 override (MN:VFS:Mailbox:Backend) gboolean
79 is (MNVFSMailboxBackend *dummy,
80 MNVFSMailboxBackendClass *class,
81 MNVFSMailbox *mailbox)
82 {
83 GnomeVFSURI *sequences_uri;
84 gboolean is;
85
86 sequences_uri = gnome_vfs_uri_append_file_name(mailbox->vfs_uri, SEQUENCES_FILE);
87 is = mn_vfs_test(sequences_uri, G_FILE_TEST_IS_REGULAR);
88 gnome_vfs_uri_unref(sequences_uri);
89
90 if (! is)
91 {
92 GnomeVFSURI *cache_uri;
93
94 cache_uri = gnome_vfs_uri_append_file_name(mailbox->vfs_uri, XMH_CACHE_FILE);
95 is = mn_vfs_test(cache_uri, G_FILE_TEST_IS_REGULAR);
96 gnome_vfs_uri_unref(cache_uri);
97 }
98
99 return is;
100 }
101
102 override (MN:VFS:Mailbox:Backend) void
103 check (MNVFSMailboxBackend *backend, int check_id)
104 {
105 GnomeVFSURI *sequences_uri;
106 GnomeVFSResult result;
107 GnomeVFSHandle *handle;
108
109 mn_vfs_mailbox_backend_monitor(backend, check_id, backend->mailbox->uri, GNOME_VFS_MONITOR_DIRECTORY);
110
111 sequences_uri = gnome_vfs_uri_append_file_name(backend->mailbox->vfs_uri, SEQUENCES_FILE);
112 result = gnome_vfs_open_uri(&handle, sequences_uri, GNOME_VFS_OPEN_READ);
113 gnome_vfs_uri_unref(sequences_uri);
114
115 if (result == GNOME_VFS_OK)
116 {
117 MNVFSReadLineContext *context = NULL;
118 const char *line;
119 GSList *messages = NULL;
120 int num_errors = 0;
121 GnomeVFSResult close_result;
122
123 while ((result = mn_vfs_read_line(&context, handle, &line)) == GNOME_VFS_OK)
124 if (g_str_has_prefix(line, "unseen: "))
125 {
126 int first;
127 char **elements;
128 int i;
129
130 elements = g_strsplit(line + 8, " ", 0);
131 for (i = 0; elements[i]; i++)
132 {
133 int last;
134 int n;
135
136 n = sscanf(elements[i], "%d-%d", &first, &last);
137 if (n >= 1)
138 {
139 int j;
140
141 if (n == 1)
142 last = first;
143
144 for (j = first; j <= last; j++)
145 {
146 char *filename;
147 GnomeVFSURI *message_uri;
148 MNMessage *message;
149 GError *err = NULL;
150
151 if (mn_reentrant_mailbox_check_aborted(MN_REENTRANT_MAILBOX(backend->mailbox), check_id))
152 {
153 g_strfreev(elements);
154 goto loop_end;
155 }
156
157 filename = g_strdup_printf("%i", j);
158 message_uri = gnome_vfs_uri_append_file_name(backend->mailbox->vfs_uri, filename);
159 g_free(filename);
160
161 /*
162 * We set handle_status to FALSE, since
163 * messages in the unseen sequence are by
164 * definition unseen (that is, new).
165 */
166
167 message = mn_message_new_from_uri(MN_MAILBOX(backend->mailbox),
168 message_uri,
169 MN_MESSAGE_NEW,
170 FALSE,
171 &err);
172 if (message)
173 messages = g_slist_prepend(messages, message);
174 else if (err)
175 {
176 char *message_text_uri;
177
178 message_text_uri = gnome_vfs_uri_to_string(message_uri, GNOME_VFS_URI_HIDE_PASSWORD);
179 mn_mailbox_warning(MN_MAILBOX(backend->mailbox), "cannot read message \"%s\": %s",
180 message_text_uri, err->message);
181 g_free(message_text_uri);
182 g_error_free(err);
183
184 num_errors++;
185 }
186
187 gnome_vfs_uri_unref(message_uri);
188 }
189 }
190 }
191 g_strfreev(elements);
192 }
193
194 loop_end:
195 mn_vfs_read_line_context_free(context);
196 close_result = gnome_vfs_close(handle);
197
198 GDK_THREADS_ENTER();
199
200 if (! mn_reentrant_mailbox_check_aborted(MN_REENTRANT_MAILBOX(backend->mailbox), check_id))
201 {
202 if (result == GNOME_VFS_ERROR_EOF || result == GNOME_VFS_OK)
203 {
204 if (close_result == GNOME_VFS_OK)
205 {
206 mn_mailbox_set_messages(MN_MAILBOX(backend->mailbox), messages);
207
208 if (num_errors != 0)
209 mn_mailbox_set_error(MN_MAILBOX(backend->mailbox),
210 ngettext("cannot read %i message",
211 "cannot read %i messages",
212 num_errors),
213 num_errors);
214 }
215 else
216 mn_mailbox_set_error(MN_MAILBOX(backend->mailbox), _("unable to close %s: %s"), SEQUENCES_FILE, gnome_vfs_result_to_string(close_result));
217 }
218 else
219 mn_mailbox_set_error(MN_MAILBOX(backend->mailbox), _("error while reading %s: %s"), SEQUENCES_FILE, gnome_vfs_result_to_string(result));
220 }
221
222 mn_g_object_slist_free(messages);
223
224 gdk_flush();
225 GDK_THREADS_LEAVE();
226 }
227 else
228 {
229 GnomeVFSURI *cache_uri;
230 gboolean cache_exists;
231
232 cache_uri = gnome_vfs_uri_append_file_name(backend->mailbox->vfs_uri, XMH_CACHE_FILE);
233 cache_exists = mn_vfs_test(cache_uri, G_FILE_TEST_IS_REGULAR);
234 gnome_vfs_uri_unref(cache_uri);
235
236 if (! mn_reentrant_mailbox_check_aborted(MN_REENTRANT_MAILBOX(backend->mailbox), check_id))
237 {
238 GDK_THREADS_ENTER();
239
240 if (cache_exists)
241 mn_mailbox_set_messages(MN_MAILBOX(backend->mailbox), NULL);
242 else
243 mn_mailbox_set_error(MN_MAILBOX(backend->mailbox), _("unable to open %s: %s"), SEQUENCES_FILE, gnome_vfs_result_to_string(result));
244
245 gdk_flush();
246 GDK_THREADS_LEAVE();
247 }
248 }
249 }
250 }