示例#1
0
/**
 * asb_context_disable_multiarch_pkgs:
 **/
static void
asb_context_disable_multiarch_pkgs (AsbContext *ctx)
{
	AsbContextPrivate *priv = GET_PRIVATE (ctx);
	AsbPackage *pkg;
	const gchar *arch;
	gboolean found_arch = FALSE;
	guint i;

	/* are there any 64-bit packages in the repo? */
	for (i = 0; i < priv->packages->len; i++) {
		pkg = ASB_PACKAGE (g_ptr_array_index (priv->packages, i));
		if (g_strcmp0 (asb_package_get_arch (pkg), "x86_64") == 0) {
			found_arch = TRUE;
			break;
		}
	}
	if (!found_arch)
		return;

	/* disable any alternate-arch packages */
	for (i = 0; i < priv->packages->len; i++) {
		pkg = ASB_PACKAGE (g_ptr_array_index (priv->packages, i));
		arch = asb_package_get_arch (pkg);
		if (arch == NULL)
			continue;
		if (g_strcmp0 (arch, "x86_64") != 0 &&
		    g_strcmp0 (arch, "noarch") != 0) {
			g_debug ("disabling alternate-arch %s",
				 asb_package_get_filename (pkg));
			asb_package_set_enabled (pkg, FALSE);
		}
	}
}
/**
 * asb_package_deb_explode:
 **/
static gboolean
asb_package_deb_explode (AsbPackage *pkg,
			 const gchar *dir,
			 GPtrArray *glob,
			 GError **error)
{
	guint i;
	const gchar *data_names[] = { "data.tar.xz",
				      "data.tar.bz2",
				      "data.tar.gz",
				      "data.tar.lzma",
				      "data.tar",
				      NULL };

	/* first decompress the main deb */
	if (!asb_utils_explode (asb_package_get_filename (pkg),
				dir, NULL, error))
		return FALSE;

	/* then decompress the data file */
	for (i = 0; data_names[i] != NULL; i++) {
		_cleanup_free_ gchar *data_fn = NULL;
		data_fn = g_build_filename (dir, data_names[i], NULL);
		if (g_file_test (data_fn, G_FILE_TEST_EXISTS)) {
			if (!asb_utils_explode (data_fn, dir, glob, error))
				return FALSE;
		}
	}
	return TRUE;
}
示例#3
0
/**
 * asb_task_set_package:
 * @task: A #AsbTask
 * @pkg: A #AsbPackage
 *
 * Sets the package used for the task.
 *
 * Since: 0.1.0
 **/
void
asb_task_set_package (AsbTask *task, AsbPackage *pkg)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	priv->tmpdir = g_build_filename (asb_context_get_temp_dir (priv->ctx),
					 asb_package_get_nevr (pkg), NULL);
	priv->filename = g_strdup (asb_package_get_filename (pkg));
	priv->pkg = g_object_ref (pkg);
}
/**
 * asb_package_deb_ensure_filelists:
 **/
static gboolean
asb_package_deb_ensure_filelists (AsbPackage *pkg, GError **error)
{
	const gchar *argv[4] = { "dpkg", "--contents", "fn", NULL };
	const gchar *fn;
	guint i;
	_cleanup_free_ gchar *output = NULL;
	_cleanup_ptrarray_unref_ GPtrArray *files = NULL;
	_cleanup_strv_free_ gchar **lines = NULL;

	/* spawn sync */
	argv[2] = asb_package_get_filename (pkg);
	if (!g_spawn_sync (NULL, (gchar **) argv, NULL,
			   G_SPAWN_SEARCH_PATH,
			   NULL, NULL,
			   &output, NULL, NULL, error))
		return FALSE;

	/* parse output */
	files = g_ptr_array_new_with_free_func (g_free);
	lines = g_strsplit (output, "\n", -1);
	for (i = 0; lines[i] != NULL; i++) {
		fn = g_strrstr (lines[i], " ");
		if (fn == NULL)
			continue;
		/* ignore directories */
		if (g_str_has_suffix (fn, "/"))
			continue;
		g_ptr_array_add (files, g_strdup (fn + 2));
	}

	/* save */
	g_ptr_array_add (files, NULL);
	asb_package_set_filelist (pkg, (gchar **) files->pdata);
	return TRUE;
}
示例#5
0
/**
 * asb_task_process:
 * @task: A #AsbTask
 * @error_not_used: A #GError or %NULL
 *
 * Processes the task.
 *
 * Returns: %TRUE for success, %FALSE otherwise
 *
 * Since: 0.1.0
 **/
