Add functions to help simplify parsing of command line arguments as well as files containing shell-style variables. These functions will parse strings where values either stand alone or are of the key=value format. The idea is to reduce the code surrounding /proc/cmdline handling as well as add in support for easy parsing of files containing shell variables (e.g., ifcfg files). --- loader/Makefile.am | 5 +- loader/readvars.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++ loader/readvars.h | 29 ++++++++++++ 3 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 loader/readvars.c create mode 100644 loader/readvars.h diff --git a/loader/Makefile.am b/loader/Makefile.am index 306ef11..0d52fe7 100644 --- a/loader/Makefile.am +++ b/loader/Makefile.am @@ -54,11 +54,12 @@ loader_SOURCES = loader.c copy.c moduleinfo.c loadermisc.c \ getparts.c dirbrowser.c fwloader.c ibft.c hardware.c \ method.c cdinstall.c hdinstall.c nfsinstall.c \ urlinstall.c net.c urls.c telnet.c telnetd.c \ - rpmextract.c + rpmextract.c readvars.c init_CFLAGS = $(COMMON_CFLAGS) $(GLIB_CFLAGS) init_LDADD = $(GLIB_LIBS) $(top_srcdir)/pyanaconda/isys/libisys.la -init_SOURCES = init.c undomounts.c shutdown.c copy.c modules.c +init_SOURCES = init.c undomounts.c shutdown.c copy.c modules.c \ + readvars.c shutdown_CFLAGS = $(COMMON_CFLAGS) -DAS_SHUTDOWN=1 shutdown_SOURCES = shutdown.c undomounts.c diff --git a/loader/readvars.c b/loader/readvars.c new file mode 100644 index 0000000..b453175 --- /dev/null +++ b/loader/readvars.c @@ -0,0 +1,125 @@ +/* + * readvars.c + * Copyright (C) 2009, 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> + */ + +#include <stdio.h> +#include <ctype.h> +#include <glib.h> + +#include "../pyanaconda/isys/log.h" + +/* + * Given a string with shell-style variables listed (e.g., the contents of an + * /etc/sysconfig file), parse the contents and generate a hash table of the + * variables read. Return the hash table to the caller. Caller is + * responsible for freeing memory associated with the hash table: + * + * table = readvars_read_conf("VAR1=val1\nVAR2=val2\n"); + * g_hash_table_destroy(table); + * + * Errors encountered during parsing will result in this function returning + * NULL. + * + * Variables can also be standalone (done so this function can parse the + * contents of /proc/cmdline). If they lack a value and are just in the + * string as a single token, they will become a hash table key with an + * NULL value. + */ +GHashTable *readvars_parse_string(gchar *contents) { + gint argc = 0, i = 0; + gchar **argv = NULL; + GError *e = NULL; + GHashTable *conf = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_free); + + if (contents == NULL) { + return NULL; + } + + if (!g_shell_parse_argv(contents, &argc, &argv, &e)) { + if (e != NULL) { + logMessage(ERROR, "%s(%d): %s", __func__, __LINE__, e->message); + g_error_free(e); + } + + return NULL; + } + + while (i < argc) { + gchar **tokens = g_strsplit(argv[i], "=", 0); + guint len = g_strv_length(tokens); + gchar *key = NULL, *value = NULL; + e = NULL; + + if (len == 1 || len == 2) { + key = g_strdup(tokens[0]); + } + + if (len == 2) { + value = g_shell_unquote(tokens[1], &e); + + if (value == NULL && e != NULL) { + logMessage(ERROR, "%s(%d): %s", __func__, __LINE__, + e->message); + g_error_free(e); + } + } + + if (key != NULL) { + g_hash_table_insert(conf, key, value); + } + + g_strfreev(tokens); + i++; + } + + g_strfreev(argv); + return conf; +} + +/* + * Read contents of file and call readvars_parse_string() with that string, + * caller is responsible for cleanup in the same style as + * readvars_parse_string(). + */ +GHashTable *readvars_parse_file(gchar *filename) { + gsize len = 0; + gchar *input = NULL; + GError *e = NULL; + GHashTable *ret = NULL; + + if (filename == NULL) { + return NULL; + } + + if (!g_file_get_contents(filename, &input, &len, &e)) { + if (e != NULL) { + logMessage(ERROR, "%s(%d): %s", __func__, __LINE__, e->message); + g_error_free(e); + } + + g_free(input); + return NULL; + } + + ret = readvars_parse_string(input); + g_free(input); + + return ret; +} diff --git a/loader/readvars.h b/loader/readvars.h new file mode 100644 index 0000000..8938c04 --- /dev/null +++ b/loader/readvars.h @@ -0,0 +1,29 @@ +/* + * readvars.h + * Copyright (C) 2009, 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> + */ + +#include <glib.h> + +#ifndef READVARS_H +#define READVARS_H + +GHashTable *readvars_parse_string(gchar *); +GHashTable *readvars_parse_file(gchar *); + +#endif -- 1.7.1.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list