summaryrefslogtreecommitdiff
path: root/src/libostree/ostree-kernel-args.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2014-01-16 13:04:00 -0500
committerColin Walters <walters@verbum.org>2014-01-16 15:07:55 -0500
commitb2d0ba7ac1e742586eeb3018d88e01dc436d5b4d (patch)
tree01abcbdef606c1587e9a3ade713a08511debdd89 /src/libostree/ostree-kernel-args.c
parent7db2031fa06621d0564f859776e072130d49a867 (diff)
downloadostree-b2d0ba7ac1e742586eeb3018d88e01dc436d5b4d.tar.gz
deploy: Rework kernel arguments, add --karg-append to "admin deploy"
The "ordered hash" code was really just for kernel arguments. And it turns out it needs to be a multihash (for e.g. multiple console= arguments). So turn the OstreeOrderedHash into OstreeKernelArgs, and move the bits to split key=value and such into there. Now we're not making this public API yet - the public OstreeSysroot just takes char **kargs. To facilitate code reuse between ostree/ and libostree/, make it a noinst libtool library. It'll be duplicated in the binary and library, but that's OK for now. We can investigate making OstreeKernelArgs public later. https://bugzilla.gnome.org/show_bug.cgi?id=721136
Diffstat (limited to 'src/libostree/ostree-kernel-args.c')
-rw-r--r--src/libostree/ostree-kernel-args.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/libostree/ostree-kernel-args.c b/src/libostree/ostree-kernel-args.c
new file mode 100644
index 00000000..f31932ed
--- /dev/null
+++ b/src/libostree/ostree-kernel-args.c
@@ -0,0 +1,263 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2013,2014 Colin Walters <walters@verbum.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ostree-kernel-args.h"
+
+#include <string.h>
+
+struct _OstreeKernelArgs {
+ GPtrArray *order;
+ GHashTable *table;
+};
+
+static char *
+split_keyeq (char *arg)
+{
+ char *eq;
+
+ eq = strchr (arg, '=');
+ if (eq)
+ {
+ /* Note key/val are in one malloc block,
+ * so we don't free val...
+ */
+ *eq = '\0';
+ return eq+1;
+ }
+ else
+ {
+ /* ...and this allows us to insert a constant
+ * string.
+ */
+ return "";
+ }
+}
+
+OstreeKernelArgs *
+_ostree_kernel_args_new (void)
+{
+ OstreeKernelArgs *ret;
+ ret = g_new0 (OstreeKernelArgs, 1);
+ ret->order = g_ptr_array_new_with_free_func (g_free);
+ ret->table = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, (GDestroyNotify)g_ptr_array_unref);
+ return ret;
+}
+
+void
+_ostree_kernel_args_free (OstreeKernelArgs *kargs)
+{
+ if (!kargs)
+ return;
+ g_ptr_array_unref (kargs->order);
+ g_hash_table_unref (kargs->table);
+ g_free (kargs);
+}
+
+void
+_ostree_kernel_args_cleanup (void *loc)
+{
+ _ostree_kernel_args_free (*((OstreeKernelArgs**)loc));
+}
+
+void
+_ostree_kernel_args_replace_take (OstreeKernelArgs *kargs,
+ char *arg)
+{
+ gboolean existed;
+ GPtrArray *values = g_ptr_array_new_with_free_func (g_free);
+ const char *value = split_keyeq (arg);
+
+ existed = g_hash_table_remove (kargs->table, arg);
+ if (!existed)
+ g_ptr_array_add (kargs->order, arg);
+ g_ptr_array_add (values, g_strdup (value));
+ g_hash_table_replace (kargs->table, arg, values);
+}
+
+void
+_ostree_kernel_args_replace (OstreeKernelArgs *kargs,
+ const char *arg)
+{
+ _ostree_kernel_args_replace_take (kargs, g_strdup (arg));
+}
+
+void
+_ostree_kernel_args_append (OstreeKernelArgs *kargs,
+ const char *arg)
+{
+ gboolean existed = TRUE;
+ GPtrArray *values;
+ char *duped = g_strdup (arg);
+ const char *val = split_keyeq (duped);
+
+ values = g_hash_table_lookup (kargs->table, duped);
+ if (!values)
+ {
+ values = g_ptr_array_new_with_free_func (g_free);
+ existed = FALSE;
+ }
+
+ g_ptr_array_add (values, g_strdup (val));
+
+ if (!existed)
+ {
+ g_hash_table_replace (kargs->table, duped, values);
+ g_ptr_array_add (kargs->order, duped);
+ }
+ else
+ {
+ g_free (duped);
+ }
+}
+
+void
+_ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs,
+ char **argv)
+{
+ char **strviter;
+
+ for (strviter = argv; strviter && *strviter; strviter++)
+ {
+ const char *arg = *strviter;
+ _ostree_kernel_args_replace (kargs, arg);
+ }
+}
+
+void
+_ostree_kernel_args_append_argv (OstreeKernelArgs *kargs,
+ char **argv)
+{
+ char **strviter;
+
+ for (strviter = argv; strviter && *strviter; strviter++)
+ {
+ const char *arg = *strviter;
+ _ostree_kernel_args_append (kargs, arg);
+ }
+}
+
+void
+_ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
+ const char *options)
+{
+ char **args = NULL;
+ char **iter;
+
+ if (!options)
+ return;
+
+ args = g_strsplit (options, " ", -1);
+ for (iter = args; *iter; iter++)
+ {
+ char *arg = *iter;
+ _ostree_kernel_args_append (kargs, arg);
+ }
+ g_strfreev (args);
+}
+
+OstreeKernelArgs *
+_ostree_kernel_args_from_string (const char *options)
+{
+ OstreeKernelArgs *ret;
+
+ ret = _ostree_kernel_args_new ();
+ _ostree_kernel_args_parse_append (ret, options);
+
+ return ret;
+}
+
+char **
+_ostree_kernel_args_to_strv (OstreeKernelArgs *kargs)
+{
+ GPtrArray *strv = g_ptr_array_new ();
+ guint i;
+
+ for (i = 0; i < kargs->order->len; i++)
+ {
+ const char *key = kargs->order->pdata[i];
+ GPtrArray *values = g_hash_table_lookup (kargs->table, key);
+ guint j;
+
+ g_assert (values != NULL);
+
+ for (j = 0; j < values->len; j++)
+ {
+ const char *value = values->pdata[j];
+
+ g_ptr_array_add (strv, g_strconcat (key, "=", value, NULL));
+ }
+ }
+ g_ptr_array_add (strv, NULL);
+
+ return (char**)g_ptr_array_free (strv, FALSE);
+}
+
+char *
+_ostree_kernel_args_to_string (OstreeKernelArgs *kargs)
+{
+ GString *buf = g_string_new ("");
+ gboolean first = TRUE;
+ guint i;
+
+ for (i = 0; i < kargs->order->len; i++)
+ {
+ const char *key = kargs->order->pdata[i];
+ GPtrArray *values = g_hash_table_lookup (kargs->table, key);
+ guint j;
+
+ g_assert (values != NULL);
+
+ for (j = 0; j < values->len; j++)
+ {
+ const char *value = values->pdata[j];
+
+ if (first)
+ first = FALSE;
+ else
+ g_string_append_c (buf, ' ');
+
+ if (value && *value)
+ {
+ g_string_append (buf, key);
+ g_string_append_c (buf, '=');
+ g_string_append (buf, value);
+ }
+ else
+ g_string_append (buf, key);
+ }
+ }
+
+ return g_string_free (buf, FALSE);
+}
+
+const char *
+_ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
+{
+ GPtrArray *values = g_hash_table_lookup (kargs->table, key);
+
+ if (!values)
+ return NULL;
+
+ g_assert (values->len > 0);
+ return (char*)values->pdata[values->len-1];
+}