static void gs_plugin_key_colors_set_for_pixbuf (GsApp *app, GdkPixbuf *pb, guint number) { GList *l; gint rowstride, n_channels; gint x, y; guchar *pixels, *p; guint bin_size = 200; guint i; guint number_of_bins; g_autoptr(AsImage) im = NULL; /* go through each pixel */ n_channels = gdk_pixbuf_get_n_channels (pb); rowstride = gdk_pixbuf_get_rowstride (pb); pixels = gdk_pixbuf_get_pixels (pb); for (bin_size = 250; bin_size > 0; bin_size -= 2) { g_autoptr(GHashTable) hash = NULL; hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); for (y = 0; y < gdk_pixbuf_get_height (pb); y++) { for (x = 0; x < gdk_pixbuf_get_width (pb); x++) { CdColorRGB8 tmp; GsColorBin *s; gpointer key; /* disregard any with alpha */ p = pixels + y * rowstride + x * n_channels; if (p[3] != 255) continue; /* find in cache */ tmp.R = (guint8) (p[0] / bin_size); tmp.G = (guint8) (p[1] / bin_size); tmp.B = (guint8) (p[2] / bin_size); key = GUINT_TO_POINTER (cd_color_rgb8_to_uint32 (&tmp)); s = g_hash_table_lookup (hash, key); if (s != NULL) { s->color.red += _convert_from_rgb8 (p[0]); s->color.green += _convert_from_rgb8 (p[1]); s->color.blue += _convert_from_rgb8 (p[2]); s->cnt++; continue; } /* add to hash table */ s = g_new0 (GsColorBin, 1); s->color.red = _convert_from_rgb8 (p[0]); s->color.green = _convert_from_rgb8 (p[1]); s->color.blue = _convert_from_rgb8 (p[2]); s->color.alpha = 1.0; s->cnt = 1; g_hash_table_insert (hash, key, s); } } number_of_bins = g_hash_table_size (hash); // g_debug ("number of colors: %i", number_of_bins); if (number_of_bins >= number) { g_autoptr(GList) values = NULL; /* order by most popular */ values = g_hash_table_get_values (hash); values = g_list_sort (values, gs_color_bin_sort_cb); for (l = values; l != NULL; l = l->next) { GsColorBin *s = l->data; g_autofree GdkRGBA *color = g_new0 (GdkRGBA, 1); color->red = s->color.red / s->cnt; color->green = s->color.green / s->cnt; color->blue = s->color.blue / s->cnt; gs_app_add_key_color (app, color); } return; } } /* the algorithm failed, so just return a monochrome ramp */ for (i = 0; i < 3; i++) { g_autofree GdkRGBA *color = g_new0 (GdkRGBA, 1); color->red = (gdouble) i / 3.f; color->green = color->red; color->blue = color->red; color->alpha = 1.0f; gs_app_add_key_color (app, color); } }
/** * xdg_app_review_parse_reviews: */ static GPtrArray * xdg_app_review_parse_reviews (const gchar *data, gsize data_len, GError **error) { JsonArray *json_reviews; JsonNode *json_root; guint i; g_autoptr(JsonParser) json_parser = NULL; g_autoptr(GPtrArray) reviews = NULL; /* nothing */ if (data == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "server returned no data"); return NULL; } /* parse the data and find the array or ratings */ json_parser = json_parser_new (); if (!json_parser_load_from_data (json_parser, data, data_len, error)) return NULL; json_root = json_parser_get_root (json_parser); if (json_root == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no root"); return NULL; } if (json_node_get_node_type (json_root) != JSON_NODE_ARRAY) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no array"); return NULL; } /* parse each rating */ reviews = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); json_reviews = json_node_get_array (json_root); for (i = 0; i < json_array_get_length (json_reviews); i++) { JsonNode *json_review; JsonObject *json_item; g_autoptr(GsReview) review = NULL; /* extract the data */ json_review = json_array_get_element (json_reviews, i); if (json_node_get_node_type (json_review) != JSON_NODE_OBJECT) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no object type"); return NULL; } json_item = json_node_get_object (json_review); if (json_item == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no object"); return NULL; } /* create review */ review = xdg_app_review_parse_review_object (json_item); g_ptr_array_add (reviews, g_object_ref (review)); } return g_steal_pointer (&reviews); }
/** * xdg_app_review_parse_ratings: */ static GArray * xdg_app_review_parse_ratings (const gchar *data, gsize data_len, GError **error) { GArray *ratings; JsonNode *json_root; JsonObject *json_item; guint i; g_autoptr(JsonParser) json_parser = NULL; const gchar *names[] = { "star0", "star1", "star2", "star3", "star4", "star5", NULL }; /* nothing */ if (data == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "server returned no data"); return NULL; } /* parse the data and find the success */ json_parser = json_parser_new (); if (!json_parser_load_from_data (json_parser, data, data_len, error)) return NULL; json_root = json_parser_get_root (json_parser); if (json_root == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no error root"); return NULL; } if (json_node_get_node_type (json_root) != JSON_NODE_OBJECT) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no error object"); return NULL; } json_item = json_node_get_object (json_root); if (json_item == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no error object"); return NULL; } /* get data array */ ratings = g_array_sized_new (FALSE, TRUE, sizeof(guint32), 6); for (i = 0; names[i] != NULL; i++) { guint64 tmp; if (!json_object_has_member (json_item, names[i])) continue; tmp = json_object_get_int_member (json_item, names[i]); g_array_append_val (ratings, tmp); } return ratings; }
static gboolean handle_get_user_information (XdpImplAccount *object, GDBusMethodInvocation *invocation, const char *arg_handle, const char *arg_app_id, const char *arg_parent_window, GVariant *arg_options) { g_autoptr(Request) request = NULL; const char *sender; AccountDialogHandle *handle; g_autoptr(GError) error = NULL; const char *user_name; const char *real_name; const char *icon_file; GtkWidget *dialog; GdkDisplay *display; GdkScreen *screen; ExternalWindow *external_parent = NULL; GtkWidget *fake_parent; const char *reason; sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle); user_name = org_freedesktop_accounts_user_get_user_name (user); real_name = org_freedesktop_accounts_user_get_real_name (user); icon_file = org_freedesktop_accounts_user_get_icon_file (user); if (!g_variant_lookup (arg_options, "reason", "&s", &reason)) reason = NULL; if (arg_parent_window) { external_parent = create_external_window_from_handle (arg_parent_window); if (!external_parent) g_warning ("Failed to associate portal window with parent window %s", arg_parent_window); } if (external_parent) display = external_window_get_display (external_parent); else display = gdk_display_get_default (); screen = gdk_display_get_default_screen (display); fake_parent = g_object_new (GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, "screen", screen, NULL); g_object_ref_sink (fake_parent); dialog = GTK_WIDGET (account_dialog_new (arg_app_id, user_name, real_name, icon_file, reason)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); handle = g_new0 (AccountDialogHandle, 1); handle->impl = object; handle->invocation = invocation; handle->request = g_object_ref (request); handle->dialog = g_object_ref (dialog); handle->external_parent = external_parent; handle->user_name = g_strdup (user_name); handle->real_name = g_strdup (real_name); handle->icon_uri = g_filename_to_uri (icon_file, NULL, NULL); g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); g_signal_connect (dialog, "done", G_CALLBACK (account_dialog_done), handle); gtk_widget_realize (dialog); if (external_parent) external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog)); gtk_widget_show (dialog); request_export (request, g_dbus_method_invocation_get_connection (invocation)); return TRUE; }
gboolean flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; g_autoptr(FlatpakDir) dir = NULL; const char *repository; const char *name; const char *branch = NULL; g_autofree char *ref = NULL; gboolean is_app; g_autoptr(GFile) deploy_dir = NULL; g_autoptr(GPtrArray) related = NULL; int i; context = g_option_context_new ("REPOSITORY NAME [BRANCH] - Install an application or runtime"); if (!flatpak_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error)) return FALSE; if (opt_bundle) return install_bundle (dir, context, argc, argv, cancellable, error); if (argc < 3) return usage_error (context, "REPOSITORY and NAME must be specified", error); repository = argv[1]; name = argv[2]; if (argc >= 4) branch = argv[3]; if (!opt_app && !opt_runtime) opt_app = opt_runtime = TRUE; ref = flatpak_dir_find_remote_ref (dir, repository, name, branch, opt_arch, opt_app, opt_runtime, &is_app, cancellable, error); if (ref == NULL) return FALSE; deploy_dir = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable); if (deploy_dir != NULL) { g_auto(GStrv) parts = flatpak_decompose_ref (ref, error); return flatpak_fail (error, "%s %s, branch %s is already installed", is_app ? "App" : "Runtime", name, parts[3]); } if (!flatpak_dir_install (dir, opt_no_pull, opt_no_deploy, ref, repository, (const char **)opt_subpaths, NULL, cancellable, error)) return FALSE; if (!opt_no_related) { g_autoptr(GError) local_error = NULL; if (opt_no_pull) related = flatpak_dir_find_local_related (dir, ref, repository, NULL, &local_error); else related = flatpak_dir_find_remote_related (dir, ref, repository, NULL, &local_error); if (related == NULL) { g_printerr ("Warning: Problem looking for related refs: %s\n", local_error->message); g_clear_error (&local_error); } else { for (i = 0; i < related->len; i++) { FlatpakRelated *rel = g_ptr_array_index (related, i); g_auto(GStrv) parts = NULL; if (!rel->download) continue; parts = g_strsplit (rel->ref, "/", 0); g_print ("Installing related: %s\n", parts[1]); if (!flatpak_dir_install_or_update (dir, opt_no_pull, opt_no_deploy, rel->ref, repository, (const char **)rel->subpaths, NULL, cancellable, &local_error)) { g_printerr ("Warning: Failed to install related ref: %s\n", rel->ref); g_clear_error (&local_error); } } } } return TRUE; }
/** * ot_file_replace_contents_at: * * Like g_file_replace_contents(), except using a fd-relative * directory, and optionally enforces use of fdatasync(). */ gboolean ot_file_replace_contents_at (int dfd, const char *path, GBytes *contents, gboolean datasync, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int fd; g_autofree char *tmpname = NULL; g_autoptr(GOutputStream) stream = NULL; g_autoptr(GInputStream) instream = NULL; if (!gs_file_open_in_tmpdir_at (dfd, 0644, &tmpname, &stream, cancellable, error)) goto out; g_assert (G_IS_FILE_DESCRIPTOR_BASED (stream)); fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (stream)); instream = g_memory_input_stream_new_from_bytes (contents); if (g_bytes_get_size (contents) > 0) { int r = posix_fallocate (fd, 0, g_bytes_get_size (contents)); if (r != 0) { gs_set_error_from_errno (error, r); goto out; } } if (g_output_stream_splice (stream, instream, 0, cancellable, error) < 0) goto out; if (datasync && fdatasync (fd) != 0) { gs_set_error_from_errno (error, errno); goto out; } if (!g_output_stream_close (stream, cancellable, error)) goto out; if (renameat (dfd, tmpname, dfd, path) == -1) { gs_set_error_from_errno (error, errno); goto out; } g_clear_pointer (&tmpname, g_free); ret = TRUE; out: if (tmpname) (void) unlinkat (dfd, tmpname, 0); return ret; }
gboolean ide_doap_load_from_file (IdeDoap *self, GFile *file, GCancellable *cancellable, GError **error) { g_autoptr(XmlReader) reader = NULL; g_return_val_if_fail (IDE_IS_DOAP (self), FALSE); g_return_val_if_fail (G_IS_FILE (file), FALSE); g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE); reader = xml_reader_new (); if (!xml_reader_load_from_file (reader, file, cancellable, error)) return FALSE; if (!xml_reader_read_start_element (reader, "Project")) { g_set_error (error, IDE_DOAP_ERROR, IDE_DOAP_ERROR_INVALID_FORMAT, "Project element is missing from doap."); return FALSE; } g_object_freeze_notify (G_OBJECT (self)); xml_reader_read (reader); do { const gchar *element_name; element_name = xml_reader_get_local_name (reader); if (ide_str_equal0 (element_name, "name") || ide_str_equal0 (element_name, "shortdesc") || ide_str_equal0 (element_name, "description")) { gchar *str; str = xml_reader_read_string (reader); if (str != NULL) g_object_set (self, element_name, g_strstrip (str), NULL); g_free (str); } else if (ide_str_equal0 (element_name, "category") || ide_str_equal0 (element_name, "homepage") || ide_str_equal0 (element_name, "download-page") || ide_str_equal0 (element_name, "bug-database")) { gchar *str; str = xml_reader_get_attribute (reader, "rdf:resource"); if (str != NULL) g_object_set (self, element_name, g_strstrip (str), NULL); g_free (str); } else if (ide_str_equal0 (element_name, "programming-language")) { gchar *str; str = xml_reader_read_string (reader); if (!ide_str_empty0 (str)) ide_doap_add_language (self, g_strstrip (str)); g_free (str); } else if (ide_str_equal0 (element_name, "maintainer")) { if (!ide_doap_parse_maintainer (self, reader)) break; } } while (xml_reader_read_to_next (reader)); g_object_thaw_notify (G_OBJECT (self)); return TRUE; }
/** * as_pool_load_desktop_entries: * * Load fresh metadata from .desktop files. */ static void as_pool_load_desktop_entries (AsPool *pool) { GPtrArray *cpts; guint i; g_autoptr(AsMetadata) metad = NULL; g_autoptr(GPtrArray) de_files = NULL; GError *error = NULL; AsPoolPrivate *priv = GET_PRIVATE (pool); /* prepare metadata parser */ metad = as_metadata_new (); as_metadata_set_locale (metad, priv->locale); /* find .desktop files */ g_debug ("Searching for data in: %s", APPLICATIONS_DIR); de_files = as_utils_find_files_matching (APPLICATIONS_DIR, "*.desktop", FALSE, NULL); if (de_files == NULL) { g_debug ("Unable find .desktop files."); return; } /* parse the found data */ for (i = 0; i < de_files->len; i++) { g_autoptr(GFile) infile = NULL; const gchar *fname; fname = (const gchar*) g_ptr_array_index (de_files, i); g_debug ("Reading: %s", fname); infile = g_file_new_for_path (fname); if (!g_file_query_exists (infile, NULL)) { g_warning ("Metadata file '%s' does not exist.", fname); continue; } as_metadata_parse_file (metad, infile, AS_FORMAT_KIND_UNKNOWN, &error); if (error != NULL) { g_debug ("WARNING: %s", error->message); g_error_free (error); error = NULL; } } /* add found components to the metadata pool */ cpts = as_metadata_get_components (metad); for (i = 0; i < cpts->len; i++) { AsComponent *cpt = AS_COMPONENT (g_ptr_array_index (cpts, i)); /* We only read .desktop files from system directories at time */ as_component_set_scope (cpt, AS_COMPONENT_SCOPE_SYSTEM); as_pool_add_component_internal (pool, cpt, FALSE, &error); if (error != NULL) { g_debug ("Metadata ignored: %s", error->message); g_error_free (error); error = NULL; } } }
/** * asb_utils_explode: * @filename: package filename * @dir: directory to decompress into * @glob: (element-type utf8): filename globs, or %NULL * @error: A #GError or %NULL * * Decompresses the package into a given directory. * * Returns: %TRUE for success, %FALSE otherwise * * Since: 0.1.0 **/ gboolean asb_utils_explode (const gchar *filename, const gchar *dir, GPtrArray *glob, GError **error) { const gchar *tmp; gboolean ret = TRUE; gboolean valid; int r; struct archive *arch = NULL; struct archive *arch_preview = NULL; struct archive_entry *entry; g_autoptr(GHashTable) matches = NULL; /* populate a hash with all the files, symlinks and hardlinks that * actually need decompressing */ arch_preview = archive_read_new (); archive_read_support_format_all (arch_preview); archive_read_support_filter_all (arch_preview); r = archive_read_open_filename (arch_preview, filename, 1024 * 32); if (r) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Cannot open: %s", archive_error_string (arch_preview)); goto out; } matches = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (;;) { g_autofree gchar *path = NULL; r = archive_read_next_header (arch_preview, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Cannot read header: %s", archive_error_string (arch_preview)); goto out; } /* get the destination filename */ tmp = archive_entry_pathname (entry); if (tmp == NULL) continue; path = asb_utils_sanitise_path (tmp); if (glob != NULL) { if (asb_glob_value_search (glob, path) == NULL) continue; } g_hash_table_insert (matches, g_strdup (path), GINT_TO_POINTER (1)); /* add hardlink */ tmp = archive_entry_hardlink (entry); if (tmp != NULL) { g_hash_table_insert (matches, asb_utils_sanitise_path (tmp), GINT_TO_POINTER (1)); } /* add symlink */ tmp = archive_entry_symlink (entry); if (tmp != NULL) { if (g_path_is_absolute (tmp)) { g_hash_table_insert (matches, asb_utils_sanitise_path (tmp), GINT_TO_POINTER (1)); } else { g_autofree gchar *parent_dir = g_path_get_dirname (path); g_hash_table_insert (matches, asb_utils_resolve_relative_symlink (parent_dir, tmp), GINT_TO_POINTER (1)); } } } /* decompress anything matching either glob */ arch = archive_read_new (); archive_read_support_format_all (arch); archive_read_support_filter_all (arch); r = archive_read_open_filename (arch, filename, 1024 * 32); if (r) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Cannot open: %s", archive_error_string (arch)); goto out; } for (;;) { g_autofree gchar *path = NULL; r = archive_read_next_header (arch, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Cannot read header: %s", archive_error_string (arch)); goto out; } /* only extract if valid */ tmp = archive_entry_pathname (entry); path = asb_utils_sanitise_path (tmp); if (g_hash_table_lookup (matches, path) == NULL) continue; valid = asb_utils_explode_file (entry, dir); if (!valid) continue; if (g_file_test (archive_entry_pathname (entry), G_FILE_TEST_EXISTS)) { g_debug ("skipping as %s already exists", archive_entry_pathname (entry)); continue; } if (archive_entry_symlink (entry) == NULL) { archive_entry_set_mode (entry, S_IRGRP | S_IWGRP | S_IRUSR | S_IWUSR); } r = archive_read_extract (arch, entry, 0); if (r != ARCHIVE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Cannot extract %s: %s", archive_entry_pathname (entry), archive_error_string (arch)); goto out; } } out: if (arch_preview != NULL) { archive_read_close (arch_preview); archive_read_free (arch_preview); } if (arch != NULL) { archive_read_close (arch); archive_read_free (arch); } return ret; }
/** * as_pool_add_component_internal: * @pool: An instance of #AsPool * @cpt: The #AsComponent to add to the pool. * @pedantic_noadd: If %TRUE, always emit an error if component couldn't be added. * @error: A #GError or %NULL * * Internal. */ static gboolean as_pool_add_component_internal (AsPool *pool, AsComponent *cpt, gboolean pedantic_noadd, GError **error) { const gchar *cdid = NULL; AsComponent *existing_cpt; gint pool_priority; AsPoolPrivate *priv = GET_PRIVATE (pool); cdid = as_component_get_data_id (cpt); if (as_component_is_ignored (cpt)) { if (pedantic_noadd) g_set_error (error, AS_POOL_ERROR, AS_POOL_ERROR_FAILED, "Skipping '%s' from inclusion into the pool: Component is ignored.", cdid); return FALSE; } existing_cpt = g_hash_table_lookup (priv->cpt_table, cdid); if (as_component_get_origin_kind (cpt) == AS_ORIGIN_KIND_DESKTOP_ENTRY) { g_autofree gchar *tmp_cdid = NULL; /* .desktop entries might map to existing metadata data with or without .desktop suffix, we need to check for that. * (the .desktop suffix is optional for desktop-application metainfo files, and the desktop-entry parser will automatically * omit it if the desktop-entry-id is following the reverse DNS scheme) */ if (existing_cpt == NULL) { tmp_cdid = g_strdup_printf ("%s.desktop", cdid); existing_cpt = g_hash_table_lookup (priv->cpt_table, tmp_cdid); } } if (existing_cpt == NULL) { /* add additional data to the component, e.g. external screenshots. Also refines * the component's icon paths */ as_component_complete (cpt, priv->screenshot_service_url, priv->icon_dirs); g_hash_table_insert (priv->cpt_table, g_strdup (cdid), g_object_ref (cpt)); return TRUE; } /* perform metadata merges if necessary */ if (as_component_get_merge_kind (cpt) != AS_MERGE_KIND_NONE) { g_autoptr(GPtrArray) matches = NULL; guint i; /* we merge the data into all components with matching IDs at time */ matches = as_pool_get_components_by_id (pool, as_component_get_id (cpt)); for (i = 0; i < matches->len; i++) { AsComponent *match = AS_COMPONENT (g_ptr_array_index (matches, i)); as_merge_components (match, cpt); } return TRUE; } /* if we are here, we might have duplicates and no merges, so check if we should replace a component * with data of higher priority, or if we have an actual error in the metadata */ pool_priority = as_component_get_priority (existing_cpt); if (pool_priority < as_component_get_priority (cpt)) { g_hash_table_replace (priv->cpt_table, g_strdup (cdid), g_object_ref (cpt)); g_debug ("Replaced '%s' with data of higher priority.", cdid); } else { /* bundles are treated specially here */ if ((!as_component_has_bundle (existing_cpt)) && (as_component_has_bundle (cpt))) { GPtrArray *bundles; /* propagate bundle information to existing component */ bundles = as_component_get_bundles (cpt); as_component_set_bundles_array (existing_cpt, bundles); return TRUE; } /* experimental multiarch support */ if (as_component_get_architecture (cpt) != NULL) { if (as_arch_compatible (as_component_get_architecture (cpt), priv->current_arch)) { const gchar *earch; /* this component is compatible with our current architecture */ earch = as_component_get_architecture (existing_cpt); if (earch != NULL) { if (as_arch_compatible (earch, priv->current_arch)) { g_hash_table_replace (priv->cpt_table, g_strdup (cdid), g_object_ref (cpt)); g_debug ("Preferred component for native architecture for %s (was %s)", cdid, earch); return TRUE; } else { g_debug ("Ignored additional entry for '%s' on architecture %s.", cdid, earch); return FALSE; } } } } if (pool_priority == as_component_get_priority (cpt)) { g_set_error (error, AS_POOL_ERROR, AS_POOL_ERROR_COLLISION, "Detected colliding ids: %s was already added with the same priority.", cdid); return FALSE; } else { if (pedantic_noadd) g_set_error (error, AS_POOL_ERROR, AS_POOL_ERROR_COLLISION, "Detected colliding ids: %s was already added with a higher priority.", cdid); return FALSE; } } return TRUE; }
/** * as_pool_load_appstream: * * Load fresh metadata from AppStream directories. */ static gboolean as_pool_load_appstream (AsPool *pool, GError **error) { GPtrArray *cpts; g_autoptr(GPtrArray) merge_cpts = NULL; guint i; gboolean ret; g_autoptr(AsMetadata) metad = NULL; g_autoptr(GPtrArray) mdata_files = NULL; GError *tmp_error = NULL; AsPoolPrivate *priv = GET_PRIVATE (pool); /* see if we can use the caches */ if (!as_pool_metadata_changed (pool)) { g_autofree gchar *fname = NULL; g_debug ("Caches are up to date."); if (as_flags_contains (priv->cache_flags, AS_CACHE_FLAG_USE_SYSTEM)) { g_debug ("Using cached data."); fname = g_strdup_printf ("%s/%s.gvz", priv->sys_cache_path, priv->locale); if (g_file_test (fname, G_FILE_TEST_EXISTS)) { return as_pool_load_cache_file (pool, fname, error); } else { g_debug ("Missing cache for language '%s', attempting to load fresh data.", priv->locale); } } else { g_debug ("Not using system cache."); } } /* prepare metadata parser */ metad = as_metadata_new (); as_metadata_set_format_style (metad, AS_FORMAT_STYLE_COLLECTION); as_metadata_set_locale (metad, priv->locale); /* find AppStream metadata */ ret = TRUE; mdata_files = g_ptr_array_new_with_free_func (g_free); /* find XML data */ for (i = 0; i < priv->xml_dirs->len; i++) { const gchar *xml_path = (const gchar *) g_ptr_array_index (priv->xml_dirs, i); guint j; if (g_file_test (xml_path, G_FILE_TEST_IS_DIR)) { g_autoptr(GPtrArray) xmls = NULL; g_debug ("Searching for data in: %s", xml_path); xmls = as_utils_find_files_matching (xml_path, "*.xml*", FALSE, NULL); if (xmls != NULL) { for (j = 0; j < xmls->len; j++) { const gchar *val; val = (const gchar *) g_ptr_array_index (xmls, j); g_ptr_array_add (mdata_files, g_strdup (val)); } } } } /* find YAML metadata */ for (i = 0; i < priv->yaml_dirs->len; i++) { const gchar *yaml_path = (const gchar *) g_ptr_array_index (priv->yaml_dirs, i); guint j; if (g_file_test (yaml_path, G_FILE_TEST_IS_DIR)) { g_autoptr(GPtrArray) yamls = NULL; g_debug ("Searching for data in: %s", yaml_path); yamls = as_utils_find_files_matching (yaml_path, "*.yml*", FALSE, NULL); if (yamls != NULL) { for (j = 0; j < yamls->len; j++) { const gchar *val; val = (const gchar *) g_ptr_array_index (yamls, j); g_ptr_array_add (mdata_files, g_strdup (val)); } } } } /* parse the found data */ for (i = 0; i < mdata_files->len; i++) { g_autoptr(GFile) infile = NULL; const gchar *fname; fname = (const gchar*) g_ptr_array_index (mdata_files, i); g_debug ("Reading: %s", fname); infile = g_file_new_for_path (fname); if (!g_file_query_exists (infile, NULL)) { g_warning ("Metadata file '%s' does not exist.", fname); continue; } as_metadata_parse_file (metad, infile, AS_FORMAT_KIND_UNKNOWN, &tmp_error); if (tmp_error != NULL) { g_debug ("WARNING: %s", tmp_error->message); g_error_free (tmp_error); tmp_error = NULL; ret = FALSE; } } /* add found components to the metadata pool */ cpts = as_metadata_get_components (metad); merge_cpts = g_ptr_array_new (); for (i = 0; i < cpts->len; i++) { AsComponent *cpt = AS_COMPONENT (g_ptr_array_index (cpts, i)); /* TODO: We support only system components at time */ as_component_set_scope (cpt, AS_COMPONENT_SCOPE_SYSTEM); /* deal with merge-components later */ if (as_component_get_merge_kind (cpt) != AS_MERGE_KIND_NONE) { g_ptr_array_add (merge_cpts, cpt); continue; } as_pool_add_component (pool, cpt, &tmp_error); if (tmp_error != NULL) { g_debug ("Metadata ignored: %s", tmp_error->message); g_error_free (tmp_error); tmp_error = NULL; } } /* we need to merge the merge-components into the pool last, so the merge process can fetch * all components with matching IDs from the pool */ for (i = 0; i < merge_cpts->len; i++) { AsComponent *mcpt = AS_COMPONENT (g_ptr_array_index (merge_cpts, i)); as_pool_add_component (pool, mcpt, &tmp_error); if (tmp_error != NULL) { g_debug ("Merge component ignored: %s", tmp_error->message); g_error_free (tmp_error); tmp_error = NULL; } } return ret; }
/** * as_merge_components: * * Merge selected data from two components. */ static void as_merge_components (AsComponent *dest_cpt, AsComponent *src_cpt) { guint i; AsMergeKind merge_kind; merge_kind = as_component_get_merge_kind (src_cpt); g_return_if_fail (merge_kind != AS_MERGE_KIND_NONE); /* FIXME: We need to merge more attributes */ /* merge stuff in append mode */ if (merge_kind == AS_MERGE_KIND_APPEND) { GPtrArray *suggestions; GPtrArray *cats; /* merge categories */ cats = as_component_get_categories (src_cpt); if (cats->len > 0) { g_autoptr(GHashTable) cat_table = NULL; GPtrArray *dest_categories; cat_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < cats->len; i++) { const gchar *cat = (const gchar*) g_ptr_array_index (cats, i); g_hash_table_add (cat_table, g_strdup (cat)); } dest_categories = as_component_get_categories (dest_cpt); if (dest_categories->len > 0) { for (i = 0; i < dest_categories->len; i++) { const gchar *cat = (const gchar*) g_ptr_array_index (dest_categories, i); g_hash_table_add (cat_table, g_strdup (cat)); } } g_ptr_array_set_size (dest_categories, 0); as_hash_table_string_keys_to_array (cat_table, dest_categories); } /* merge suggestions */ suggestions = as_component_get_suggested (src_cpt); if (suggestions != NULL) { for (i = 0; i < suggestions->len; i++) { as_component_add_suggested (dest_cpt, AS_SUGGESTED (g_ptr_array_index (suggestions, i))); } } } /* merge stuff in replace mode */ if (merge_kind == AS_MERGE_KIND_REPLACE) { gchar **pkgnames; /* merge names */ if (as_component_get_name (src_cpt) != NULL) as_component_set_name (dest_cpt, as_component_get_name (src_cpt), as_component_get_active_locale (src_cpt)); /* merge package names */ pkgnames = as_component_get_pkgnames (src_cpt); if ((pkgnames != NULL) && (pkgnames[0] != '\0')) as_component_set_pkgnames (dest_cpt, as_component_get_pkgnames (src_cpt)); /* merge bundles */ if (as_component_has_bundle (src_cpt)) as_component_set_bundles_array (dest_cpt, as_component_get_bundles (src_cpt)); } g_debug ("Merged data for '%s'", as_component_get_data_id (dest_cpt)); }
/** * as_pool_refresh_cache: * @pool: An instance of #AsPool. * @force: Enforce refresh, even if source data has not changed. * * Update the AppStream cache. There is normally no need to call this function manually, because cache updates are handled * transparently in the background. * * Returns: %TRUE if the cache was updated, %FALSE on error or if the cache update was not necessary and has been skipped. */ gboolean as_pool_refresh_cache (AsPool *pool, gboolean force, GError **error) { AsPoolPrivate *priv = GET_PRIVATE (pool); gboolean ret = FALSE; gboolean ret_poolupdate; g_autofree gchar *cache_fname = NULL; g_autoptr(GError) tmp_error = NULL; /* try to create cache directory, in case it doesn't exist */ g_mkdir_with_parents (priv->sys_cache_path, 0755); if (!as_utils_is_writable (priv->sys_cache_path)) { g_set_error (error, AS_POOL_ERROR, AS_POOL_ERROR_TARGET_NOT_WRITABLE, _("Cache location '%s' is not writable."), priv->sys_cache_path); return FALSE; } /* collect metadata */ #ifdef HAVE_APT_SUPPORT /* currently, we only do something here if we are running with explicit APT support compiled in */ as_pool_scan_apt (pool, force, &tmp_error); if (tmp_error != NULL) { /* the exact error is not forwarded here, since we might be able to partially update the cache */ g_warning ("Error while collecting metadata: %s", tmp_error->message); g_error_free (tmp_error); tmp_error = NULL; } #endif /* create the filename of our cache */ cache_fname = g_strdup_printf ("%s/%s.gvz", priv->sys_cache_path, priv->locale); /* check if we need to refresh the cache * (which is only necessary if the AppStream data has changed) */ if (!as_pool_metadata_changed (pool)) { g_debug ("Data did not change, no cache refresh needed."); if (force) { g_debug ("Forcing refresh anyway."); } else { return FALSE; } } g_debug ("Refreshing AppStream cache"); /* ensure we start with an empty pool */ as_pool_clear (pool); /* NOTE: we will only cache AppStream metadata, no .desktop file metadata etc. */ /* find them wherever they are */ ret = as_pool_load_appstream (pool, &tmp_error); ret_poolupdate = as_pool_refine_data (pool) && ret; if (tmp_error != NULL) { /* the exact error is not forwarded here, since we might be able to partially update the cache */ g_warning ("Error while updating the in-memory data pool: %s", tmp_error->message); g_error_free (tmp_error); tmp_error = NULL; } /* save the cache object */ as_pool_save_cache_file (pool, cache_fname, &tmp_error); if (tmp_error != NULL) { /* the exact error is not forwarded here, since we might be able to partially update the cache */ g_warning ("Error while updating the cache: %s", tmp_error->message); g_error_free (tmp_error); tmp_error = NULL; ret = FALSE; } else { ret = TRUE; } if (ret) { if (!ret_poolupdate) { g_set_error (error, AS_POOL_ERROR, AS_POOL_ERROR_INCOMPLETE, _("AppStream data pool was loaded, but some metadata was ignored due to errors.")); } /* update the cache mtime, to not needlessly rebuild it again */ as_touch_location (cache_fname); as_pool_check_cache_ctime (pool); } else { g_set_error (error, AS_POOL_ERROR, AS_POOL_ERROR_FAILED, _("AppStream cache update failed.")); } return TRUE; }
static void gb_vim_complete_edit_files (GtkSourceView *source_view, const gchar *command, GPtrArray *ar, const gchar *prefix) { GbWorkbench *workbench; IdeContext *context; IdeVcs *vcs; GFile *workdir; g_autoptr(GFile) child = NULL; g_autoptr(GFile) parent = NULL; IDE_ENTRY; g_assert (command); g_assert (ar); g_assert (prefix); if (!(workbench = gb_widget_get_workbench (GTK_WIDGET (source_view))) || !(context = gb_workbench_get_context (workbench)) || !(vcs = ide_context_get_vcs (context)) || !(workdir = ide_vcs_get_working_directory (vcs))) IDE_EXIT; child = g_file_get_child (workdir, prefix); if (g_file_query_exists (child, NULL)) { if (g_file_query_file_type (child, 0, NULL) == G_FILE_TYPE_DIRECTORY) { g_autoptr(GFileEnumerator) fe = NULL; GFileInfo *descendent; if (!g_str_has_suffix (prefix, "/")) { g_ptr_array_add (ar, g_strdup_printf ("%s %s/", command, prefix)); IDE_EXIT; } fe = g_file_enumerate_children (child, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (fe == NULL) IDE_EXIT; while ((descendent = g_file_enumerator_next_file (fe, NULL, NULL))) { const gchar *name; name = g_file_info_get_display_name (descendent); g_ptr_array_add (ar, g_strdup_printf ("%s %s%s", command, prefix, name)); g_object_unref (descendent); } IDE_EXIT; } } parent = g_file_get_parent (child); if (parent != NULL) { g_autoptr(GFileEnumerator) fe = NULL; g_autofree gchar *relpath = NULL; GFileInfo *descendent; const gchar *slash; relpath = g_file_get_relative_path (workdir, parent); if (relpath && g_str_has_prefix (relpath, "./")) { gchar *tmp = relpath; relpath = g_strdup (relpath + 2); g_free (tmp); } #ifdef IDE_ENABLE_TRACE { g_autofree gchar *parent_path = g_file_get_path (parent); IDE_TRACE_MSG ("parent_path: %s", parent_path); } #endif if ((slash = strrchr (prefix, G_DIR_SEPARATOR))) prefix = slash + 1; fe = g_file_enumerate_children (parent, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (fe == NULL) IDE_EXIT; while ((descendent = g_file_enumerator_next_file (fe, NULL, NULL))) { const gchar *name; name = g_file_info_get_display_name (descendent); IDE_TRACE_MSG ("name=%s prefix=%s", name, prefix); if (name && g_str_has_prefix (name, prefix)) { gchar *path; if (relpath) path = g_strdup_printf ("%s %s/%s", command, relpath, name); else path = g_strdup_printf ("%s %s", command, name); IDE_TRACE_MSG ("edit completion: %s", path); g_ptr_array_add (ar, path); } g_object_unref (descendent); } IDE_EXIT; } IDE_EXIT; }
static void ide_keybindings_reload (IdeKeybindings *self) { GdkScreen *screen; PeasEngine *engine; const GList *list; IDE_ENTRY; g_assert (IDE_IS_KEYBINDINGS (self)); { g_autofree gchar *path = NULL; g_autoptr(GBytes) bytes = NULL; g_autoptr(GError) error = NULL; if (self->mode == NULL) self->mode = g_strdup ("default"); IDE_TRACE_MSG ("Loading %s keybindings", self->mode); path = g_strdup_printf ("/org/gnome/builder/keybindings/%s.css", self->mode); bytes = g_resources_lookup_data (path, G_RESOURCE_LOOKUP_FLAGS_NONE, &error); if (error == NULL) { /* * We use -1 for the length so that the CSS provider knows that the * string is \0 terminated. This is guaranteed to us by GResources so * that interned data can be used as C strings. */ gtk_css_provider_load_from_data (self->css_provider, g_bytes_get_data (bytes, NULL), -1, &error); } if (error) g_warning ("%s", error->message); } engine = peas_engine_get_default (); screen = gdk_screen_get_default (); if (self->plugin_providers != NULL) { GHashTableIter iter; GtkStyleProvider *provider; g_hash_table_iter_init (&iter, self->plugin_providers); while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&provider)) gtk_style_context_remove_provider_for_screen (screen, provider); g_clear_pointer (&self->plugin_providers, g_hash_table_unref); } self->plugin_providers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); list = peas_engine_get_plugin_list (engine); for (; list != NULL; list = list->next) { PeasPluginInfo *plugin_info = list->data; if (!peas_plugin_info_is_loaded (plugin_info)) continue; ide_keybindings_load_plugin (self, plugin_info, engine); } IDE_EXIT; }
static gboolean archive_spawnv (GFile *dir, char **output, GError **error, const gchar * const *argv) { g_autoptr(GSubprocessLauncher) launcher = NULL; g_autoptr(GSubprocess) subp = NULL; GInputStream *in; g_autoptr(GOutputStream) out = NULL; g_autoptr(GMainLoop) loop = NULL; SpawnData data = {0}; g_autofree gchar *commandline = NULL; launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); if (output) g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); if (dir) { g_autofree char *path = g_file_get_path (dir); g_subprocess_launcher_set_cwd (launcher, path); } commandline = g_strjoinv (" ", (gchar **) argv); g_debug ("Running '%s'", commandline); subp = g_subprocess_launcher_spawnv (launcher, argv, error); if (subp == NULL) return FALSE; loop = g_main_loop_new (NULL, FALSE); data.loop = loop; data.refs = 1; if (output) { data.refs++; in = g_subprocess_get_stdout_pipe (subp); out = g_memory_output_stream_new_resizable (); g_output_stream_splice_async (out, in, G_OUTPUT_STREAM_SPLICE_NONE, 0, NULL, spawn_output_spliced_cb, &data); } g_subprocess_wait_async (subp, NULL, spawn_exit_cb, &data); g_main_loop_run (loop); if (data.error) { g_propagate_error (error, data.error); g_clear_error (&data.splice_error); return FALSE; } if (out) { if (data.splice_error) { g_propagate_error (error, data.splice_error); return FALSE; } /* Null terminate */ g_output_stream_write (out, "\0", 1, NULL, NULL); g_output_stream_close (out, NULL, NULL); *output = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); } return TRUE; }
gboolean flatpak_builtin_enter (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; int rest_argv_start, rest_argc; const char *ns_name[5] = { "user", "ipc", "net", "pid", "mnt" }; int ns_fd[G_N_ELEMENTS (ns_name)]; char pid_ns[256]; ssize_t pid_ns_len; char self_ns[256]; ssize_t self_ns_len; char *pid_s; int pid, i; g_autofree char *environment_path = NULL; g_autoptr(GPtrArray) argv_array = NULL; g_autoptr(GPtrArray) envp_array = NULL; g_autofree char *environment = NULL; gsize environment_len; char *e; g_autofree char *pulse_path = NULL; g_autofree char *session_bus_path = NULL; g_autofree char *xdg_runtime_dir = NULL; int status; uid = getuid (); gid = getgid (); context = g_option_context_new ("MONITORPID [COMMAND [args...]] - Run a command inside a running sandbox"); rest_argc = 0; for (i = 1; i < argc; i++) { /* The non-option is the command, take it out of the arguments */ if (argv[i][0] != '-') { rest_argv_start = i; rest_argc = argc - i; argc = i; break; } } if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) return FALSE; if (rest_argc < 2) { usage_error (context, "MONITORPID and COMMAND must be specified", error); return FALSE; } pid_s = argv[rest_argv_start]; pid = atoi (pid_s); if (pid <= 0) return flatpak_fail (error, "Invalid pid %s\n", pid_s); environment_path = g_strdup_printf ("/proc/%d/environ", pid); if (!g_file_get_contents (environment_path, &environment, &environment_len, error)) return FALSE; for (i = 0; i < G_N_ELEMENTS (ns_name); i++) { g_autofree char *path = g_strdup_printf ("/proc/%d/ns/%s", pid, ns_name[i]); g_autofree char *self_path = g_strdup_printf ("/proc/self/ns/%s", ns_name[i]); pid_ns_len = readlink (path, pid_ns, sizeof (pid_ns) - 1); if (pid_ns_len <= 0) return flatpak_fail (error, "Invalid %s namespace for pid %d\n", ns_name[i], pid); pid_ns[pid_ns_len] = 0; self_ns_len = readlink (self_path, self_ns, sizeof (self_ns) - 1); if (self_ns_len <= 0) return flatpak_fail (error, "Invalid %s namespace for self\n", ns_name[i]); self_ns[self_ns_len] = 0; if (strcmp (self_ns, pid_ns) == 0) { /* No need to setns to the same namespace, it will only fail */ ns_fd[i] = -1; } else { ns_fd[i] = open (path, O_RDONLY); if (ns_fd[i] == -1) return flatpak_fail (error, "Can't open %s namespace: %s", ns_name[i], strerror (errno)); } } for (i = 0; i < G_N_ELEMENTS (ns_fd); i++) { if (ns_fd[i] != -1) { if (setns (ns_fd[i], 0) == -1) return flatpak_fail (error, "Can't enter %s namespace: %s", ns_name[i], strerror (errno)); close (ns_fd[i]); } } envp_array = g_ptr_array_new_with_free_func (g_free); for (e = environment; e < environment + environment_len; e = e + strlen (e) + 1) { if (*e != 0 && !g_str_has_prefix (e, "DISPLAY=") && !g_str_has_prefix (e, "PULSE_SERVER=") && !g_str_has_prefix (e, "PULSE_CLIENTCONFIG=") && !g_str_has_prefix (e, "XDG_RUNTIME_DIR=") && !g_str_has_prefix (e, "DBUS_SYSTEM_BUS_ADDRESS=") && !g_str_has_prefix (e, "DBUS_SESSION_BUS_ADDRESS=")) { if (g_str_has_prefix (e, "_LD_LIBRARY_PATH=")) e++; g_ptr_array_add (envp_array, g_strdup (e)); } } xdg_runtime_dir = g_strdup_printf ("/run/user/%d", uid); g_ptr_array_add (envp_array, g_strdup_printf ("XDG_RUNTIME_DIR=%s", xdg_runtime_dir)); if (g_file_test ("/tmp/.X11-unix/X99", G_FILE_TEST_EXISTS)) g_ptr_array_add (envp_array, g_strdup ("DISPLAY=:99.0")); pulse_path = g_strdup_printf ("/run/user/%d/pulse/native", uid); if (g_file_test (pulse_path, G_FILE_TEST_EXISTS)) { g_ptr_array_add (envp_array, g_strdup_printf ("PULSE_SERVER=unix:%s", pulse_path)); g_ptr_array_add (envp_array, g_strdup_printf ("PULSE_CLIENTCONFIG=/run/user/%d/pulse/config", uid)); } session_bus_path = g_strdup_printf ("/run/user/%d/bus", uid); if (g_file_test (session_bus_path, G_FILE_TEST_EXISTS)) g_ptr_array_add (envp_array, g_strdup_printf ("DBUS_SESSION_BUS_ADDRESS=unix:%s", session_bus_path)); if (g_file_test ("/run/dbus/system_bus_socket", G_FILE_TEST_EXISTS)) g_ptr_array_add (envp_array, g_strdup ("DBUS_SYSTEM_BUS_ADDRESS=unix:/run/dbus/system_bus_socket")); g_ptr_array_add (envp_array, NULL); argv_array = g_ptr_array_new_with_free_func (g_free); for (i = 1; i < rest_argc; i++) g_ptr_array_add (argv_array, g_strdup (argv[rest_argv_start + i])); g_ptr_array_add (argv_array, NULL); if (!g_spawn_sync (NULL, (char **) argv_array->pdata, (char **) envp_array->pdata, G_SPAWN_SEARCH_PATH_FROM_ENVP | G_SPAWN_CHILD_INHERITS_STDIN, child_setup, NULL, NULL, NULL, &status, error)) return FALSE; exit (status); }
static gboolean extract_archive (GFile *destination, GFile *archive_file, guint strip_components, GError **error) { ArchiveType type; g_autofree char *archive_path = NULL; archive_path = g_file_get_path (archive_file); g_debug ("Uncompress %s\n", archive_path); type = get_type (archive_file); if (is_tar (type)) { g_autofree char *strip_components_str = g_strdup_printf ("--strip-components=%u", strip_components); /* tar_decompress_flag can return NULL, so put it last */ if (!tar (destination, error, "xf", archive_path, "--no-same-owner", strip_components_str, tar_decompress_flag (type), NULL)) return FALSE; } else if (type == ZIP) { g_autoptr(GFile) zip_dest = NULL; zip_dest = create_uncompress_directory (destination, strip_components, error); if (zip_dest == NULL) return FALSE; if (!unzip (zip_dest, error, archive_path, NULL)) return FALSE; if (strip_components > 0 && !strip_components_into (destination, zip_dest, strip_components, error)) return FALSE; } else if (type == RPM) { g_autoptr(GFile) rpm_dest = NULL; rpm_dest = create_uncompress_directory (destination, strip_components, error); if (rpm_dest == NULL) return FALSE; if (!unrpm (rpm_dest, archive_path, error)) return FALSE; if (strip_components > 0 && !strip_components_into (destination, rpm_dest, strip_components, error)) return FALSE; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown archive format of '%s'", archive_path); return FALSE; } return TRUE; }
static gboolean enumerate_instances (Column *columns, GError **error) { g_autoptr(GPtrArray) instances = NULL; FlatpakTablePrinter *printer; int i, j; if (columns[0].name == NULL) return TRUE; printer = flatpak_table_printer_new (); flatpak_table_printer_set_columns (printer, columns); instances = flatpak_instance_get_all (); if (instances->len == 0) { /* nothing to show */ return TRUE; } for (j = 0; j < instances->len; j++) { FlatpakInstance *instance = (FlatpakInstance *) g_ptr_array_index (instances, j); flatpak_table_printer_add_column (printer, flatpak_instance_get_id (instance)); for (i = 0; columns[i].name; i++) { if (strcmp (columns[i].name, "pid") == 0) { g_autofree char *pid = g_strdup_printf ("%d", flatpak_instance_get_pid (instance)); flatpak_table_printer_add_column (printer, pid); } else if (strcmp (columns[i].name, "child-pid") == 0) { g_autofree char *pid = g_strdup_printf ("%d", flatpak_instance_get_child_pid (instance)); flatpak_table_printer_add_column (printer, pid); } else if (strcmp (columns[i].name, "application") == 0) flatpak_table_printer_add_column (printer, flatpak_instance_get_app (instance)); else if (strcmp (columns[i].name, "arch") == 0) flatpak_table_printer_add_column (printer, flatpak_instance_get_arch (instance)); else if (strcmp (columns[i].name, "branch") == 0) flatpak_table_printer_add_column (printer, flatpak_instance_get_branch (instance)); else if (strcmp (columns[i].name, "commit") == 0) flatpak_table_printer_add_column_len (printer, flatpak_instance_get_commit (instance), 12); else if (strcmp (columns[i].name, "runtime") == 0) { const char *full_ref = flatpak_instance_get_runtime (instance); if (full_ref != NULL) { g_auto(GStrv) ref = flatpak_decompose_ref (full_ref, NULL); flatpak_table_printer_add_column (printer, ref[1]); } } else if (strcmp (columns[i].name, "runtime-branch") == 0) { const char *full_ref = flatpak_instance_get_runtime (instance); if (full_ref != NULL) { g_auto(GStrv) ref = flatpak_decompose_ref (full_ref, NULL); flatpak_table_printer_add_column (printer, ref[3]); } } else if (strcmp (columns[i].name, "runtime-commit") == 0) flatpak_table_printer_add_column_len (printer, flatpak_instance_get_runtime_commit (instance), 12); } flatpak_table_printer_finish_row (printer); } flatpak_table_printer_print (printer); flatpak_table_printer_free (printer); return TRUE; }
static void ide_frame_pan_end (IdeFrame *self, GdkEventSequence *sequence, GtkGesturePan *gesture) { IdeFramePrivate *priv = ide_frame_get_instance_private (self); IdeFramePrivate *dest_priv; IdeFrame *dest; GtkAllocation alloc; GtkWidget *grid; GtkWidget *column; gdouble x, y; gint direction; gint index = 0; IDE_ENTRY; g_assert (IDE_IS_FRAME (self)); g_assert (GTK_IS_GESTURE_PAN (gesture)); if (priv->pan_theatric == NULL || priv->pan_page == NULL) IDE_GOTO (cleanup); gtk_widget_get_allocation (GTK_WIDGET (self), &alloc); gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (gesture), &x, &y); if (x > DISTANCE_THRESHOLD (&alloc)) direction = 1; else if (x < -DISTANCE_THRESHOLD (&alloc)) direction = -1; else direction = 0; grid = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_GRID); g_assert (grid != NULL); g_assert (IDE_IS_GRID (grid)); column = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_GRID_COLUMN); g_assert (column != NULL); g_assert (IDE_IS_GRID_COLUMN (column)); gtk_container_child_get (GTK_CONTAINER (grid), GTK_WIDGET (column), "index", &index, NULL); dest = _ide_grid_get_nth_stack (IDE_GRID (grid), index + direction); dest_priv = ide_frame_get_instance_private (dest); g_assert (dest != NULL); g_assert (IDE_IS_FRAME (dest)); gtk_widget_get_allocation (GTK_WIDGET (dest), &alloc); if (!is_uninitialized (&alloc)) { AnimationState *state; state = g_slice_new0 (AnimationState); state->source = g_object_ref (self); state->dest = g_object_ref (dest); state->page = g_object_ref (priv->pan_page); state->theatric = g_object_ref (priv->pan_theatric); gtk_widget_translate_coordinates (GTK_WIDGET (dest_priv->top_stack), grid, 0, 0, &alloc.x, &alloc.y); /* * Use EASE_OUT_CUBIC, because user initiated the beginning of the * acceleration curve just by swiping. No need to duplicate. */ dzl_object_animate_full (state->theatric, DZL_ANIMATION_EASE_OUT_CUBIC, TRANSITION_DURATION, gtk_widget_get_frame_clock (GTK_WIDGET (self)), animation_state_complete, state, "x", alloc.x, "width", alloc.width, NULL); if (dest != self) { g_ptr_array_add (priv->in_transition, g_object_ref (priv->pan_page)); gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (priv->pan_page)); } IDE_TRACE_MSG ("Animating transition to %s column", dest != self ? "another" : "same"); } else { g_autoptr(IdePage) page = g_object_ref (priv->pan_page); IDE_TRACE_MSG ("Moving page to a previously non-existant column"); gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (page)); gtk_widget_show (GTK_WIDGET (page)); gtk_container_add (GTK_CONTAINER (dest_priv->stack), GTK_WIDGET (page)); } cleanup: g_clear_object (&priv->pan_theatric); g_clear_object (&priv->pan_page); gtk_widget_queue_draw (gtk_widget_get_toplevel (GTK_WIDGET (self))); ide_frame_set_cursor (self, "arrow"); IDE_EXIT; }
/* The hierarchy looks like this: * /tmp/first_dir/first_dir_dir1/dir1_child * /tmp/first_dir/first_dir_dir2/dir2_child * /tmp/second_dir * We're copying first_dir to second_dir. */ static void test_copy_third_hierarchy (void) { g_autoptr (GFile) root = NULL; g_autoptr (GFile) first_dir = NULL; g_autoptr (GFile) second_dir = NULL; g_autoptr (GFile) file = NULL; g_autoptr (GFile) result_file = NULL; g_autolist (GFile) files = NULL; create_third_hierarchy ("copy"); root = g_file_new_for_path (g_get_tmp_dir ()); g_assert_true (root != NULL); first_dir = g_file_get_child (root, "copy_first_dir"); files = g_list_prepend (files, g_object_ref (first_dir)); g_assert_true (first_dir != NULL); file = g_file_get_child (first_dir, "copy_first_dir_dir1"); g_assert_true (file != NULL); file = g_file_get_child (file, "copy_dir1_child"); g_assert_true (file != NULL); file = g_file_get_child (first_dir, "copy_first_dir_dir2"); g_assert_true (file != NULL); file = g_file_get_child (file, "copy_dir2_child"); g_assert_true (file != NULL); second_dir = g_file_get_child (root, "copy_second_dir"); g_assert_true (second_dir != NULL); nautilus_file_operations_copy_sync (files, second_dir); result_file = g_file_get_child (second_dir, "copy_first_dir"); g_assert_true (g_file_query_exists (result_file, NULL)); file = g_file_get_child (result_file, "copy_first_dir_dir1"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (file, "copy_dir1_child"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (result_file, "copy_first_dir_dir1"); file = g_file_get_child (result_file, "copy_first_dir_dir2"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (file, "copy_dir2_child"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (result_file, "copy_first_dir_dir2"); file = g_file_get_child (first_dir, "copy_first_dir_dir1"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (file, "copy_dir1_child"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (first_dir, "copy_first_dir_dir1"); file = g_file_get_child (first_dir, "copy_first_dir_dir2"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (file, "copy_dir2_child"); g_assert_true (g_file_query_exists (file, NULL)); file = g_file_get_child (first_dir, "copy_first_dir_dir2"); g_assert_true (g_file_query_exists (file, NULL)); g_assert_true (g_file_query_exists (first_dir, NULL)); empty_directory_by_prefix (root, "copy"); }
static void gpk_log_startup_cb (GtkApplication *application, gpointer user_data) { g_autoptr(GError) error = NULL; GtkTreeSelection *selection; GtkWidget *widget; GtkWindow *window; guint retval; client = pk_client_new (); g_object_set (client, "background", FALSE, NULL); /* get UI */ builder = gtk_builder_new (); retval = gtk_builder_add_from_resource (builder, "/org/gnome/packagekit/gpk-log.ui", &error); if (retval == 0) { g_warning ("failed to load ui: %s", error->message); goto out; } window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_simple")); gtk_window_set_icon_name (window, GPK_ICON_SOFTWARE_LOG); gtk_window_set_application (window, application); /* set a size, as the screen allows */ gpk_window_set_size_request (window, 1200, 1200); /* if command line arguments are set, then setup UI */ if (filter != NULL) { widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package")); gtk_entry_set_text (GTK_ENTRY(widget), filter); } widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_refresh")); g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_refresh_cb), NULL); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_filter")); g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_filter_cb), NULL); /* hit enter in the search box for filter */ widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package")); g_signal_connect (widget, "activate", G_CALLBACK (gpk_log_button_filter_cb), NULL); /* autocompletion can be turned off as it's slow */ g_signal_connect (widget, "key-release-event", G_CALLBACK (gpk_log_entry_filter_cb), NULL); /* create list stores */ list_store = gtk_list_store_new (GPK_LOG_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); /* create transaction_id tree view */ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_simple")); gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (list_store)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); g_signal_connect (selection, "changed", G_CALLBACK (gpk_log_treeview_clicked_cb), NULL); /* add columns to the tree view */ pk_treeview_add_general_columns (GTK_TREE_VIEW (widget)); gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), GPK_LOG_COLUMN_TIMESPEC, GTK_SORT_DESCENDING); /* show */ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_simple")); gtk_widget_show (widget); /* set the parent window if it is specified */ if (xid != 0) { g_debug ("Setting xid %i", xid); gpk_window_set_parent_xid (GTK_WINDOW (widget), xid); } /* get the update list */ gpk_log_refresh (); out: g_object_unref (list_store); g_object_unref (client); g_free (transaction_id); g_free (filter); if (transactions != NULL) g_ptr_array_unref (transactions); }
int main (int argc, char **argv) { GList *list = NULL; GList *categories = NULL; GOptionContext *context; gboolean prefer_local = FALSE; gboolean ret; gboolean show_results = FALSE; gboolean verbose = FALSE; guint64 refine_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT; gint i; gint cache_age = 0; gint repeat = 1; int status = 0; g_auto(GStrv) plugin_names = NULL; g_autoptr(GError) error = NULL; g_autoptr(GsDebug) debug = gs_debug_new (); g_autofree gchar *plugin_names_str = NULL; g_autofree gchar *refine_flags_str = NULL; g_autoptr(GsApp) app = NULL; g_autoptr(GFile) file = NULL; g_autoptr(GsPluginLoader) plugin_loader = NULL; g_autoptr(AsProfile) profile = NULL; g_autoptr(AsProfileTask) ptask = NULL; const GOptionEntry options[] = { { "show-results", '\0', 0, G_OPTION_ARG_NONE, &show_results, "Show the results for the action", NULL }, { "refine-flags", '\0', 0, G_OPTION_ARG_STRING, &refine_flags_str, "Set any refine flags required for the action", NULL }, { "repeat", '\0', 0, G_OPTION_ARG_INT, &repeat, "Repeat the action this number of times", NULL }, { "cache-age", '\0', 0, G_OPTION_ARG_INT, &cache_age, "Use this maximum cache age in seconds", NULL }, { "prefer-local", '\0', 0, G_OPTION_ARG_NONE, &prefer_local, "Prefer local file sources to AppStream", NULL }, { "plugin-names", '\0', 0, G_OPTION_ARG_STRING, &plugin_names_str, "Whitelist only these plugin names", NULL }, { "verbose", '\0', 0, G_OPTION_ARG_NONE, &verbose, "Show verbose debugging information", NULL }, { NULL} }; setlocale (LC_ALL, ""); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &argv); context = g_option_context_new (NULL); g_option_context_set_summary (context, "GNOME Software Test Program"); g_option_context_add_main_entries (context, options, NULL); g_option_context_add_group (context, gtk_get_option_group (TRUE)); ret = g_option_context_parse (context, &argc, &argv, &error); if (!ret) { g_print ("Failed to parse options: %s\n", error->message); goto out; } if (verbose) g_setenv ("GS_DEBUG", "1", TRUE); /* prefer local sources */ if (prefer_local) g_setenv ("GNOME_SOFTWARE_PREFER_LOCAL", "true", TRUE); /* parse any refine flags */ refine_flags = gs_cmd_parse_refine_flags (refine_flags_str, &error); if (refine_flags == G_MAXUINT64) { g_print ("Flag unknown: %s\n", error->message); goto out; } profile = as_profile_new (); ptask = as_profile_start_literal (profile, "GsCmd"); /* load plugins */ plugin_loader = gs_plugin_loader_new (); gs_plugin_loader_set_location (plugin_loader, "./plugins/.libs"); if (plugin_names_str != NULL) plugin_names = g_strsplit (plugin_names_str, ",", -1); ret = gs_plugin_loader_setup (plugin_loader, plugin_names, &error); if (!ret) { g_print ("Failed to setup plugins: %s\n", error->message); goto out; } gs_plugin_loader_dump_state (plugin_loader); /* do action */ if (argc == 2 && g_strcmp0 (argv[1], "installed") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_get_installed (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 3 && g_strcmp0 (argv[1], "search") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_search (plugin_loader, argv[2], refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 3 && g_strcmp0 (argv[1], "action-upgrade-download") == 0) { app = gs_app_new (argv[2]); gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE); ret = gs_plugin_loader_app_action (plugin_loader, app, GS_PLUGIN_LOADER_ACTION_UPGRADE_DOWNLOAD, NULL, &error); if (ret) gs_app_list_add (&list, app); } else if (argc == 3 && g_strcmp0 (argv[1], "refine") == 0) { app = gs_app_new (argv[2]); for (i = 0; i < repeat; i++) { ret = gs_plugin_loader_app_refine (plugin_loader, app, refine_flags, NULL, &error); if (!ret) break; } gs_app_list_add (&list, app); } else if (argc == 3 && g_strcmp0 (argv[1], "launch") == 0) { app = gs_app_new (argv[2]); for (i = 0; i < repeat; i++) { ret = gs_plugin_loader_app_action (plugin_loader, app, GS_PLUGIN_LOADER_ACTION_LAUNCH, NULL, &error); if (!ret) break; } } else if (argc == 3 && g_strcmp0 (argv[1], "filename-to-app") == 0) { file = g_file_new_for_path (argv[2]); app = gs_plugin_loader_file_to_app (plugin_loader, file, refine_flags, NULL, &error); if (app == NULL) { ret = FALSE; } else { gs_app_list_add (&list, app); } } else if (argc == 2 && g_strcmp0 (argv[1], "updates") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_get_updates (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "upgrades") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_get_distro_upgrades (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "sources") == 0) { list = gs_plugin_loader_get_sources (plugin_loader, refine_flags, NULL, &error); if (list == NULL) ret = FALSE; } else if (argc == 2 && g_strcmp0 (argv[1], "popular") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_get_popular (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "featured") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_get_featured (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "get-categories") == 0) { for (i = 0; i < repeat; i++) { if (categories != NULL) gs_app_list_free (categories); categories = gs_plugin_loader_get_categories (plugin_loader, refine_flags, NULL, &error); if (categories == NULL) { ret = FALSE; break; } } } else if (argc == 3 && g_strcmp0 (argv[1], "get-category-apps") == 0) { g_autoptr(GsCategory) category = NULL; g_auto(GStrv) split = NULL; split = g_strsplit (argv[2], "/", 2); if (g_strv_length (split) == 1) { category = gs_category_new (NULL, split[0], NULL); } else { g_autoptr(GsCategory) parent = NULL; parent = gs_category_new (NULL, split[0], NULL); category = gs_category_new (parent, split[1], NULL); } for (i = 0; i < repeat; i++) { if (list != NULL) gs_app_list_free (list); list = gs_plugin_loader_get_category_apps (plugin_loader, category, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc >= 2 && g_strcmp0 (argv[1], "refresh") == 0) { GsPluginRefreshFlags refresh_flags; refresh_flags = gs_cmd_refresh_flag_from_string (argv[2]); ret = gs_plugin_loader_refresh (plugin_loader, cache_age, refresh_flags, NULL, &error); } else { ret = FALSE; g_set_error_literal (&error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Did not recognise option, use 'installed', " "'updates', 'popular', 'get-categories', " "'get-category-apps', 'filename-to-app', " "'sources', 'refresh', 'launch' or 'search'"); } if (!ret) { g_print ("Failed: %s\n", error->message); goto out; } if (show_results) { gs_cmd_show_results_apps (list); gs_cmd_show_results_categories (categories); } out: if (profile != NULL) as_profile_dump (profile); g_option_context_free (context); gs_app_list_free (list); gs_app_list_free (categories); return status; }
static gboolean apply_revision_override (RpmostreedTransaction *transaction, OstreeRepo *repo, OstreeAsyncProgress *progress, RpmOstreeSysrootUpgrader *upgrader, const char *revision, GCancellable *cancellable, GError **error) { g_autoptr(GKeyFile) origin = NULL; g_autofree char *checksum = NULL; g_autofree char *version = NULL; const char *refspec; origin = rpmostree_sysroot_upgrader_dup_origin (upgrader); if (origin == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Booted deployment has no origin"); return FALSE; } if (!rpmostreed_parse_revision (revision, &checksum, &version, error)) return FALSE; refspec = rpmostree_sysroot_upgrader_get_refspec (upgrader); if (refspec == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not find refspec for booted deployment"); return FALSE; } if (version != NULL) { rpmostreed_transaction_emit_message_printf (transaction, "Resolving version '%s'", version); if (!rpmostreed_repo_lookup_version (repo, refspec, version, progress, cancellable, &checksum, error)) return FALSE; } else { g_assert (checksum != NULL); rpmostreed_transaction_emit_message_printf (transaction, "Validating checksum '%s'", checksum); if (!rpmostreed_repo_lookup_checksum (repo, refspec, checksum, progress, cancellable, error)) return FALSE; } g_key_file_set_string (origin, "origin", "override-commit", checksum); if (version != NULL) { g_autofree char *comment = NULL; /* Add a comment with the version, to be nice. */ comment = g_strdup_printf ("Version %s [%.10s]", version, checksum); g_key_file_set_comment (origin, "origin", "override-commit", comment, NULL); } if (!rpmostree_sysroot_upgrader_set_origin (upgrader, origin, cancellable, error)) return FALSE; return TRUE; }
gboolean flatpak_complete_install (FlatpakCompletion *completion) { g_autoptr(GOptionContext) context = NULL; g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GError) error = NULL; g_auto(GStrv) refs = NULL; int i; context = g_option_context_new (""); if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv, 0, &dir, NULL, NULL)) return FALSE; if (!opt_app && !opt_runtime) opt_app = opt_runtime = TRUE; flatpak_completion_debug ("install argc %d", completion->argc); switch (completion->argc) { case 0: case 1: /* REMOTE */ flatpak_complete_options (completion, global_entries); flatpak_complete_options (completion, options); flatpak_complete_options (completion, user_entries); { g_auto(GStrv) remotes = flatpak_dir_list_remotes (dir, NULL, NULL); if (remotes == NULL) return FALSE; for (i = 0; remotes[i] != NULL; i++) flatpak_complete_word (completion, "%s ", remotes[i]); } break; case 2: /* Name */ refs = flatpak_dir_find_remote_refs (dir, completion->argv[1], NULL, NULL, opt_arch, opt_app, opt_runtime, NULL, &error); if (refs == NULL) flatpak_completion_debug ("find remote refs error: %s", error->message); for (i = 0; refs != NULL && refs[i] != NULL; i++) { g_auto(GStrv) parts = flatpak_decompose_ref (refs[i], NULL); if (parts) flatpak_complete_word (completion, "%s ", parts[1]); } break; case 3: /* Branch */ refs = flatpak_dir_find_remote_refs (dir, completion->argv[1], completion->argv[2], NULL, opt_arch, opt_app, opt_runtime, NULL, &error); if (refs == NULL) flatpak_completion_debug ("find remote refs error: %s", error->message); for (i = 0; refs != NULL && refs[i] != NULL; i++) { g_auto(GStrv) parts = flatpak_decompose_ref (refs[i], NULL); if (parts) flatpak_complete_word (completion, "%s ", parts[3]); } break; default: break; } return TRUE; }
gboolean fu_keyring_verify_file (FuKeyring *keyring, const gchar *filename, const gchar *signature, GError **error) { FuKeyringPrivate *priv = GET_PRIVATE (keyring); gboolean has_header; gpgme_error_t rc; gpgme_signature_t s; gpgme_verify_result_t result; g_auto(gpgme_data_t) data = NULL; g_auto(gpgme_data_t) sig = NULL; g_autoptr(GString) sig_v1 = NULL; g_return_val_if_fail (FU_IS_KEYRING (keyring), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (signature != NULL, FALSE); /* setup context */ if (!fu_keyring_setup (keyring, error)) return FALSE; /* has header already */ has_header = g_strstr_len (signature, -1, "BEGIN PGP SIGNATURE") != NULL; /* load file data */ rc = gpgme_data_new_from_file (&data, filename, 1); if (rc != GPG_ERR_NO_ERROR) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to load %s: %s", filename, gpgme_strerror (rc)); return FALSE; } /* load signature */ sig_v1 = g_string_new (""); if (!has_header) { g_string_append (sig_v1, "-----BEGIN PGP SIGNATURE-----\n"); g_string_append (sig_v1, "Version: GnuPG v1\n\n"); } g_string_append_printf (sig_v1, "%s\n", signature); if (!has_header) g_string_append (sig_v1, "-----END PGP SIGNATURE-----\n"); rc = gpgme_data_new_from_mem (&sig, sig_v1->str, sig_v1->len, 0); if (rc != GPG_ERR_NO_ERROR) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to load signature %s: %s", signature, gpgme_strerror (rc)); return FALSE; } /* verify */ rc = gpgme_op_verify (priv->ctx, sig, data, NULL); if (rc != GPG_ERR_NO_ERROR) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to verify %s: %s", filename, gpgme_strerror (rc)); return FALSE; } /* verify the result */ result = gpgme_op_verify_result (priv->ctx); if (result == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "no result record from libgpgme"); return FALSE; } /* look at each signature */ for (s = result->signatures; s != NULL ; s = s->next ) { g_debug ("returned signature fingerprint %s", s->fpr); if (!fu_keyring_check_signature (s, error)) return FALSE; } return TRUE; }
/** * xdg_app_review_parse_success: */ static gboolean xdg_app_review_parse_success (const gchar *data, gsize data_len, GError **error) { JsonNode *json_root; JsonObject *json_item; const gchar *msg = NULL; g_autoptr(JsonParser) json_parser = NULL; /* nothing */ if (data == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "server returned no data"); return FALSE; } /* parse the data and find the success */ json_parser = json_parser_new (); if (!json_parser_load_from_data (json_parser, data, data_len, error)) return FALSE; json_root = json_parser_get_root (json_parser); if (json_root == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no error root"); return FALSE; } if (json_node_get_node_type (json_root) != JSON_NODE_OBJECT) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no error object"); return FALSE; } json_item = json_node_get_object (json_root); if (json_item == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no error object"); return FALSE; } /* failed? */ if (json_object_has_member (json_item, "msg")) msg = json_object_get_string_member (json_item, "msg"); if (!json_object_get_boolean_member (json_item, "success")) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, msg != NULL ? msg : "unknown failure"); return FALSE; } /* just for the console */ if (msg != NULL) g_debug ("success: %s", msg); return TRUE; }
gboolean xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; g_autoptr(XdgAppDeploy) app_deploy = NULL; g_autoptr(XdgAppDeploy) runtime_deploy = NULL; g_autoptr(GFile) app_files = NULL; g_autoptr(GFile) runtime_files = NULL; g_autoptr(GFile) app_id_dir = NULL; g_autoptr(GFile) app_cache_dir = NULL; g_autoptr(GFile) app_data_dir = NULL; g_autoptr(GFile) app_config_dir = NULL; g_autoptr(GFile) home = NULL; g_autoptr(GFile) user_font1 = NULL; g_autoptr(GFile) user_font2 = NULL; g_autoptr(XdgAppSessionHelper) session_helper = NULL; g_autofree char *runtime = NULL; g_autofree char *default_command = NULL; g_autofree char *runtime_ref = NULL; g_autofree char *app_ref = NULL; g_autofree char *doc_mount_path = NULL; g_autoptr(GKeyFile) metakey = NULL; g_autoptr(GKeyFile) runtime_metakey = NULL; g_autoptr(GPtrArray) argv_array = NULL; g_auto(GStrv) envp = NULL; g_autoptr(GPtrArray) dbus_proxy_argv = NULL; g_autofree char *monitor_path = NULL; const char *app; const char *branch = "master"; const char *command = "/bin/sh"; int i; int rest_argv_start, rest_argc; int sync_proxy_pipes[2]; g_autoptr(XdgAppContext) arg_context = NULL; g_autoptr(XdgAppContext) app_context = NULL; g_autoptr(XdgAppContext) overrides = NULL; g_autoptr(GDBusConnection) session_bus = NULL; context = g_option_context_new ("APP [args...] - Run an app"); rest_argc = 0; for (i = 1; i < argc; i++) { /* The non-option is the command, take it out of the arguments */ if (argv[i][0] != '-') { rest_argv_start = i; rest_argc = argc - i; argc = i; break; } } arg_context = xdg_app_context_new (); g_option_context_add_group (context, xdg_app_context_get_options (arg_context)); if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) return FALSE; if (rest_argc == 0) return usage_error (context, "APP must be specified", error); app = argv[rest_argv_start]; if (opt_branch) branch = opt_branch; if (!xdg_app_is_valid_name (app)) return xdg_app_fail (error, "'%s' is not a valid application name", app); if (!xdg_app_is_valid_branch (branch)) return xdg_app_fail (error, "'%s' is not a valid branch name", branch); app_ref = xdg_app_build_app_ref (app, branch, opt_arch); app_deploy = xdg_app_find_deploy_for_ref (app_ref, cancellable, error); if (app_deploy == NULL) return FALSE; metakey = xdg_app_deploy_get_metadata (app_deploy); argv_array = g_ptr_array_new_with_free_func (g_free); dbus_proxy_argv = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (argv_array, g_strdup (HELPER)); g_ptr_array_add (argv_array, g_strdup ("-l")); if (!xdg_app_run_add_extension_args (argv_array, metakey, app_ref, cancellable, error)) return FALSE; if (opt_runtime) runtime = opt_runtime; else { runtime = g_key_file_get_string (metakey, "Application", opt_devel ? "sdk" : "runtime", error); if (*error) return FALSE; } runtime_ref = g_build_filename ("runtime", runtime, NULL); runtime_deploy = xdg_app_find_deploy_for_ref (runtime_ref, cancellable, error); if (runtime_deploy == NULL) return FALSE; runtime_metakey = xdg_app_deploy_get_metadata (runtime_deploy); app_context = xdg_app_context_new (); if (!xdg_app_context_load_metadata (app_context, runtime_metakey, error)) return FALSE; if (!xdg_app_context_load_metadata (app_context, metakey, error)) return FALSE; overrides = xdg_app_deploy_get_overrides (app_deploy); xdg_app_context_merge (app_context, overrides); xdg_app_context_merge (app_context, arg_context); if (!xdg_app_run_add_extension_args (argv_array, runtime_metakey, runtime_ref, cancellable, error)) return FALSE; if ((app_id_dir = xdg_app_ensure_data_dir (app, cancellable, error)) == NULL) return FALSE; app_cache_dir = g_file_get_child (app_id_dir, "cache"); g_ptr_array_add (argv_array, g_strdup ("-B")); g_ptr_array_add (argv_array, g_strdup_printf ("/var/cache=%s", gs_file_get_path_cached (app_cache_dir))); app_data_dir = g_file_get_child (app_id_dir, "data"); g_ptr_array_add (argv_array, g_strdup ("-B")); g_ptr_array_add (argv_array, g_strdup_printf ("/var/data=%s", gs_file_get_path_cached (app_data_dir))); app_config_dir = g_file_get_child (app_id_dir, "config"); g_ptr_array_add (argv_array, g_strdup ("-B")); g_ptr_array_add (argv_array, g_strdup_printf ("/var/config=%s", gs_file_get_path_cached (app_config_dir))); app_files = xdg_app_deploy_get_files (app_deploy); runtime_files = xdg_app_deploy_get_files (runtime_deploy); default_command = g_key_file_get_string (metakey, "Application", "command", error); if (*error) return FALSE; if (opt_command) command = opt_command; else command = default_command; session_helper = xdg_app_session_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, "org.freedesktop.XdgApp", "/org/freedesktop/XdgApp/SessionHelper", NULL, NULL); if (session_helper && xdg_app_session_helper_call_request_monitor_sync (session_helper, &monitor_path, NULL, NULL)) { g_ptr_array_add (argv_array, g_strdup ("-m")); g_ptr_array_add (argv_array, monitor_path); } else g_ptr_array_add (argv_array, g_strdup ("-r")); session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if (session_bus) { g_autoptr (GError) local_error = NULL; g_autoptr (GDBusMessage) reply = NULL; g_autoptr (GDBusMessage) msg = g_dbus_message_new_method_call ("org.freedesktop.portal.Documents", "/org/freedesktop/portal/documents", "org.freedesktop.portal.Documents", "GetMountPoint"); g_dbus_message_set_body (msg, g_variant_new ("()")); reply = g_dbus_connection_send_message_with_reply_sync (session_bus, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 30000, NULL, NULL, NULL); if (reply) { if (g_dbus_message_to_gerror (reply, &local_error)) { g_warning ("Can't get document portal: %s\n", local_error->message); } else g_variant_get (g_dbus_message_get_body (reply), "(^ay)", &doc_mount_path); } } xdg_app_run_add_environment_args (argv_array, dbus_proxy_argv, doc_mount_path, app, app_context, app_id_dir); g_ptr_array_add (argv_array, g_strdup ("-b")); g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/fonts=%s", SYSTEM_FONTS_DIR)); if (opt_devel) g_ptr_array_add (argv_array, g_strdup ("-c")); home = g_file_new_for_path (g_get_home_dir ()); user_font1 = g_file_resolve_relative_path (home, ".local/share/fonts"); user_font2 = g_file_resolve_relative_path (home, ".fonts"); if (g_file_query_exists (user_font1, NULL)) { g_autofree char *path = g_file_get_path (user_font1); g_ptr_array_add (argv_array, g_strdup ("-b")); g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path)); } else if (g_file_query_exists (user_font2, NULL)) { g_autofree char *path = g_file_get_path (user_font2); g_ptr_array_add (argv_array, g_strdup ("-b")); g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path)); } /* Must run this before spawning the dbus proxy, to ensure it ends up in the app cgroup */ xdg_app_run_in_transient_unit (app); if (dbus_proxy_argv->len > 0) { char x; if (pipe (sync_proxy_pipes) < 0) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to create sync pipe"); return FALSE; } g_ptr_array_insert (dbus_proxy_argv, 0, g_strdup (DBUSPROXY)); g_ptr_array_insert (dbus_proxy_argv, 1, g_strdup_printf ("--fd=%d", sync_proxy_pipes[1])); g_ptr_array_add (dbus_proxy_argv, NULL); /* NULL terminate */ if (!g_spawn_async (NULL, (char **)dbus_proxy_argv->pdata, NULL, G_SPAWN_SEARCH_PATH, dbus_spawn_child_setup, GINT_TO_POINTER (sync_proxy_pipes[1]), NULL, error)) return FALSE; close (sync_proxy_pipes[1]); /* Sync with proxy, i.e. wait until its listening on the sockets */ if (read (sync_proxy_pipes[0], &x, 1) != 1) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Failed to sync with dbus proxy"); return FALSE; } g_ptr_array_add (argv_array, g_strdup ("-S")); g_ptr_array_add (argv_array, g_strdup_printf ("%d", sync_proxy_pipes[0])); } g_ptr_array_add (argv_array, g_strdup ("-a")); g_ptr_array_add (argv_array, g_file_get_path (app_files)); g_ptr_array_add (argv_array, g_strdup ("-I")); g_ptr_array_add (argv_array, g_strdup (app)); g_ptr_array_add (argv_array, g_file_get_path (runtime_files)); g_ptr_array_add (argv_array, g_strdup (command)); for (i = 1; i < rest_argc; i++) g_ptr_array_add (argv_array, g_strdup (argv[rest_argv_start + i])); g_ptr_array_add (argv_array, NULL); envp = g_get_environ (); envp = xdg_app_run_apply_env_default (envp); envp = xdg_app_run_apply_env_vars (envp, app_context); envp = xdg_app_run_apply_env_appid (envp, app_id_dir); if (execvpe (HELPER, (char **)argv_array->pdata, envp) == -1) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to start app"); return FALSE; } /* Not actually reached... */ return TRUE; }
/** * xdg_app_review_get_ratings: */ static GArray * xdg_app_review_get_ratings (GsPlugin *plugin, GsApp *app, GError **error) { GArray *ratings; guint status_code; g_autofree gchar *cachedir = NULL; g_autofree gchar *cachefn = NULL; g_autofree gchar *data = NULL; g_autofree gchar *uri = NULL; g_autoptr(GFile) cachefn_file = NULL; g_autoptr(SoupMessage) msg = NULL; /* look in the cache */ cachedir = gs_utils_get_cachedir ("ratings", error); if (cachedir == NULL) return NULL; cachefn = g_strdup_printf ("%s/%s.json", cachedir, gs_app_get_id_no_prefix (app)); cachefn_file = g_file_new_for_path (cachefn); if (gs_utils_get_file_age (cachefn_file) < XDG_APP_REVIEW_CACHE_AGE_MAX) { g_autofree gchar *json_data = NULL; if (!g_file_get_contents (cachefn, &json_data, NULL, error)) return NULL; g_debug ("got ratings data for %s from %s", gs_app_get_id_no_prefix (app), cachefn); return xdg_app_review_parse_ratings (json_data, -1, error); } /* create the GET data *with* the machine hash so we can later * review the application ourselves */ uri = g_strdup_printf ("%s/ratings/%s", plugin->priv->review_server, gs_app_get_id_no_prefix (app)); msg = soup_message_new (SOUP_METHOD_GET, uri); status_code = soup_session_send_message (plugin->soup_session, msg); if (status_code != SOUP_STATUS_OK) { if (!xdg_app_review_parse_success (msg->response_body->data, msg->response_body->length, error)) return NULL; /* not sure what to do here */ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "status code invalid"); return NULL; } g_debug ("xdg-app-review returned: %s", msg->response_body->data); ratings = xdg_app_review_parse_ratings (msg->response_body->data, msg->response_body->length, error); if (ratings == NULL) return NULL; /* save to the cache */ if (!g_file_set_contents (cachefn, msg->response_body->data, msg->response_body->length, error)) return NULL; return ratings; }
void gs_screenshot_image_load_async (GsScreenshotImage *ssimg, GCancellable *cancellable) { AsImage *im = NULL; const gchar *url; g_autofree gchar *basename = NULL; g_autofree gchar *cache_kind = NULL; g_autofree gchar *cachefn_thumb = NULL; g_autofree gchar *sizedir = NULL; g_autoptr(SoupURI) base_uri = NULL; g_return_if_fail (GS_IS_SCREENSHOT_IMAGE (ssimg)); g_return_if_fail (AS_IS_SCREENSHOT (ssimg->screenshot)); g_return_if_fail (ssimg->width != 0); g_return_if_fail (ssimg->height != 0); /* load an image according to the scale factor */ ssimg->scale = (guint) gtk_widget_get_scale_factor (GTK_WIDGET (ssimg)); im = as_screenshot_get_image (ssimg->screenshot, ssimg->width * ssimg->scale, ssimg->height * ssimg->scale); /* if we've failed to load a HiDPI image, fallback to LoDPI */ if (im == NULL && ssimg->scale > 1) { ssimg->scale = 1; im = as_screenshot_get_image (ssimg->screenshot, ssimg->width, ssimg->height); } if (im == NULL) { /* TRANSLATORS: this is when we request a screenshot size that * the generator did not create or the parser did not add */ gs_screenshot_image_set_error (ssimg, _("Screenshot size not found")); return; } /* check if the URL points to a local file */ url = as_image_get_url (im); if (g_str_has_prefix (url, "file://")) { g_free (ssimg->filename); ssimg->filename = g_strdup (url + 7); if (g_file_test (ssimg->filename, G_FILE_TEST_EXISTS)) { as_screenshot_show_image (ssimg); return; } } basename = gs_screenshot_get_cachefn_for_url (url); if (ssimg->width == G_MAXUINT || ssimg->height == G_MAXUINT) { sizedir = g_strdup ("unknown"); } else { sizedir = g_strdup_printf ("%ux%u", ssimg->width * ssimg->scale, ssimg->height * ssimg->scale); } cache_kind = g_build_filename ("screenshots", sizedir, NULL); g_free (ssimg->filename); ssimg->filename = gs_utils_get_cache_filename (cache_kind, basename, GS_UTILS_CACHE_FLAG_NONE, NULL); if (ssimg->filename == NULL) { /* TRANSLATORS: this is when we try create the cache directory * but we were out of space or permission was denied */ gs_screenshot_image_set_error (ssimg, _("Could not create cache")); return; } /* does local file already exist and has recently been downloaded */ if (g_file_test (ssimg->filename, G_FILE_TEST_EXISTS)) { guint64 age_max; g_autoptr(GFile) file = NULL; /* show the image we have in cache while we're checking for the * new screenshot (which probably won't have changed) */ as_screenshot_show_image (ssimg); /* verify the cache age against the maximum allowed */ age_max = g_settings_get_uint (ssimg->settings, "screenshot-cache-age-maximum"); file = g_file_new_for_path (ssimg->filename); /* image new enough, not re-requesting from server */ if (age_max > 0 && gs_utils_get_file_age (file) < age_max) return; } /* if we're not showing a full-size image, we try loading a blurred * smaller version of it straight away */ if (!ssimg->showing_image && ssimg->width > AS_IMAGE_THUMBNAIL_WIDTH && ssimg->height > AS_IMAGE_THUMBNAIL_HEIGHT) { const gchar *url_thumb; g_autofree gchar *basename_thumb = NULL; g_autofree gchar *cache_kind_thumb = NULL; im = as_screenshot_get_image (ssimg->screenshot, AS_IMAGE_THUMBNAIL_WIDTH * ssimg->scale, AS_IMAGE_THUMBNAIL_HEIGHT * ssimg->scale); url_thumb = as_image_get_url (im); basename_thumb = gs_screenshot_get_cachefn_for_url (url_thumb); cache_kind_thumb = g_build_filename ("screenshots", "112x63", NULL); cachefn_thumb = gs_utils_get_cache_filename (cache_kind_thumb, basename_thumb, GS_UTILS_CACHE_FLAG_NONE, NULL); if (cachefn_thumb == NULL) return; if (g_file_test (cachefn_thumb, G_FILE_TEST_EXISTS)) gs_screenshot_image_show_blurred (ssimg, cachefn_thumb); } /* re-request the cache filename, which might be different as it needs * to be writable this time */ g_free (ssimg->filename); ssimg->filename = gs_utils_get_cache_filename (cache_kind, basename, GS_UTILS_CACHE_FLAG_WRITEABLE, NULL); /* download file */ g_debug ("downloading %s to %s", url, ssimg->filename); base_uri = soup_uri_new (url); if (base_uri == NULL || !SOUP_URI_VALID_FOR_HTTP (base_uri)) { /* TRANSLATORS: this is when we try to download a screenshot * that was not a valid URL */ gs_screenshot_image_set_error (ssimg, _("Screenshot not valid")); return; } /* cancel any previous messages */ if (ssimg->message != NULL) { soup_session_cancel_message (ssimg->session, ssimg->message, SOUP_STATUS_CANCELLED); g_clear_object (&ssimg->message); } ssimg->message = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); if (ssimg->message == NULL) { /* TRANSLATORS: this is when networking is not available */ gs_screenshot_image_set_error (ssimg, _("Screenshot not available")); return; } /* not all servers support If-Modified-Since, but worst case we just * re-download the entire file again every 30 days */ if (g_file_test (ssimg->filename, G_FILE_TEST_EXISTS)) { g_autoptr(GFile) file = g_file_new_for_path (ssimg->filename); gs_screenshot_soup_msg_set_modified_request (ssimg->message, file); } /* send async */ soup_session_queue_message (ssimg->session, g_object_ref (ssimg->message) /* transfer full */, gs_screenshot_image_complete_cb, g_object_ref (ssimg)); }