예제 #1
0
/**
 * asb_plugin_process_filename:
 */
static gboolean
asb_plugin_process_filename (AsbPlugin *plugin,
			     AsbPackage *pkg,
			     const gchar *filename,
			     GList **apps,
			     GError **error)
{
	_cleanup_object_unref_ AsbApp *app = NULL;

	app = asb_app_new (pkg, NULL);
	if (!as_app_parse_file (AS_APP (app), filename,
				AS_APP_PARSE_FLAG_APPEND_DATA,
				error))
		return FALSE;
	if (as_app_get_id_kind (AS_APP (app)) != AS_ID_KIND_ADDON &&
	    as_app_get_id_kind (AS_APP (app)) != AS_ID_KIND_FONT) {
		g_set_error (error,
			     ASB_PLUGIN_ERROR,
			     ASB_PLUGIN_ERROR_FAILED,
			     "%s is not an addon or font",
			     as_app_get_id (AS_APP (app)));
		return FALSE;
	}
	asb_app_set_requires_appdata (app, FALSE);
	asb_app_set_hidpi_enabled (app, asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS));
	asb_plugin_add_app (apps, AS_APP (app));
	return TRUE;
}
예제 #2
0
static AsApp *
load_appdata (const gchar *prefix, const gchar *app_name, GError **error)
{
	g_autofree gchar *appdata_basename = NULL;
	g_autofree gchar *appdata_path = NULL;
	g_autoptr(AsApp) app = NULL;
	g_autoptr(GPtrArray) problems = NULL;
	AsProblemKind problem_kind;
	AsProblem *problem;
	guint i;

	appdata_basename = g_strconcat (app_name,
					".appdata.xml",
					NULL);
	appdata_path = g_build_filename (prefix,
					 "share",
					 "appdata",
					 appdata_basename,
					 NULL);
	g_debug ("Looking for %s", appdata_path);

	app = as_app_new ();
	if (!as_app_parse_file (app, appdata_path,
				AS_APP_PARSE_FLAG_USE_HEURISTICS,
				error))
		return NULL;
	if (as_app_get_kind (app) == AS_APP_KIND_UNKNOWN) {
		g_set_error (error,
			     AS_APP_ERROR,
			     AS_APP_ERROR_FAILED,
			     "%s has no recognised type",
			     as_app_get_id (AS_APP (app)));
		return NULL;
	}

	problems = as_app_validate (app,
				    AS_APP_VALIDATE_FLAG_NO_NETWORK |
				    AS_APP_VALIDATE_FLAG_RELAX,
				    error);
	if (problems == NULL)
		return NULL;
	for (i = 0; i < problems->len; i++) {
		problem = g_ptr_array_index (problems, i);
		problem_kind = as_problem_get_kind (problem);
		as_compose_app_log (app,
				    "AppData problem: %s : %s",
				    as_problem_kind_to_string (problem_kind),
				    as_problem_get_message (problem));
	}
	if (problems->len > 0) {
		g_set_error (error,
			     AS_APP_ERROR,
			     AS_APP_ERROR_FAILED,
			     "AppData file %s was not valid",
			     appdata_path);
		return NULL;
	}

	return g_steal_pointer (&app);
}
예제 #3
0
static AsApp *
load_desktop (const gchar *prefix,
	      const gchar *icons_dir,
	      guint        min_icon_size,
	      const gchar *app_name,
	      const gchar *appdata_id,
	      GError **error)
{
	AsIcon *icon;
	g_autofree gchar *desktop_basename = NULL;
	g_autofree gchar *desktop_path = NULL;
	g_autoptr(AsApp) app = NULL;

	if (appdata_id != NULL)
		desktop_basename = g_strdup (appdata_id);
	else
		desktop_basename = g_strconcat (app_name, ".desktop", NULL);
	desktop_path = g_build_filename (prefix, "share/applications", desktop_basename, NULL);

	app = as_app_new ();
	if (!as_app_parse_file (app, desktop_path,
				AS_APP_PARSE_FLAG_USE_HEURISTICS |
				AS_APP_PARSE_FLAG_ALLOW_VETO,
				error))
		return NULL;
	if (as_app_get_kind (app) == AS_APP_KIND_UNKNOWN) {
		g_set_error (error,
			     AS_APP_ERROR,
			     AS_APP_ERROR_FAILED,
			     "%s has no recognised type",
			     as_app_get_id (AS_APP (app)));
		return NULL;
	}

	icon = as_app_get_icon_default (AS_APP (app));
	if (icon != NULL) {
		g_autofree gchar *key = NULL;
		key = g_strdup (as_icon_get_name (icon));
		if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) {
			as_compose_app_log (app,
					    "using stock icon %s", key);
		} else {
			g_autoptr(GError) error_local = NULL;
			gboolean ret;

			g_ptr_array_set_size (as_app_get_icons (AS_APP (app)), 0);
			ret = add_icons (app,
					 icons_dir,
					 min_icon_size,
					 prefix,
					 key,
					 error);
			if (!ret)
				return NULL;
		}
	}

	return g_steal_pointer (&app);
}
예제 #4
0
static gboolean
asb_plugin_desktop_refine (AsbPlugin *plugin,
			   AsbPackage *pkg,
			   const gchar *filename,
			   AsbApp *app,
			   const gchar *tmpdir,
			   GError **error)
{
	AsIcon *icon;
	AsAppParseFlags parse_flags = AS_APP_PARSE_FLAG_USE_HEURISTICS |
				      AS_APP_PARSE_FLAG_ALLOW_VETO;
	gboolean ret;
	g_autoptr(AsApp) desktop_app = NULL;
	g_autoptr(GdkPixbuf) pixbuf = NULL;

	/* use GenericName fallback */
	if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_USE_FALLBACKS))
		parse_flags |= AS_APP_PARSE_FLAG_USE_FALLBACKS;

	/* create app */
	desktop_app = as_app_new ();
	if (!as_app_parse_file (desktop_app, filename, parse_flags, error))
		return FALSE;

	/* copy all metadata */
	as_app_subsume_full (AS_APP (app), desktop_app, AS_APP_SUBSUME_FLAG_NO_OVERWRITE);

	/* is the icon a stock-icon-name? */
	icon = as_app_get_icon_default (AS_APP (app));
	if (icon != NULL) {
		g_autofree gchar *key = NULL;
		key = g_strdup (as_icon_get_name (icon));
		if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) {
			asb_package_log (pkg,
					 ASB_PACKAGE_LOG_LEVEL_DEBUG,
					 "using stock icon %s", key);
		} else {
			g_autoptr(GError) error_local = NULL;
			g_ptr_array_set_size (as_app_get_icons (AS_APP (app)), 0);
			ret = asb_plugin_desktop_add_icons (plugin,
							    app,
							    tmpdir,
							    key,
							    &error_local);
			if (!ret) {
				as_app_add_veto (AS_APP (app), "%s",
						 error_local->message);
			}
		}
	}

	return TRUE;
}
예제 #5
0
/**
 * appdata_validate_and_show_results:
 **/
