Statistics
| Revision:

root / libsylph / mbox.c @ 2640

History | View | Annotate | Download (11.8 kB)

1 1 hiro
/*
2 578 hiro
 * LibSylph -- E-Mail client library
3 2536 hiro
 * Copyright (C) 1999-2010 Hiroyuki Yamamoto
4 1 hiro
 *
5 578 hiro
 * This library is free software; you can redistribute it and/or
6 578 hiro
 * modify it under the terms of the GNU Lesser General Public
7 578 hiro
 * License as published by the Free Software Foundation; either
8 578 hiro
 * version 2.1 of the License, or (at your option) any later version.
9 1 hiro
 *
10 578 hiro
 * This library is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 578 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 578 hiro
 * Lesser General Public License for more details.
14 1 hiro
 *
15 578 hiro
 * You should have received a copy of the GNU Lesser General Public
16 578 hiro
 * License along with this library; if not, write to the Free Software
17 578 hiro
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include "defs.h"
25 1 hiro
26 1 hiro
#include <glib.h>
27 92 hiro
#include <glib/gi18n.h>
28 1 hiro
#include <stdio.h>
29 1 hiro
#include <unistd.h>
30 1 hiro
#include <string.h>
31 1 hiro
#include <fcntl.h>
32 1 hiro
#include <sys/file.h>
33 1 hiro
#include <ctype.h>
34 1 hiro
#include <time.h>
35 1 hiro
36 1 hiro
#include "mbox.h"
37 1 hiro
#include "procmsg.h"
38 2248 hiro
#include "procheader.h"
39 1 hiro
#include "folder.h"
40 1 hiro
#include "filter.h"
41 1 hiro
#include "prefs_common.h"
42 1 hiro
#include "prefs_account.h"
43 1 hiro
#include "account.h"
44 1 hiro
#include "utils.h"
45 1 hiro
46 1 hiro
#define FPUTS_TO_TMP_ABORT_IF_FAIL(s) \
47 1 hiro
{ \
48 1 hiro
        if (fputs(s, tmp_fp) == EOF) { \
49 1 hiro
                g_warning(_("can't write to temporary file\n")); \
50 1 hiro
                fclose(tmp_fp); \
51 1 hiro
                fclose(mbox_fp); \
52 478 hiro
                g_unlink(tmp_file); \
53 1 hiro
                g_free(tmp_file); \
54 1 hiro
                return -1; \
55 1 hiro
        } \
56 1 hiro
}
57 1 hiro
58 1 hiro
gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
59 1 hiro
{
60 1531 hiro
        return proc_mbox_full(dest, mbox, folder_table,
61 1535 hiro
                              folder_table ? TRUE : FALSE,
62 1535 hiro
                              folder_table && prefs_common.enable_junk &&
63 1535 hiro
                              prefs_common.filter_junk_on_recv ? TRUE : FALSE);
64 1531 hiro
}
65 1531 hiro
66 1531 hiro
gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
67 1535 hiro
                    GHashTable *folder_table, gboolean apply_filter,
68 1535 hiro
                    gboolean filter_junk)
69 1531 hiro
{
70 1 hiro
        FILE *mbox_fp;
71 2091 hiro
        gchar buf[BUFFSIZE], from_line[BUFFSIZE];
72 1 hiro
        gchar *tmp_file;
73 2196 hiro
        gint new_msgs = 0;
74 2196 hiro
        gint count = 0;
75 2196 hiro
        Folder *folder;
76 1 hiro
77 1 hiro
        g_return_val_if_fail(dest != NULL, -1);
78 2196 hiro
        g_return_val_if_fail(dest->folder != NULL, -1);
79 1 hiro
        g_return_val_if_fail(mbox != NULL, -1);
80 1 hiro
81 1 hiro
        debug_print(_("Getting messages from %s into %s...\n"), mbox, dest->path);
82 1 hiro
83 2196 hiro
        folder = dest->folder;
84 2196 hiro
85 478 hiro
        if ((mbox_fp = g_fopen(mbox, "rb")) == NULL) {
86 1 hiro
                FILE_OP_ERROR(mbox, "fopen");
87 1 hiro
                return -1;
88 1 hiro
        }
89 1 hiro
90 1 hiro
        /* ignore empty lines on the head */
91 1 hiro
        do {
92 1 hiro
                if (fgets(buf, sizeof(buf), mbox_fp) == NULL) {
93 1 hiro
                        g_warning(_("can't read mbox file.\n"));
94 1 hiro
                        fclose(mbox_fp);
95 1 hiro
                        return -1;
96 1 hiro
                }
97 1 hiro
        } while (buf[0] == '\n' || buf[0] == '\r');
