2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2024 Hiroyuki Yamamoto and the Claws Mail 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 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, see <http://www.gnu.org/licenses/>.
21 # include "claws-features.h"
25 #include <glib/gi18n.h>
33 #include <sys/types.h>
40 # include <sys/time.h>
45 #include "procheader.h"
46 #include "statusbar.h"
49 #include "localfolder.h"
51 #include "mailmbox_folder.h"
52 #include "mailmbox_parse.h"
53 #include "file-utils.h"
55 #define MAILMBOX_CACHE_DIR "mailmboxcache"
57 static Folder
*s_claws_mailmbox_folder_new(const gchar
*name
, const gchar
*path
);
59 static void claws_mailmbox_folder_destroy(Folder
*folder
);
61 static FolderItem
*claws_mailmbox_folder_item_new(Folder
*folder
);
63 static void claws_mailmbox_folder_item_destroy(Folder
*folder
, FolderItem
*_item
);
65 static gchar
*claws_mailmbox_item_get_path(Folder
*folder
, FolderItem
*item
);
67 static gint
claws_mailmbox_get_num_list(Folder
*folder
, FolderItem
*item
,
68 GSList
**list
, gboolean
*old_uids_valid
);
70 static MsgInfo
*claws_mailmbox_get_msginfo(Folder
*folder
,
71 FolderItem
*item
, gint num
);
73 static GSList
*claws_mailmbox_get_msginfos(Folder
*folder
, FolderItem
*item
,
76 static gchar
*s_claws_mailmbox_fetch_msg(Folder
*folder
, FolderItem
*item
, gint num
);
78 static gint
claws_mailmbox_add_msg(Folder
*folder
, FolderItem
*dest
,
79 const gchar
*file
, MsgFlags
*flags
);
81 static gint
claws_mailmbox_add_msgs(Folder
*folder
, FolderItem
*dest
,
83 GHashTable
*relation
);
85 static gint
s_claws_mailmbox_copy_msg(Folder
*folder
,
86 FolderItem
*dest
, MsgInfo
*msginfo
);
88 static gint
claws_mailmbox_copy_msgs(Folder
*folder
, FolderItem
*dest
,
89 MsgInfoList
*msglist
, GHashTable
*relation
);
91 static gint
claws_mailmbox_remove_msg(Folder
*folder
, FolderItem
*item
, gint num
);
92 static gint
claws_mailmbox_remove_msgs( Folder
*folder
, FolderItem
*item
, MsgInfoList
*msglist
, GHashTable
*relation
);
93 static gint
claws_mailmbox_remove_all_msg(Folder
*folder
, FolderItem
*item
);
95 static FolderItem
*claws_mailmbox_create_folder(Folder
*folder
, FolderItem
*parent
,
98 static gboolean
claws_mailmbox_scan_required(Folder
*folder
, FolderItem
*_item
);
100 static gint
claws_mailmbox_rename_folder(Folder
*folder
,
101 FolderItem
*item
, const gchar
*name
);
103 static gint
claws_mailmbox_remove_folder(Folder
*folder
, FolderItem
*item
);
105 static gint
claws_mailmbox_create_tree(Folder
*folder
);
107 static gint
claws_mailmbox_folder_item_close(Folder
*folder
, FolderItem
*item
);
109 static FolderClass claws_mailmbox_class
;
111 static gchar
* get_cache_dir(void)
113 static gchar
*mbox_cache_dir
= NULL
;
116 mbox_cache_dir
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
117 MAILMBOX_CACHE_DIR
, NULL
);
119 return mbox_cache_dir
;
123 FolderClass
*claws_mailmbox_get_class(void)
125 if (claws_mailmbox_class
.idstr
== NULL
) {
126 claws_mailmbox_class
.type
= F_MBOX
;
127 claws_mailmbox_class
.idstr
= "mailmbox";
128 claws_mailmbox_class
.uistr
= "mbox";
130 /* Folder functions */
131 claws_mailmbox_class
.new_folder
= s_claws_mailmbox_folder_new
;
132 claws_mailmbox_class
.destroy_folder
= claws_mailmbox_folder_destroy
;
133 claws_mailmbox_class
.set_xml
= folder_local_set_xml
;
134 claws_mailmbox_class
.get_xml
= folder_local_get_xml
;
135 claws_mailmbox_class
.create_tree
= claws_mailmbox_create_tree
;
137 /* FolderItem functions */
138 claws_mailmbox_class
.item_new
= claws_mailmbox_folder_item_new
;
139 claws_mailmbox_class
.item_destroy
= claws_mailmbox_folder_item_destroy
;
140 claws_mailmbox_class
.item_get_path
= claws_mailmbox_item_get_path
;
141 claws_mailmbox_class
.create_folder
= claws_mailmbox_create_folder
;
142 claws_mailmbox_class
.rename_folder
= claws_mailmbox_rename_folder
;
143 claws_mailmbox_class
.remove_folder
= claws_mailmbox_remove_folder
;
144 claws_mailmbox_class
.close
= claws_mailmbox_folder_item_close
;
145 claws_mailmbox_class
.get_num_list
= claws_mailmbox_get_num_list
;
146 claws_mailmbox_class
.scan_required
= claws_mailmbox_scan_required
;
148 /* Message functions */
149 claws_mailmbox_class
.get_msginfo
= claws_mailmbox_get_msginfo
;
150 claws_mailmbox_class
.get_msginfos
= claws_mailmbox_get_msginfos
;
151 claws_mailmbox_class
.fetch_msg
= s_claws_mailmbox_fetch_msg
;
152 claws_mailmbox_class
.add_msg
= claws_mailmbox_add_msg
;
153 claws_mailmbox_class
.add_msgs
= claws_mailmbox_add_msgs
;
154 claws_mailmbox_class
.copy_msg
= s_claws_mailmbox_copy_msg
;
155 claws_mailmbox_class
.copy_msgs
= claws_mailmbox_copy_msgs
;
156 claws_mailmbox_class
.remove_msg
= claws_mailmbox_remove_msg
;
157 claws_mailmbox_class
.remove_msgs
= claws_mailmbox_remove_msgs
;
158 claws_mailmbox_class
.remove_all_msg
= claws_mailmbox_remove_all_msg
;
160 return &claws_mailmbox_class
;
164 static void claws_mailmbox_folder_init(Folder
*folder
,
165 const gchar
*name
, const gchar
*path
)
167 folder_local_folder_init(folder
, name
, path
);
170 static Folder
*s_claws_mailmbox_folder_new(const gchar
*name
, const gchar
*path
)
174 folder
= (Folder
*)g_new0(MAILMBOXFolder
, 1);
175 folder
->klass
= &claws_mailmbox_class
;
176 claws_mailmbox_folder_init(folder
, name
, path
);
181 static void claws_mailmbox_folder_destroy(Folder
*folder
)
183 folder_local_folder_destroy(LOCAL_FOLDER(folder
));
186 typedef struct _MAILMBOXFolderItem MAILMBOXFolderItem
;
187 struct _MAILMBOXFolderItem
191 struct claws_mailmbox_folder
* mbox
;
194 static FolderItem
*claws_mailmbox_folder_item_new(Folder
*folder
)
196 MAILMBOXFolderItem
*item
;
198 item
= g_new0(MAILMBOXFolderItem
, 1);
200 item
->old_max_uid
= 0;
202 return (FolderItem
*)item
;
205 #define MAX_UID_FILE "max-uid"
207 static void read_max_uid_value(FolderItem
*item
, guint
* pmax_uid
)
215 path
= folder_item_get_path(item
);
216 file
= g_strconcat(path
, G_DIR_SEPARATOR_S
, MAX_UID_FILE
, NULL
);
219 f
= claws_fopen(file
, "r");
223 r
= claws_fread(&max_uid
, sizeof(max_uid
), 1, f
);
231 * pmax_uid
= max_uid
;
234 static void write_max_uid_value(FolderItem
*item
, guint max_uid
)
241 path
= folder_item_get_path(item
);
242 file
= g_strconcat(path
, G_DIR_SEPARATOR_S
, MAX_UID_FILE
, NULL
);
245 f
= claws_fopen(file
, "w");
249 r
= claws_fwrite(&max_uid
, sizeof(max_uid
), 1, f
);
255 claws_safe_fclose(f
);
258 static void claws_mailmbox_folder_item_destroy(Folder
*folder
, FolderItem
*_item
)
260 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
262 g_return_if_fail(item
!= NULL
);
264 if (item
->mbox
!= NULL
) {
265 write_max_uid_value(_item
, item
->mbox
->mb_written_uid
);
266 claws_mailmbox_done(item
->mbox
);
271 static gint
claws_mailmbox_folder_item_close(Folder
*folder
, FolderItem
*item_
)
273 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)item_
;
275 g_return_val_if_fail(folder
->klass
->type
== F_MBOX
, -1);
276 g_return_val_if_fail(item
!= NULL
, -1);
277 g_return_val_if_fail(item
->mbox
!= NULL
, -1);
279 return -claws_mailmbox_expunge(item
->mbox
);
282 static void claws_mailmbox_folder_create_parent(const gchar
* path
)
284 if (!is_file_exist(path
)) {
287 new_path
= g_path_get_dirname(path
);
288 if (new_path
[strlen(new_path
) - 1] == G_DIR_SEPARATOR
)
289 new_path
[strlen(new_path
) - 1] = '\0';
291 if (!is_dir_exist(new_path
))
292 make_dir_hier(new_path
);
298 static gchar
* claws_mailmbox_folder_get_path(Folder
*folder
, FolderItem
*item
)
303 g_return_val_if_fail(item
!= NULL
, NULL
);
305 if (item
->path
&& item
->path
[0] == G_DIR_SEPARATOR
) {
306 claws_mailmbox_folder_create_parent(item
->path
);
307 return g_strdup(item
->path
);
310 folder_path
= g_strdup(LOCAL_FOLDER(item
->folder
)->rootpath
);
311 g_return_val_if_fail(folder_path
!= NULL
, NULL
);
313 if (folder_path
[0] == G_DIR_SEPARATOR
) {
315 path
= g_strconcat(folder_path
, G_DIR_SEPARATOR_S
,
319 path
= g_strdup(folder_path
);
322 path
= g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S
,
323 folder_path
, G_DIR_SEPARATOR_S
,
326 path
= g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S
,
332 claws_mailmbox_folder_create_parent(path
);
337 static int claws_mailmbox_item_sync(FolderItem
*_item
, int validate_uid
)
339 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
342 if (item
->mbox
== NULL
) {
347 read_max_uid_value(_item
, &written_uid
);
348 path
= claws_mailmbox_folder_get_path(_item
->folder
, _item
);
349 r
= claws_mailmbox_init(path
, 0, 0, written_uid
, &item
->mbox
);
350 debug_print("init %d: %p\n", r
, item
->mbox
);
352 if (r
!= MAILMBOX_NO_ERROR
)
357 r
= claws_mailmbox_validate_read_lock(item
->mbox
);
358 if (r
!= MAILMBOX_NO_ERROR
) {
359 debug_print("read lock: %d\n", r
);
363 claws_mailmbox_read_unlock(item
->mbox
);
366 r
= claws_mailmbox_validate_write_lock(item
->mbox
);
367 if (r
!= MAILMBOX_NO_ERROR
) {
368 debug_print("write lock: %d\n", r
);
372 if (item
->mbox
->mb_written_uid
< item
->mbox
->mb_max_uid
) {
373 r
= claws_mailmbox_expunge_no_lock(item
->mbox
);
374 if (r
!= MAILMBOX_NO_ERROR
)
377 claws_mailmbox_write_unlock(item
->mbox
);
383 claws_mailmbox_write_unlock(item
->mbox
);
388 static struct claws_mailmbox_folder
* get_mbox(FolderItem
*_item
, int validate_uid
)
390 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
392 claws_mailmbox_item_sync(_item
, validate_uid
);
397 static gint
claws_mailmbox_get_num_list(Folder
*folder
, FolderItem
*item
,
398 GSList
**list
, gboolean
*old_uids_valid
)
402 struct claws_mailmbox_folder
* mbox
;
404 g_return_val_if_fail(item
!= NULL
, -1);
406 debug_print("mbox_get_last_num(): Scanning %s ...\n", item
->path
);
408 *old_uids_valid
= TRUE
;
410 mbox
= get_mbox(item
, 1);
414 for(i
= 0 ; i
< carray_count(mbox
->mb_tab
) ; i
++) {
415 struct claws_mailmbox_msg_info
* msg
;
417 msg
= carray_get(mbox
->mb_tab
, i
);
419 *list
= g_slist_prepend(*list
,
420 GINT_TO_POINTER(msg
->msg_uid
));
428 static gchar
*s_claws_mailmbox_fetch_msg(Folder
*folder
, FolderItem
*item
, gint num
)
433 struct claws_mailmbox_folder
* mbox
;
439 g_return_val_if_fail(item
!= NULL
, NULL
);
440 g_return_val_if_fail(num
> 0, NULL
);
442 mbox
= get_mbox(item
, 0);
446 path
= folder_item_get_path(item
);
447 if (!is_dir_exist(path
))
449 file
= g_strconcat(path
, G_DIR_SEPARATOR_S
, itos(num
), NULL
);
451 if (is_file_exist(file
)) {
455 r
= claws_mailmbox_fetch_msg(mbox
, num
, &data
, &len
);
456 if (r
!= MAILMBOX_NO_ERROR
)
459 old_mask
= umask(0077);
460 f
= claws_fopen(file
, "w");
465 r
= claws_fwrite(data
, 1, len
, f
);
469 claws_safe_fclose(f
);
481 static MsgInfo
*claws_mailmbox_parse_msg(guint uid
,
482 const char * data
, size_t len
, FolderItem
*_item
)
486 struct claws_mailmbox_folder
* mbox
;
489 struct claws_mailmbox_msg_info
* info
;
491 MAILMBOXFolderItem
* item
= (MAILMBOXFolderItem
*)_item
;
493 flags
.perm_flags
= MSG_NEW
|MSG_UNREAD
;
496 g_return_val_if_fail(item
!= NULL
, NULL
);
497 g_return_val_if_fail(data
!= NULL
, NULL
);
499 if (_item
->stype
== F_QUEUE
) {
500 MSG_SET_TMP_FLAGS(flags
, MSG_QUEUED
);
501 } else if (_item
->stype
== F_DRAFT
) {
502 MSG_SET_TMP_FLAGS(flags
, MSG_DRAFT
);
507 key
.data
= (char *) &uid
;
508 key
.len
= sizeof(uid
);
510 r
= chash_get(mbox
->mb_hash
, &key
, &value
);
514 info
= (struct claws_mailmbox_msg_info
*) value
.data
;
516 msginfo
= procheader_parse_str(data
, flags
, FALSE
, FALSE
);
517 if (!msginfo
) return NULL
;
519 msginfo
->msgnum
= uid
;
520 msginfo
->folder
= _item
;
521 msginfo
->size
= (goffset
)(info
->msg_size
- info
->msg_start_len
);
526 static MsgInfo
*claws_mailmbox_get_msginfo(Folder
*folder
,
527 FolderItem
*item
, gint num
)
533 struct claws_mailmbox_folder
* mbox
;
535 g_return_val_if_fail(item
!= NULL
, NULL
);
536 g_return_val_if_fail(num
> 0, NULL
);
538 mbox
= get_mbox(item
, 0);
542 r
= claws_mailmbox_validate_read_lock(mbox
);
543 if (r
!= MAILMBOX_NO_ERROR
)
546 r
= claws_mailmbox_fetch_msg_headers_no_lock(mbox
, num
, &data
, &len
);
547 if (r
!= MAILMBOX_NO_ERROR
)
550 msginfo
= claws_mailmbox_parse_msg(num
, data
, len
, item
);
554 claws_mailmbox_read_unlock(mbox
);
559 claws_mailmbox_read_unlock(mbox
);
564 static GSList
*claws_mailmbox_get_msginfos(Folder
*folder
, FolderItem
*item
,
570 struct claws_mailmbox_folder
* mbox
;
572 g_return_val_if_fail(item
!= NULL
, NULL
);
574 mbox
= get_mbox(item
, 0);
578 r
= claws_mailmbox_validate_read_lock(mbox
);
579 if (r
!= MAILMBOX_NO_ERROR
)
584 for (cur
= msgnum_list
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
590 num
= GPOINTER_TO_INT(cur
->data
);
592 r
= claws_mailmbox_fetch_msg_headers_no_lock(mbox
, num
, &data
, &len
);
593 if (r
!= MAILMBOX_NO_ERROR
)
596 msginfo
= claws_mailmbox_parse_msg(num
, data
, len
, item
);
600 ret
= g_slist_append(ret
, msginfo
);
603 claws_mailmbox_read_unlock(mbox
);
611 static gint
claws_mailmbox_add_msg(Folder
*folder
, FolderItem
*dest
,
612 const gchar
*file
, MsgFlags
*flags
)
616 MsgFileInfo fileinfo
;
618 g_return_val_if_fail(file
!= NULL
, -1);
620 fileinfo
.msginfo
= NULL
;
621 fileinfo
.file
= (gchar
*)file
;
622 fileinfo
.flags
= flags
;
623 file_list
.data
= &fileinfo
;
624 file_list
.next
= NULL
;
626 ret
= claws_mailmbox_add_msgs(folder
, dest
, &file_list
, NULL
);
632 static gint
claws_mailmbox_add_msgs(Folder
*folder
, FolderItem
*dest
,
634 GHashTable
*relation
)
638 struct claws_mailmbox_folder
* mbox
;
639 carray
* append_list
;
640 struct claws_mailmbox_append_info append_info
;
643 g_return_val_if_fail(dest
!= NULL
, -1);
644 g_return_val_if_fail(file_list
!= NULL
, -1);
646 mbox
= get_mbox(dest
, 0);
648 debug_print("mbox not found\n");
651 r
= claws_mailmbox_validate_write_lock(mbox
);
652 if (r
!= MAILMBOX_NO_ERROR
) {
653 debug_print("claws_mailmbox_validate_write_lock failed with %d\n", r
);
656 r
= claws_mailmbox_expunge_no_lock(mbox
);
657 if (r
!= MAILMBOX_NO_ERROR
) {
658 debug_print("claws_mailmbox_expunge_no_lock failed with %d\n", r
);
664 append_list
= carray_new(1);
665 if (append_list
== NULL
) {
666 debug_print("append_list is null\n");
670 r
= carray_set_size(append_list
, 1);
672 debug_print("carray_set_size failed with %d\n", r
);
676 carray_set(append_list
, 0, &append_info
);
678 for (cur
= file_list
; cur
!= NULL
; cur
= cur
->next
) {
680 struct stat stat_info
;
683 struct claws_mailmbox_msg_info
* msg
;
685 MsgFileInfo
*fileinfo
;
687 fileinfo
= (MsgFileInfo
*)cur
->data
;
689 fd
= open(fileinfo
->file
, O_RDONLY
);
691 debug_print("%s couldn't be opened\n", fileinfo
->file
);
695 r
= fstat(fd
, &stat_info
);
697 debug_print("%s couldn't be stat'ed\n", fileinfo
->file
);
701 len
= stat_info
.st_size
;
702 data
= mmap(NULL
, len
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
703 if (data
== MAP_FAILED
) {
704 debug_print("mmap failed\n");
708 append_info
.ai_message
= data
;
709 append_info
.ai_size
= len
;
711 cur_token
= mbox
->mb_mapping_size
;
713 r
= claws_mailmbox_append_message_list_no_lock(mbox
, append_list
);
714 if (r
!= MAILMBOX_NO_ERROR
) {
715 debug_print("claws_mailmbox_append_message_list_no_lock failed with %d\n", r
);
722 r
= claws_mailmbox_parse_additionnal(mbox
, &cur_token
);
723 if (r
!= MAILMBOX_NO_ERROR
) {
724 debug_print("claws_mailmbox_parse_additionnal failed with %d\n", r
);
728 msg
= carray_get(mbox
->mb_tab
, carray_count(mbox
->mb_tab
) - 1);
730 if (relation
!= NULL
)
731 g_hash_table_insert(relation
,
732 fileinfo
->msginfo
!= NULL
?
733 (gpointer
) fileinfo
->msginfo
:
735 GINT_TO_POINTER(msg
->msg_uid
));
737 last_num
= msg
->msg_uid
;
749 claws_mailmbox_sync(mbox
);
751 carray_free(append_list
);
752 claws_mailmbox_write_unlock(mbox
);
757 carray_free(append_list
);
759 claws_mailmbox_write_unlock(mbox
);
763 static gint
s_claws_mailmbox_copy_msg(Folder
*folder
,
764 FolderItem
*dest
, MsgInfo
*msginfo
)
768 g_return_val_if_fail(msginfo
!= NULL
, -1);
770 msglist
.data
= msginfo
;
773 return claws_mailmbox_copy_msgs(folder
, dest
, &msglist
, NULL
);
776 static gint
claws_mailmbox_copy_msgs(Folder
*folder
, FolderItem
*dest
,
777 MsgInfoList
*msglist
, GHashTable
*relation
)
783 g_return_val_if_fail(folder
!= NULL
, -1);
784 g_return_val_if_fail(dest
!= NULL
, -1);
785 g_return_val_if_fail(msglist
!= NULL
, -1);
787 msginfo
= (MsgInfo
*)msglist
->data
;
788 g_return_val_if_fail(msginfo
->folder
!= NULL
, -1);
790 file_list
= procmsg_get_message_file_list(msglist
);
791 g_return_val_if_fail(file_list
!= NULL
, -1);
793 ret
= claws_mailmbox_add_msgs(folder
, dest
, file_list
, relation
);
795 procmsg_message_file_list_free(file_list
);
801 static gint
claws_mailmbox_remove_msg(Folder
*folder
, FolderItem
*item
, gint num
)
803 struct claws_mailmbox_folder
* mbox
;
806 g_return_val_if_fail(item
!= NULL
, -1);
808 mbox
= get_mbox(item
, 0);
812 r
= claws_mailmbox_delete_msg(mbox
, num
);
813 if (r
!= MAILMBOX_NO_ERROR
)
820 claws_mailmbox_remove_msgs( Folder
*folder
, FolderItem
*item
,
821 MsgInfoList
*msglist
, GHashTable
*relation
)
823 struct claws_mailmbox_folder
*mbox
;
825 gint total
= 0, curnum
= 0;
827 g_return_val_if_fail( item
!=NULL
, -1 );
828 mbox
=get_mbox(item
,0);
829 g_return_val_if_fail( mbox
!=NULL
, -1 );
831 total
= g_slist_length(msglist
);
833 statusbar_print_all(_("Deleting messages..."));
837 for( cur
=msglist
; cur
; cur
=cur
->next
)
839 MsgInfo
*msginfo
=(MsgInfo
*) cur
->data
;
844 if( MSG_IS_MOVE(msginfo
->flags
) && MSG_IS_MOVE_DONE(msginfo
->flags
) )
846 msginfo
->flags
.tmp_flags
&=~MSG_MOVE_DONE
;
850 statusbar_progress_all(curnum
, total
, 100);
851 if (curnum
% 100 == 0)
855 claws_mailmbox_delete_msg(mbox
,msginfo
->msgnum
);
860 r
= claws_mailmbox_expunge(mbox
);
862 statusbar_progress_all(0,0,0);
870 static gint
claws_mailmbox_remove_all_msg(Folder
*folder
, FolderItem
*item
)
872 struct claws_mailmbox_folder
* mbox
;
876 g_return_val_if_fail(item
!= NULL
, -1);
878 mbox
= get_mbox(item
, 0);
882 for(i
= 0 ; i
< carray_count(mbox
->mb_tab
) ; i
++) {
883 struct claws_mailmbox_msg_info
* msg
;
885 msg
= carray_get(mbox
->mb_tab
, i
);
889 r
= claws_mailmbox_delete_msg(mbox
, msg
->msg_uid
);
890 if (r
!= MAILMBOX_NO_ERROR
)
898 static gchar
* claws_mailmbox_get_new_path(FolderItem
* parent
, gchar
* name
)
902 if (strchr(name
, G_DIR_SEPARATOR
) == NULL
) {
903 if (parent
->path
!= NULL
)
904 path
= g_strconcat(parent
->path
, ".sbd", G_DIR_SEPARATOR_S
, name
, NULL
);
906 path
= g_strdup(name
);
909 path
= g_strdup(name
);
914 static gchar
* claws_mailmbox_get_folderitem_name(gchar
* name
)
918 foldername
= g_path_get_basename(name
);
923 static FolderItem
*claws_mailmbox_create_folder(Folder
*folder
, FolderItem
*parent
,
927 FolderItem
*new_item
;
930 g_return_val_if_fail(folder
!= NULL
, NULL
);
931 g_return_val_if_fail(parent
!= NULL
, NULL
);
932 g_return_val_if_fail(name
!= NULL
, NULL
);
934 path
= claws_mailmbox_get_new_path(parent
, (gchar
*) name
);
936 foldername
= claws_mailmbox_get_folderitem_name((gchar
*) name
);
938 new_item
= folder_item_new(folder
, foldername
, path
);
939 folder_item_append(parent
, new_item
);
941 if (!strcmp(name
, "inbox")) {
942 new_item
->stype
= F_INBOX
;
943 new_item
->folder
->inbox
= new_item
;
944 } else if (!strcmp(name
, "outbox")) {
945 new_item
->stype
= F_OUTBOX
;
946 new_item
->folder
->outbox
= new_item
;
947 } else if (!strcmp(name
, "draft")) {
948 new_item
->stype
= F_DRAFT
;
949 new_item
->folder
->draft
= new_item
;
950 } else if (!strcmp(name
, "queue")) {
951 new_item
->stype
= F_QUEUE
;
952 new_item
->folder
->queue
= new_item
;
953 } else if (!strcmp(name
, "trash")) {
954 new_item
->stype
= F_TRASH
;
955 new_item
->folder
->trash
= new_item
;
966 static gboolean
claws_mailmbox_scan_required(Folder
*folder
, FolderItem
*_item
)
968 struct claws_mailmbox_folder
* mbox
;
969 MAILMBOXFolderItem
*item
= (MAILMBOXFolderItem
*)_item
;
972 g_return_val_if_fail(folder
!= NULL
, FALSE
);
973 g_return_val_if_fail(item
!= NULL
, FALSE
);
975 if (item
->item
.path
== NULL
)
978 mbox
= get_mbox(_item
, 0);
982 scan_required
= (item
->old_max_uid
!= item
->mbox
->mb_max_uid
);
984 item
->old_max_uid
= item
->mbox
->mb_max_uid
;
986 return scan_required
;
990 static gint
claws_mailmbox_rename_folder(Folder
*folder
,
991 FolderItem
*item
, const gchar
*name
)
997 g_return_val_if_fail(folder
!= NULL
, -1);
998 g_return_val_if_fail(item
!= NULL
, -1);
999 g_return_val_if_fail(item
->path
!= NULL
, -1);
1000 g_return_val_if_fail(name
!= NULL
, -1);
1002 parent
= folder_item_parent(item
);
1003 g_return_val_if_fail(parent
, -1);
1005 path
= claws_mailmbox_get_new_path(parent
, (gchar
*) name
);
1006 foldername
= claws_mailmbox_get_folderitem_name((gchar
*) name
);
1008 if (rename(item
->path
, path
) == -1) {
1011 debug_print("Cannot rename folder item\n");
1019 item
->name
= foldername
;
1025 static gint
claws_mailmbox_remove_folder(Folder
*folder
, FolderItem
*item
)
1027 g_return_val_if_fail(folder
!= NULL
, -1);
1028 g_return_val_if_fail(item
!= NULL
, -1);
1029 g_return_val_if_fail(item
->path
!= NULL
, -1);
1031 folder_item_remove(item
);
1035 #define MAKE_DIR_IF_NOT_EXIST(dir) \
1037 if (!is_dir_exist(dir)) { \
1038 if (is_file_exist(dir)) { \
1039 debug_print("File `%s' already exists.\n" \
1040 "Can't create folder.", dir); \
1043 if (mkdir(dir, S_IRWXU) < 0) { \
1044 FILE_OP_ERROR(dir, "mkdir"); \
1047 if (chmod(dir, S_IRWXU) < 0) \
1048 FILE_OP_ERROR(dir, "chmod"); \
1052 static gint
claws_mailmbox_create_tree(Folder
*folder
)
1056 g_return_val_if_fail(folder
!= NULL
, -1);
1058 CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), -1);
1059 rootpath
= LOCAL_FOLDER(folder
)->rootpath
;
1060 MAKE_DIR_IF_NOT_EXIST(rootpath
);
1061 CHDIR_RETURN_VAL_IF_FAIL(rootpath
, -1);
1066 #undef MAKE_DIR_IF_NOT_EXIST
1069 static char * quote_mailbox(char * mb
)
1071 char path
[PATH_MAX
];
1076 remaining
= sizeof(path
) - 1;
1081 if (((* mb
>= 'a') && (* mb
<= 'z')) ||
1082 ((* mb
>= 'A') && (* mb
<= 'Z')) ||
1083 ((* mb
>= '0') && (* mb
<= '9'))) {
1095 snprintf(p
, 3, "%02x", (unsigned char) (* mb
));
1110 static gchar
*claws_mailmbox_item_get_path(Folder
*folder
, FolderItem
*item
)
1112 gchar
*itempath
, *path
;
1115 if (item
->path
== NULL
)
1118 if (folder
->name
== NULL
)
1121 folderpath
= quote_mailbox(folder
->name
);
1122 if (folderpath
== NULL
)
1124 itempath
= quote_mailbox(item
->path
);
1125 if (itempath
== NULL
) {
1129 path
= g_strconcat(get_cache_dir(),
1130 G_DIR_SEPARATOR_S
, folderpath
,
1131 G_DIR_SEPARATOR_S
, itempath
, NULL
);