GSList *grouplist_dialog(Folder *folder) { GNode *node; FolderItem *item; if (dialog && gtk_widget_get_visible(dialog)) return NULL; if (!dialog) grouplist_dialog_create(); news_folder = folder; gtk_widget_show(dialog); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); manage_window_set_transient(GTK_WINDOW(dialog)); gtk_widget_grab_focus(ok_button); gtk_widget_grab_focus(ctree); GTK_EVENTS_FLUSH(); subscribed = NULL; for (node = folder->node->children; node != NULL; node = node->next) { item = FOLDER_ITEM(node->data); subscribed = g_slist_append(subscribed, g_strdup(item->path)); } grouplist_dialog_set_list(NULL, TRUE); if (ack) gtk_main(); manage_window_focus_out(dialog, NULL, NULL); gtk_widget_hide(dialog); if (!ack) { slist_free_strings_full(subscribed); subscribed = NULL; for (node = folder->node->children; node != NULL; node = node->next) { item = FOLDER_ITEM(node->data); subscribed = g_slist_append(subscribed, g_strdup(item->path)); } } grouplist_clear(); return subscribed; }
static gint mh_scan_tree(Folder *folder) { FolderItem *item; gchar *rootpath; cm_return_val_if_fail(folder != NULL, -1); if (!folder->node) { item = folder_item_new(folder, folder->name, NULL); item->folder = folder; folder->node = item->node = g_node_new(item); } else item = FOLDER_ITEM(folder->node->data); rootpath = folder_item_get_path(item); if (change_dir(rootpath) < 0) { g_free(rootpath); return -1; } g_free(rootpath); mh_create_tree(folder); mh_remove_missing_folder_items(folder); mh_scan_tree_recursive(item); return 0; }
static FolderItem *news_find_child_item(FolderItem *item, const gchar *path) { GNode *node; FolderItem *child; for (node = item->node->children; node != NULL; node = node->next) { child = FOLDER_ITEM(node->data); if (g_strcmp0(child->path, path) == 0) { return child; } } return NULL; }
void news_remove_group_list_cache(Folder *folder) { gchar *path, *filename; cm_return_if_fail(folder != NULL); cm_return_if_fail(FOLDER_CLASS(folder) == &news_class); path = folder_item_get_path(FOLDER_ITEM(folder->node->data)); filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL); g_free(path); if (is_file_exist(filename)) { if (claws_unlink(filename) < 0) FILE_OP_ERROR(filename, "remove"); } g_free(filename); }
/* Helper function for foldercheck_set_tree */ static void foldercheck_insert_gnode_in_store(GtkTreeStore *store, GNode *node, GtkTreeIter *parent) { FolderItem *item; GtkTreeIter child; GNode *iter; g_return_if_fail(node != NULL); g_return_if_fail(node->data != NULL); g_return_if_fail(store != NULL); item = FOLDER_ITEM(node->data); foldercheck_append_item(store, item, &child, parent); /* insert its children (this node as parent) */ for(iter = node->children; iter != NULL; iter = iter->next) foldercheck_insert_gnode_in_store(store, iter, &child); }
static gboolean mh_remove_missing_folder_items_func(GNode *node, gpointer data) { FolderItem *item; gchar *path; cm_return_val_if_fail(node->data != NULL, FALSE); if (G_NODE_IS_ROOT(node)) return FALSE; item = FOLDER_ITEM(node->data); path = folder_item_get_path(item); if (!is_dir_exist(path)) { debug_print("folder '%s' not found. removing...\n", path?path:"(null)"); folder_item_remove(item); } g_free(path); return FALSE; }
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); }
static void rssyl_update_format_func(FolderItem *item, gpointer data) { RFolderItem *ritem; RUpdateFormatCtx *ctx = (RUpdateFormatCtx *)data; Folder *f = NULL; FolderItem *new_item = NULL; gchar *name; OldRFeed *of; if( !IS_RSSYL_FOLDER_ITEM(item) ) return; /* Do not do anything once we reached first new folder * (which we created earlier in this process) */ if( ctx->reached_first_new ) return; if( item->folder == ctx->n_first ) { ctx->reached_first_new = TRUE; debug_print("RSSyl: (FORMAT) reached first new folder\n"); return; } debug_print("RSSyl: (FORMAT) item '%s'\n", item->name); if( folder_item_parent(item) == NULL ) { /* Root rssyl folder */ ctx->oldroots = g_slist_prepend(ctx->oldroots, item); /* Create its counterpart */ name = rssyl_strreplace(folder_item_get_name(item), " (RSSyl)", ""); debug_print("RSSyl: (FORMAT) adding new root folder '%s'\n", name); f = folder_new(rssyl_folder_get_class(), name, NULL); g_free(name); g_return_if_fail(f != NULL); folder_add(f); folder_write_list(); new_item = FOLDER_ITEM(f->node->data); /* If user has more than one old rssyl foldertrees, keep the n_first * pointer at the beginning of first one. */ if (ctx->n_first == NULL) ctx->n_first = f; ctx->n_parent = new_item; } else { /* Non-root folder */ if (folder_item_parent(item) == ctx->o_prev) { /* We went one step deeper in folder hierarchy, adjust pointers * to parents */ ctx->o_parent = ctx->o_prev; ctx->n_parent = ctx->n_prev; } else if (folder_item_parent(item) != ctx->o_parent) { /* We are not in same folder anymore, which can only mean we have * moved up in the hierarchy. Find a correct parent */ while (folder_item_parent(item) != ctx->o_parent) { ctx->o_parent = folder_item_parent(ctx->o_parent); ctx->n_parent = folder_item_parent(ctx->n_parent); if (ctx->o_parent == NULL) { /* This shouldn't happen, unless we are magically moved to a * completely different folder structure */ debug_print("RSSyl: MISHAP WHILE UPGRADING STORAGE FORMAT: couldn't find folder parent\n"); alertpanel_error(_("Internal problem while upgrading storage format. This should not happen. Please report this, with debug output attached.\n")); return; } } } else { /* We have remained in the same subfolder, nothing to do here */ } debug_print("RSSyl: (FORMAT) adding folder '%s'\n", item->name); new_item = folder_create_folder(ctx->n_parent, item->name); if (new_item == NULL) { debug_print("RSSyl: (FORMAT) couldn't add folder '%s', skipping it\n", item->name); return; } of = rssyl_old_feed_get_by_name(ctx->oldfeeds, item->name); if (of != NULL && of->url != NULL) { /* Folder with an actual subscribed feed */ debug_print("RSSyl: (FORMAT) making '%s' a feed with URL '%s'\n", item->name, of->url); ritem = (RFolderItem *)new_item; ritem->url = g_strdup(of->url); rssyl_feed_start_refresh_timeout(ritem); ritem->official_title = g_strdup(of->official_name); ritem->default_refresh_interval = (of->default_refresh_interval != 0 ? TRUE : FALSE); ritem->refresh_interval = of->refresh_interval; ritem->keep_old = (of->expired_num > -1 ? TRUE : FALSE); ritem->fetch_comments = (of->fetch_comments != 0 ? TRUE : FALSE); ritem->fetch_comments_max_age = of->fetch_comments_for; ritem->silent_update = of->silent_update; ritem->ssl_verify_peer = of->ssl_verify_peer; folder_item_prefs_copy_prefs(item, &ritem->item); } rssyl_update_format_move_contents(item, new_item); /* destroy the new folder's cache so we'll re-read the migrated one */ if (new_item->cache) { msgcache_destroy(new_item->cache); new_item->cache = NULL; } /* Store folderlist with the new folder */ folder_item_scan(new_item); folder_write_list(); } ctx->o_prev = item; ctx->n_prev = new_item; }
static void subscribe_newsgroup_cb(GtkAction *action, gpointer data) { FolderView *folderview = (FolderView *)data; Folder *folder; FolderItem *item; FolderItem *rootitem; FolderItem *newitem; GSList *new_subscr; GSList *cur; GNode *gnode; MainWindow *mainwin = mainwindow_get_mainwindow(); if ((item = folderview_get_selected_item(folderview)) == NULL) return; if (mainwin->lock_count || news_folder_locked(item->folder)) return; folder = item->folder; cm_return_if_fail(folder != NULL); cm_return_if_fail(FOLDER_TYPE(folder) == F_NEWS); cm_return_if_fail(folder->account != NULL); if ((rootitem = folder_item_parent(item)) == NULL) rootitem = item; new_subscr = grouplist_dialog(folder); /* remove unsubscribed newsgroups */ for (gnode = folder->node->children; gnode != NULL; ) { GNode *next = gnode->next; item = FOLDER_ITEM(gnode->data); if (g_slist_find_custom(new_subscr, item->path, (GCompareFunc)g_ascii_strcasecmp) != NULL) { gnode = next; continue; } if (folderview_get_opened_item(folderview) == item) { summary_clear_all(folderview->summaryview); folderview_close_opened(folderview, TRUE); } folderview_remove_item(folderview, item); folder_item_remove(item); gnode = next; } folderview_freeze(folderview); /* add subscribed newsgroups */ for (cur = new_subscr; cur != NULL; cur = cur->next) { gchar *name = (gchar *)cur->data; FolderUpdateData hookdata; if (news_find_child_item(rootitem, name) != NULL) continue; newitem = folder_item_new(folder, name, name); folder_item_append(rootitem, newitem); hookdata.folder = newitem->folder; hookdata.update_flags = FOLDER_TREE_CHANGED | FOLDER_ADD_FOLDERITEM; hookdata.item = newitem; hookdata.item2 = NULL; hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata); } folderview_thaw(folderview); slist_free_strings_full(new_subscr); folder_write_list(); }
GSList *news_get_group_list(Folder *folder) { gchar *path, *filename; FILE *fp; GSList *list = NULL; GSList *last = NULL; gchar buf[BUFFSIZE]; cm_return_val_if_fail(folder != NULL, NULL); cm_return_val_if_fail(FOLDER_CLASS(folder) == &news_class, NULL); path = folder_item_get_path(FOLDER_ITEM(folder->node->data)); if (!is_dir_exist(path)) make_dir_hier(path); filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL); g_free(path); if ((fp = g_fopen(filename, "rb")) == NULL) { NewsSession *session; gint ok; clist *grouplist = NULL; clistiter *cur; fp = g_fopen(filename, "wb"); if (!fp) { g_free(filename); return NULL; } session = news_session_get(folder); if (!session) { fclose(fp); g_free(filename); return NULL; } ok = nntp_threaded_list(folder, &grouplist); if (ok != NEWSNNTP_NO_ERROR) { if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; } fclose(fp); g_free(filename); return NULL; } if (grouplist) { for (cur = clist_begin(grouplist); cur; cur = clist_next(cur)) { struct newsnntp_group_info *info = (struct newsnntp_group_info *) clist_content(cur); if (fprintf(fp, "%s %d %d %c\n", info->grp_name, info->grp_last, info->grp_first, info->grp_type) < 0) { log_error(LOG_PROTOCOL, ("Can't write newsgroup list\n")); session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; fclose(fp); g_free(filename); newsnntp_list_free(grouplist); return NULL; } } newsnntp_list_free(grouplist); } if (fclose(fp) == EOF) { log_error(LOG_PROTOCOL, ("Can't write newsgroup list\n")); session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; g_free(filename); return NULL; } if ((fp = g_fopen(filename, "rb")) == NULL) { FILE_OP_ERROR(filename, "fopen"); g_free(filename); return NULL; } } while (fgets(buf, sizeof(buf), fp) != NULL) { gchar *p = buf; gchar *name; gint last_num; gint first_num; gchar type; NewsGroupInfo *ginfo; p = strchr(p, ' '); if (!p) continue; *p = '\0'; p++; name = buf; if (sscanf(p, "%d %d %c", &last_num, &first_num, &type) < 3) continue; ginfo = news_group_info_new(name, first_num, last_num, type); if (!last) last = list = g_slist_append(NULL, ginfo); else { last = g_slist_append(last, ginfo); last = last->next; } } fclose(fp); g_free(filename); list = g_slist_sort(list, (GCompareFunc)news_group_info_compare); return list; }