98 1 hiro
99 1 hiro
        if (strncmp(buf, "From ", 5) != 0) {
100 1 hiro
                g_warning(_("invalid mbox format: %s\n"), mbox);
101 1 hiro
                fclose(mbox_fp);
102 1 hiro
                return -1;
103 1 hiro
        }
104 1 hiro
105 1 hiro
        strcpy(from_line, buf);
106 1 hiro
        if (fgets(buf, sizeof(buf), mbox_fp) == NULL) {
107 1 hiro
                g_warning(_("malformed mbox: %s\n"), mbox);
108 1 hiro
                fclose(mbox_fp);
109 1 hiro
                return -1;
110 1 hiro
        }
111 1 hiro
112 1 hiro
        tmp_file = get_tmp_file();
113 1 hiro
114 1 hiro
        do {
115 1 hiro
                FILE *tmp_fp;
116 1 hiro
                GSList *cur;
117 1 hiro
                gchar *startp, *endp, *rpath;
118 1 hiro
                gint empty_line;
119 1 hiro
                gboolean is_next_msg = FALSE;
120 2078 hiro
                gboolean is_junk = FALSE;
121 1 hiro
                FilterInfo *fltinfo;
122 2248 hiro
                MsgInfo *msginfo;
123 1 hiro
124 2196 hiro
                count++;
125 2196 hiro
                if (folder->ui_func)
126 2196 hiro
                        folder->ui_func(folder, dest, folder->ui_func_data ? dest->folder->ui_func_data : GINT_TO_POINTER(count));
127 2196 hiro
128 478 hiro
                if ((tmp_fp = g_fopen(tmp_file, "wb")) == NULL) {
129 1 hiro
                        FILE_OP_ERROR(tmp_file, "fopen");
130 1 hiro
                        g_warning(_("can't open temporary file\n"));
131 1 hiro
                        g_free(tmp_file);
132 1 hiro
                        fclose(mbox_fp);
133 1 hiro
                        return -1;
134 1 hiro
                }
135 1 hiro
                if (change_file_mode_rw(tmp_fp, tmp_file) < 0)
136 1 hiro
                        FILE_OP_ERROR(tmp_file, "chmod");
137 1 hiro
138 1 hiro
                /* convert unix From into Return-Path */
139 1 hiro
                startp = from_line + 5;
140 1 hiro
                endp = strchr(startp, ' ');
141 1 hiro
                if (endp == NULL)
142 1 hiro
                        rpath = g_strdup(startp);
143 1 hiro
                else
144 1 hiro
                        rpath = g_strndup(startp, endp - startp);
145 1 hiro
                g_strstrip(rpath);
146 1 hiro
                g_snprintf(from_line, sizeof(from_line),
147 1 hiro
                           "Return-Path: %s\n", rpath);
148 1 hiro
                g_free(rpath);
149 1 hiro
150 1 hiro
                FPUTS_TO_TMP_ABORT_IF_FAIL(from_line);
151 1 hiro
                FPUTS_TO_TMP_ABORT_IF_FAIL(buf);
152 1 hiro
                from_line[0] = '\0';
153 1 hiro
154 1 hiro
                empty_line = 0;
155 1 hiro
156 1 hiro
                while (fgets(buf, sizeof(buf), mbox_fp) != NULL) {
157 1 hiro
                        if (buf[0] == '\n' || buf[0] == '\r') {
158 1 hiro
                                empty_line++;
159 1 hiro
                                buf[0] = '\0';
160 1 hiro
                                continue;
161 1 hiro
                        }
162 1 hiro
163 1 hiro
                        /* From separator */
164 1 hiro
                        while (!strncmp(buf, "From ", 5)) {
165 1 hiro
                                strcpy(from_line, buf);
166 1 hiro
                                if (fgets(buf, sizeof(buf), mbox_fp) == NULL) {
167 1 hiro
                                        buf[0] = '\0';
168 1 hiro
                                        break;
169 1 hiro
                                }
170 1 hiro
171 1 hiro
                                if (is_header_line(buf)) {
172 1 hiro
                                        is_next_msg = TRUE;
173 1 hiro
                                        break;
174 1 hiro
                                } else if (!strncmp(buf, "From ", 5)) {
175 1 hiro
                                        continue;
176 1 hiro
                                } else if (!strncmp(buf, ">From ", 6)) {
177 1 hiro
                                        g_memmove(buf, buf + 1, strlen(buf));
178 1 hiro
                                        is_next_msg = TRUE;
179 1 hiro
                                        break;
180 1 hiro
                                } else {
181 1 hiro
                                        g_warning(_("unescaped From found:\n%s"),
182 1 hiro
                                                  from_line);
183 1 hiro
                                        break;
184 1 hiro
                                }
185 1 hiro
                        }
186 1 hiro
                        if (is_next_msg) break;
187 1 hiro
188 1 hiro
                        if (empty_line > 0) {
189 1 hiro
                                while (empty_line--)
190 1 hiro
                                        FPUTS_TO_TMP_ABORT_IF_FAIL("\n");
191 1 hiro
                                empty_line = 0;
192 1 hiro
                        }
193 1 hiro
194 1 hiro
                        if (from_line[0] != '\0') {
195 1 hiro
                                FPUTS_TO_TMP_ABORT_IF_FAIL(from_line);
196 1 hiro
                                from_line[0] = '\0';
197 1 hiro
                        }
198 1 hiro
199 1 hiro
                        if (buf[0] != '\0') {
200 1 hiro
                                if (!strncmp(buf, ">From ", 6)) {
201 1 hiro
                                        FPUTS_TO_TMP_ABORT_IF_FAIL(buf + 1);
202 1 hiro
                                } else
203 1 hiro
                                        FPUTS_TO_TMP_ABORT_IF_FAIL(buf);
204 1 hiro
205 1 hiro
                                buf[0] = '\0';
206 1 hiro
                        }
207 1 hiro
                }
208 1 hiro
209 1 hiro
                if (empty_line > 0) {
210 1 hiro
                        while (--empty_line)
211 1 hiro
                                FPUTS_TO_TMP_ABORT_IF_FAIL("\n");
212 1 hiro
                }
213 1 hiro
214 1 hiro
                if (fclose(tmp_fp) == EOF) {
215 1 hiro
                        FILE_OP_ERROR(tmp_file, "fclose");
216 1 hiro
                        g_warning(_("can't write to temporary file\n"));
217 478 hiro
                        g_unlink(tmp_file);
218 1 hiro
                        g_free(tmp_file);
219 1 hiro
                        fclose(mbox_fp);
220 1 hiro
                        return -1;
221 1 hiro
                }
222 1 hiro
223 1 hiro
                fltinfo = filter_info_new();
224 1 hiro
                fltinfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
225 1 hiro
                fltinfo->flags.tmp_flags = MSG_RECEIVED;
226 1 hiro
227 2248 hiro
                msginfo = procheader_parse_file(tmp_file, fltinfo->flags,
228 2248 hiro
                                                FALSE);
229 2248 hiro
                if (!msginfo) {
230 2248 hiro
                        g_warning("proc_mbox_full: procheader_parse_file failed");
231 2248 hiro
                        filter_info_free(fltinfo);
232 2248 hiro
                        g_unlink(tmp_file);
233 2248 hiro
                        g_free(tmp_file);
234 2248 hiro
                        fclose(mbox_fp);
235 2248 hiro
                        return -1;
236 2248 hiro
                }
237 2536 hiro
                fltinfo->flags = msginfo->flags;
238 2248 hiro
                msginfo->file_path = g_strdup(tmp_file);
239 2248 hiro
240 1535 hiro
                if (filter_junk && prefs_common.enable_junk &&
241 1464 hiro
                    prefs_common.filter_junk_before) {
242 2248 hiro
                        filter_apply_msginfo(prefs_common.junk_fltlist, msginfo,
243 2248 hiro
                                             fltinfo);
244 2078 hiro
                        if (fltinfo->drop_done)
245 2078 hiro
                                is_junk = TRUE;
246 1464 hiro
                }
247 1464 hiro
248 1531 hiro
                if (!fltinfo->drop_done && apply_filter)
249 2248 hiro
                        filter_apply_msginfo(prefs_common.fltlist, msginfo,
250 2248 hiro
                                             fltinfo);
251 1 hiro
252 1464 hiro
                if (!fltinfo->drop_done &&
253 1535 hiro
                    filter_junk && prefs_common.enable_junk &&
254 1464 hiro
                    !prefs_common.filter_junk_before) {
255 2248 hiro
                        filter_apply_msginfo(prefs_common.junk_fltlist, msginfo,
256 2248 hiro
                                             fltinfo);
257 2078 hiro
                        if (fltinfo->drop_done)
258 2078 hiro
                                is_junk = TRUE;
259 1464 hiro
                }
260 1464 hiro
261 1 hiro
                if (fltinfo->actions[FLT_ACTION_MOVE] == FALSE &&
262 1 hiro
                    fltinfo->actions[FLT_ACTION_DELETE] == FALSE) {
263 2248 hiro
                        msginfo->flags = fltinfo->flags;
264 2248 hiro
                        if (folder_item_add_msg_msginfo(dest, msginfo, FALSE) < 0) {
265 2248 hiro
                                procmsg_msginfo_free(msginfo);
266 1 hiro
                                filter_info_free(fltinfo);
267 478 hiro
                                g_unlink(tmp_file);
268 1 hiro
                                g_free(tmp_file);
269 1 hiro
                                fclose(mbox_fp);
270 1 hiro
                                return -1;
271 1 hiro
                        }
272 1 hiro
                        fltinfo->dest_list = g_slist_append(fltinfo->dest_list,
273 1 hiro
                                                            dest);
274 1 hiro
                }
275 1 hiro
276 1 hiro
                for (cur = fltinfo->dest_list; cur != NULL; cur = cur->next) {
277 1 hiro
                        FolderItem *drop_folder = (FolderItem *)cur->data;
278 1 hiro
                        gint val = 0;
279 1 hiro
280 1 hiro
                        if (folder_table) {
281 1 hiro
                                val = GPOINTER_TO_INT(g_hash_table_lookup
282 1 hiro
                                                      (folder_table,
283 1 hiro
                                                       drop_folder));
284 1 hiro
                        }
285 1 hiro
                        if (val == 0) {
286 1 hiro
                                if (folder_table) {
287 1 hiro
                                        g_hash_table_insert(folder_table,
288 1 hiro
                                                            drop_folder,
289 1 hiro
                                                            GINT_TO_POINTER(1));
290 1 hiro
                                }
291 1 hiro
                        }
292 1 hiro
                }
293 1 hiro
294 2078 hiro
                if (!is_junk &&
295 2078 hiro
                    fltinfo->actions[FLT_ACTION_DELETE] == FALSE &&
296 2078 hiro
                    fltinfo->actions[FLT_ACTION_MARK_READ] == FALSE)
297 2196 hiro
                        new_msgs++;
298 2078 hiro
299 2248 hiro
                procmsg_msginfo_free(msginfo);
300 1 hiro
                filter_info_free(fltinfo);
301 478 hiro
                g_unlink(tmp_file);
302 1 hiro
        } while (from_line[0] != '\0');
