2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 Hiroyuki Yamamoto & The Sylpheed Claws Team
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.
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.
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.
25 #include <sys/types.h>
29 #include "mbox_folder.h"
32 #include "procheader.h"
36 #define MSGBUFSIZE 8192
38 static gboolean
mbox_write_data(FILE * mbox_fp
, FILE * new_fp
,
39 gchar
* new_filename
, gint size
);
40 static gboolean
mbox_rewrite(gchar
* mbox
);
41 static gboolean
mbox_purge_deleted(gchar
* mbox
);
42 static gchar
* mbox_get_new_path(FolderItem
* parent
, gchar
* name
);
43 static gchar
* mbox_get_folderitem_name(gchar
* name
);
47 static gchar
* mbox_folder_create_parent(const gchar
* path
)
49 if (!is_file_exist(path
)) {
52 new_path
= g_dirname(path
);
53 if (new_path
[strlen(new_path
) - 1] == G_DIR_SEPARATOR
)
54 new_path
[strlen(new_path
) - 1] = '\0';
56 if (!is_dir_exist(new_path
))
57 make_dir_hier(new_path
);
64 static gchar
*mbox_folder_get_path(FolderItem
*item
)
69 g_return_val_if_fail(item
!= NULL
, NULL
);
71 if (item
->path
&& item
->path
[0] == G_DIR_SEPARATOR
) {
72 mbox_folder_create_parent(item
->path
);
73 return g_strdup(item
->path
);
76 folder_path
= g_strdup(LOCAL_FOLDER(item
->folder
)->rootpath
);
77 g_return_val_if_fail(folder_path
!= NULL
, NULL
);
79 if (folder_path
[0] == G_DIR_SEPARATOR
) {
81 path
= g_strconcat(folder_path
, G_DIR_SEPARATOR_S
,
85 path
= g_strdup(folder_path
);
88 path
= g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S
,
89 folder_path
, G_DIR_SEPARATOR_S
,
92 path
= g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S
,
98 mbox_folder_create_parent(path
);
104 /**********************************************************/
108 /**********************************************************/
111 static GSList
* file_lock
= NULL
;
113 static gboolean
mbox_file_lock_file(gchar
* base
)
115 gchar
*lockfile
, *locklink
;
119 lockfile
= g_strdup_printf("%s.%d", base
, getpid());
120 if ((lockfp
= fopen(lockfile
, "w")) == NULL
) {
121 FILE_OP_ERROR(lockfile
, "fopen");
122 g_warning(_("can't create lock file %s\n"), lockfile
);
123 g_warning(_("use 'flock' instead of 'file' if possible.\n"));
128 fprintf(lockfp
, "%d\n", getpid());
131 locklink
= g_strconcat(base
, ".lock", NULL
);
132 while (link(lockfile
, locklink
) < 0) {
133 FILE_OP_ERROR(lockfile
, "link");
135 g_warning(_("can't create %s\n"), lockfile
);
141 g_warning(_("mailbox is owned by another"
142 " process, waiting...\n"));
152 static gboolean
mbox_fcntl_lockwrite_file(FILE * fp
)
156 lck
.l_type
= F_WRLCK
;
161 if (fcntl(fileno(fp
), F_SETLK
, &lck
) < 0)
167 static gboolean
mbox_fcntl_lockread_file(FILE * fp
)
171 lck
.l_type
= F_RDLCK
;
176 if (fcntl(fileno(fp
), F_SETLK
, &lck
) < 0)
182 static gboolean
mbox_fcntl_unlock_file(FILE * fp
)
186 lck
.l_type
= F_UNLCK
;
191 if (fcntl(fileno(fp
), F_SETLK
, &lck
) < 0)
197 static gboolean
mbox_file_unlock_file(gchar
* base
)
201 lockfile
= g_strdup_printf("%s.lock", base
);
208 static gboolean
mbox_lockread_file(FILE * fp
, gchar
* base
)
212 result
= mbox_fcntl_lockread_file(fp
);
214 if ((result
= mbox_file_lock_file(base
)) == TRUE
) {
215 file_lock
= g_slist_append(file_lock
, g_strdup(base
));
216 debug_print("lockfile lock %s.\n", base
);
219 g_warning(_("could not lock read file %s\n"), base
);
222 debug_print("fcntl lock %s.\n", base
);
227 static gboolean
mbox_lockwrite_file(FILE * fp
, gchar
* base
)
231 result
= mbox_fcntl_lockwrite_file(fp
);
233 if ((result
= mbox_file_lock_file(base
)) == TRUE
) {
234 file_lock
= g_slist_append(file_lock
, g_strdup(base
));
235 debug_print("lockfile lock %s.\n", base
);
238 g_warning(_("could not lock write file %s\n"), base
);
241 debug_print("fcntl lock %s.\n", base
);
246 static gboolean
mbox_unlock_file(FILE * fp
, gchar
* base
)
248 gboolean result
= FALSE
;
250 gboolean unlocked
= FALSE
;
252 for(l
= file_lock
; l
!= NULL
; l
= g_slist_next(l
)) {
253 gchar
* data
= l
->data
;
255 if (strcmp(data
, base
) == 0) {
256 file_lock
= g_slist_remove(file_lock
, data
);
258 result
= mbox_file_unlock_file(base
);
260 debug_print("lockfile unlock - %s.\n", base
);
266 result
= mbox_fcntl_unlock_file(fp
);
267 debug_print("fcntl unlock - %s.\n", base
);
273 /**********************************************************/
277 /**********************************************************/
279 #define MAILFILE_ERROR_NO_ERROR 0x000
280 #define MAILFILE_ERROR_FILE_NOT_FOUND 0x001
281 #define MAILFILE_ERROR_MEMORY 0x002
282 #define MAILFILE_ERROR_MESSAGE_NOT_FOUND 0x003
284 static int mailfile_error
= MAILFILE_ERROR_NO_ERROR
;
286 #define STATE_BEGIN 0x000
287 #define STATE_TEXT_READ 0x001
288 #define STATE_FROM_READ 0x002
289 #define STATE_FIELD_READ 0x003
290 #define STATE_END 0x004
291 #define STATE_END_OF_FILE 0x005
292 #define STATE_MEM_ERROR 0x006
293 #define STATE_TEXT_BEGIN 0x007
295 #define STATE_MASK 0x0FF /* filter state from functions */
297 #define STATE_RESTORE_POS 0x100 /* go back while reading */
299 typedef struct _mailfile mailfile
;
323 #define MSG_IS_INVALID(msg) \
324 ((msg).perm_flags == (msg).tmp_flags && (msg).tmp_flags == -1)
326 #define MSG_SET_INVALID(msg) \
327 ((msg).perm_flags = (msg).tmp_flags = -1)
329 static int startFrom(char * s
)
331 return (strncmp(s
, "From ", 5) == 0);
334 static int startSpace(char * s
)
336 return ((*s
== ' ') || (*s
== '\t'));
339 static int startEmpty(char * s
)
344 static void free_msg_list(GList
* l
)
346 GList
* elt
= g_list_first(l
);
351 elt
= g_list_next(elt
);
358 static mailfile
* mailfile_init_from_file(FILE * f
, gchar
* filename
)
361 GList
* msg_list
= NULL
;
368 struct _message
* data
= NULL
;
374 while (state
!= STATE_END_OF_FILE
) {
375 if ((state
& STATE_RESTORE_POS
) == 0) {
376 former_pos
= lastpos
;
379 r
= fgets(s
, 256, f
);
382 ignore_next
= (s
[strlen(s
) - 1] != '\n');
387 switch(state
& 0x0F) {
390 state
= STATE_END_OF_FILE
;
391 else if (startFrom(s
)) {
392 state
= STATE_FROM_READ
;
394 data
= g_new0(struct _message
, 1);
396 free_msg_list(msg_list
);
401 data
->msgnum
= msgnum
;
402 data
->offset
= lastpos
;
403 data
->header
= lastpos
;
406 data
->messageid
= NULL
;
407 data
->fromspace
= NULL
;
408 MSG_SET_INVALID(data
->flags
);
409 MSG_SET_INVALID(data
->old_flags
);
410 data
->fetched
= FALSE
;
411 msg_list
= g_list_append(msg_list
,
419 case STATE_TEXT_READ
:
422 else if (startFrom(s
))
423 state
= STATE_END
| STATE_RESTORE_POS
;
425 state
= STATE_TEXT_READ
;
428 case STATE_TEXT_BEGIN
:
429 data
->content
= lastpos
;
432 else if (startFrom(s
)) {
433 state
= STATE_END
| STATE_RESTORE_POS
;
436 state
= STATE_TEXT_READ
;
440 case STATE_FROM_READ
:
441 data
->content
= lastpos
;
444 else if (startSpace(s
))
445 state
= STATE_FROM_READ
;
446 else if (startEmpty(s
))
447 state
= STATE_TEXT_READ
;
449 state
= STATE_FIELD_READ
;
452 case STATE_FIELD_READ
:
453 data
->content
= lastpos
;
456 else if (startSpace(s
))
457 state
= STATE_FIELD_READ
;
458 else if (startEmpty(s
)) {
459 state
= STATE_TEXT_BEGIN
;
462 state
= STATE_FIELD_READ
;
466 if ((state
& STATE_MASK
) == STATE_END
) {
467 state
= STATE_BEGIN
| (state
& STATE_RESTORE_POS
);
473 r
= fgets(s
, 256, f
);
474 if (r
== NULL
|| *r
== '\0')
477 while (s
[strlen(s
) - 1] != '\n');
481 mf
= (mailfile
*) g_new0(struct _mailfile
, 1);
483 free_msg_list(msg_list
);
484 mailfile_error
= MAILFILE_ERROR_MEMORY
;
488 mf
->msg_list
= g_list_first(msg_list
);
490 mf
->filename
= g_strdup(filename
);
493 mailfile_error
= MAILFILE_ERROR_NO_ERROR
;
498 static mailfile
* mailfile_init(char * filename
)
504 f
= fopen(filename
, "r");
507 mailfile_error
= MAILFILE_ERROR_FILE_NOT_FOUND
;
511 mbox_lockread_file(f
, filename
);
513 mf
= mailfile_init_from_file(f
, filename
);
515 mbox_unlock_file(f
, filename
);
522 static void mailfile_done(mailfile
* f
)
524 free_msg_list(f
->msg_list
);
531 #define MAX_READ 4096
533 static char * readfile(char * filename, int offset, int max_offset)
542 handle = fopen(filename, "r");
544 if (handle == NULL) {
545 mailfile_error = MAILFILE_ERROR_FILE_NOT_FOUND;
549 size = max_offset - offset;
551 message = (char *) malloc(size + 1);
552 if (message == NULL) {
554 mailfile_error = MAILFILE_ERROR_MEMORY;
558 fseek(handle, offset, SEEK_SET);
562 if ((size - pos) > MAX_READ)
567 bread = fread(message + pos, 1, max, handle);
583 static char * mailfile_readmsg(mailfile f, int index)
589 struct _message * msginfo;
591 nth = g_list_nth(f->msg_list, index);
594 mailfile_error = MAILFILE_ERROR_MESSAGE_NOT_FOUND;
598 msginfo = (struct _message *)nth->data;
600 offset = msginfo->offset;
601 max_offset = msginfo->end;
602 message = readfile(f->filename, offset, max_offset);
604 mailfile_error = MAILFILE_ERROR_NO_ERROR;
609 static char * mailfile_readheader(mailfile f, int index)
615 struct _message * msginfo;
617 nth = g_list_nth(f->msg_list, index);
620 mailfile_error = MAILFILE_ERROR_MESSAGE_NOT_FOUND;
624 msginfo = (struct _message *)nth->data;
626 offset = msginfo->offset;
627 max_offset = msginfo->content;
628 message = readfile(f->filename, offset, max_offset);
630 mailfile_error = MAILFILE_ERROR_NO_ERROR;
635 static int mailfile_count(mailfile * f)
637 return g_list_length(f->msg_list);
640 static int mailfile_find_deleted(mailfile f, char * filename)
644 handle = fopen(filename, "r");
647 struct _message m = elt->data;
648 n = fread(&m.deleted, sizeof(int), 1, handle);
651 elt = g_list_next(elt);
660 /**********************************************************/
662 /* mbox cache operations */
664 /**********************************************************/
671 gboolean modification
;
674 typedef struct _mboxcache mboxcache
;
676 static GHashTable
* mbox_cache_table
= NULL
;
678 static MsgInfo
*mbox_parse_msg(FILE * fp
, struct _message
* msg
,
682 MsgFlags flags
= { 0, 0 };
684 MSG_SET_PERM_FLAGS(flags
, MSG_NEW
| MSG_UNREAD
);
686 g_return_val_if_fail(fp
!= NULL
, NULL
);
689 if (item
->stype
== F_QUEUE
) {
690 MSG_SET_TMP_FLAGS(flags
, MSG_QUEUED
);
691 } else if (item
->stype
== F_DRAFT
) {
692 MSG_SET_TMP_FLAGS(flags
, MSG_DRAFT
);
696 msginfo
= procheader_file_parse(fp
, flags
, FALSE
);
698 if (!msginfo
) return NULL
;
701 msginfo
->msgnum
= msg
->msgnum
;
702 msginfo
->folder
= item
;
708 static void mbox_cache_init()
710 mbox_cache_table
= g_hash_table_new(g_str_hash
, g_str_equal
);
713 static void mbox_cache_done()
715 g_hash_table_destroy(mbox_cache_table
);
718 static void mbox_cache_free_mbox(mboxcache
* cache
)
720 g_hash_table_remove(mbox_cache_table
, cache
->filename
);
723 mailfile_done(cache
->mf
);
725 g_ptr_array_free(cache
->tab_mf
, FALSE
);
727 g_free(cache
->filename
);
731 static void mbox_cache_get_msginfo_from_file(FILE * fp
, GList
* msg_list
)
736 for(l
= msg_list
; l
!= NULL
; l
= g_list_next(l
)) {
737 struct _message
* msg
;
739 msg
= (struct _message
*) l
->data
;
741 fseek(fp
, msg
->header
, SEEK_SET
);
742 msginfo
= mbox_parse_msg(fp
, msg
, NULL
);
746 g_strdup(msginfo
->msgid
);
747 if (msginfo
->fromspace
)
749 g_strdup(msginfo
->fromspace
);
750 msg
->flags
= msginfo
->flags
;
751 msg
->old_flags
= msginfo
->flags
;
753 procmsg_msginfo_free(msginfo
);
758 static void mbox_cache_get_msginfo(gchar
* filename
, GList
* msg_list
)
762 fp
= fopen(filename
, "r");
766 mbox_cache_get_msginfo_from_file(fp
, msg_list
);
770 static mboxcache
* mbox_cache_read_mbox(gchar
* filename
)
777 if (stat(filename
, &s
) < 0)
780 mf
= mailfile_init(filename
);
784 cache
= g_new0(mboxcache
, 1);
786 cache
->mtime
= s
.st_mtime
;
788 cache
->filename
= g_strdup(filename
);
789 cache
->modification
= FALSE
;
791 cache
->tab_mf
= g_ptr_array_new();
792 for(l
= mf
->msg_list
; l
!= NULL
; l
= g_list_next(l
))
793 g_ptr_array_add(cache
->tab_mf
, l
->data
);
795 mbox_cache_get_msginfo(filename
, mf
->msg_list
);
797 debug_print(_("read mbox - %s\n"), filename
);
802 static mboxcache
* mbox_cache_read_mbox_from_file(FILE * fp
, gchar
* filename
)
809 if (stat(filename
, &s
) < 0)
812 mf
= mailfile_init_from_file(fp
, filename
);
816 cache
= g_new0(mboxcache
, 1);
818 cache
->mtime
= s
.st_mtime
;
820 cache
->filename
= g_strdup(filename
);
822 cache
->tab_mf
= g_ptr_array_new();
823 for(l
= mf
->msg_list
; l
!= NULL
; l
= g_list_next(l
))
824 g_ptr_array_add(cache
->tab_mf
, l
->data
);
826 mbox_cache_get_msginfo_from_file(fp
, mf
->msg_list
);
828 debug_print(_("read mbox from file - %s\n"), filename
);
833 static void mbox_cache_insert_mbox(mboxcache
* data
)
835 if (mbox_cache_table
== NULL
)
838 g_hash_table_insert(mbox_cache_table
, data
->filename
, data
);
841 static mboxcache
* mbox_cache_get_mbox(gchar
* filename
)
843 if (mbox_cache_table
== NULL
)
846 return g_hash_table_lookup(mbox_cache_table
, filename
);
850 static gint
mbox_cache_get_count(gchar
* filename
)
854 cache
= mbox_cache_get_mbox(filename
);
857 if (cache
->mf
== NULL
)
859 return cache
->mf
->count
;
862 static gint
mbox_cache_get_mtime(gchar
* filename
)
866 cache
= mbox_cache_get_mbox(filename
);
872 static GList
* mbox_cache_get_msg_list(gchar
* filename
)
876 cache
= mbox_cache_get_mbox(filename
);
881 if (cache
->mf
== NULL
)
884 return cache
->mf
->msg_list
;
887 static void mbox_cache_synchronize_lists(GList
* old_msg_list
,
888 GList
* new_msg_list
)
893 for(l2
= old_msg_list
; l2
!= NULL
; l2
= g_list_next(l2
)) {
894 struct _message
* msg2
= l2
->data
;
896 if ((msg2
->messageid
== NULL
) ||
897 (msg2
->fromspace
== NULL
))
900 for(l
= new_msg_list
; l
!= NULL
; l
= g_list_next(l
)) {
901 struct _message
* msg
= l
->data
;
903 if ((msg
->messageid
== NULL
) ||
904 (msg
->fromspace
== NULL
))
907 if ((strcmp(msg
->messageid
, msg2
->messageid
) == 0) &&
908 (strcmp(msg
->fromspace
, msg2
->fromspace
) == 0)) {
909 if (msg2
->flags
.perm_flags
!= msg2
->old_flags
.perm_flags
) {
910 msg
->flags
= msg2
->flags
;
918 static void mbox_cache_synchronize(gchar
* filename
, gboolean sync
)
920 mboxcache
* new_cache
;
921 mboxcache
* old_cache
;
922 gboolean scan_new
= TRUE
;
925 old_cache
= mbox_cache_get_mbox(filename
);
927 if (old_cache
!= NULL
) {
928 if (stat(filename
, &s
) < 0) {
929 FILE_OP_ERROR(filename
, "stat");
930 } else if (old_cache
->mtime
== s
.st_mtime
) {
931 debug_print("Folder is not modified.\n");
940 if (strstr(filename, "trash") == 0)
941 printf("old_cache: %p %s\n", old_cache, filename);
943 printf("begin old\n");
944 for(l = old_cache->mf->msg_list ; l != NULL ;
945 l = g_list_next(l)) {
946 struct _message * msg = l->data;
953 new_cache
= mbox_cache_read_mbox(filename
);
956 if (strstr(filename, "trash") == 0)
957 printf("new_cache: %p %s\n", new_cache, filename);
959 printf("begin new\n");
960 for(l = new_cache->mf->msg_list ; l != NULL ;
961 l = g_list_next(l)) {
962 struct _message * msg = l->data;
972 if (sync
&& new_cache
&& old_cache
)
973 mbox_cache_synchronize_lists(old_cache
->mf
->msg_list
,
974 new_cache
->mf
->msg_list
);
976 if (old_cache
!= NULL
)
977 mbox_cache_free_mbox(old_cache
);
980 mbox_cache_insert_mbox(new_cache
);
982 printf("insert %p %s\n", new_cache, new_cache->filename);
983 printf("inserted %s %p\n", filename,
984 mbox_cache_get_mbox(filename));
990 static void mbox_cache_synchronize_from_file(FILE * fp
, gchar
* filename
,
993 mboxcache
* new_cache
;
994 mboxcache
* old_cache
;
995 gboolean scan_new
= TRUE
;
998 old_cache
= mbox_cache_get_mbox(filename
);
1000 if (old_cache
!= NULL
) {
1001 if (stat(filename
, &s
) < 0) {
1002 FILE_OP_ERROR(filename
, "stat");
1003 } else if (old_cache
->mtime
== s
.st_mtime
) {
1004 debug_print("Folder is not modified.\n");
1015 if (strstr(filename, "trash") == 0)
1016 printf("old_cache: %p %s\n", old_cache, filename);
1019 printf("begin old\n");
1020 for(l = old_cache->mf->msg_list ; l != NULL ;
1021 l = g_list_next(l)) {
1022 struct _message * msg = l->data;
1023 printf("%p\n", msg);
1025 printf("end old\n");
1029 new_cache
= mbox_cache_read_mbox_from_file(fp
, filename
);
1032 if (strstr(filename, "trash") == 0)
1033 printf("new_cache: %p %s\n", new_cache, filename);
1036 printf("begin new\n");
1037 for(l = new_cache->mf->msg_list ; l != NULL ;
1038 l = g_list_next(l)) {
1039 struct _message * msg = l->data;
1040 printf("%p\n", msg);
1042 printf("end new\n");
1049 if (sync
&& new_cache
&& old_cache
)
1050 mbox_cache_synchronize_lists(old_cache
->mf
->msg_list
,
1051 new_cache
->mf
->msg_list
);
1053 if (old_cache
!= NULL
)
1054 mbox_cache_free_mbox(old_cache
);
1057 mbox_cache_insert_mbox(new_cache
);
1059 printf("insert %p %s\n", new_cache, new_cache->filename);
1060 printf("inserted %s %p\n", filename,
1061 mbox_cache_get_mbox(filename));
1067 gboolean
mbox_cache_msg_fetched(gchar
* filename
, gint num
)
1069 struct _message
* msg
;
1072 cache
= mbox_cache_get_mbox(filename
);
1077 msg
= (struct _message
*) g_ptr_array_index(cache
->tab_mf
,
1082 return msg
->fetched
;
1085 void mbox_cache_msg_set_fetched(gchar
* filename
, gint num
)
1087 struct _message
* msg
;
1090 cache
= mbox_cache_get_mbox(filename
);
1095 msg
= (struct _message
*) g_ptr_array_index(cache
->tab_mf
,
1100 msg
->fetched
= TRUE
;
1103 struct _message
* mbox_cache_get_msg(gchar
* filename
, gint num
)
1107 cache
= mbox_cache_get_mbox(filename
);
1109 if (cache
== NULL
) {
1113 return (struct _message
*) g_ptr_array_index(cache
->tab_mf
,
1118 /**********************************************************/
1120 /* mbox operations */
1122 /**********************************************************/
1125 GSList
*mbox_get_msg_list(Folder
*folder
, FolderItem
*item
, gboolean use_cache
)
1134 struct timeval tv_before
, tv_after
, tv_result
;
1136 gettimeofday(&tv_before
, NULL
);
1141 mbox_path
= mbox_folder_get_path(item
);
1143 if (mbox_path
== NULL
)
1146 mbox_purge_deleted(mbox_path
);
1148 fp
= fopen(mbox_path
, "r");
1155 mbox_lockread_file(fp
, mbox_path
);
1157 mbox_cache_synchronize_from_file(fp
, mbox_path
, TRUE
);
1159 item
->last_num
= mbox_cache_get_count(mbox_path
);
1161 for(l
= mbox_cache_get_msg_list(mbox_path
) ; l
!= NULL
;
1162 l
= g_list_next(l
)) {
1163 struct _message
* msg
;
1165 msg
= (struct _message
*) l
->data
;
1167 if (MSG_IS_INVALID(msg
->flags
) || !MSG_IS_REALLY_DELETED(msg
->flags
)) {
1168 fseek(fp
, msg
->header
, SEEK_SET
);
1170 msginfo
= mbox_parse_msg(fp
, msg
, item
);
1172 if (!MSG_IS_INVALID(msg
->flags
))
1173 msginfo
->flags
= msg
->flags
;
1175 msg
->old_flags
= msginfo
->flags
;
1176 msg
->flags
= msginfo
->flags
;
1179 mlist
= g_slist_append(mlist
, msginfo
);
1182 MSG_SET_PERM_FLAGS(msg
->flags
, MSG_REALLY_DELETED
);
1186 mbox_unlock_file(fp
, mbox_path
);
1193 gettimeofday(&tv_after
, NULL
);
1195 timersub(&tv_after
, &tv_before
, &tv_result
);
1196 g_print("mbox_get_msg_list: %s: elapsed time: %ld.%06ld sec\n",
1197 mbox_path
, tv_result
.tv_sec
, tv_result
.tv_usec
);
1203 static gboolean
mbox_extract_msg(FolderItem
* item
, gint msgnum
,
1204 gchar
* dest_filename
)
1206 struct _message
* msg
;
1213 /* GList * msg_list;*/
1214 gboolean already_fetched
;
1217 mbox_path
= mbox_folder_get_path(item
);
1219 if (mbox_path
== NULL
)
1222 src
= fopen(mbox_path
, "r");
1228 mbox_lockread_file(src
, mbox_path
);
1230 mbox_cache_synchronize_from_file(src
, mbox_path
, TRUE
);
1232 already_fetched
= mbox_cache_msg_fetched(mbox_path
, msgnum
);
1234 if (already_fetched
) {
1235 mbox_unlock_file(src
, mbox_path
);
1241 msg
= mbox_cache_get_msg(mbox_path
, msgnum
);
1244 mbox_unlock_file(src
, mbox_path
);
1250 offset
= msg
->offset
;
1251 max_offset
= msg
->end
;
1253 size
= max_offset
- offset
;
1255 fseek(src
, offset
, SEEK_SET
);
1257 dest
= fopen(dest_filename
, "w");
1259 mbox_unlock_file(src
, mbox_path
);
1265 if (change_file_mode_rw(dest
, dest_filename
) < 0) {
1266 FILE_OP_ERROR(dest_filename
, "chmod");
1267 g_warning(_("can't change file mode\n"));
1270 if (!mbox_write_data(src
, dest
, dest_filename
, size
)) {
1271 mbox_unlock_file(src
, mbox_path
);
1274 unlink(dest_filename
);
1282 FILE_OP_ERROR(mbox_path
, "fread");
1286 mbox_cache_msg_set_fetched(mbox_path
, msgnum
);
1288 if (fclose(dest
) == -1) {
1289 FILE_OP_ERROR(dest_filename
, "fclose");
1293 mbox_unlock_file(src
, mbox_path
);
1295 if (fclose(src
) == -1) {
1296 FILE_OP_ERROR(mbox_path
, "fclose");
1303 unlink(dest_filename
);
1310 gchar
*mbox_fetch_msg(Folder
*folder
, FolderItem
*item
, gint num
)
1315 g_return_val_if_fail(item
!= NULL
, NULL
);
1316 g_return_val_if_fail(num
> 0 && num
<= item
->last_num
, NULL
);
1318 path
= folder_item_get_path(item
);
1319 if (!is_dir_exist(path
))
1320 make_dir_hier(path
);
1322 filename
= g_strconcat(path
, G_DIR_SEPARATOR_S
, itos(num
), NULL
);
1326 if (!mbox_extract_msg(item
, num
, filename
)) {
1334 gint
mbox_add_msg(Folder
*folder
, FolderItem
*dest
, const gchar
*file
,
1335 gboolean remove_source
)
1344 gchar from_line
[MSGBUFSIZE
];
1346 if (dest
->last_num
< 0) {
1347 mbox_scan_folder(folder
, dest
);
1348 if (dest
->last_num
< 0) return -1;
1351 src_fp
= fopen(file
, "r");
1352 if (src_fp
== NULL
) {
1356 mbox_path
= mbox_folder_get_path(dest
);
1357 if (mbox_path
== NULL
)
1360 dest_fp
= fopen(mbox_path
, "a");
1361 if (dest_fp
== NULL
) {
1367 if (change_file_mode_rw(dest_fp
, mbox_path
) < 0) {
1368 FILE_OP_ERROR(mbox_path
, "chmod");
1369 g_warning(_("can't change file mode\n"));
1372 old_size
= ftell(dest_fp
);
1374 mbox_lockwrite_file(dest_fp
, mbox_path
);
1376 if (fgets(from_line
, sizeof(from_line
), src_fp
) == NULL
) {
1377 mbox_unlock_file(dest_fp
, mbox_path
);
1378 g_warning(_("unvalid file - %s.\n"), file
);
1385 if (strncmp(from_line
, "From ", 5) != 0) {
1388 if (stat(file
, &s
) < 0) {
1389 mbox_unlock_file(dest_fp
, mbox_path
);
1390 g_warning(_("unvalid file - %s.\n"), file
);
1397 fprintf(dest_fp
, "From - %s", ctime(&s
.st_mtime
));
1400 fputs(from_line
, dest_fp
);
1403 n_read
= fread(buf
, 1, sizeof(buf
), src_fp
);
1404 if ((n_read
< (gint
) sizeof(buf
)) && ferror(src_fp
))
1406 if (fwrite(buf
, n_read
, 1, dest_fp
) < 1) {
1407 mbox_unlock_file(dest_fp
, mbox_path
);
1408 g_warning(_("writing to %s failed.\n"), mbox_path
);
1409 ftruncate(fileno(dest_fp
), old_size
);
1416 if (n_read
< (gint
) sizeof(buf
))
1422 if (ferror(src_fp
)) {
1423 FILE_OP_ERROR(mbox_path
, "fread");
1426 mbox_unlock_file(dest_fp
, mbox_path
);
1428 if (fclose(src_fp
) == -1) {
1429 FILE_OP_ERROR(file
, "fclose");
1433 if (fclose(dest_fp
) == -1) {
1434 FILE_OP_ERROR(mbox_path
, "fclose");
1440 ftruncate(fileno(dest_fp
), old_size
);
1445 if (remove_source
) {
1446 if (unlink(file
) < 0)
1447 FILE_OP_ERROR(file
, "unlink");
1453 return dest
->last_num
;
1457 gint
mbox_remove_msg(Folder
*folder
, FolderItem
*item
, gint num
)
1459 struct _message
* msg
;
1462 mbox_path
= mbox_folder_get_path(item
);
1463 if (mbox_path
== NULL
)
1466 mbox_cache_synchronize(mbox_path
, TRUE
);
1468 msg
= mbox_cache_get_msg(mbox_path
, num
);
1473 MSG_SET_PERM_FLAGS(msg
->flags
, MSG_REALLY_DELETED
);
1478 gint
mbox_remove_all_msg(Folder
*folder
, FolderItem
*item
)
1483 mbox_path
= mbox_folder_get_path(item
);
1484 if (mbox_path
== NULL
)
1487 fp
= fopen(mbox_path
, "w");
1501 gint mbox_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
1506 filename = mbox_fetch_msg(folder, msginfo->folder, msginfo->msgnum);
1507 if (filename == NULL)
1510 msgnum = mbox_add_msg(folder, dest, filename, TRUE);
1513 MSG_SET_FLAGS(msginfo->flags, MSG_REALLY_DELETED);
1514 mbox_change_flags(folder, msginfo->folder, msginfo);
1520 gint mbox_move_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
1523 gchar * mbox_path = NULL;
1525 for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
1526 MsgInfo * msginfo = (MsgInfo *) l->data;
1528 if (msginfo->folder && mbox_path == NULL)
1529 mbox_path = mbox_folder_get_path(msginfo->folder);
1531 mbox_move_msg(folder, dest, msginfo);
1535 mbox_cache_synchronize(mbox_path);
1539 mbox_path = mbox_folder_get_path(dest);
1540 mbox_cache_synchronize(mbox_path);
1543 return dest->last_num;
1548 gint mbox_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
1553 filename = mbox_fetch_msg(folder, msginfo->folder, msginfo->msgnum);
1554 if (filename == NULL)
1557 msgnum = mbox_add_msg(folder, dest, filename, FALSE);
1562 gint mbox_copy_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
1565 gchar * mbox_path = NULL;
1567 for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
1568 MsgInfo * msginfo = (MsgInfo *) l->data;
1570 if (msginfo->folder && mbox_path == NULL)
1571 mbox_path = mbox_folder_get_path(msginfo->folder);
1573 mbox_copy_msg(folder, dest, msginfo);
1577 mbox_cache_synchronize(mbox_path);
1581 mbox_path = mbox_folder_get_path(dest);
1582 mbox_cache_synchronize(mbox_path);
1585 return dest->last_num;
1589 struct _copy_flags_info
1595 typedef struct _copy_flags_info CopyFlagsInfo
;
1597 GSList
* copy_flags_data
= NULL
;
1599 gint
mbox_copy_msg(Folder
*folder
, FolderItem
*dest
, MsgInfo
*msginfo
)
1601 Folder
* src_folder
;
1606 struct _message
* msg
;
1607 CopyFlagsInfo
* flags_info
;
1609 src_folder
= msginfo
->folder
->folder
;
1611 g_return_val_if_fail(src_folder
->fetch_msg
!= NULL
, -1);
1614 mbox_path = mbox_folder_get_path(msginfo->folder);
1615 mbox_rewrite(mbox_path);
1619 filename
= src_folder
->fetch_msg(src_folder
,
1622 if (filename
== NULL
)
1625 num
= folder
->add_msg(folder
, dest
, filename
, FALSE
);
1628 mbox_path = mbox_folder_get_path(dest);
1629 msg = mbox_cache_get_msg(mbox_path, num);
1631 msg->flags = msginfo->flags;
1638 flags_info
= g_new0(CopyFlagsInfo
, 1);
1639 flags_info
->num
= num
;
1640 flags_info
->flags
= msginfo
->flags
;
1641 copy_flags_data
= g_slist_append(copy_flags_data
, flags_info
);
1646 void mbox_finished_copy(Folder
*folder
, FolderItem
*dest
)
1652 mbox_path
= mbox_folder_get_path(dest
);
1653 if (mbox_path
== NULL
)
1656 mbox_cache_synchronize(mbox_path
, TRUE
);
1658 for(l
= copy_flags_data
; l
!= NULL
; l
= g_slist_next(l
)) {
1659 CopyFlagsInfo
* flags_info
= l
->data
;
1660 struct _message
* msg
;
1662 msg
= mbox_cache_get_msg(mbox_path
, flags_info
->num
);
1664 msg
->flags
= flags_info
->flags
;
1668 if (copy_flags_data
!= NULL
) {
1669 cache
= mbox_cache_get_mbox(mbox_path
);
1670 cache
->modification
= TRUE
;
1673 g_slist_free(copy_flags_data
);
1674 copy_flags_data
= NULL
;
1676 mbox_rewrite(mbox_path
);
1681 void mbox_scan_folder(Folder
*folder
, FolderItem
*item
)
1688 mbox_path
= mbox_folder_get_path(item
);
1689 if (mbox_path
== NULL
)
1692 mbox_cache_synchronize(mbox_path
, TRUE
);
1694 cached
= mbox_cache_get_mbox(mbox_path
);
1696 if (cached
== NULL
) {
1705 n_msg
= mbox_cache_get_count(mbox_path
);
1708 item
->new = item
->unread
= item
->total
= 0;
1715 for(l
= mbox_cache_get_msg_list(mbox_path
) ; l
!= NULL
;
1716 l
= g_list_next(l
)) {
1717 struct _message
* msg
= (struct _message
*) l
->data
;
1718 if (!MSG_IS_REALLY_DELETED(msg
->flags
))
1720 if (MSG_IS_NEW(msg
->flags
) /*&& !MSG_IS_IGNORE_THREAD(msg->flags)*/)
1722 if (MSG_IS_UNREAD(msg
->flags
) /*&& !MSG_IS_IGNORE_THREAD(msg->flags)*/)
1727 item
->unread
= unread
;
1728 item
->total
= total
;
1731 debug_print(_("Last number in dir %s = %d\n"), mbox_path
,
1733 item
->last_num
= n_msg
;
1737 gchar
* mbox_get_virtual_path(FolderItem
* item
)
1742 if (item
->parent
== NULL
) {
1746 gchar
* parent_path
;
1747 gchar
* result_path
;
1749 parent_path
= mbox_get_virtual_path(item
->parent
);
1750 if (parent_path
== NULL
)
1751 result_path
= g_strdup(item
->name
);
1753 result_path
= g_strconcat(parent_path
,
1756 g_free(parent_path
);
1762 static gboolean
mbox_write_data(FILE * mbox_fp
, FILE * new_fp
,
1763 gchar
* new_filename
, gint size
)
1771 while (pos
< size
) {
1772 if ((size
- pos
) > (gint
) sizeof(buf
))
1777 n_read
= fread(buf
, 1, max
, mbox_fp
);
1779 if (n_read
< max
&& ferror(mbox_fp
)) {
1782 if (fwrite(buf
, n_read
, 1, new_fp
) < 1) {
1783 g_warning(_("writing to %s failed.\n"), new_filename
);
1796 static gboolean
mbox_write_message(FILE * mbox_fp
, FILE * new_fp
,
1797 gchar
* new_filename
,
1798 struct _message
* msg
)
1801 GPtrArray
* headers
;
1804 fseek(mbox_fp
, msg
->header
, SEEK_SET
);
1806 headers
= procheader_get_header_array_asis(mbox_fp
);
1808 for (i
= 0; i
< (gint
) headers
->len
; i
++) {
1809 Header
* h
= g_ptr_array_index(headers
, i
);
1811 if (!procheader_headername_equal(h
->name
,
1813 !procheader_headername_equal(h
->name
,
1815 fwrite(h
->name
, strlen(h
->name
),
1817 if (h
->name
[strlen(h
->name
) - 1] != ' ')
1818 fwrite(" ", 1, 1, new_fp
);
1819 fwrite(h
->body
, strlen(h
->body
),
1821 fwrite("\n", 1, 1, new_fp
);
1823 procheader_header_free(h
);
1824 g_ptr_array_remove_index(headers
, i
);
1828 g_ptr_array_free(headers
, FALSE
);
1830 if (!MSG_IS_INVALID(msg
->flags
)) {
1832 fwrite("Status: ", strlen("Status: "), 1, new_fp
);
1833 if (!MSG_IS_UNREAD(msg
->flags
))
1834 fwrite("R", 1, 1, new_fp
);
1835 fwrite("O", 1, 1, new_fp
);
1836 fwrite("\n", 1, 1, new_fp
);
1838 /* X-Status header */
1839 if (MSG_IS_REALLY_DELETED(msg
->flags
)
1840 || MSG_IS_MARKED(msg
->flags
)
1841 || MSG_IS_DELETED(msg
->flags
)
1842 || MSG_IS_REPLIED(msg
->flags
)
1843 || MSG_IS_FORWARDED(msg
->flags
)) {
1844 fwrite("X-Status: ", strlen("X-Status: "), 1, new_fp
);
1845 if (MSG_IS_REALLY_DELETED(msg
->flags
))
1846 fwrite("D", 1, 1, new_fp
); /* really deleted */
1848 if (MSG_IS_MARKED(msg
->flags
))
1849 fwrite("F", 1, 1, new_fp
);
1850 if (MSG_IS_DELETED(msg
->flags
))
1851 fwrite("d", 1, 1, new_fp
);
1852 if (MSG_IS_REPLIED(msg
->flags
))
1853 fwrite("r", 1, 1, new_fp
);
1854 if (MSG_IS_FORWARDED(msg
->flags
))
1855 fwrite("f", 1, 1, new_fp
);
1857 fwrite("\n", 1, 1, new_fp
);
1861 fwrite("\n", 1, 1, new_fp
);
1863 size
= msg
->end
- msg
->content
;
1864 fseek(mbox_fp
, msg
->content
, SEEK_SET
);
1866 return mbox_write_data(mbox_fp
, new_fp
, new_filename
, size
);
1869 void mbox_update_mark(Folder
* folder
, FolderItem
* item
)
1873 mbox_path
= mbox_folder_get_path(item
);
1874 if (mbox_path
== NULL
)
1877 mbox_rewrite(mbox_path
);
1881 void mbox_change_flags(Folder
* folder
, FolderItem
* item
, MsgInfo
* info
)
1883 struct _message
* msg
;
1887 mbox_path
= mbox_folder_get_path(item
);
1888 if (mbox_path
== NULL
)
1891 msg
= mbox_cache_get_msg(mbox_path
, info
->msgnum
);
1893 cache
= mbox_cache_get_mbox(mbox_path
);
1897 if ((msg
== NULL
) || (cache
== NULL
))
1900 msg
->flags
= info
->flags
;
1902 cache
->modification
= TRUE
;
1906 static gboolean
mbox_rewrite(gchar
* mbox
)
1917 msg_list
= mbox_cache_get_msg_list(mbox
);
1919 cache
= mbox_cache_get_mbox(mbox
);
1923 if (!cache
->modification
) {
1924 debug_print(_("no modification - %s\n"), mbox
);
1928 debug_print(_("save modification - %s\n"), mbox
);
1930 mbox_fp
= fopen(mbox
, "r+");
1931 mbox_lockwrite_file(mbox_fp
, mbox
);
1933 mbox_cache_synchronize_from_file(mbox_fp
, mbox
, TRUE
);
1935 new = g_strconcat(mbox
, ".", itos((int) mbox
), NULL
);
1936 new_fp
= fopen(new, "w");
1938 if (change_file_mode_rw(new_fp
, new) < 0) {
1939 FILE_OP_ERROR(new, "chmod");
1940 g_warning(_("can't change file mode\n"));
1943 mbox_lockwrite_file(new_fp
, new);
1948 msg_list
= mbox_cache_get_msg_list(mbox
);
1949 for(l
= msg_list
; l
!= NULL
; l
= g_list_next(l
)) {
1950 struct _message
* msg
= (struct _message
*) l
->data
;
1951 if (!mbox_write_message(mbox_fp
, new_fp
, new, msg
)) {
1960 if (rename(new, mbox
) == -1) {
1961 g_warning(_("can't rename %s to %s\n"), new, mbox
);
1962 mbox_unlock_file(new_fp
, new);
1964 mbox_unlock_file(mbox_fp
, mbox
);
1969 if (change_file_mode_rw(new_fp
, mbox
) < 0) {
1970 FILE_OP_ERROR(new, "chmod");
1971 g_warning(_("can't change file mode\n"));
1974 mbox_unlock_file(new_fp
, new);
1978 mbox_unlock_file(mbox_fp
, mbox
);
1982 debug_print(_("%i messages written - %s\n"), count
, mbox
);
1984 cache
= mbox_cache_get_mbox(mbox
);
1989 mbox_cache_synchronize(mbox
, FALSE
);
1994 static gboolean
mbox_purge_deleted(gchar
* mbox
)
2001 gboolean modification
= FALSE
;
2005 mbox_cache_synchronize(mbox
, TRUE
);
2007 msg_list
= mbox_cache_get_msg_list(mbox
);
2009 for(l
= msg_list
; l
!= NULL
; l
= g_list_next(l
)) {
2010 struct _message
* msg
= (struct _message
*) l
->data
;
2011 if (MSG_IS_INVALID(msg
->flags
) && MSG_IS_REALLY_DELETED(msg
->flags
)) {
2012 modification
= TRUE
;
2017 if (!modification
) {
2018 debug_print(_("no deleted messages - %s\n"), mbox
);
2022 debug_print(_("purge deleted messages - %s\n"), mbox
);
2024 mbox_fp
= fopen(mbox
, "r+");
2025 mbox_lockwrite_file(mbox_fp
, mbox
);
2027 mbox_cache_synchronize_from_file(mbox_fp
, mbox
, TRUE
);
2029 new = g_strconcat(mbox
, ".", itos((int) mbox
), NULL
);
2030 new_fp
= fopen(new, "w");
2032 if (change_file_mode_rw(new_fp
, new) < 0) {
2033 FILE_OP_ERROR(new, "chmod");
2034 g_warning(_("can't change file mode\n"));
2037 mbox_lockwrite_file(new_fp
, new);
2042 msg_list
= mbox_cache_get_msg_list(mbox
);
2043 for(l
= msg_list
; l
!= NULL
; l
= g_list_next(l
)) {
2044 struct _message
* msg
= (struct _message
*) l
->data
;
2045 if (MSG_IS_INVALID(msg
->flags
) || !MSG_IS_REALLY_DELETED(msg
->flags
)) {
2046 if (!mbox_write_message(mbox_fp
, new_fp
, new, msg
)) {
2056 if (rename(new, mbox
) == -1) {
2057 g_warning(_("can't rename %s to %s\n"), new, mbox
);
2058 mbox_unlock_file(new_fp
, new);
2060 mbox_unlock_file(mbox_fp
, mbox
);
2065 if (change_file_mode_rw(new_fp
, mbox
) < 0) {
2066 FILE_OP_ERROR(new, "chmod");
2067 g_warning(_("can't change file mode\n"));
2070 mbox_unlock_file(new_fp
, new);
2074 mbox_unlock_file(mbox_fp
, mbox
);
2078 debug_print(_("%i messages written - %s\n"), count
, mbox
);
2080 mbox_cache_synchronize(mbox
, FALSE
);
2085 #define MAKE_DIR_IF_NOT_EXIST(dir) \
2087 if (!is_dir_exist(dir)) { \
2088 if (is_file_exist(dir)) { \
2089 g_warning(_("File `%s' already exists.\n" \
2090 "Can't create folder."), dir); \
2093 if (mkdir(dir, S_IRWXU) < 0) { \
2094 FILE_OP_ERROR(dir, "mkdir"); \
2097 if (chmod(dir, S_IRWXU) < 0) \
2098 FILE_OP_ERROR(dir, "chmod"); \
2102 gint
mbox_create_tree(Folder
*folder
)
2106 g_return_val_if_fail(folder
!= NULL
, -1);
2108 CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), -1);
2109 rootpath
= LOCAL_FOLDER(folder
)->rootpath
;
2110 MAKE_DIR_IF_NOT_EXIST(rootpath
);
2111 CHDIR_RETURN_VAL_IF_FAIL(rootpath
, -1);
2116 #undef MAKE_DIR_IF_NOT_EXIST
2118 static gchar
* mbox_get_new_path(FolderItem
* parent
, gchar
* name
)
2122 if (strchr(name
, '/') == NULL
) {
2123 if (parent
->path
!= NULL
)
2124 path
= g_strconcat(parent
->path
, ".sbd", G_DIR_SEPARATOR_S
, name
, NULL
);
2126 path
= g_strdup(name
);
2129 path
= g_strdup(name
);
2134 static gchar
* mbox_get_folderitem_name(gchar
* name
)
2138 foldername
= g_strdup(g_basename(name
));
2143 FolderItem
*mbox_create_folder(Folder
*folder
, FolderItem
*parent
,
2147 FolderItem
*new_item
;
2150 g_return_val_if_fail(folder
!= NULL
, NULL
);
2151 g_return_val_if_fail(parent
!= NULL
, NULL
);
2152 g_return_val_if_fail(name
!= NULL
, NULL
);
2154 path
= mbox_get_new_path(parent
, (gchar
*) name
);
2156 foldername
= mbox_get_folderitem_name((gchar
*) name
);
2158 new_item
= folder_item_new(foldername
, path
);
2159 folder_item_append(parent
, new_item
);
2161 if (!strcmp(name
, "inbox")) {
2162 new_item
->stype
= F_INBOX
;
2163 new_item
->folder
->inbox
= new_item
;
2164 } else if (!strcmp(name
, "outbox")) {
2165 new_item
->stype
= F_OUTBOX
;
2166 new_item
->folder
->outbox
= new_item
;
2167 } else if (!strcmp(name
, "draft")) {
2168 new_item
->stype
= F_DRAFT
;
2169 new_item
->folder
->draft
= new_item
;
2170 } else if (!strcmp(name
, "queue")) {
2171 new_item
->stype
= F_QUEUE
;
2172 new_item
->folder
->queue
= new_item
;
2173 } else if (!strcmp(name
, "trash")) {
2174 new_item
->stype
= F_TRASH
;
2175 new_item
->folder
->trash
= new_item
;
2184 gint
mbox_rename_folder(Folder
*folder
, FolderItem
*item
, const gchar
*name
)
2189 g_return_val_if_fail(folder
!= NULL
, -1);
2190 g_return_val_if_fail(item
!= NULL
, -1);
2191 g_return_val_if_fail(item
->path
!= NULL
, -1);
2192 g_return_val_if_fail(name
!= NULL
, -1);
2194 path
= mbox_get_new_path(item
->parent
, (gchar
*) name
);
2195 foldername
= mbox_get_folderitem_name((gchar
*) name
);
2197 if (rename(item
->path
, path
) == -1) {
2200 g_warning(_("Cannot rename folder item"));
2208 item
->name
= foldername
;
2214 gint
mbox_remove_folder(Folder
*folder
, FolderItem
*item
)
2216 g_return_val_if_fail(folder
!= NULL
, -1);
2217 g_return_val_if_fail(item
!= NULL
, -1);
2218 g_return_val_if_fail(item
->path
!= NULL
, -1);
2220 folder_item_remove(item
);