2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2003 Hiroyuki Yamamoto
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.
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.
23 # include "claws-features.h"
27 #include <glib/gi18n.h>
36 #include <sys/types.h>
43 # include <sys/time.h>
48 #include "procheader.h"
49 #include "statusbar.h"
52 #include "localfolder.h"
54 #include "mailmbox_folder.h"
55 #include "mailmbox_parse.h"
56 #include "file-utils.h"
58 #define MAILMBOX_CACHE_DIR "mailmboxcache"
60 static Folder
*s_claws_mailmbox_folder_new(const gchar
*name
, const gchar
*path
);
62 static void claws_mailmbox_folder_destroy(Folder
*folder
);
64 static FolderItem
*claws_mailmbox_folder_item_new(Folder
*folder
);
66 static void claws_mailmbox_folder_item_destroy(Folder
*folder
, FolderItem
*_item
);
68 static gchar
*claws_mailmbox_item_get_path(Folder
*folder
, FolderItem
*item
);
70 static gint
claws_mailmbox_get_num_list(Folder
*folder
, FolderItem
*item
,
71 GSList
**list
, gboolean
*old_uids_valid
);
73 static MsgInfo
*claws_mailmbox_get_msginfo(Folder
*folder
,
74 FolderItem
*item
, gint num
);
76 static GSList
*claws_mailmbox_get_msginfos(Folder
*folder
, FolderItem
*item
,
79 static gchar
*s_claws_mailmbox_fetch_msg(Folder
*folder
, FolderItem
*item
, gint num
);
81 static gint
claws_mailmbox_add_msg(Folder
*folder
, FolderItem
*dest
,
82 const gchar
*file
, MsgFlags
*flags
);
84 static gint
claws_mailmbox_add_msgs(Folder
*folder
, FolderItem
*dest
,
86 GHashTable
*relation
);
88 static gint
s_claws_mailmbox_copy_msg(Folder
*folder
,
89 FolderItem
*dest
, MsgInfo
*msginfo
);
91 static gint
claws_mailmbox_copy_msgs(Folder
*folder
, FolderItem
*dest
,
92 MsgInfoList
*msglist
, GHashTable
*relation
);
94 static gint
claws_mailmbox_remove_msg(Folder
*folder
, FolderItem
*item
, gint num
);
95 static gint
claws_mailmbox_remove_msgs( Folder
*folder
, FolderItem
*item
, MsgInfoList
*msglist
, GHashTable
*relation
);
96 static gint
claws_mailmbox_remove_all_msg(Folder
*folder
, FolderItem
*item
);
98 static FolderItem
*claws_mailmbox_create_folder(Folder
*folder
, FolderItem
*parent
,
101 static gboolean
claws_mailmbox_scan_required(Folder
*folder
, FolderItem
*_item
);
103 static gint
claws_mailmbox_rename_folder(Folder
*folder
,
104 FolderItem
*item
, const gchar
*name
);
106 static gint
claws_mailmbox_remove_folder(Folder
*folder
, FolderItem
*item
);
108 static gint
claws_mailmbox_create_tree(Folder
*folder
);
110 static gint
claws_mailmbox_folder_item_close(Folder
*folder
, FolderItem
*item
);
112 static FolderClass claws_mailmbox_class
;
114 static gchar
* get_cache_dir(void)
116 static gchar
*mbox_cache_dir
= NULL
;
119 mbox_cache_dir
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
120 MAILMBOX_CACHE_DIR
, NULL
);
122 return mbox_cache_dir
;
126 FolderClass
*claws_mailmbox_get_class(void)
128 if (claws_mailmbox_class
.idstr
== NULL
) {
129 claws_mailmbox_class
.type
= F_MBOX
;
130 claws_mailmbox_class
.idstr
= "mailmbox";
131 claws_mailmbox_class
.uistr
= "mbox";
133 /* Folder functions */
134 claws_mailmbox_class
.new_folder
= s_claws_mailmbox_folder_new
;
135 claws_mailmbox_class
.destroy_folder
= claws_mailmbox_folder_destroy
;
136 claws_mailmbox_class
.set_xml
= folder_local_set_xml
;
137 claws_mailmbox_class
.get_xml
= folder_local_get_xml
;
138 claws_mailmbox_class
.create_tree
= claws_mailmbox_create_tree
;
140 /* FolderItem functions */
141 claws_mailmbox_class
.item_new
= claws_mailmbox_folder_item_new
;
142 claws_mailmbox_class
.item_destroy
= claws_mailmbox_folder_item_destroy
;
143 claws_mailmbox_class
.item_get_path
= claws_mailmbox_item_get_path
;
144 claws_mailmbox_class
.create_folder
= claws_mailmbox_create_folder
;
145 claws_mailmbox_class
.rename_folder
= claws_mailmbox_rename_folder
;
146 claws_mailmbox_class
.remove_folder
= claws_mailmbox_remove_folder
;
147 claws_mailmbox_class
.close
= claws_mailmbox_folder_item_close
;
148 claws_mailmbox_class
.get_num_list
= claws_mailmbox_get_num_list
;
149 claws_mailmbox_class
.scan_required
= claws_mailmbox_scan_required
;
151 /* Message functions */
152 claws_mailmbox_class
.get_msginfo
= claws_mailmbox_get_msginfo
;
153 claws_mailmbox_class
.get_msginfos
= claws_mailmbox_get_msginfos
;
154 claws_mailmbox_class
.fetch_msg
= s_claws_mailmbox_fetch_msg
;
155 claws_mailmbox_class
.add_msg
= claws_mailmbox_add_msg
;
156 claws_mailmbox_class
.add_msgs
= claws_mailmbox_add_msgs
;
157 claws_mailmbox_class
.copy_msg
= s_claws_mailmbox_copy_msg
;
158 claws_mailmbox_class
.copy_msgs
= claws_mailmbox_copy_msgs
;
159 claws_mailmbox_class
.remove_msg
= claws_mailmbox_remove_msg
;
160 claws_mailmbox_class
.remove_msgs
= claws_mailmbox_remove_msgs
;
161 claws_mailmbox_class
.remove_all_msg
= claws_mailmbox_remove_all_msg
;
163 return &claws_mailmbox_class
;
167 static void claws_mailmbox_folder_init(Folder
*folder
,
168 const gchar
*name
, const gchar
*path
)
170 folder_local_folder_init(folder
, name
, path
);
173 static Folder
*s_claws_mailmbox_folder_new(const gchar
*name
, const gchar
*path
)
177 folder
= (Folder
*)g_new0(MAILMBOXFolder
, 1);
178 folder
->klass
= &claws_mailmbox_class
;
179 claws_mailmbox_folder_init(folder
, name
, path
);
184 static void claws_mailmbox_folder_destroy(Folder
*folder
)
186 folder_local_folder_destroy(LOCAL_FOLDER(folder
));
189 typedef struct _MAILMBOXFolderItem MAILMBOXFolderItem
;
190 struct _MAILMBOXFolderItem
194 struct claws_mailmbox_folder
* mbox
;
197 static FolderItem
*claws_mailmbox_folder_item_new(Folder
*folder
)
199 MAILMBOXFolderItem
*item
;
201 item
= g_new0(MAILMBOXFolderItem
, 1);
203 item
->old_max_uid
= 0;
205 return (FolderItem
*)item
;
208 #define MAX_UID_FILE "max-uid"
210 static void read_max_uid_value(FolderItem
*item
, guint
* pmax_uid
)
218 path
= folder_item_get_path(item
);
219 file
= g_strconcat(path
, G_DIR_SEPARATOR_S
, MAX_UID_FILE
, NULL
);
222 f
= claws_fopen(file
, "r");
226 r
= claws_fread(&max_uid
, sizeof(max_uid
), 1, f
);
234 * pmax_uid
= max_uid
;
237 static void write_max_uid_value(FolderItem
*item
, guint max_uid
)
244 path
= folder_item_get_path(item
);
245 file
= g_strconcat(path
, G_DIR_SEPARATOR_S
, MAX_UID_FILE
, NULL
);
248 f
= claws_fopen(file
, "w");
252 r
= claws_fwrite(&max_uid
, sizeof(max_uid
), 1, f
);
258 claws_safe_fclose(f
);
261 static void claws_mailmbox_folder_item_destroy(Folder
*folder
, FolderItem
*_item
)
263 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
265 g_return_if_fail(item
!= NULL
);
267 if (item
->mbox
!= NULL
) {
268 write_max_uid_value(_item
, item
->mbox
->mb_written_uid
);
269 claws_mailmbox_done(item
->mbox
);
274 static gint
claws_mailmbox_folder_item_close(Folder
*folder
, FolderItem
*item_
)
276 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)item_
;
278 g_return_val_if_fail(folder
->klass
->type
== F_MBOX
, -1);
279 g_return_val_if_fail(item
!= NULL
, -1);
280 g_return_val_if_fail(item
->mbox
!= NULL
, -1);
282 return -claws_mailmbox_expunge(item
->mbox
);
285 static void claws_mailmbox_folder_create_parent(const gchar
* path
)
287 if (!is_file_exist(path
)) {
290 new_path
= g_path_get_dirname(path
);
291 if (new_path
[strlen(new_path
) - 1] == G_DIR_SEPARATOR
)
292 new_path
[strlen(new_path
) - 1] = '\0';
294 if (!is_dir_exist(new_path
))
295 make_dir_hier(new_path
);
301 static gchar
* claws_mailmbox_folder_get_path(Folder
*folder
, FolderItem
*item
)
306 g_return_val_if_fail(item
!= NULL
, NULL
);
308 if (item
->path
&& item
->path
[0] == G_DIR_SEPARATOR
) {
309 claws_mailmbox_folder_create_parent(item
->path
);
310 return g_strdup(item
->path
);
313 folder_path
= g_strdup(LOCAL_FOLDER(item
->folder
)->rootpath
);
314 g_return_val_if_fail(folder_path
!= NULL
, NULL
);
316 if (folder_path
[0] == G_DIR_SEPARATOR
) {
318 path
= g_strconcat(folder_path
, G_DIR_SEPARATOR_S
,
322 path
= g_strdup(folder_path
);
325 path
= g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S
,
326 folder_path
, G_DIR_SEPARATOR_S
,
329 path
= g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S
,
335 claws_mailmbox_folder_create_parent(path
);
340 static int claws_mailmbox_item_sync(FolderItem
*_item
, int validate_uid
)
342 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
345 if (item
->mbox
== NULL
) {
350 read_max_uid_value(_item
, &written_uid
);
351 path
= claws_mailmbox_folder_get_path(_item
->folder
, _item
);
352 r
= claws_mailmbox_init(path
, 0, 0, written_uid
, &item
->mbox
);
353 debug_print("init %d: %p\n", r
, item
->mbox
);
355 if (r
!= MAILMBOX_NO_ERROR
)
360 r
= claws_mailmbox_validate_read_lock(item
->mbox
);
361 if (r
!= MAILMBOX_NO_ERROR
) {
362 debug_print("read lock: %d\n", r
);
366 claws_mailmbox_read_unlock(item
->mbox
);
369 r
= claws_mailmbox_validate_write_lock(item
->mbox
);
370 if (r
!= MAILMBOX_NO_ERROR
) {
371 debug_print("write lock: %d\n", r
);
375 if (item
->mbox
->mb_written_uid
< item
->mbox
->mb_max_uid
) {
376 r
= claws_mailmbox_expunge_no_lock(item
->mbox
);
377 if (r
!= MAILMBOX_NO_ERROR
)
380 claws_mailmbox_write_unlock(item
->mbox
);
386 claws_mailmbox_write_unlock(item
->mbox
);
391 static struct claws_mailmbox_folder
* get_mbox(FolderItem
*_item
, int validate_uid
)
393 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
395 claws_mailmbox_item_sync(_item
, validate_uid
);
400 static gint
claws_mailmbox_get_num_list(Folder
*folder
, FolderItem
*item
,
401 GSList
**list
, gboolean
*old_uids_valid
)
405 struct claws_mailmbox_folder
* mbox
;
407 g_return_val_if_fail(item
!= NULL
, -1);
409 debug_print("mbox_get_last_num(): Scanning %s ...\n", item
->path
);
411 *old_uids_valid
= TRUE
;
413 mbox
= get_mbox(item
, 1);
417 for(i
= 0 ; i
< carray_count(mbox
->mb_tab
) ; i
++) {
418 struct claws_mailmbox_msg_info
* msg
;
420 msg
= carray_get(mbox
->mb_tab
, i
);
422 *list
= g_slist_prepend(*list
,
423 GINT_TO_POINTER(msg
->msg_uid
));
431 static gchar
*s_claws_mailmbox_fetch_msg(Folder
*folder
, FolderItem
*item
, gint num
)
436 struct claws_mailmbox_folder
* mbox
;
442 g_return_val_if_fail(item
!= NULL
, NULL
);
443 g_return_val_if_fail(num
> 0, NULL
);
445 mbox
= get_mbox(item
, 0);
449 path
= folder_item_get_path(item
);
450 if (!is_dir_exist(path
))
452 file
= g_strconcat(path
, G_DIR_SEPARATOR_S
, itos(num
), NULL
);
454 if (is_file_exist(file
)) {
458 r
= claws_mailmbox_fetch_msg(mbox
, num
, &data
, &len
);
459 if (r
!= MAILMBOX_NO_ERROR
)
462 old_mask
= umask(0077);
463 f
= claws_fopen(file
, "w");
468 r
= claws_fwrite(data
, 1, len
, f
);
472 claws_safe_fclose(f
);
484 static MsgInfo
*claws_mailmbox_parse_msg(guint uid
,
485 const char * data
, size_t len
, FolderItem
*_item
)
489 struct claws_mailmbox_folder
* mbox
;
492 struct claws_mailmbox_msg_info
* info
;
494 MAILMBOXFolderItem
* item
= (MAILMBOXFolderItem
*)_item
;
496 flags
.perm_flags
= MSG_NEW
|MSG_UNREAD
;
499 g_return_val_if_fail(item
!= NULL
, NULL
);
500 g_return_val_if_fail(data
!= NULL
, NULL
);
502 if (_item
->stype
== F_QUEUE
) {
503 MSG_SET_TMP_FLAGS(flags
, MSG_QUEUED
);
504 } else if (_item
->stype
== F_DRAFT
) {
505 MSG_SET_TMP_FLAGS(flags
, MSG_DRAFT
);
510 key
.data
= (char *) &uid
;
511 key
.len
= sizeof(uid
);
513 r
= chash_get(mbox
->mb_hash
, &key
, &value
);
517 info
= (struct claws_mailmbox_msg_info
*) value
.data
;
519 msginfo
= procheader_parse_str(data
, flags
, FALSE
, FALSE
);
520 if (!msginfo
) return NULL
;
522 msginfo
->msgnum
= uid
;
523 msginfo
->folder
= _item
;
524 msginfo
->size
= (goffset
)(info
->msg_size
- info
->msg_start_len
);
529 static MsgInfo
*claws_mailmbox_get_msginfo(Folder
*folder
,
530 FolderItem
*item
, gint num
)
536 struct claws_mailmbox_folder
* mbox
;
538 g_return_val_if_fail(item
!= NULL
, NULL
);
539 g_return_val_if_fail(num
> 0, NULL
);
541 mbox
= get_mbox(item
, 0);
545 r
= claws_mailmbox_validate_read_lock(mbox
);
546 if (r
!= MAILMBOX_NO_ERROR
)
549 r
= claws_mailmbox_fetch_msg_headers_no_lock(mbox
, num
, &data
, &len
);
550 if (r
!= MAILMBOX_NO_ERROR
)
553 msginfo
= claws_mailmbox_parse_msg(num
, data
, len
, item
);
557 claws_mailmbox_read_unlock(mbox
);
562 claws_mailmbox_read_unlock(mbox
);
567 static GSList
*claws_mailmbox_get_msginfos(Folder
*folder
, FolderItem
*item
,
573 struct claws_mailmbox_folder
* mbox
;
575 g_return_val_if_fail(item
!= NULL
, NULL
);
577 mbox
= get_mbox(item
, 0);
581 r
= claws_mailmbox_validate_read_lock(mbox
);
582 if (r
!= MAILMBOX_NO_ERROR
)
587 for (cur
= msgnum_list
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
593 num
= GPOINTER_TO_INT(cur
->data
);
595 r
= claws_mailmbox_fetch_msg_headers_no_lock(mbox
, num
, &data
, &len
);
596 if (r
!= MAILMBOX_NO_ERROR
)
599 msginfo
= claws_mailmbox_parse_msg(num
, data
, len
, item
);
603 ret
= g_slist_append(ret
, msginfo
);
606 claws_mailmbox_read_unlock(mbox
);
614 static gint
claws_mailmbox_add_msg(Folder
*folder
, FolderItem
*dest
,
615 const gchar
*file
, MsgFlags
*flags
)
619 MsgFileInfo fileinfo
;
621 g_return_val_if_fail(file
!= NULL
, -1);
623 fileinfo
.msginfo
= NULL
;
624 fileinfo
.file
= (gchar
*)file
;
625 fileinfo
.flags
= flags
;
626 file_list
.data
= &fileinfo
;
627 file_list
.next
= NULL
;
629 ret
= claws_mailmbox_add_msgs(folder
, dest
, &file_list
, NULL
);
635 static gint
claws_mailmbox_add_msgs(Folder
*folder
, FolderItem
*dest
,
637 GHashTable
*relation
)
641 struct claws_mailmbox_folder
* mbox
;
642 carray
* append_list
;
643 struct claws_mailmbox_append_info append_info
;
646 g_return_val_if_fail(dest
!= NULL
, -1);
647 g_return_val_if_fail(file_list
!= NULL
, -1);
649 mbox
= get_mbox(dest
, 0);
651 debug_print("mbox not found\n");
654 r
= claws_mailmbox_validate_write_lock(mbox
);
655 if (r
!= MAILMBOX_NO_ERROR
) {
656 debug_print("claws_mailmbox_validate_write_lock failed with %d\n", r
);
659 r
= claws_mailmbox_expunge_no_lock(mbox
);
660 if (r
!= MAILMBOX_NO_ERROR
) {
661 debug_print("claws_mailmbox_expunge_no_lock failed with %d\n", r
);
667 append_list
= carray_new(1);
668 if (append_list
== NULL
) {
669 debug_print("append_list is null\n");
673 r
= carray_set_size(append_list
, 1);
675 debug_print("carray_set_size failed with %d\n", r
);
679 carray_set(append_list
, 0, &append_info
);
681 for (cur
= file_list
; cur
!= NULL
; cur
= cur
->next
) {
683 struct stat stat_info
;
686 struct claws_mailmbox_msg_info
* msg
;
688 MsgFileInfo
*fileinfo
;
690 fileinfo
= (MsgFileInfo
*)cur
->data
;
692 fd
= open(fileinfo
->file
, O_RDONLY
);
694 debug_print("%s couldn't be opened\n", fileinfo
->file
);
698 r
= fstat(fd
, &stat_info
);
700 debug_print("%s couldn't be stat'ed\n", fileinfo
->file
);
704 len
= stat_info
.st_size
;
705 data
= mmap(NULL
, len
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
706 if (data
== MAP_FAILED
) {
707 debug_print("mmap failed\n");
711 append_info
.ai_message
= data
;
712 append_info
.ai_size
= len
;
714 cur_token
= mbox
->mb_mapping_size
;
716 r
= claws_mailmbox_append_message_list_no_lock(mbox
, append_list
);
717 if (r
!= MAILMBOX_NO_ERROR
) {
718 debug_print("claws_mailmbox_append_message_list_no_lock failed with %d\n", r
);
725 r
= claws_mailmbox_parse_additionnal(mbox
, &cur_token
);
726 if (r
!= MAILMBOX_NO_ERROR
) {
727 debug_print("claws_mailmbox_parse_additionnal failed with %d\n", r
);
731 msg
= carray_get(mbox
->mb_tab
, carray_count(mbox
->mb_tab
) - 1);
733 if (relation
!= NULL
)
734 g_hash_table_insert(relation
,
735 fileinfo
->msginfo
!= NULL
?
736 (gpointer
) fileinfo
->msginfo
:
738 GINT_TO_POINTER(msg
->msg_uid
));
740 last_num
= msg
->msg_uid
;
752 claws_mailmbox_sync(mbox
);
754 carray_free(append_list
);
755 claws_mailmbox_write_unlock(mbox
);
760 carray_free(append_list
);
762 claws_mailmbox_write_unlock(mbox
);
766 static gint
s_claws_mailmbox_copy_msg(Folder
*folder
,
767 FolderItem
*dest
, MsgInfo
*msginfo
)
771 g_return_val_if_fail(msginfo
!= NULL
, -1);
773 msglist
.data
= msginfo
;
776 return claws_mailmbox_copy_msgs(folder
, dest
, &msglist
, NULL
);
779 static gint
claws_mailmbox_copy_msgs(Folder
*folder
, FolderItem
*dest
,
780 MsgInfoList
*msglist
, GHashTable
*relation
)
786 g_return_val_if_fail(folder
!= NULL
, -1);
787 g_return_val_if_fail(dest
!= NULL
, -1);
788 g_return_val_if_fail(msglist
!= NULL
, -1);
790 msginfo
= (MsgInfo
*)msglist
->data
;
791 g_return_val_if_fail(msginfo
->folder
!= NULL
, -1);
793 file_list
= procmsg_get_message_file_list(msglist
);
794 g_return_val_if_fail(file_list
!= NULL
, -1);
796 ret
= claws_mailmbox_add_msgs(folder
, dest
, file_list
, relation
);
798 procmsg_message_file_list_free(file_list
);
804 static gint
claws_mailmbox_remove_msg(Folder
*folder
, FolderItem
*item
, gint num
)
806 struct claws_mailmbox_folder
* mbox
;
809 g_return_val_if_fail(item
!= NULL
, -1);
811 mbox
= get_mbox(item
, 0);
815 r
= claws_mailmbox_delete_msg(mbox
, num
);
816 if (r
!= MAILMBOX_NO_ERROR
)
823 claws_mailmbox_remove_msgs( Folder
*folder
, FolderItem
*item
,
824 MsgInfoList
*msglist
, GHashTable
*relation
)
826 struct claws_mailmbox_folder
*mbox
;
828 gint total
= 0, curnum
= 0;
830 g_return_val_if_fail( item
!=NULL
, -1 );
831 mbox
=get_mbox(item
,0);
832 g_return_val_if_fail( mbox
!=NULL
, -1 );
834 total
= g_slist_length(msglist
);
836 statusbar_print_all(_("Deleting messages..."));
840 for( cur
=msglist
; cur
; cur
=cur
->next
)
842 MsgInfo
*msginfo
=(MsgInfo
*) cur
->data
;
847 if( MSG_IS_MOVE(msginfo
->flags
) && MSG_IS_MOVE_DONE(msginfo
->flags
) )
849 msginfo
->flags
.tmp_flags
&=~MSG_MOVE_DONE
;
853 statusbar_progress_all(curnum
, total
, 100);
854 if (curnum
% 100 == 0)
858 claws_mailmbox_delete_msg(mbox
,msginfo
->msgnum
);
863 r
= claws_mailmbox_expunge(mbox
);
865 statusbar_progress_all(0,0,0);
873 static gint
claws_mailmbox_remove_all_msg(Folder
*folder
, FolderItem
*item
)
875 struct claws_mailmbox_folder
* mbox
;
879 g_return_val_if_fail(item
!= NULL
, -1);
881 mbox
= get_mbox(item
, 0);
885 for(i
= 0 ; i
< carray_count(mbox
->mb_tab
) ; i
++) {
886 struct claws_mailmbox_msg_info
* msg
;
888 msg
= carray_get(mbox
->mb_tab
, i
);
892 r
= claws_mailmbox_delete_msg(mbox
, msg
->msg_uid
);
893 if (r
!= MAILMBOX_NO_ERROR
)
901 static gchar
* claws_mailmbox_get_new_path(FolderItem
* parent
, gchar
* name
)
905 if (strchr(name
, G_DIR_SEPARATOR
) == NULL
) {
906 if (parent
->path
!= NULL
)
907 path
= g_strconcat(parent
->path
, ".sbd", G_DIR_SEPARATOR_S
, name
, NULL
);
909 path
= g_strdup(name
);
912 path
= g_strdup(name
);
917 static gchar
* claws_mailmbox_get_folderitem_name(gchar
* name
)
921 foldername
= g_path_get_basename(name
);
926 static FolderItem
*claws_mailmbox_create_folder(Folder
*folder
, FolderItem
*parent
,
930 FolderItem
*new_item
;
933 g_return_val_if_fail(folder
!= NULL
, NULL
);
934 g_return_val_if_fail(parent
!= NULL
, NULL
);
935 g_return_val_if_fail(name
!= NULL
, NULL
);
937 path
= claws_mailmbox_get_new_path(parent
, (gchar
*) name
);
939 foldername
= claws_mailmbox_get_folderitem_name((gchar
*) name
);
941 new_item
= folder_item_new(folder
, foldername
, path
);
942 folder_item_append(parent
, new_item
);
944 if (!strcmp(name
, "inbox")) {
945 new_item
->stype
= F_INBOX
;
946 new_item
->folder
->inbox
= new_item
;
947 } else if (!strcmp(name
, "outbox")) {
948 new_item
->stype
= F_OUTBOX
;
949 new_item
->folder
->outbox
= new_item
;
950 } else if (!strcmp(name
, "draft")) {
951 new_item
->stype
= F_DRAFT
;
952 new_item
->folder
->draft
= new_item
;
953 } else if (!strcmp(name
, "queue")) {
954 new_item
->stype
= F_QUEUE
;
955 new_item
->folder
->queue
= new_item
;
956 } else if (!strcmp(name
, "trash")) {
957 new_item
->stype
= F_TRASH
;
958 new_item
->folder
->trash
= new_item
;
969 static gboolean
claws_mailmbox_scan_required(Folder
*folder
, FolderItem
*_item
)
971 struct claws_mailmbox_folder
* mbox
;
972 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
975 g_return_val_if_fail(folder
!= NULL
, FALSE
);
976 g_return_val_if_fail(item
!= NULL
, FALSE
);
978 if (item
->item
.path
== NULL
)
981 mbox
= get_mbox(_item
, 0);
985 scan_required
= (item
->old_max_uid
!= item
->mbox
->mb_max_uid
);
987 item
->old_max_uid
= item
->mbox
->mb_max_uid
;
989 return scan_required
;
993 static gint
claws_mailmbox_rename_folder(Folder
*folder
,
994 FolderItem
*item
, const gchar
*name
)
1000 g_return_val_if_fail(folder
!= NULL
, -1);
1001 g_return_val_if_fail(item
!= NULL
, -1);
1002 g_return_val_if_fail(item
->path
!= NULL
, -1);
1003 g_return_val_if_fail(name
!= NULL
, -1);
1005 parent
= folder_item_parent(item
);
1006 g_return_val_if_fail(parent
, -1);
1008 path
= claws_mailmbox_get_new_path(parent
, (gchar
*) name
);
1009 foldername
= claws_mailmbox_get_folderitem_name((gchar
*) name
);
1011 if (rename(item
->path
, path
) == -1) {
1014 debug_print("Cannot rename folder item\n");
1022 item
->name
= foldername
;
1028 static gint
claws_mailmbox_remove_folder(Folder
*folder
, FolderItem
*item
)
1030 g_return_val_if_fail(folder
!= NULL
, -1);
1031 g_return_val_if_fail(item
!= NULL
, -1);
1032 g_return_val_if_fail(item
->path
!= NULL
, -1);
1034 folder_item_remove(item
);
1038 #define MAKE_DIR_IF_NOT_EXIST(dir) \
1040 if (!is_dir_exist(dir)) { \
1041 if (is_file_exist(dir)) { \
1042 debug_print("File `%s' already exists.\n" \
1043 "Can't create folder.", dir); \
1046 if (mkdir(dir, S_IRWXU) < 0) { \
1047 FILE_OP_ERROR(dir, "mkdir"); \
1050 if (chmod(dir, S_IRWXU) < 0) \
1051 FILE_OP_ERROR(dir, "chmod"); \
1055 static gint
claws_mailmbox_create_tree(Folder
*folder
)
1059 g_return_val_if_fail(folder
!= NULL
, -1);
1061 CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), -1);
1062 rootpath
= LOCAL_FOLDER(folder
)->rootpath
;
1063 MAKE_DIR_IF_NOT_EXIST(rootpath
);
1064 CHDIR_RETURN_VAL_IF_FAIL(rootpath
, -1);
1069 #undef MAKE_DIR_IF_NOT_EXIST
1072 static char * quote_mailbox(char * mb
)
1074 char path
[PATH_MAX
];
1079 remaining
= sizeof(path
) - 1;
1084 if (((* mb
>= 'a') && (* mb
<= 'z')) ||
1085 ((* mb
>= 'A') && (* mb
<= 'Z')) ||
1086 ((* mb
>= '0') && (* mb
<= '9'))) {
1098 snprintf(p
, 3, "%02x", (unsigned char) (* mb
));
1113 static gchar
*claws_mailmbox_item_get_path(Folder
*folder
, FolderItem
*item
)
1115 gchar
*itempath
, *path
;
1118 if (item
->path
== NULL
)
1121 if (folder
->name
== NULL
)
1124 folderpath
= quote_mailbox(folder
->name
);
1125 if (folderpath
== NULL
)
1127 itempath
= quote_mailbox(item
->path
);
1128 if (itempath
== NULL
) {
1132 path
= g_strconcat(get_cache_dir(),
1133 G_DIR_SEPARATOR_S
, folderpath
,
1134 G_DIR_SEPARATOR_S
, itempath
, NULL
);