303 1 hiro
304 1 hiro
        g_free(tmp_file);
305 1 hiro
        fclose(mbox_fp);
306 2196 hiro
        debug_print("%d new messages found.\n", new_msgs);
307 1 hiro
308 2196 hiro
        return new_msgs;
309 1 hiro
}
310 1 hiro
311 1 hiro
gint lock_mbox(const gchar *base, LockType type)
312 1 hiro
{
313 472 hiro
#ifdef G_OS_UNIX
314 1 hiro
        gint retval = 0;
315 1 hiro
316 1 hiro
        if (type == LOCK_FILE) {
317 1 hiro
                gchar *lockfile, *locklink;
318 1 hiro
                gint retry = 0;
319 1 hiro
                FILE *lockfp;
320 1 hiro
321 1 hiro
                lockfile = g_strdup_printf("%s.%d", base, getpid());
322 478 hiro
                if ((lockfp = g_fopen(lockfile, "wb")) == NULL) {
323 1 hiro
                        FILE_OP_ERROR(lockfile, "fopen");
324 1 hiro
                        g_warning(_("can't create lock file %s\n"), lockfile);
325 1 hiro
                        g_warning(_("use 'flock' instead of 'file' if possible.\n"));
326 1 hiro
                        g_free(lockfile);
327 1 hiro
                        return -1;
328 1 hiro
                }
329 1 hiro
330 1 hiro
                fprintf(lockfp, "%d\n", getpid());
331 1 hiro
                fclose(lockfp);
332 1 hiro
333 1 hiro
                locklink = g_strconcat(base, ".lock", NULL);
334 1 hiro
                while (link(lockfile, locklink) < 0) {
335 1 hiro
                        FILE_OP_ERROR(lockfile, "link");
336 1 hiro
                        if (retry >= 5) {
337 1 hiro
                                g_warning(_("can't create %s\n"), lockfile);
338 478 hiro
                                g_unlink(lockfile);
339 1 hiro
                                g_free(lockfile);
340 1 hiro
                                return -1;
341 1 hiro
                        }
342 1 hiro
                        if (retry == 0)
343 1 hiro
                                g_warning(_("mailbox is owned by another"
344 1 hiro
                                            " process, waiting...\n"));
345 1 hiro
                        retry++;
346 1 hiro
                        sleep(5);
347 1 hiro
                }
348 478 hiro
                g_unlink(lockfile);
349 1 hiro
                g_free(lockfile);
350 1 hiro
        } else if (type == LOCK_FLOCK) {
351 1 hiro
                gint lockfd;
352 1 hiro
353 1 hiro
#if HAVE_FLOCK
354 1 hiro
                if ((lockfd = open(base, O_RDONLY)) < 0) {
355 1 hiro
#else
356 1 hiro
                if ((lockfd = open(base, O_RDWR)) < 0) {
357 1 hiro
#endif
358 1 hiro
                        FILE_OP_ERROR(base, "open");
359 1 hiro
                        return -1;
360 1 hiro
                }
361 1 hiro
#if HAVE_FLOCK
362 1 hiro
                if (flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
363 1 hiro
                        perror("flock");
364 1 hiro
#else
365 1 hiro
#if HAVE_LOCKF
366 1 hiro
                if (lockf(lockfd, F_TLOCK, 0) < 0) {
367 1 hiro
                        perror("lockf");
368 1 hiro
#else
369 1 hiro
                {
370 1 hiro
#endif
371 1 hiro
#endif /* HAVE_FLOCK */
372 1 hiro
                        g_warning(_("can't lock %s\n"), base);
373 1 hiro
                        if (close(lockfd) < 0)
374 1 hiro
                                perror("close");
375 1 hiro
                        return -1;
376 1 hiro
                }
377 1 hiro
                retval = lockfd;
378 1 hiro
        } else {
379 1 hiro
                g_warning(_("invalid lock type\n"));
380 1 hiro
                return -1;
381 1 hiro
        }
382 1 hiro
383 1 hiro
        return retval;
384 472 hiro
#else
385 472 hiro
        return -1;
386 472 hiro
#endif /* G_OS_UNIX */
387 1 hiro
}
388 1 hiro
389 1 hiro
gint unlock_mbox(const gchar *base, gint fd, LockType type)
390 1 hiro
{
391 1 hiro
        if (type == LOCK_FILE) {
392 1 hiro
                gchar *lockfile;
393 1 hiro
394 1 hiro
                lockfile = g_strconcat(base, ".lock", NULL);
395 478 hiro
                if (g_unlink(lockfile) < 0) {
396 1 hiro
                        FILE_OP_ERROR(lockfile, "unlink");
397 1 hiro
                        g_free(lockfile);
398 1 hiro
                        return -1;
399 1 hiro
                }
400 1 hiro
                g_free(lockfile);
401 1 hiro
402 1 hiro
                return 0;
403 1 hiro
        } else if (type == LOCK_FLOCK) {
404 1 hiro
#if HAVE_FLOCK
405 1 hiro
                if (flock(fd, LOCK_UN) < 0) {
406 1 hiro
                        perror("flock");
407 1 hiro
#else
408 1 hiro
#if HAVE_LOCKF
409 1 hiro
                if (lockf(fd, F_ULOCK, 0) < 0) {
410 1 hiro
                        perror("lockf");
411 1 hiro
#else
412 1 hiro
                {
413 1 hiro
#endif
414 1 hiro
#endif /* HAVE_FLOCK */
415 1 hiro
                        g_warning(_("can't unlock %s\n"), base);
416 1 hiro
                        if (close(fd) < 0)
417 1 hiro
                                perror("close");
418 1 hiro
                        return -1;
419 1 hiro
                }
420 1 hiro
421 1 hiro
                if (close(fd) < 0) {
422 1 hiro
                        perror("close");
423 1 hiro
                        return -1;
424 1 hiro
                }
425 1 hiro
426 1 hiro
                return 0;
427 1 hiro
        }
428 1 hiro
429 1 hiro
        g_warning(_("invalid lock type\n"));
430 1 hiro
        return -1;
431 1 hiro
}
432 1 hiro
433 1 hiro
gint copy_mbox(const gchar *src, const gchar *dest)
434 1 hiro
{
435 1 hiro
        return copy_file(src, dest, TRUE);
436 1 hiro
}
437 1 hiro
438 1 hiro
void empty_mbox(const gchar *mbox)
439 1 hiro
{
440 469 hiro
#if HAVE_TRUNCATE
441 1 hiro
        if (truncate(mbox, 0) < 0) {
442 469 hiro
#endif
443 1 hiro
                FILE *fp;
444 1 hiro
445 469 hiro
#if HAVE_TRUNCATE
446 1 hiro
                FILE_OP_ERROR(mbox, "truncate");
447 469 hiro
#endif
448 478 hiro
                if ((fp = g_fopen(mbox, "wb")) == NULL) {
449 1 hiro
                        FILE_OP_ERROR(mbox, "fopen");
450 1 hiro
                        g_warning(_("can't truncate mailbox to zero.\n"));
451 1 hiro
                        return;
452 1 hiro
                }
453 1 hiro
                fclose(fp);
454 469 hiro
#if HAVE_TRUNCATE
455 1 hiro
        }
456 469 hiro
#endif
457 1 hiro
}
458 1 hiro
459 1 hiro
/* read all messages in SRC, and store them into one MBOX file. */
460 1 hiro
gint export_to_mbox(FolderItem *src, const gchar *mbox)
461 1 hiro
{
462 1 hiro
        GSList *mlist;
463 1 hiro
        GSList *cur;
464 1 hiro
        MsgInfo *msginfo;
465 1 hiro
        FILE *msg_fp;
466 1 hiro
        FILE *mbox_fp;
467 1 hiro
        gchar buf[BUFFSIZE];
468 1325 hiro
        PrefsAccount *cur_ac;
469 2205 hiro
        gint count = 0, length;
470 1 hiro
471 1 hiro
        g_return_val_if_fail(src != NULL, -1);
472 1 hiro
        g_return_val_if_fail(src->folder != NULL, -1);
473 1 hiro
        g_return_val_if_fail(mbox != NULL, -1);
474 1 hiro
475 1 hiro
        debug_print(_("Exporting messages from %s into %s...\n"),
476 1 hiro
                    src->path, mbox);
477 1 hiro
478 478 hiro
        if ((mbox_fp = g_fopen(mbox, "wb")) == NULL) {
479 1 hiro
                FILE_OP_ERROR(mbox, "fopen");
480 1 hiro
                return -1;
481 1 hiro
        }
482 1 hiro
483 1325 hiro
        cur_ac = account_get_current_account();
484 1325 hiro
485 1 hiro
        mlist = folder_item_get_msg_list(src, TRUE);
486 2205 hiro
        length = g_slist_length(mlist);
487 1 hiro
488 1 hiro
        for (cur = mlist; cur != NULL; cur = cur->next) {
489 1 hiro
                msginfo = (MsgInfo *)cur->data;
490 1 hiro
491 2205 hiro
                count++;
492 2205 hiro
                if (src->folder->ui_func)
493 2205 hiro
                        src->folder->ui_func(src->folder, src, src->folder->ui_func_data ? src->folder->ui_func_data : GINT_TO_POINTER(count));
494 2205 hiro
495 1 hiro
                msg_fp = procmsg_open_message(msginfo);
496 1 hiro
                if (!msg_fp) {
497 1 hiro
                        procmsg_msginfo_free(msginfo);
498 1 hiro
                        continue;
499 1 hiro
                }
500 1 hiro
501 1 hiro
                strncpy2(buf,
502 1 hiro
                         msginfo->from ? msginfo->from :
503 1325 hiro
                         cur_ac && cur_ac->address ?
504 1325 hiro
                         cur_ac->address : "unknown",
505 1 hiro
                         sizeof(buf));
506 1 hiro
                extract_address(buf);
507 1 hiro
508 1 hiro
                fprintf(mbox_fp, "From %s %s",
509 1 hiro
                        buf, ctime(&msginfo->date_t));
510 1 hiro
511 1 hiro
                while (fgets(buf, sizeof(buf), msg_fp) != NULL) {
512 1 hiro
                        if (!strncmp(buf, "From ", 5))
513 1 hiro
                                fputc('>', mbox_fp);
514 1 hiro
                        fputs(buf, mbox_fp);
515 1 hiro
                }
516 1 hiro
                fputc('\n', mbox_fp);
517 1 hiro
518 1 hiro
                fclose(msg_fp);
519 1 hiro
                procmsg_msginfo_free(msginfo);
520 1 hiro
        }
521 1 hiro
522 1 hiro
        g_slist_free(mlist);
523 1 hiro
524 1 hiro
        fclose(mbox_fp);
525 1 hiro
526 1 hiro
        return 0;
527 1 hiro
}