gboolean
asb_task_process (AsbTask *task, GError **error_not_used)
{
	AsRelease *release;
	AsbApp *app;
	AsbPlugin *plugin = NULL;
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	GList *apps = NULL;
	GList *l;
	GPtrArray *array;
	gboolean ret;
	gchar *cache_id;
	guint i;
	guint nr_added = 0;
	g_autoptr(GError) error = NULL;
	g_autofree gchar *basename = NULL;

	/* reset the profile timer */
	asb_package_log_start (priv->pkg);

	/* ensure nevra read */
	if (!asb_package_ensure (priv->pkg,
				 ASB_PACKAGE_ENSURE_NEVRA,
				 error_not_used))
		return FALSE;

	g_debug ("starting: %s", asb_package_get_name (priv->pkg));

	/* treat archive as a special case */
	if (g_str_has_suffix (priv->filename, ".cab")) {
		AsApp *app_tmp;
		GPtrArray *apps_tmp;
		g_autoptr(AsStore) store = as_store_new ();
		g_autoptr(GFile) file = g_file_new_for_path (priv->filename);
		if (!as_store_from_file (store, file, NULL, NULL, &error)) {
			asb_package_log (priv->pkg,
					 ASB_PACKAGE_LOG_LEVEL_WARNING,
					 "Failed to parse %s: %s",
					 asb_package_get_filename (priv->pkg),
					 error->message);
			return TRUE;
		}
		apps_tmp = as_store_get_apps (store);
		for (i = 0; i < apps_tmp->len; i++) {
			g_autoptr(AsbApp) app2 = NULL;
			app_tmp = AS_APP (g_ptr_array_index (apps_tmp, i));
			app2 = asb_app_new (priv->pkg, as_app_get_id (app_tmp));
			as_app_subsume (AS_APP (app2), app_tmp);
			asb_context_add_app (priv->ctx, app2);

			/* set cache-id in case we want to use the metadata directly */
			if (asb_context_get_flag (priv->ctx, ASB_CONTEXT_FLAG_ADD_CACHE_ID)) {
				cache_id = asb_utils_get_cache_id_for_filename (priv->filename);
				as_app_add_metadata (AS_APP (app2),
						     "X-CacheID",
						     cache_id);
				g_free (cache_id);
			}
			nr_added++;
		}
		g_debug ("added %i apps from archive", apps_tmp->len);
		goto skip;
	}

	/* ensure file list read */
	if (!asb_package_ensure (priv->pkg,
				 ASB_PACKAGE_ENSURE_FILES,
				 error_not_used))
		return FALSE;

	/* did we get a file match on any plugin */
	basename = g_path_get_basename (priv->filename);
	asb_package_log (priv->pkg,
			 ASB_PACKAGE_LOG_LEVEL_DEBUG,
			 "Getting filename match for %s",
			 basename);
	asb_task_add_suitable_plugins (task);
	if (priv->plugins_to_run->len == 0) {
		asb_context_add_app_ignore (priv->ctx, priv->pkg);
		goto out;
	}

	/* delete old tree if it exists */
	ret = asb_utils_ensure_exists_and_empty (priv->tmpdir, &error);
	if (!ret) {
		asb_package_log (priv->pkg,
				 ASB_PACKAGE_LOG_LEVEL_WARNING,
				 "Failed to clear: %s", error->message);
		goto out;
	}

	/* explode tree */
	g_debug ("decompressing files: %s", asb_package_get_name (priv->pkg));
	asb_package_log (priv->pkg,
			 ASB_PACKAGE_LOG_LEVEL_DEBUG,
			 "Exploding tree for %s",
			 asb_package_get_name (priv->pkg));
	ret = asb_package_explode (priv->pkg,
				   priv->tmpdir,
				   asb_context_get_file_globs (priv->ctx),
				   &error);
	if (!ret) {
		asb_package_log (priv->pkg,
				 ASB_PACKAGE_LOG_LEVEL_WARNING,
				 "Failed to explode: %s", error->message);
		g_clear_error (&error);
		goto skip;
	}

	/* add extra packages */
	if (!asb_package_ensure (priv->pkg,
				 ASB_PACKAGE_ENSURE_DEPS |
				 ASB_PACKAGE_ENSURE_SOURCE,
				 error_not_used))
		return FALSE;
	ret = asb_task_explode_extra_packages (task, &error);
	if (!ret) {
		asb_package_log (priv->pkg,
				 ASB_PACKAGE_LOG_LEVEL_WARNING,
				 "Failed to explode extra file: %s",
				 error->message);
		goto skip;
	}

	/* run plugins */
	g_debug ("examining: %s", asb_package_get_name (priv->pkg));
	for (i = 0; i < priv->plugins_to_run->len; i++) {
		GList *apps_tmp = NULL;
		plugin = g_ptr_array_index (priv->plugins_to_run, i);
		asb_package_log (priv->pkg,
				 ASB_PACKAGE_LOG_LEVEL_DEBUG,
				 "Processing %s with %s",
				 basename,
				 plugin->name);
		apps_tmp = asb_plugin_process (plugin, priv->pkg, priv->tmpdir, &error);
		if (apps_tmp == NULL) {
			asb_package_log (priv->pkg,
					 ASB_PACKAGE_LOG_LEVEL_WARNING,
					 "Failed to run process '%s': %s",
					 plugin->name, error->message);
			g_clear_error (&error);
		}
		for (l = apps_tmp; l != NULL; l = l->next) {
			app = ASB_APP (l->data);
			asb_plugin_add_app (&apps, AS_APP (app));
		}
		g_list_free_full (apps_tmp, g_object_unref);
	}
	if (apps == NULL)
		goto skip;

	/* print */
	g_debug ("processing: %s", asb_package_get_name (priv->pkg));
	for (l = apps; l != NULL; l = l->next) {
		app = l->data;

		/* never set */
		if (as_app_get_id (AS_APP (app)) == NULL) {
			asb_package_log (priv->pkg,
					 ASB_PACKAGE_LOG_LEVEL_INFO,
					 "app id not set for %s",
					 asb_package_get_name (priv->pkg));
			continue;
		}

		/* copy data from pkg into app */
		if (!asb_package_ensure (priv->pkg,
					 ASB_PACKAGE_ENSURE_LICENSE |
					 ASB_PACKAGE_ENSURE_RELEASES |
					 ASB_PACKAGE_ENSURE_VCS |
					 ASB_PACKAGE_ENSURE_URL,
					 error_not_used))
			return FALSE;
		if (asb_package_get_url (priv->pkg) != NULL &&
		    as_app_get_url_item (AS_APP (app), AS_URL_KIND_HOMEPAGE) == NULL) {
			as_app_add_url (AS_APP (app),
					AS_URL_KIND_HOMEPAGE,
					asb_package_get_url (priv->pkg));
		}
		if (asb_package_get_license (priv->pkg) != NULL &&
		    as_app_get_project_license (AS_APP (app)) == NULL) {
			as_app_set_project_license (AS_APP (app),
						    asb_package_get_license (priv->pkg));
		}

		/* add the source name so we can suggest these together */
		if (g_strcmp0 (asb_package_get_source_pkgname (priv->pkg),
			       asb_package_get_name (priv->pkg)) != 0) {
			as_app_set_source_pkgname (AS_APP (app),
						   asb_package_get_source_pkgname (priv->pkg));
		}

		/* set all the releases on the app */
		array = asb_package_get_releases (priv->pkg);
		for (i = 0; i < array->len; i++) {
			release = g_ptr_array_index (array, i);
			as_app_add_release (AS_APP (app), release);
		}

		/* run each refine plugin on each app */
		ret = asb_plugin_loader_process_app (asb_context_get_plugin_loader (priv->ctx),
						     priv->pkg,
						     app,
						     priv->tmpdir,
						     &error);
		if (!ret) {
			asb_package_log (priv->pkg,
					 ASB_PACKAGE_LOG_LEVEL_WARNING,
					 "Failed to run process on %s: %s",
					 as_app_get_id (AS_APP (app)),
					 error->message);
			g_clear_error (&error);
			goto skip;
		}

		/* set cache-id in case we want to use the metadata directly */
		if (asb_context_get_flag (priv->ctx, ASB_CONTEXT_FLAG_ADD_CACHE_ID)) {
			cache_id = asb_utils_get_cache_id_for_filename (priv->filename);
			as_app_add_metadata (AS_APP (app),
					     "X-CacheID",
					     cache_id);
			g_free (cache_id);
		}

		/* set the VCS information into the metadata */
		if (asb_package_get_vcs (priv->pkg) != NULL) {
			as_app_add_metadata (AS_APP (app),
					     "VersionControlSystem",
					     asb_package_get_vcs (priv->pkg));
		}

		/* save any screenshots early */
		if (array->len == 0) {
			if (!asb_app_save_resources (ASB_APP (app),
						     ASB_APP_SAVE_FLAG_SCREENSHOTS,
						     error_not_used))
				return FALSE;
		}

		/* all okay */
		asb_context_add_app (priv->ctx, app);
		nr_added++;
	}
skip:
	/* add a dummy element to the AppStream metadata so that we don't keep
	 * parsing this every time */
	if (asb_context_get_flag (priv->ctx, ASB_CONTEXT_FLAG_ADD_CACHE_ID) && nr_added == 0)
		asb_context_add_app_ignore (priv->ctx, priv->pkg);

	/* delete tree */
	g_debug ("deleting temp files: %s", asb_package_get_name (priv->pkg));
	if (!asb_utils_rmtree (priv->tmpdir, &error)) {
		asb_package_log (priv->pkg,
				 ASB_PACKAGE_LOG_LEVEL_WARNING,
				 "Failed to delete tree: %s",
				 error->message);
		goto out;
	}

	/* write log */
	g_debug ("writing log: %s", asb_package_get_name (priv->pkg));
	if (!asb_package_log_flush (priv->pkg, &error)) {
		asb_package_log (priv->pkg,
				 ASB_PACKAGE_LOG_LEVEL_WARNING,
				 "Failed to write package log: %s",
				 error->message);
		goto out;
	}
out:
	/* clear loaded resources */
	asb_package_close (priv->pkg, NULL);
	asb_package_clear (priv->pkg,
			   ASB_PACKAGE_ENSURE_DEPS |
			   ASB_PACKAGE_ENSURE_FILES);
	g_list_free_full (apps, (GDestroyNotify) g_object_unref);
	return TRUE;
}
/**
 * asb_package_deb_ensure_simple:
 **/
