/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }