Ejemplo n.º 1
0
void collection_free(CollectionData *cd)
{
	if (!cd) return;

	DEBUG_1("collection \"%s\" freed", cd->name);

	collection_load_stop(cd);
	collection_list_free(cd->list);

	file_data_unregister_notify_func(collection_notify_cb, cd);

	collection_list = g_list_remove(collection_list, cd);

	g_hash_table_destroy(cd->existence);

	g_free(cd->path);
	g_free(cd->name);

	g_free(cd);
}
Ejemplo n.º 2
0
static gint collection_load_private(CollectionData *cd, const gchar *path, gint append, gint flush)
{
	gchar s_buf[2048];
	FILE *f;
	gchar *pathl;
	gint official = FALSE;
	gint success = TRUE;
	guint total = 0;
	guint fail = 0;

	collection_load_stop(cd);

	if (flush) collect_manager_flush();

	if (!append)
		{
		collection_list_free(cd->list);
		cd->list = NULL;
		}

	if (!path && !cd->path) return FALSE;

	if (!path) path = cd->path;

	/* load it */
	pathl = path_from_utf8(path);
	f = fopen(pathl, "r");
	g_free(pathl);
	if (!f)
		{
		printf("Failed to open collection file: \"%s\"\n", path);
		return FALSE;
		}

	while (fgets(s_buf, sizeof(s_buf), f))
		{
		gchar *buf;
		if (s_buf[0]=='#')
			{
			if (strncasecmp(s_buf, GQVIEW_COLLECTION_MARKER, strlen(GQVIEW_COLLECTION_MARKER)) == 0)
				{
				/* Looks like an official collection, allow unchecked input.
				 * All this does is allow adding files that may not exist,
				 * which is needed for the collection manager to work.
				 * Also unofficial files abort after too many invalid entries.
				 */
				official = TRUE;
				}
			else if (strncmp(s_buf, "#geometry:", 10 ) == 0 &&
			    scan_geometry(s_buf + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h) )
				{
				cd->window_read = TRUE;
				}
			continue;
			}
		if (s_buf[0]=='\n') continue;

		buf = quoted_value(s_buf);
		if (buf)
			{
			gint valid;

			valid = (buf[0] == '/' && collection_add_check(cd, buf, FALSE, flush));
			g_free(buf);

			total++;
			if (!valid && !official)
				{
				fail++;
				if (fail > GQVIEW_COLLECTION_FAIL_MIN &&
				    fail * 100 / total > GQVIEW_COLLECTION_FAIL_PERCENT)
					{
					printf("Too many invalid filenames in unoffical collection file, closing: %s\n", path);
					success = FALSE;
					break;
					}
				}
			}
		}

	fclose(f);

	cd->list = collection_list_sort(cd->list, cd->sort_method);
	if (!append) cd->changed = FALSE;

	return success;
}
Ejemplo n.º 3
0
static gboolean collection_load_private(CollectionData *cd, const gchar *path, CollectionLoadFlags flags)
{
	gchar s_buf[GQ_COLLECTION_READ_BUFSIZE];
	FILE *f;
	gchar *pathl;
	gboolean limit_failures = TRUE;
	gboolean success = TRUE;
	gboolean has_official_header = FALSE;
	gboolean has_geometry_header = FALSE;
	gboolean has_gqview_header   = FALSE;
	gboolean need_header	 = TRUE;
	guint total = 0;
	guint fail = 0;
	gboolean changed = FALSE;
	CollectManagerEntry *entry = NULL;
	guint flush = !!(flags & COLLECTION_LOAD_FLUSH);
	guint append = !!(flags & COLLECTION_LOAD_APPEND);
	guint only_geometry = !!(flags & COLLECTION_LOAD_GEOMETRY);

	if (!only_geometry)
		{
		collection_load_stop(cd);

		if (flush)
			collect_manager_flush();
		else
			entry = collect_manager_get_entry(path);

		if (!append)
			{
			collection_list_free(cd->list);
			cd->list = NULL;
			}
		}

	if (!path && !cd->path) return FALSE;

	if (!path) path = cd->path;

	DEBUG_1("collection load: append=%d flush=%d only_geometry=%d path=%s",
			  append, flush, only_geometry, path);

	/* load it */
	pathl = path_from_utf8(path);
	f = fopen(pathl, "r");
	g_free(pathl);
	if (!f)
		{
		log_printf("Failed to open collection file: \"%s\"\n", path);
		return FALSE;
		}

	while (fgets(s_buf, sizeof(s_buf), f))
		{
		gchar *buf;
		gchar *p = s_buf;

		/* Skip whitespaces and empty lines */
		while (*p && g_ascii_isspace(*p)) p++;
		if (*p == '\n' || *p == '\r') continue;

		/* Parse comments */
		if (*p == '#')
			{
			if (!need_header) continue;
			if (g_ascii_strncasecmp(p, GQ_COLLECTION_MARKER, strlen(GQ_COLLECTION_MARKER)) == 0)
				{
				/* Looks like an official collection, allow unchecked input.
				 * All this does is allow adding files that may not exist,
				 * which is needed for the collection manager to work.
				 * Also unofficial files abort after too many invalid entries.
				 */
				has_official_header = TRUE;
				limit_failures = FALSE;
				}
			else if (strncmp(p, "#geometry:", 10 ) == 0 &&
				 scan_geometry(p + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h))
				{
				has_geometry_header = TRUE;
				cd->window_read = TRUE;
				if (only_geometry) break;
				}
			else if (g_ascii_strncasecmp(p, "#GQview collection", strlen("#GQview collection")) == 0)
				{
				/* As 2008/04/15 there is no difference between our collection file format
				 * and GQview 2.1.5 collection file format so ignore failures as well. */
				has_gqview_header = TRUE;
				limit_failures = FALSE;
				}
			need_header = (!has_official_header && !has_gqview_header) || !has_geometry_header;
			continue;
			}

		if (only_geometry) continue;

		/* Read filenames */
		while (*p && *p != '"') p++;
		if (*p) p++;
		buf = p;
		while (*p && *p != '"') p++;
		*p = 0;
		if (*buf)
			{
			gboolean valid;

			if (!flush)
				changed |= collect_manager_process_action(entry, &buf);

			valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE));
			if (!valid) DEBUG_1("collection invalid file: %s", buf);

			total++;
			if (!valid)
				{
				fail++;
				if (limit_failures &&
				    fail > GQ_COLLECTION_FAIL_MIN &&
				    fail * 100 / total > GQ_COLLECTION_FAIL_PERCENT)
					{
					log_printf("%d invalid filenames in unofficial collection file, closing: %s\n", fail, path);
					success = FALSE;
					break;
					}
				}
			}
		}

	DEBUG_1("collection files: total = %d fail = %d official=%d gqview=%d geometry=%d",
			  total, fail, has_official_header, has_gqview_header, has_geometry_header);

	fclose(f);
	if (only_geometry) return has_geometry_header;

	if (!flush)
		{
		gchar *buf = NULL;
		while (collect_manager_process_action(entry, &buf))
			{
			collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE);
			changed = TRUE;
			g_free(buf);
			buf = NULL;
			}
		}

	cd->list = collection_list_sort(cd->list, cd->sort_method);

	if (!flush && changed && success)
		collection_save_private(cd, path);

	if (!flush)
		collect_manager_entry_reset(entry);

	if (!append) cd->changed = FALSE;

	return success;
}