diff options
author | Colin Walters <walters@verbum.org> | 2014-01-16 13:04:00 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2014-01-16 15:07:55 -0500 |
commit | b2d0ba7ac1e742586eeb3018d88e01dc436d5b4d (patch) | |
tree | 01abcbdef606c1587e9a3ade713a08511debdd89 /src/libostree/ostree-kernel-args.c | |
parent | 7db2031fa06621d0564f859776e072130d49a867 (diff) | |
download | ostree-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.c | 263 |
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]; +} |