static gint
appdata_validate_and_show_results (const gchar *filename_original,
				   const gchar *filename,
				   const gchar *output_format,
				   AsAppValidateFlags flags)
{
	AsApp *app;
	GError *error = NULL;
	GPtrArray *problems = NULL;
	const gchar *tmp;
	gboolean ret;
	gint retval = EXIT_CODE_SUCCESS;

	/* scan file for problems */
	app = as_app_new ();
	as_app_set_source_kind (app, AS_APP_SOURCE_KIND_APPDATA);
	ret = as_app_parse_file (app, filename,
				 AS_APP_PARSE_FLAG_NONE,
				 &error);
	if (!ret) {
		retval = EXIT_CODE_FAILURE;
		g_print ("Failed: %s\n", error->message);
		g_error_free (error);
		goto out;
	}
	problems = as_app_validate (app, flags, &error);
	if (problems == NULL) {
		retval = EXIT_CODE_FAILURE;
		g_print ("Failed: %s\n", error->message);
		g_error_free (error);
		goto out;
	}
	if (problems->len > 0)
		retval = EXIT_CODE_WARNINGS;

	/* print problems */
	tmp = filename_original != NULL ? filename_original : filename;
	if (g_strcmp0 (output_format, "html") == 0) {
		appdata_validate_format_html (tmp, problems);
	} else if (g_strcmp0 (output_format, "xml") == 0) {
		appdata_validate_format_xml (tmp, problems);
	} else {
		appdata_validate_format_text (tmp, problems);
	}
out:
	g_object_unref (app);
	if (problems)
		g_ptr_array_unref (problems);
	return retval;
}
/**
 * cra_plugin_process_filename:
 */