static gboolean
asb_package_deb_ensure_simple (AsbPackage *pkg, GError **error)
{
	const gchar *argv[4] = { "dpkg", "--field", "fn", NULL };
	gchar *tmp;
	gchar **vr;
	guint i;
	guint j;
	_cleanup_free_ gchar *output = NULL;
	_cleanup_ptrarray_unref_ GPtrArray *deps = NULL;
	_cleanup_strv_free_ gchar **lines = NULL;

	/* spawn sync */
	argv[2] = asb_package_get_filename (pkg);
	if (!g_spawn_sync (NULL, (gchar **) argv, NULL,
			   G_SPAWN_SEARCH_PATH,
			   NULL, NULL,
			   &output, NULL, NULL, error))
		return FALSE;

	/* parse output */
	deps = g_ptr_array_new_with_free_func (g_free);
	lines = g_strsplit (output, "\n", -1);
	for (i = 0; lines[i] != NULL; i++) {
		if (g_str_has_prefix (lines[i], "Package: ")) {
			asb_package_set_name (pkg, lines[i] + 9);
			continue;
		}
		if (g_str_has_prefix (lines[i], "Source: ")) {
			asb_package_set_source (pkg, lines[i] + 8);
			continue;
		}
		if (g_str_has_prefix (lines[i], "Version: ")) {
			vr = g_strsplit (lines[i] + 9, "-", 2);
			tmp = g_strstr_len (vr[0], -1, ":");
			if (tmp == NULL) {
				asb_package_set_version (pkg, vr[0]);
			} else {
				*tmp = '\0';
				j = g_ascii_strtoll (vr[0], NULL, 10);
				asb_package_set_epoch (pkg, j);
				asb_package_set_version (pkg, tmp + 1);
			}
			asb_package_set_release (pkg, vr[1]);
			g_strfreev (vr);
			continue;
		}
		if (g_str_has_prefix (lines[i], "Depends: ")) {
			vr = g_strsplit (lines[i] + 9, ", ", -1);
			for (j = 0; vr[j] != NULL; j++) {
				tmp = g_strstr_len (vr[j], -1, " ");
				if (tmp != NULL)
					*tmp = '\0';
				g_ptr_array_add (deps, vr[j]);
			}
			continue;
		}
	}
	g_ptr_array_add (deps, NULL);
	asb_package_set_deps (pkg, (gchar **) deps->pdata);
	return TRUE;
}
示例#7
0
/**
 * asb_package_deb_ensure_simple:
 **/
