* src/folder.[ch]
[claws.git] / src / mbox_folder.c
index ba3e2089ca6cc5f944a112d7f2020f416502f77f..12f1af41c7da6ff15011a4291a552c34b87a6e21 100644 (file)
@@ -46,6 +46,10 @@ static gboolean mbox_purge_deleted(gchar * mbox);
 static gchar * mbox_get_new_path(FolderItem * parent, gchar * name);
 static gchar * mbox_get_folderitem_name(gchar * name);
 
+MsgInfo *mbox_fetch_msginfo(Folder *folder, FolderItem *item, gint num);
+gint mbox_get_num_list(Folder *folder, FolderItem *item, GSList **list);
+gboolean mbox_check_msgnum_validity(Folder *folder, FolderItem *item);
+
 Folder *mbox_folder_new(const gchar *name, const gchar *path)
 {
        Folder *folder;
@@ -63,24 +67,32 @@ void mbox_folder_destroy(MBOXFolder *folder)
 
 static void mbox_folder_init(Folder *folder, const gchar *name, const gchar *path)
 {
-       folder_local_folder_init(folder, name, path);
-
        folder->type = F_MBOX;
 
+       folder_local_folder_init(folder, name, path);
+
+/*
        folder->get_msg_list        = mbox_get_msg_list;
+*/
        folder->fetch_msg           = mbox_fetch_msg;
+       folder->fetch_msginfo       = mbox_fetch_msginfo;
        folder->add_msg             = mbox_add_msg;
        folder->copy_msg            = mbox_copy_msg;
        folder->remove_msg          = mbox_remove_msg;
        folder->remove_all_msg      = mbox_remove_all_msg;
+/*
        folder->scan                = mbox_scan_folder;
+*/
+       folder->get_num_list        = mbox_get_num_list;
        folder->create_tree         = mbox_create_tree;
        folder->create_folder       = mbox_create_folder;
        folder->rename_folder       = mbox_rename_folder;
        folder->remove_folder       = mbox_remove_folder;
+       folder->check_msgnum_validity
+                                   = mbox_check_msgnum_validity;
 }
 
-static gchar * mbox_folder_create_parent(const gchar * path)
+static void mbox_folder_create_parent(const gchar * path)
 {
        if (!is_file_exist(path)) {
                gchar * new_path;
@@ -729,7 +741,7 @@ static MsgInfo *mbox_parse_msg(FILE * fp, struct _message * msg,
                }
        }
 
-       msginfo = procheader_file_parse(fp, flags, FALSE, FALSE);
+       msginfo = procheader_parse_stream(fp, flags, FALSE, FALSE);
 
        if (!msginfo) return NULL;
 
@@ -746,11 +758,6 @@ static void mbox_cache_init()
        mbox_cache_table = g_hash_table_new(g_str_hash, g_str_equal);
 }
 
-static void mbox_cache_done()
-{
-       g_hash_table_destroy(mbox_cache_table);
-}
-
 static void mbox_cache_free_mbox(mboxcache * cache)
 {
        g_hash_table_remove(mbox_cache_table, cache->filename);
@@ -830,7 +837,7 @@ static mboxcache * mbox_cache_read_mbox(gchar * filename)
 
        mbox_cache_get_msginfo(filename, mf->msg_list);
 
-       debug_print(_("read mbox - %s\n"), filename);
+       debug_print("read mbox - %s\n", filename);
 
        return cache;
 }
@@ -861,7 +868,7 @@ static mboxcache * mbox_cache_read_mbox_from_file(FILE * fp, gchar * filename)
 
        mbox_cache_get_msginfo_from_file(fp, mf->msg_list);
 
-       debug_print(_("read mbox from file - %s\n"), filename);
+       debug_print("read mbox from file - %s\n", filename);
 
        return cache;
 }
@@ -895,16 +902,6 @@ static gint mbox_cache_get_count(gchar * filename)
        return cache->mf->count;
 }
 