static gboolean
cra_plugin_process_filename (CraPlugin *plugin,
			     CraPackage *pkg,
			     const gchar *filename,
			     GList **apps,
			     const gchar *tmpdir,
			     GError **error)
{
	const gchar *key;
	gboolean ret;
	_cleanup_free_ gchar *app_id = NULL;
	_cleanup_free_ gchar *full_filename = NULL;
	_cleanup_free_ gchar *icon_filename = NULL;
	_cleanup_object_unref_ CraApp *app = NULL;
	_cleanup_object_unref_ GdkPixbuf *pixbuf = NULL;

	/* create app */
	app_id = g_path_get_basename (filename);
	app = cra_app_new (pkg, app_id);
	full_filename = g_build_filename (tmpdir, filename, NULL);
	ret = as_app_parse_file (AS_APP (app),
				 full_filename,
				 AS_APP_PARSE_FLAG_USE_HEURISTICS,
				 error);
	if (!ret)
		return FALSE;

	/* NoDisplay requires AppData */
	if (as_app_get_metadata_item (AS_APP (app), "NoDisplay") != NULL)
		cra_app_add_requires_appdata (app, "NoDisplay=true");

	/* Settings or DesktopSettings requires AppData */
	if (as_app_has_category (AS_APP (app), "Settings"))
		cra_app_add_requires_appdata (app, "Category=Settings");
	if (as_app_has_category (AS_APP (app), "DesktopSettings"))
		cra_app_add_requires_appdata (app, "Category=DesktopSettings");

	/* is the icon a stock-icon-name? */
	key = as_app_get_icon (AS_APP (app));
	if (key != NULL) {
		if (as_app_get_icon_kind (AS_APP (app)) == AS_ICON_KIND_STOCK) {
			cra_package_log (pkg,
					 CRA_PACKAGE_LOG_LEVEL_DEBUG,
					 "using stock icon %s", key);
		} else {

			/* is icon XPM or GIF */
			if (g_str_has_suffix (key, ".xpm"))
				cra_app_add_veto (app, "Uses XPM icon: %s", key);
			else if (g_str_has_suffix (key, ".gif"))
				cra_app_add_veto (app, "Uses GIF icon: %s", key);
			else if (g_str_has_suffix (key, ".ico"))
				cra_app_add_veto (app, "Uses ICO icon: %s", key);

			/* find icon */
			pixbuf = cra_app_find_icon (tmpdir, key, error);
			if (pixbuf == NULL)
				return FALSE;

			/* save in target directory */
			icon_filename = g_strdup_printf ("%s.png",
							 as_app_get_id (AS_APP (app)));
			as_app_set_icon (AS_APP (app), icon_filename, -1);
			as_app_set_icon_kind (AS_APP (app), AS_ICON_KIND_CACHED);
			cra_app_set_pixbuf (app, pixbuf);
		}
	}

	/* add */
	cra_plugin_add_app (apps, app);
	return TRUE;
}
예제 #7
0
/**
 * asb_plugin_process_filename:
 */
