static gint mh_remove_msg(Folder *folder, FolderItem *item, gint num) { gboolean need_scan = FALSE; time_t last_mtime = (time_t)0; gchar *file; cm_return_val_if_fail(item != NULL, -1); file = mh_fetch_msg(folder, item, num); cm_return_val_if_fail(file != NULL, -1); need_scan = mh_scan_required(folder, item); last_mtime = item->mtime; if (claws_unlink(file) < 0) { FILE_OP_ERROR(file, "unlink"); g_free(file); return -1; } if (item->mtime == last_mtime && !need_scan) { mh_set_mtime(folder, item); } g_free(file); return 0; }
static gint mh_remove_msgs(Folder *folder, FolderItem *item, MsgInfoList *msglist, GHashTable *relation) { gboolean need_scan = FALSE; gchar *path, *file; time_t last_mtime = (time_t)0; MsgInfoList *cur; gint total = 0, curnum = 0; cm_return_val_if_fail(item != NULL, -1); path = folder_item_get_path(item); need_scan = mh_scan_required(folder, item); last_mtime = item->mtime; total = g_slist_length(msglist); if (total > 100) { statusbar_print_all(_("Deleting messages...")); } for (cur = msglist; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; if (msginfo == NULL) continue; if (MSG_IS_MOVE(msginfo->flags) && MSG_IS_MOVE_DONE(msginfo->flags)) { msginfo->flags.tmp_flags &= ~MSG_MOVE_DONE; continue; } if (total > 100) { statusbar_progress_all(curnum, total, 100); if (curnum % 100 == 0) GTK_EVENTS_FLUSH(); curnum++; } file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL); if (file == NULL) continue; if (claws_unlink(file) < 0) { g_free(file); continue; } g_free(file); } if (total > 100) { statusbar_progress_all(0,0,0); statusbar_pop_all(); } if (item->mtime == last_mtime && !need_scan) { mh_set_mtime(folder, item); } g_free(path); return 0; }
static int mh_item_close(Folder *folder, FolderItem *item) { time_t last_mtime = (time_t)0; gboolean need_scan = mh_scan_required(item->folder, item); last_mtime = item->mtime; mh_write_sequences(item, FALSE); if (item->mtime == last_mtime && !need_scan) { mh_set_mtime(folder, item); } return 0; }
gint mh_get_num_list(Folder *folder, FolderItem *item, GSList **list, gboolean *old_uids_valid) { gchar *path; GDir *dp; const gchar *d; GError *error = NULL; gint num, nummsgs = 0; cm_return_val_if_fail(item != NULL, -1); debug_print("mh_get_num_list(): Scanning %s ...\n", item->path?item->path:"(null)"); *old_uids_valid = TRUE; path = folder_item_get_path(item); cm_return_val_if_fail(path != NULL, -1); if (change_dir(path) < 0) { g_free(path); return -1; } g_free(path); if ((dp = g_dir_open(".", 0, &error)) == NULL) { g_message("Couldn't open current directory: %s (%d).\n", error->message, error->code); g_error_free(error); return -1; } while ((d = g_dir_read_name(dp)) != NULL) { if ((num = to_number(d)) > 0) { *list = g_slist_prepend(*list, GINT_TO_POINTER(num)); nummsgs++; } } g_dir_close(dp); mh_set_mtime(folder, item); return nummsgs; }
gint mh_get_num_list(Folder *folder, FolderItem *item, GSList **list, gboolean *old_uids_valid) { gchar *path; DIR *dp; struct dirent *d; gint num, nummsgs = 0; cm_return_val_if_fail(item != NULL, -1); debug_print("mh_get_num_list(): Scanning %s ...\n", item->path?item->path:"(null)"); *old_uids_valid = TRUE; path = folder_item_get_path(item); cm_return_val_if_fail(path != NULL, -1); if (change_dir(path) < 0) { g_free(path); return -1; } g_free(path); if ((dp = opendir(".")) == NULL) { FILE_OP_ERROR(item->path, "opendir"); return -1; } while ((d = readdir(dp)) != NULL) { if ((num = to_number(d->d_name)) > 0) { *list = g_slist_prepend(*list, GINT_TO_POINTER(num)); nummsgs++; } } closedir(dp); mh_set_mtime(folder, item); return nummsgs; }
static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist, GHashTable *relation) { gboolean dest_need_scan = FALSE; gboolean src_need_scan = FALSE; FolderItem *src = NULL; gchar *srcfile; gchar *destfile; FolderItemPrefs *prefs; MsgInfo *msginfo = NULL; MsgInfoList *cur = NULL; gint curnum = 0, total = 0; gchar *srcpath = NULL; gboolean full_fetch = FALSE; time_t last_dest_mtime = (time_t)0; time_t last_src_mtime = (time_t)0; cm_return_val_if_fail(dest != NULL, -1); cm_return_val_if_fail(msglist != NULL, -1); msginfo = (MsgInfo *)msglist->data; cm_return_val_if_fail(msginfo != NULL, -1); if (msginfo->folder == dest) { g_warning("the src folder is identical to the dest.\n"); return -1; } if (msginfo->folder->folder != dest->folder) full_fetch = TRUE; if (FOLDER_TYPE(msginfo->folder->folder) == F_MH) { src = msginfo->folder; } if (dest->last_num < 0) { mh_get_last_num(folder, dest); if (dest->last_num < 0) return -1; } prefs = dest->prefs; srcpath = folder_item_get_path(msginfo->folder); dest_need_scan = mh_scan_required(dest->folder, dest); last_dest_mtime = dest->mtime; if (src) { src_need_scan = mh_scan_required(src->folder, src); last_src_mtime = src->mtime; } total = g_slist_length(msglist); if (total > 100) { if (MSG_IS_MOVE(msginfo->flags)) statusbar_print_all(_("Moving messages...")); else statusbar_print_all(_("Copying messages...")); } for (cur = msglist; cur; cur = cur->next) { msginfo = (MsgInfo *)cur->data; if (!msginfo) { goto err_reset_status; } if (!full_fetch) { srcfile = g_strconcat(srcpath, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL); } else { srcfile = procmsg_get_message_file(msginfo); } if (!srcfile) { goto err_reset_status; } destfile = mh_get_new_msg_filename(dest); if (!destfile) { g_free(srcfile); goto err_reset_status; } if (total > 100) { statusbar_progress_all(curnum, total, 100); if (curnum % 100 == 0) GTK_EVENTS_FLUSH(); curnum++; } debug_print("Copying message %s%c%d to %s ...\n", msginfo->folder->path, G_DIR_SEPARATOR, msginfo->msgnum, dest->path); if (MSG_IS_MOVE(msginfo->flags)) { msginfo->flags.tmp_flags &= ~MSG_MOVE_DONE; if (move_file(srcfile, destfile, TRUE) < 0) { FILE_OP_ERROR(srcfile, "move"); if (copy_file(srcfile, destfile, TRUE) < 0) { FILE_OP_ERROR(srcfile, "copy"); g_free(srcfile); g_free(destfile); goto err_reset_status; } } else { /* say unlinking's not necessary */ msginfo->flags.tmp_flags |= MSG_MOVE_DONE; } } else if (copy_file(srcfile, destfile, TRUE) < 0) { FILE_OP_ERROR(srcfile, "copy"); g_free(srcfile); g_free(destfile); goto err_reset_status; } if (prefs && prefs->enable_folder_chmod && prefs->folder_chmod) { if (chmod(destfile, prefs->folder_chmod) < 0) FILE_OP_ERROR(destfile, "chmod"); } if (relation) { if (g_hash_table_lookup(relation, msginfo) != NULL) g_warning("already in : %p", msginfo); g_hash_table_insert(relation, msginfo, GINT_TO_POINTER(dest->last_num+1)); } g_free(srcfile); g_free(destfile); dest->last_num++; } g_free(srcpath); mh_write_sequences(dest, TRUE); if (dest->mtime == last_dest_mtime && !dest_need_scan) { mh_set_mtime(folder, dest); } if (src && src->mtime == last_src_mtime && !src_need_scan) { mh_set_mtime(folder, src); } if (total > 100) { statusbar_progress_all(0,0,0); statusbar_pop_all(); } return dest->last_num; err_reset_status: g_free(srcpath); mh_write_sequences(dest, TRUE); if (total > 100) { statusbar_progress_all(0,0,0); statusbar_pop_all(); } return -1; }
static void mh_scan_tree_recursive(FolderItem *item) { Folder *folder; #ifdef G_OS_WIN32 GDir *dir; #else DIR *dp; struct dirent *d; #endif const gchar *dir_name; struct stat s; gchar *real_path, *entry, *utf8entry, *utf8name; gint n_msg = 0; cm_return_if_fail(item != NULL); cm_return_if_fail(item->folder != NULL); folder = item->folder; real_path = item->path ? mh_filename_from_utf8(item->path) : g_strdup("."); #ifdef G_OS_WIN32 dir = g_dir_open(real_path, 0, NULL); if (!dir) { g_warning("failed to open directory: %s\n", real_path); g_free(real_path); return; } #else dp = opendir(real_path); if (!dp) { FILE_OP_ERROR(real_path, "opendir"); return; } #endif g_free(real_path); debug_print("scanning %s ...\n", item->path ? item->path : LOCAL_FOLDER(item->folder)->rootpath); if (folder->ui_func) folder->ui_func(folder, item, folder->ui_func_data); #ifdef G_OS_WIN32 while ((dir_name = g_dir_read_name(dir)) != NULL) { #else while ((d = readdir(dp)) != NULL) { dir_name = d->d_name; #endif if (dir_name[0] == '.') continue; utf8name = mh_filename_to_utf8(dir_name); if (item->path) utf8entry = g_strconcat(item->path, G_DIR_SEPARATOR_S, utf8name, NULL); else utf8entry = g_strdup(utf8name); entry = mh_filename_from_utf8(utf8entry); if ( #if !defined(G_OS_WIN32) && defined(HAVE_DIRENT_D_TYPE) d->d_type == DT_DIR || (d->d_type == DT_UNKNOWN && #endif g_stat(entry, &s) == 0 && S_ISDIR(s.st_mode) #if !defined(G_OS_WIN32) && defined(HAVE_DIRENT_D_TYPE) ) #endif ) { FolderItem *new_item = NULL; GNode *node; node = item->node; for (node = node->children; node != NULL; node = node->next) { FolderItem *cur_item = FOLDER_ITEM(node->data); gchar *curpath = mh_filename_from_utf8(cur_item->path); if (!strcmp2(curpath, entry)) { new_item = cur_item; g_free(curpath); break; } g_free(curpath); } if (!new_item) { debug_print("new folder '%s' found.\n", entry); new_item = folder_item_new(folder, utf8name, utf8entry); folder_item_append(item, new_item); } if (!item->path) { if (!folder->inbox && !strcmp(dir_name, INBOX_DIR)) { new_item->stype = F_INBOX; folder->inbox = new_item; } else if (!folder->outbox && !strcmp(dir_name, OUTBOX_DIR)) { new_item->stype = F_OUTBOX; folder->outbox = new_item; } else if (!folder->draft && !strcmp(dir_name, DRAFT_DIR)) { new_item->stype = F_DRAFT; folder->draft = new_item; } else if (!folder->queue && !strcmp(dir_name, QUEUE_DIR)) { new_item->stype = F_QUEUE; folder->queue = new_item; } else if (!folder->trash && !strcmp(dir_name, TRASH_DIR)) { new_item->stype = F_TRASH; folder->trash = new_item; } } mh_scan_tree_recursive(new_item); } else if (to_number(dir_name) > 0) n_msg++; g_free(entry); g_free(utf8entry); g_free(utf8name); } #ifdef G_OS_WIN32 g_dir_close(dir); #else closedir(dp); #endif mh_set_mtime(folder, item); } static gboolean mh_rename_folder_func(GNode *node, gpointer data) { FolderItem *item = node->data; gchar **paths = data; const gchar *oldpath = paths[0]; const gchar *newpath = paths[1]; gchar *base; gchar *new_itempath; gint oldpathlen; oldpathlen = strlen(oldpath); if (strncmp(oldpath, item->path, oldpathlen) != 0) { g_warning("path doesn't match: %s, %s\n", oldpath, item->path); return TRUE; } base = item->path + oldpathlen; while (*base == G_DIR_SEPARATOR) base++; if (*base == '\0') new_itempath = g_strdup(newpath); else new_itempath = g_strconcat(newpath, G_DIR_SEPARATOR_S, base, NULL); g_free(item->path); item->path = new_itempath; return FALSE; }
static void mh_scan_tree_recursive(FolderItem *item) { Folder *folder; GDir *dir; const gchar *dir_name; gchar *real_path, *entry, *utf8entry, *utf8name; gint n_msg = 0; GError *error = NULL; cm_return_if_fail(item != NULL); cm_return_if_fail(item->folder != NULL); folder = item->folder; real_path = item->path ? mh_filename_from_utf8(item->path) : g_strdup("."); dir = g_dir_open(real_path, 0, &error); if (!dir) { g_warning("failed to open directory '%s': %s (%d)", real_path, error->message, error->code); g_error_free(error); g_free(real_path); return; } g_free(real_path); debug_print("scanning %s ...\n", item->path ? item->path : LOCAL_FOLDER(item->folder)->rootpath); if (folder->ui_func) folder->ui_func(folder, item, folder->ui_func_data); while ((dir_name = g_dir_read_name(dir)) != NULL) { if (dir_name[0] == '.') continue; utf8name = mh_filename_to_utf8(dir_name); if (item->path) utf8entry = g_strconcat(item->path, G_DIR_SEPARATOR_S, utf8name, NULL); else utf8entry = g_strdup(utf8name); entry = mh_filename_from_utf8(utf8entry); if (g_file_test(entry, G_FILE_TEST_IS_DIR)) { FolderItem *new_item = NULL; GNode *node; node = item->node; for (node = node->children; node != NULL; node = node->next) { FolderItem *cur_item = FOLDER_ITEM(node->data); gchar *curpath = mh_filename_from_utf8(cur_item->path); if (!strcmp2(curpath, entry)) { new_item = cur_item; g_free(curpath); break; } g_free(curpath); } if (!new_item) { debug_print("new folder '%s' found.\n", entry); new_item = folder_item_new(folder, utf8name, utf8entry); folder_item_append(item, new_item); } if (!item->path) { if (!folder->inbox && !strcmp(dir_name, INBOX_DIR)) { new_item->stype = F_INBOX; folder->inbox = new_item; } else if (!folder->outbox && !strcmp(dir_name, OUTBOX_DIR)) { new_item->stype = F_OUTBOX; folder->outbox = new_item; } else if (!folder->draft && !strcmp(dir_name, DRAFT_DIR)) { new_item->stype = F_DRAFT; folder->draft = new_item; } else if (!folder->queue && !strcmp(dir_name, QUEUE_DIR)) { new_item->stype = F_QUEUE; folder->queue = new_item; } else if (!folder->trash && !strcmp(dir_name, TRASH_DIR)) { new_item->stype = F_TRASH; folder->trash = new_item; } } mh_scan_tree_recursive(new_item); } else if (to_number(dir_name) > 0) n_msg++; g_free(entry); g_free(utf8entry); g_free(utf8name); } g_dir_close(dir); mh_set_mtime(folder, item); }