static gboolean
asb_package_deb_ensure_simple (AsbPackage *pkg, GError **error)
{
	const gchar *argv[4] = { "dpkg", "--field", "fn", NULL };
	gchar *tmp;
	guint i;
	guint j;
	g_autofree gchar *output = NULL;
	g_auto(GStrv) lines = NULL;

	/* spawn sync */
	argv[2] = asb_package_get_filename (pkg);
	if (!g_spawn_sync (NULL, (gchar **) argv, NULL,
			   G_SPAWN_SEARCH_PATH,
			   NULL, NULL,
			   &output, NULL, NULL, error))
		return FALSE;

	/* parse output */
	lines = g_strsplit (output, "\n", -1);
	for (i = 0; lines[i] != NULL; i++) {
		if (g_str_has_prefix (lines[i], "Package: ")) {
			asb_package_set_name (pkg, lines[i] + 9);
			continue;
		}
		if (g_str_has_prefix (lines[i], "Source: ")) {
			asb_package_set_source (pkg, lines[i] + 8);
			continue;
		}
		if (g_str_has_prefix (lines[i], "Version: ")) {
			g_auto(GStrv) vr = NULL;
			vr = g_strsplit (lines[i] + 9, "-", 2);
			tmp = g_strstr_len (vr[0], -1, ":");
			if (tmp == NULL) {
				asb_package_set_version (pkg, vr[0]);
			} else {
				*tmp = '\0';
				j = g_ascii_strtoll (vr[0], NULL, 10);
				asb_package_set_epoch (pkg, j);
				asb_package_set_version (pkg, tmp + 1);
			}
			if (vr[1] != NULL) {
				asb_package_set_release (pkg, vr[1]);
			} else {
				/* packages don't actually have to have a
				 * release value like rpm; in this case fake
				 * something plausible */
				asb_package_set_release (pkg, "0");
			}
			continue;
		}
		if (g_str_has_prefix (lines[i], "Depends: ")) {
			g_auto(GStrv) vr = NULL;
			vr = g_strsplit (lines[i] + 9, ", ", -1);
			for (j = 0; vr[j] != NULL; j++) {
				tmp = g_strstr_len (vr[j], -1, " ");
				if (tmp != NULL)
					*tmp = '\0';
				asb_package_add_dep (pkg, vr[j]);
			}
			continue;
		}
	}
	return TRUE;
}