static gboolean
asb_plugin_process_filename (AsbPlugin *plugin,
			     AsbPackage *pkg,
			     const gchar *filename,
			     GList **apps,
			     const gchar *tmpdir,
			     GError **error)
{
	AsIcon *icon;
	AsAppParseFlags parse_flags = AS_APP_PARSE_FLAG_USE_HEURISTICS;
	gboolean ret;
	_cleanup_free_ gchar *app_id = NULL;
	_cleanup_free_ gchar *full_filename = NULL;
	_cleanup_object_unref_ AsbApp *app = NULL;
	_cleanup_object_unref_ GdkPixbuf *pixbuf = NULL;

	/* use GenericName fallback */
	if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_USE_FALLBACKS))
		parse_flags |= AS_APP_PARSE_FLAG_USE_FALLBACKS;

	/* create app */
	app_id = g_path_get_basename (filename);
	app = asb_app_new (pkg, app_id);
	asb_app_set_hidpi_enabled (app, asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS));
	full_filename = g_build_filename (tmpdir, filename, NULL);
	if (!as_app_parse_file (AS_APP (app), full_filename, parse_flags, error))
		return FALSE;

	/* NoDisplay apps are never included */
	if (as_app_get_metadata_item (AS_APP (app), "NoDisplay") != NULL)
		asb_app_add_requires_appdata (app, "NoDisplay=true");

	/* Settings or DesktopSettings requires AppData */
	if (!asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_IGNORE_SETTINGS)) {
		if (as_app_has_category (AS_APP (app), "Settings"))
			asb_app_add_requires_appdata (app, "Category=Settings");
		if (as_app_has_category (AS_APP (app), "DesktopSettings"))
			asb_app_add_requires_appdata (app, "Category=DesktopSettings");
	}

	/* is the icon a stock-icon-name? */
	icon = as_app_get_icon_default (AS_APP (app));
	if (icon != NULL) {
		_cleanup_free_ gchar *key = NULL;
		key = g_strdup (as_icon_get_name (icon));
		if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) {
			asb_package_log (pkg,
					 ASB_PACKAGE_LOG_LEVEL_DEBUG,
					 "using stock icon %s", key);
		} else {
			_cleanup_error_free_ GError *error_local = NULL;
			g_ptr_array_set_size (as_app_get_icons (AS_APP (app)), 0);
			ret = asb_plugin_desktop_add_icons (plugin,
							    app,
							    tmpdir,
							    key,
							    &error_local);
			if (!ret) {
				as_app_add_veto (AS_APP (app), "%s",
						 error_local->message);
			}
		}
	}

	/* add */
	asb_plugin_add_app (apps, AS_APP (app));
	return TRUE;
}
예제 #8
0
static gboolean
asb_plugin_process_filename (AsbPlugin *plugin,
			     AsbPackage *pkg,
			     const gchar *filename,
			     GList **apps,
			     GError **error)
{
	AsProblemKind problem_kind;
	AsProblem *problem;
	GPtrArray *icons;
	const gchar *tmp;
	guint i;
	g_autoptr(AsbApp) app = NULL;
	g_autoptr(GPtrArray) problems = NULL;

	app = asb_app_new (NULL, NULL);
	if (!as_app_parse_file (AS_APP (app), filename,
				AS_APP_PARSE_FLAG_USE_HEURISTICS,
				error))
		return FALSE;
	if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_UNKNOWN) {
		g_set_error (error,
			     ASB_PLUGIN_ERROR,
			     ASB_PLUGIN_ERROR_FAILED,
			     "%s has no recognised type",
			     as_app_get_id (AS_APP (app)));
		return FALSE;
	}

	/* validate */
	problems = as_app_validate (AS_APP (app),
				    AS_APP_VALIDATE_FLAG_NO_NETWORK |
				    AS_APP_VALIDATE_FLAG_RELAX,
				    error);
	if (problems == NULL)
		return FALSE;
	asb_app_set_package (app, pkg);
	for (i = 0; i < problems->len; i++) {
		problem = g_ptr_array_index (problems, i);
		problem_kind = as_problem_get_kind (problem);
		asb_package_log (asb_app_get_package (app),
				 ASB_PACKAGE_LOG_LEVEL_WARNING,
				 "AppData problem: %s : %s",
				 as_problem_kind_to_string (problem_kind),
				 as_problem_get_message (problem));
	}

	/* nuke things that do not belong */
	icons = as_app_get_icons (AS_APP (app));
	if (icons->len > 0)
		g_ptr_array_set_size (icons, 0);

	/* fix up the project license */
	tmp = as_app_get_project_license (AS_APP (app));
	if (tmp != NULL && !as_utils_is_spdx_license (tmp)) {
		g_autofree gchar *license_spdx = NULL;
		license_spdx = as_utils_license_to_spdx (tmp);
		if (as_utils_is_spdx_license (license_spdx)) {
			asb_package_log (asb_app_get_package (app),
					 ASB_PACKAGE_LOG_LEVEL_WARNING,
					 "project license fixup: %s -> %s",
					 tmp, license_spdx);
			as_app_set_project_license (AS_APP (app), license_spdx);
		} else {
			asb_package_log (asb_app_get_package (app),
					 ASB_PACKAGE_LOG_LEVEL_WARNING,
					 "project license is invalid: %s", tmp);
			as_app_set_project_license (AS_APP (app), NULL);
		}
	}

	/* check license */
	tmp = as_app_get_metadata_license (AS_APP (app));
	if (tmp == NULL) {
		g_set_error (error,
			     ASB_PLUGIN_ERROR,
			     ASB_PLUGIN_ERROR_FAILED,
			     "AppData %s has no licence",
			     filename);
		return FALSE;
	}
	if (!as_utils_is_spdx_license (tmp)) {
		g_set_error (error,
			     ASB_PLUGIN_ERROR,
			     ASB_PLUGIN_ERROR_FAILED,
			     "AppData %s license '%s' invalid",
			     filename, tmp);
		return FALSE;
	}

	/* log updateinfo */
	tmp = as_app_get_update_contact (AS_APP (app));
	if (tmp != NULL) {
		asb_package_log (asb_app_get_package (app),
				 ASB_PACKAGE_LOG_LEVEL_INFO,
				 "Upstream contact <%s>", tmp);
	}

	/* add icon for firmware */
	if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_FIRMWARE) {
		g_autoptr(AsIcon) icon = NULL;
		icon = as_icon_new ();
		as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
		as_icon_set_name (icon, "application-x-executable");
		as_app_add_icon (AS_APP (app), icon);
	}

	/* fix up input methods */
	if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_INPUT_METHOD) {
		g_autoptr(AsIcon) icon = NULL;
		icon = as_icon_new ();
		as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
		as_icon_set_name (icon, "system-run-symbolic");
		as_app_add_icon (AS_APP (app), icon);
		as_app_add_category (AS_APP (app), "Addons");
		as_app_add_category (AS_APP (app), "InputSources");
	}

	/* fix up codecs */
	if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_CODEC) {
		g_autoptr(AsIcon) icon = NULL;
		icon = as_icon_new ();
		as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
		as_icon_set_name (icon, "application-x-executable");
		as_app_add_icon (AS_APP (app), icon);
		as_app_add_category (AS_APP (app), "Addons");
		as_app_add_category (AS_APP (app), "Codecs");
	}

	/* success */
	asb_app_set_hidpi_enabled (app, asb_context_get_flag (plugin->ctx,
							      ASB_CONTEXT_FLAG_HIDPI_ICONS));
	asb_plugin_add_app (apps, AS_APP (app));
	return TRUE;
}
예제 #9
0
static gboolean
as_store_cab_from_bytes_with_origin (AsStore *store,
				     GBytes *bytes,
				     const gchar *basename,
				     GCancellable *cancellable,
				     GError **error)
{
	g_autoptr(GCabCabinet) gcab = NULL;
	g_autoptr(GError) error_local = NULL;
	g_autofree gchar *tmp_path = NULL;
	g_autoptr(GFile) tmp_file = NULL;
	g_autoptr(GInputStream) input_stream = NULL;
	g_autoptr(GPtrArray) filelist = NULL;
	guint i;

	/* open the file */
	gcab = gcab_cabinet_new ();
	input_stream = g_memory_input_stream_new_from_bytes (bytes);
	if (!gcab_cabinet_load (gcab, input_stream, NULL, &error_local)) {
		g_set_error (error,
			     AS_STORE_ERROR,
			     AS_STORE_ERROR_FAILED,
			     "cannot load .cab file: %s",
			     error_local->message);
		return FALSE;
	}

	/* decompress to /tmp */
	tmp_path = g_dir_make_tmp ("appstream-glib-XXXXXX", &error_local);
	if (tmp_path == NULL) {
		g_set_error (error,
			     AS_STORE_ERROR,
			     AS_STORE_ERROR_FAILED,
			     "failed to create temp dir: %s",
			     error_local->message);
		return FALSE;
	}

	/* extract the entire cab file */
	filelist = g_ptr_array_new_with_free_func (g_free);
	tmp_file = g_file_new_for_path (tmp_path);
	if (!gcab_cabinet_extract_simple (gcab, tmp_file,
					  as_store_cab_cb,
					  filelist, NULL, &error_local)) {
		g_set_error (error,
			     AS_STORE_ERROR,
			     AS_STORE_ERROR_FAILED,
			     "failed to extract .cab file: %s",
			     error_local->message);
		return FALSE;
	}

	/* loop through each file looking for components */
	for (i = 0; i < filelist->len; i++) {
		AsRelease *rel;
		AsChecksum *csum_tmp;
		const gchar *fn;
		g_autofree gchar *tmp_fn = NULL;
		g_autoptr(AsApp) app = NULL;

		/* debug */
		fn = g_ptr_array_index (filelist, i);
		g_debug ("found file %u\t%s", i, fn);

		/* if inf or metainfo, add */
		if (as_format_guess_kind (fn) != AS_FORMAT_KIND_METAINFO)
			continue;

		tmp_fn = g_build_filename (tmp_path, fn, NULL);
		app = as_app_new ();
		if (!as_app_parse_file (app, tmp_fn,
					AS_APP_PARSE_FLAG_NONE, &error_local)) {
			g_set_error (error,
				     AS_STORE_ERROR,
				     AS_STORE_ERROR_FAILED,
				     "%s could not be loaded: %s",
				     tmp_fn,
				     error_local->message);
			return FALSE;
		}

		/* only process the latest release */
		rel = as_app_get_release_default (app);
		if (rel == NULL) {
			g_set_error_literal (error,
					     AS_STORE_ERROR,
					     AS_STORE_ERROR_FAILED,
					     "no releases in metainfo file");
			return FALSE;
		}

		/* ensure we always have a container checksum */
		csum_tmp = as_release_get_checksum_by_target (rel, AS_CHECKSUM_TARGET_CONTAINER);
		if (csum_tmp == NULL) {
			g_autoptr(AsChecksum) csum = NULL;
			csum = as_checksum_new ();
			as_checksum_set_target (csum, AS_CHECKSUM_TARGET_CONTAINER);
			if (basename != NULL)
				as_checksum_set_filename (csum, basename);
			as_release_add_checksum (rel, csum);
		}

		/* set the container checksum */
		if (!as_store_cab_verify_checksum_cab (rel, bytes, error))
			return FALSE;

		/* this is the size of the cab file itself */
		if (as_release_get_size (rel, AS_SIZE_KIND_DOWNLOAD) == 0)
			as_release_set_size (rel, AS_SIZE_KIND_DOWNLOAD,
					     g_bytes_get_size (bytes));

		/* ensure we always have a content checksum */
		csum_tmp = as_release_get_checksum_by_target (rel, AS_CHECKSUM_TARGET_CONTENT);
		if (csum_tmp == NULL) {
			g_autoptr(AsChecksum) csum = NULL;
			csum = as_checksum_new ();
			as_checksum_set_target (csum, AS_CHECKSUM_TARGET_CONTENT);
			/* if this isn't true, a firmware needs to set in
			 * the metainfo.xml file something like:
			 * <checksum target="content" filename="FLASH.ROM"/> */
			as_checksum_set_filename (csum, "firmware.bin");
			as_release_add_checksum (rel, csum);
			csum_tmp = csum;
		}
		if (!as_store_cab_verify_checksum_fw (csum_tmp, tmp_path, error))
			return FALSE;

		/* set blobs */
		if (!as_store_cab_set_release_blobs (rel, tmp_path, error))
			return FALSE;

		/* add any component to the store */
		as_store_add_app (store, app);
	}

	/* delete temp files */
	for (i = 0; i < filelist->len; i++) {
		const gchar *fn;
		g_autofree gchar *tmp_fn = NULL;
		fn = g_ptr_array_index (filelist, i);
		tmp_fn = g_build_filename (tmp_path, fn, NULL);
		g_unlink (tmp_fn);
	}
	g_rmdir (tmp_path);

	/* success */
	return TRUE;
}