gboolean ostree_bootconfig_parser_write (OstreeBootconfigParser *self, GFile *output, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GHashTableIter hashiter; gpointer hashkey, hashvalue; GString *buf = g_string_new (""); gs_unref_bytes GBytes *bytes = NULL; guint i; gs_unref_hashtable GHashTable *written_overrides = NULL; written_overrides = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < self->lines->len; i++) { GVariant *linedata = self->lines->pdata[i]; const char *key; const char *value; const char *line; g_variant_get (linedata, "(&s&s)", &key, &line); value = g_hash_table_lookup (self->options, key); if (value == NULL) { g_string_append (buf, line); g_string_append_c (buf, '\n'); } else { write_key (self, buf, key, value); g_hash_table_insert (written_overrides, (gpointer)key, (gpointer)key); } } g_hash_table_iter_init (&hashiter, self->options); while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)) { if (g_hash_table_lookup (written_overrides, hashkey)) continue; write_key (self, buf, hashkey, hashvalue); } bytes = g_string_free_to_bytes (buf); buf = NULL; if (!ot_gfile_replace_contents_fsync (output, bytes, cancellable, error)) goto out; ret = TRUE; out: if (buf) g_string_free (buf, TRUE); return ret; }
static gboolean _ostree_bootloader_uboot_write_config (OstreeBootloader *bootloader, int bootversion, GCancellable *cancellable, GError **error) { OstreeBootloaderUboot *self = OSTREE_BOOTLOADER_UBOOT (bootloader); g_autoptr(GFile) new_config_path = NULL; g_autofree char *config_contents = NULL; g_autofree char *new_config_contents = NULL; g_autoptr(GPtrArray) new_lines = NULL; /* This should follow the symbolic link to the current bootversion. */ config_contents = glnx_file_get_contents_utf8_at (AT_FDCWD, gs_file_get_path_cached (self->config_path), NULL, cancellable, error); if (!config_contents) return FALSE; new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, "boot/loader.%d/uEnv.txt", bootversion); new_lines = g_ptr_array_new_with_free_func (g_free); if (!create_config_from_boot_loader_entries (self, bootversion, new_lines, cancellable, error)) return FALSE; new_config_contents = _ostree_sysroot_join_lines (new_lines); { g_autoptr(GBytes) new_config_contents_bytes = g_bytes_new_static (new_config_contents, strlen (new_config_contents)); if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes, cancellable, error)) return FALSE; } return TRUE; }
static gboolean _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, int bootversion, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; OstreeBootloaderSyslinux *self = OSTREE_BOOTLOADER_SYSLINUX (bootloader); gs_unref_object GFile *new_config_path = NULL; gs_free char *config_contents = NULL; gs_free char *new_config_contents = NULL; gs_unref_ptrarray GPtrArray *new_lines = NULL; gs_unref_ptrarray GPtrArray *tmp_lines = NULL; gs_free char *kernel_arg = NULL; gboolean saw_default = FALSE; gboolean regenerate_default = FALSE; gboolean parsing_label = FALSE; char **lines = NULL; char **iter; guint i; new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, "boot/loader.%d/syslinux.cfg", bootversion); /* This should follow the symbolic link to the current bootversion. */ config_contents = gs_file_load_contents_utf8 (self->config_path, cancellable, error); if (!config_contents) goto out; lines = g_strsplit (config_contents, "\n", -1); new_lines = g_ptr_array_new_with_free_func (g_free); tmp_lines = g_ptr_array_new_with_free_func (g_free); /* Note special iteration condition here; we want to also loop one * more time at the end where line = NULL to ensure we finish off * processing the last LABEL. */ iter = lines; while (TRUE) { char *line = *iter; gboolean skip = FALSE; if (parsing_label && (line == NULL || !g_str_has_prefix (line, "\t"))) { parsing_label = FALSE; if (kernel_arg == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No KERNEL argument found after LABEL"); goto out; } /* If this is a non-ostree kernel, just emit the lines * we saw. */ if (!g_str_has_prefix (kernel_arg, "/ostree/")) { for (i = 0; i < tmp_lines->len; i++) { g_ptr_array_add (new_lines, tmp_lines->pdata[i]); tmp_lines->pdata[i] = NULL; /* Transfer ownership */ } } else { /* Otherwise, we drop the config on the floor - it * will be regenerated. */ g_ptr_array_set_size (tmp_lines, 0); } } if (line == NULL) break; if (!parsing_label && (g_str_has_prefix (line, "LABEL "))) { parsing_label = TRUE; g_ptr_array_set_size (tmp_lines, 0); } else if (parsing_label && g_str_has_prefix (line, "\tKERNEL ")) { g_free (kernel_arg); kernel_arg = g_strdup (line + strlen ("\tKERNEL ")); } else if (!parsing_label && (g_str_has_prefix (line, "DEFAULT "))) { saw_default = TRUE; /* XXX Searching for patterns in the title is rather brittle, * but this hack is at least noted in the code that builds * the title to hopefully avoid regressions. */ if (g_str_has_prefix (line, "DEFAULT ostree:") || /* old format */ strstr (line, "(ostree") != NULL) /* new format */ { regenerate_default = TRUE; } skip = TRUE; } if (skip) { g_free (line); } else { if (parsing_label) { g_ptr_array_add (tmp_lines, line); } else { g_ptr_array_add (new_lines, line); } } /* Transfer ownership */ *iter = NULL; iter++; } if (!saw_default) regenerate_default = TRUE; if (!append_config_from_boostree_loader_entries (self, regenerate_default, bootversion, new_lines, cancellable, error)) goto out; new_config_contents = _ostree_sysroot_join_lines (new_lines); { gs_unref_bytes GBytes *new_config_contents_bytes = g_bytes_new_static (new_config_contents, strlen (new_config_contents)); if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes, cancellable, error)) goto out; } ret = TRUE; out: g_free (lines); /* Note we freed elements individually */ return ret; }