static gboolean as_app_parse_shell_extension_data (AsbPlugin *plugin, AsApp *app, const gchar *data, gsize len, GError **error) { JsonArray *json_array; JsonNode *json_root; JsonObject *json_obj; const gchar *tmp; g_autoptr(JsonParser) json_parser = NULL; /* parse the data */ json_parser = json_parser_new (); if (!json_parser_load_from_data (json_parser, data, (gssize) len, error)) return FALSE; json_root = json_parser_get_root (json_parser); if (json_root == NULL) { g_set_error_literal (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "no root"); return FALSE; } json_obj = json_node_get_object (json_root); if (json_obj == NULL) { g_set_error_literal (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "no object"); return FALSE; } as_app_set_kind (app, AS_APP_KIND_SHELL_EXTENSION); as_app_set_comment (app, NULL, "GNOME Shell Extension"); if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_ADD_DEFAULT_ICONS)) { as_app_add_category (AS_APP (app), "Addons"); as_app_add_category (AS_APP (app), "ShellExtensions"); } tmp = json_object_get_string_member (json_obj, "uuid"); if (tmp != NULL) { g_autofree gchar *id = NULL; id = as_utils_appstream_id_build (tmp); as_app_set_id (app, id); as_app_add_metadata (AS_APP (app), "shell-extensions::uuid", tmp); } if (json_object_has_member (json_obj, "gettext-domain")) { tmp = json_object_get_string_member (json_obj, "gettext-domain"); if (tmp != NULL) { g_autoptr(AsTranslation) transaction = NULL; transaction = as_translation_new (); as_translation_set_kind (transaction, AS_TRANSLATION_KIND_GETTEXT); as_translation_set_id (transaction, tmp); as_app_add_translation (app, transaction); } } if (json_object_has_member (json_obj, "name")) { tmp = json_object_get_string_member (json_obj, "name"); if (tmp != NULL) as_app_set_name (app, NULL, tmp); } if (json_object_has_member (json_obj, "description")) { tmp = json_object_get_string_member (json_obj, "description"); if (tmp != NULL) { g_autofree gchar *desc = NULL; desc = as_markup_import (tmp, AS_MARKUP_CONVERT_FORMAT_SIMPLE, error); if (desc == NULL) return FALSE; as_app_set_description (app, NULL, desc); } } if (json_object_has_member (json_obj, "url")) { tmp = json_object_get_string_member (json_obj, "url"); if (tmp != NULL) as_app_add_url (app, AS_URL_KIND_HOMEPAGE, tmp); } if (json_object_has_member (json_obj, "original-authors")) { json_array = json_object_get_array_member (json_obj, "original-authors"); if (json_array != NULL) { tmp = json_array_get_string_element (json_array, 0); as_app_set_developer_name (app, NULL, tmp); } } if (as_app_get_release_default (app) == NULL && json_object_has_member (json_obj, "shell-version")) { json_array = json_object_get_array_member (json_obj, "shell-version"); if (json_array != NULL) { g_autoptr(AsRelease) release = NULL; tmp = json_array_get_string_element (json_array, 0); release = as_release_new (); as_release_set_state (release, AS_RELEASE_STATE_INSTALLED); as_release_set_version (release, tmp); as_app_add_release (app, release); } } /* use a stock icon */ if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_ADD_DEFAULT_ICONS)) { g_autoptr(AsIcon) ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_STOCK); as_icon_set_name (ic, "application-x-addon-symbolic"); as_app_add_icon (app, ic); } 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; }
/** * fu_util_verify_update: **/ static gboolean fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error) { guint i; _cleanup_object_unref_ AsStore *store = NULL; _cleanup_object_unref_ GFile *xml_file = NULL; if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments: expected 'filename.xml' 'filename.rom'"); return FALSE; } store = as_store_new (); /* open existing file */ xml_file = g_file_new_for_path (values[0]); if (g_file_query_exists (xml_file, NULL)) { if (!as_store_from_file (store, xml_file, NULL, NULL, error)) return FALSE; } /* add new values */ as_store_set_api_version (store, 0.9); for (i = 1; values[i] != NULL; i++) { _cleanup_free_ gchar *guid = NULL; _cleanup_free_ gchar *id = NULL; _cleanup_object_unref_ AsApp *app = NULL; _cleanup_object_unref_ AsRelease *rel = NULL; _cleanup_object_unref_ FuRom *rom = NULL; _cleanup_object_unref_ GFile *file = NULL; _cleanup_error_free_ GError *error_local = NULL; file = g_file_new_for_path (values[i]); rom = fu_rom_new (); g_print ("Processing %s...\n", values[i]); if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, &error_local)) { g_print ("%s\n", error_local->message); continue; } /* add app to store */ app = as_app_new (); id = g_strdup_printf ("0x%04x:0x%04x", fu_rom_get_vendor (rom), fu_rom_get_model (rom)); guid = fu_guid_generate_from_string (id); as_app_set_id (app, guid, -1); as_app_set_id_kind (app, AS_ID_KIND_FIRMWARE); as_app_set_source_kind (app, AS_APP_SOURCE_KIND_INF); rel = as_release_new (); as_release_set_version (rel, fu_rom_get_version (rom), -1); as_release_set_checksum (rel, G_CHECKSUM_SHA1, fu_rom_get_checksum (rom), -1); as_app_add_release (app, rel); as_store_add_app (store, app); } if (!as_store_to_file (store, xml_file, AS_NODE_TO_XML_FLAG_ADD_HEADER | AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE, NULL, error)) return FALSE; return TRUE; }