Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
0
File: news.c Project: Mortal/claws
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);
}
Example #5
0
/* 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);
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
File: mh.c Project: buzz/claws
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);
}
Example #9
0
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;
}
Example #10
0
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();
}
Example #11
0
File: news.c Project: Mortal/claws
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;
}