-static gint mbox_cache_get_mtime(gchar * filename)
-{
-       mboxcache * cache;
-
-       cache = mbox_cache_get_mbox(filename);
-       if (cache == NULL)
-               return -1;
-       return cache->mtime;
-}
-
 static GList * mbox_cache_get_msg_list(gchar * filename)
 {
        mboxcache * cache;
@@ -970,8 +967,6 @@ static void mbox_cache_synchronize(gchar * filename, gboolean sync)
        }
 
        if (scan_new) {
-               GList * l;
-
                /*              
                if (strstr(filename, "trash") == 0)
                        printf("old_cache: %p %s\n", old_cache, filename);
@@ -1349,7 +1344,6 @@ gchar *mbox_fetch_msg(Folder *folder, FolderItem *item, gint num)
        gchar *filename;
        
        g_return_val_if_fail(item != NULL, NULL);
-       g_return_val_if_fail(num > 0 && num <= item->last_num, NULL);
 
        path = folder_item_get_path(item);
        if (!is_dir_exist(path))
@@ -1504,7 +1498,7 @@ gint mbox_remove_msg(Folder *folder, FolderItem *item, gint num)
        msg = mbox_cache_get_msg(mbox_path, num);
 
        g_free(mbox_path);
-       
+
        if (msg != NULL)
                MSG_SET_PERM_FLAGS(msg->flags, MSG_REALLY_DELETED);
 
@@ -1637,9 +1631,6 @@ gint mbox_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
        Folder * src_folder;
        gchar * filename;
        gint num;
-       gchar * destdir;
-       gchar * mbox_path;
-       struct _message * msg;
        CopyFlagsInfo * flags_info;
 
        src_folder = msginfo->folder->folder;
@@ -1764,7 +1755,7 @@ void mbox_scan_folder(Folder *folder, FolderItem *item)
                item->total = total;
        }
 
-       debug_print(_("Last number in dir %s = %d\n"), mbox_path,
+       debug_print("Last number in dir %s = %d\n", mbox_path,
                    item->total);
        item->last_num = n_msg;
        g_free(mbox_path);
@@ -1957,11 +1948,11 @@ static gboolean mbox_rewrite(gchar * mbox)
                return FALSE;
 
        if (!cache->modification) {
-               debug_print(_("no modification - %s\n"), mbox);
+               debug_print("no modification - %s\n", mbox);
                return FALSE;
        }
 
-       debug_print(_("save modification - %s\n"), mbox);
+       debug_print("save modification - %s\n", mbox);
 
        mbox_fp = fopen(mbox, "rb+");
        mbox_lockwrite_file(mbox_fp, mbox);
@@ -2015,7 +2006,7 @@ static gboolean mbox_rewrite(gchar * mbox)
 
        fclose(mbox_fp);
 
-       debug_print(_("%i messages written - %s\n"), count, mbox);
+       debug_print("%i messages written - %s\n", count, mbox);
 
        cache = mbox_cache_get_mbox(mbox);
 
@@ -2044,18 +2035,18 @@ static gboolean mbox_purge_deleted(gchar * mbox)
 
        for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
                struct _message * msg = (struct _message *) l->data;
-               if (MSG_IS_INVALID(msg->flags) && MSG_IS_REALLY_DELETED(msg->flags)) {
+               if (!MSG_IS_INVALID(msg->flags) && MSG_IS_REALLY_DELETED(msg->flags)) {
                        modification = TRUE;
                        break;
                }
        }
 
        if (!modification) {
-               debug_print(_("no deleted messages - %s\n"), mbox);
+               debug_print("no deleted messages - %s\n", mbox);
                return FALSE;
        }
 
-       debug_print(_("purge deleted messages - %s\n"), mbox);
+       debug_print("purge deleted messages - %s\n", mbox);
 
        mbox_fp = fopen(mbox, "rb+");
        mbox_lockwrite_file(mbox_fp, mbox);
@@ -2111,7 +2102,7 @@ static gboolean mbox_purge_deleted(gchar * mbox)
 
        fclose(mbox_fp);
 
-       debug_print(_("%i messages written - %s\n"), count, mbox);
+       debug_print("%i messages written - %s\n", count, mbox);
 
        mbox_cache_synchronize(mbox, FALSE);
 
@@ -2191,7 +2182,7 @@ FolderItem *mbox_create_folder(Folder *folder, FolderItem *parent,
 
        foldername = mbox_get_folderitem_name((gchar *) name);
 
-       new_item = folder_item_new(foldername, path);
+       new_item = folder_item_new(folder, foldername, path);
        folder_item_append(parent, new_item);
 
        if (!strcmp(name, "inbox")) {
@@ -2257,3 +2248,118 @@ gint mbox_remove_folder(Folder *folder, FolderItem *item)
        return 0;
 }
 
+gint mbox_get_num_list(Folder *folder, FolderItem *item, GSList **mlist)
+{
+       GList * l;
+       FILE * fp;
+       gchar * mbox_path;
+       gint nummsgs = 0;
+
+       mbox_path = mbox_folder_get_path(item);
+
+       if (mbox_path == NULL)
+               return -1;
+
+       mbox_purge_deleted(mbox_path);
+
+       fp = fopen(mbox_path, "rb");
+       
+       if (fp == NULL) {
+               g_free(mbox_path);
+               return -1;
+       }
+
+       mbox_lockread_file(fp, mbox_path);
+
+       mbox_cache_synchronize_from_file(fp, mbox_path, TRUE);
+
+       item->last_num = mbox_cache_get_count(mbox_path);
+
+       for(l = mbox_cache_get_msg_list(mbox_path) ; l != NULL ;
+           l = g_list_next(l)) {
+               struct _message * msg;
+
+               msg = (struct _message *) l->data;
+
+               if (MSG_IS_INVALID(msg->flags) || !MSG_IS_REALLY_DELETED(msg->flags)) {
+                       *mlist = g_slist_append(*mlist, GINT_TO_POINTER(msg->msgnum));
+                       nummsgs++;
+               } else {
+                       MSG_SET_PERM_FLAGS(msg->flags, MSG_REALLY_DELETED);
+               }
+       }
+
+       mbox_unlock_file(fp, mbox_path);
+
+       g_free(mbox_path);
+
+       fclose(fp);
+
+       return nummsgs;
+}
+
+MsgInfo *mbox_fetch_msginfo(Folder *folder, FolderItem *item, gint num)
+{
+       gchar *mbox_path;
+       struct _message *msg;
+       FILE *src;
+       MsgInfo *msginfo;
+       
+       g_return_val_if_fail(folder != NULL, NULL);
+       g_return_val_if_fail(item != NULL, NULL);
+
+       mbox_path = mbox_folder_get_path(item);
+
+       g_return_val_if_fail(mbox_path != NULL, NULL);
+       
+       src = fopen(mbox_path, "rb");
+       if (src == NULL) {
+               g_free(mbox_path);
+               return NULL;
+       }
+       mbox_lockread_file(src, mbox_path);
+       mbox_cache_synchronize_from_file(src, mbox_path, TRUE);
+
+       msg = mbox_cache_get_msg(mbox_path, num);
+       if (msg == NULL) {
+               mbox_unlock_file(src, mbox_path);
+               fclose(src);
+               g_free(mbox_path);
+               return NULL;
+       }
+       
+       fseek(src, msg->header, SEEK_SET);
+       msginfo = mbox_parse_msg(src, msg, item);
+
+       mbox_unlock_file(src, mbox_path);
+       fclose(src);
+       g_free(mbox_path);
+
+       return msginfo;
+}
+
+gboolean mbox_check_msgnum_validity(Folder *folder, FolderItem *item)
+{
+       mboxcache * old_cache;
+       gboolean scan_new = TRUE;
+       struct stat s;
+       gchar *filename;
+
+       filename = mbox_folder_get_path(item);
+       
+       old_cache = mbox_cache_get_mbox(filename);
+
+       if (old_cache != NULL) {
+               if (stat(filename, &s) < 0) {
+                       FILE_OP_ERROR(filename, "stat");
+               } else if (old_cache->mtime == s.st_mtime) {
+                       debug_print("Folder is not modified.\n");
+                       scan_new = FALSE;
+               }
+       }
+
+       g_free(filename);
+       
+       return !scan_new;
+}
+