Merge pull request #125 from ifupdown-ng/feature/ifparse
YAML output support
This commit is contained in:
commit
9715b41c28
12 changed files with 666 additions and 43 deletions
25
Makefile
25
Makefile
|
@ -39,8 +39,7 @@ LIBIFUPDOWN_SRC = \
|
||||||
libifupdown/lifecycle.c \
|
libifupdown/lifecycle.c \
|
||||||
libifupdown/config-parser.c \
|
libifupdown/config-parser.c \
|
||||||
libifupdown/config-file.c \
|
libifupdown/config-file.c \
|
||||||
libifupdown/compat.c \
|
libifupdown/compat.c
|
||||||
|
|
||||||
LIBIFUPDOWN_OBJ = ${LIBIFUPDOWN_SRC:.c=.o}
|
LIBIFUPDOWN_OBJ = ${LIBIFUPDOWN_SRC:.c=.o}
|
||||||
LIBIFUPDOWN_LIB = libifupdown.a
|
LIBIFUPDOWN_LIB = libifupdown.a
|
||||||
|
|
||||||
|
@ -48,7 +47,8 @@ MULTICALL_SRC = \
|
||||||
cmd/multicall.c \
|
cmd/multicall.c \
|
||||||
cmd/multicall-options.c \
|
cmd/multicall-options.c \
|
||||||
cmd/multicall-exec-options.c \
|
cmd/multicall-exec-options.c \
|
||||||
cmd/multicall-match-options.c
|
cmd/multicall-match-options.c \
|
||||||
|
cmd/pretty-print-iface.c
|
||||||
MULTICALL_OBJ = ${MULTICALL_SRC:.c=.o}
|
MULTICALL_OBJ = ${MULTICALL_SRC:.c=.o}
|
||||||
MULTICALL = ifupdown
|
MULTICALL = ifupdown
|
||||||
|
|
||||||
|
@ -74,6 +74,22 @@ MULTICALL_${CONFIG_IFCTRSTAT}_OBJ += ${IFCTRSTAT_SRC:.c=.o}
|
||||||
CMDS_${CONFIG_IFCTRSTAT} += ifctrstat
|
CMDS_${CONFIG_IFCTRSTAT} += ifctrstat
|
||||||
CPPFLAGS_${CONFIG_IFCTRSTAT} += -DCONFIG_IFCTRSTAT
|
CPPFLAGS_${CONFIG_IFCTRSTAT} += -DCONFIG_IFCTRSTAT
|
||||||
|
|
||||||
|
# enable ifparse applet (+1 KB)
|
||||||
|
CONFIG_IFPARSE ?= Y
|
||||||
|
IFPARSE_SRC = cmd/ifparse.c
|
||||||
|
MULTICALL_${CONFIG_IFPARSE}_OBJ += ${IFPARSE_SRC:.c=.o}
|
||||||
|
CMDS_${CONFIG_IFPARSE} += ifparse
|
||||||
|
CPPFLAGS_${CONFIG_IFPARSE} += -DCONFIG_IFPARSE
|
||||||
|
|
||||||
|
# enable YAML support (+2 KB)
|
||||||
|
CONFIG_YAML ?= Y
|
||||||
|
YAML_SRC = \
|
||||||
|
libifupdown/yaml-base.c \
|
||||||
|
libifupdown/yaml-writer.c
|
||||||
|
LIBIFUPDOWN_${CONFIG_YAML}_OBJ += ${YAML_SRC:.c=.o}
|
||||||
|
CPPFLAGS_${CONFIG_YAML} += -DCONFIG_YAML
|
||||||
|
|
||||||
|
LIBIFUPDOWN_OBJ += ${LIBIFUPDOWN_Y_OBJ}
|
||||||
MULTICALL_OBJ += ${MULTICALL_Y_OBJ}
|
MULTICALL_OBJ += ${MULTICALL_Y_OBJ}
|
||||||
CMDS += ${CMDS_Y}
|
CMDS += ${CMDS_Y}
|
||||||
CPPFLAGS += ${CPPFLAGS_Y}
|
CPPFLAGS += ${CPPFLAGS_Y}
|
||||||
|
@ -156,7 +172,8 @@ MANPAGES_8 = \
|
||||||
doc/ifquery.8 \
|
doc/ifquery.8 \
|
||||||
doc/ifup.8 \
|
doc/ifup.8 \
|
||||||
doc/ifdown.8 \
|
doc/ifdown.8 \
|
||||||
doc/ifctrstat.8
|
doc/ifctrstat.8 \
|
||||||
|
doc/ifparse.8
|
||||||
|
|
||||||
MANPAGES = ${MANPAGES_5} ${MANPAGES_7} ${MANPAGES_8}
|
MANPAGES = ${MANPAGES_5} ${MANPAGES_7} ${MANPAGES_8}
|
||||||
|
|
||||||
|
|
224
cmd/ifparse.c
Normal file
224
cmd/ifparse.c
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* cmd/ifparse.c
|
||||||
|
* Purpose: Redisplay /e/n/i in alternative formats.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_YAML
|
||||||
|
# include "libifupdown/yaml-base.h"
|
||||||
|
# include "libifupdown/yaml-writer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cmd/multicall.h"
|
||||||
|
#include "cmd/pretty-print-iface.h"
|
||||||
|
|
||||||
|
static bool show_all = false;
|
||||||
|
static bool allow_undefined = false;
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_show_all(const char *arg)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
show_all = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_allow_undefined(const char *arg)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
allow_undefined = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *output_fmt = "ifupdown";
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_output_fmt(const char *arg)
|
||||||
|
{
|
||||||
|
output_fmt = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct if_option local_options[] = {
|
||||||
|
{'F', "format", NULL, "output format to use", true, set_output_fmt},
|
||||||
|
{'A', "all", NULL, "show all interfaces", false, set_show_all},
|
||||||
|
{'U', "allow-undefined", NULL, "allow querying undefined (virtual) interfaces", false, set_allow_undefined},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct if_option_group local_option_group = {
|
||||||
|
.desc = "Program-specific options",
|
||||||
|
.group_size = ARRAY_SIZE(local_options),
|
||||||
|
.group = local_options
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_YAML
|
||||||
|
static void
|
||||||
|
prettyprint_interface_yaml(struct lif_interface *iface)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node doc = {};
|
||||||
|
|
||||||
|
lif_yaml_document_init(&doc, "interfaces");
|
||||||
|
|
||||||
|
struct lif_yaml_node *iface_node = lif_yaml_node_new_list(iface->ifname);
|
||||||
|
lif_yaml_node_append_child(&doc, iface_node);
|
||||||
|
|
||||||
|
if (iface->is_auto)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *iface_entry_node = lif_yaml_node_new_boolean("auto", true);
|
||||||
|
lif_yaml_node_append_child(iface_node, iface_entry_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_node *iter;
|
||||||
|
LIF_DICT_FOREACH(iter, &iface->vars)
|
||||||
|
{
|
||||||
|
struct lif_dict_entry *entry = iter->data;
|
||||||
|
const char *value = entry->data;
|
||||||
|
char addr_buf[512];
|
||||||
|
|
||||||
|
if (!strcmp(entry->key, "address"))
|
||||||
|
{
|
||||||
|
struct lif_address *addr = entry->data;
|
||||||
|
|
||||||
|
if (!lif_address_unparse(addr, addr_buf, sizeof addr_buf, true))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
value = addr_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_yaml_node *iface_entry_node = lif_yaml_node_new_string(entry->key, value);
|
||||||
|
lif_yaml_node_append_child(iface_node, iface_entry_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
lif_yaml_write(iface_node, stdout, true);
|
||||||
|
lif_yaml_node_free(&doc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct prettyprint_impl_map {
|
||||||
|
const char *name;
|
||||||
|
void (*handle)(struct lif_interface *iface);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct prettyprint_impl_map pp_impl_map[] = {
|
||||||
|
{"ifupdown", prettyprint_interface_eni},
|
||||||
|
#ifdef CONFIG_YAML
|
||||||
|
{"yaml-raw", prettyprint_interface_yaml},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
pp_impl_cmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const char *key = a;
|
||||||
|
const struct prettyprint_impl_map *impl = b;
|
||||||
|
|
||||||
|
return strcmp(key, impl->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ifparse_main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct lif_dict state = {};
|
||||||
|
struct lif_dict collection = {};
|
||||||
|
struct lif_interface_file_parse_state parse_state = {
|
||||||
|
.collection = &collection,
|
||||||
|
};
|
||||||
|
|
||||||
|
lif_interface_collection_init(&collection);
|
||||||
|
|
||||||
|
if (!lif_state_read_path(&state, exec_opts.state_file))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: could not parse %s\n", argv0, exec_opts.state_file);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lif_interface_file_parse(&parse_state, exec_opts.interfaces_file))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: could not parse %s\n", argv0, exec_opts.interfaces_file);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_opts.property == NULL && lif_lifecycle_count_rdepends(&exec_opts, &collection) == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: could not validate dependency tree\n", argv0);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lif_compat_apply(&collection))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: failed to apply compatibility glue\n", argv0);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct prettyprint_impl_map *m = bsearch(output_fmt, pp_impl_map, ARRAY_SIZE(pp_impl_map), sizeof(*m), pp_impl_cmp);
|
||||||
|
if (m == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: %s: output format not supported\n", argv0, output_fmt);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_all)
|
||||||
|
{
|
||||||
|
struct lif_node *n;
|
||||||
|
|
||||||
|
LIF_DICT_FOREACH(n, &collection)
|
||||||
|
{
|
||||||
|
struct lif_dict_entry *entry = n->data;
|
||||||
|
|
||||||
|
m->handle(entry->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind >= argc)
|
||||||
|
generic_usage(self_applet, EXIT_FAILURE);
|
||||||
|
|
||||||
|
int idx = optind;
|
||||||
|
for (; idx < argc; idx++)
|
||||||
|
{
|
||||||
|
struct lif_dict_entry *entry = lif_dict_find(&collection, argv[idx]);
|
||||||
|
struct lif_interface *iface = NULL;
|
||||||
|
|
||||||
|
if (entry != NULL)
|
||||||
|
iface = entry->data;
|
||||||
|
|
||||||
|
if (entry == NULL && allow_undefined)
|
||||||
|
iface = lif_interface_collection_find(&collection, argv[idx]);
|
||||||
|
|
||||||
|
if (iface == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: unknown interface %s\n", argv0, argv[idx]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->handle(iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct if_applet ifparse_applet = {
|
||||||
|
.name = "ifparse",
|
||||||
|
.desc = "redisplay interface configuration",
|
||||||
|
.main = ifparse_main,
|
||||||
|
.usage = "ifparse [options] <interfaces>\n ifparse [options] --all",
|
||||||
|
.manpage = "8 ifparse",
|
||||||
|
.groups = { &global_option_group, &match_option_group, &exec_option_group, &local_option_group },
|
||||||
|
};
|
|
@ -20,42 +20,7 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include "libifupdown/libifupdown.h"
|
#include "libifupdown/libifupdown.h"
|
||||||
#include "cmd/multicall.h"
|
#include "cmd/multicall.h"
|
||||||
|
#include "cmd/pretty-print-iface.h"
|
||||||
void
|
|
||||||
print_interface(struct lif_interface *iface)
|
|
||||||
{
|
|
||||||
if (!lif_lifecycle_query_dependents(&exec_opts, iface, iface->ifname))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (iface->is_auto)
|
|
||||||
printf("auto %s\n", iface->ifname);
|
|
||||||
|
|
||||||
printf("%s %s\n", iface->is_template ? "template" : "iface", iface->ifname);
|
|
||||||
|
|
||||||
struct lif_node *iter;
|
|
||||||
LIF_DICT_FOREACH(iter, &iface->vars)
|
|
||||||
{
|
|
||||||
struct lif_dict_entry *entry = iter->data;
|
|
||||||
|
|
||||||
if (!strcmp(entry->key, "address"))
|
|
||||||
{
|
|
||||||
struct lif_address *addr = entry->data;
|
|
||||||
char addr_buf[512];
|
|
||||||
|
|
||||||
if (!lif_address_unparse(addr, addr_buf, sizeof addr_buf, true))
|
|
||||||
{
|
|
||||||
printf(" # warning: failed to unparse address\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" %s %s\n", entry->key, addr_buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf(" %s %s\n", entry->key, (const char *) entry->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, struct lif_interface *parent)
|
print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, struct lif_interface *parent)
|
||||||
|
@ -147,7 +112,7 @@ list_interfaces(struct lif_dict *collection, struct match_options *opts)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (opts->pretty_print)
|
if (opts->pretty_print)
|
||||||
print_interface(iface);
|
prettyprint_interface_eni(iface);
|
||||||
else if (opts->dot)
|
else if (opts->dot)
|
||||||
print_interface_dot(collection, iface, NULL);
|
print_interface_dot(collection, iface, NULL);
|
||||||
else
|
else
|
||||||
|
@ -330,7 +295,7 @@ ifquery_main(int argc, char *argv[])
|
||||||
if (match_opts.property != NULL)
|
if (match_opts.property != NULL)
|
||||||
print_interface_property(iface, match_opts.property);
|
print_interface_property(iface, match_opts.property);
|
||||||
else
|
else
|
||||||
print_interface(iface);
|
prettyprint_interface_eni(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -36,6 +36,10 @@ extern struct if_applet ifdown_applet;
|
||||||
extern struct if_applet ifctrstat_applet;
|
extern struct if_applet ifctrstat_applet;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_IFPARSE
|
||||||
|
extern struct if_applet ifparse_applet;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct if_applet ifupdown_applet;
|
struct if_applet ifupdown_applet;
|
||||||
const struct if_applet *self_applet = NULL;
|
const struct if_applet *self_applet = NULL;
|
||||||
|
|
||||||
|
@ -46,6 +50,9 @@ struct if_applet *applet_table[] = {
|
||||||
#ifdef CONFIG_IFUPDOWN
|
#ifdef CONFIG_IFUPDOWN
|
||||||
&ifdown_applet,
|
&ifdown_applet,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_IFPARSE
|
||||||
|
&ifparse_applet,
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_IFQUERY
|
#ifdef CONFIG_IFQUERY
|
||||||
&ifquery_applet,
|
&ifquery_applet,
|
||||||
#endif
|
#endif
|
||||||
|
|
56
cmd/pretty-print-iface.c
Normal file
56
cmd/pretty-print-iface.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* cmd/pretty-print-iface.c
|
||||||
|
* Purpose: interface pretty-printer (/e/n/i style)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
#include "cmd/multicall.h"
|
||||||
|
#include "cmd/pretty-print-iface.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
prettyprint_interface_eni(struct lif_interface *iface)
|
||||||
|
{
|
||||||
|
if (!lif_lifecycle_query_dependents(&exec_opts, iface, iface->ifname))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (iface->is_auto)
|
||||||
|
printf("auto %s\n", iface->ifname);
|
||||||
|
|
||||||
|
printf("%s %s\n", iface->is_template ? "template" : "iface", iface->ifname);
|
||||||
|
|
||||||
|
struct lif_node *iter;
|
||||||
|
LIF_DICT_FOREACH(iter, &iface->vars)
|
||||||
|
{
|
||||||
|
struct lif_dict_entry *entry = iter->data;
|
||||||
|
|
||||||
|
if (!strcmp(entry->key, "address"))
|
||||||
|
{
|
||||||
|
struct lif_address *addr = entry->data;
|
||||||
|
char addr_buf[512];
|
||||||
|
|
||||||
|
if (!lif_address_unparse(addr, addr_buf, sizeof addr_buf, true))
|
||||||
|
{
|
||||||
|
printf(" # warning: failed to unparse address\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" %s %s\n", entry->key, addr_buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf(" %s %s\n", entry->key, (const char *) entry->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
23
cmd/pretty-print-iface.h
Normal file
23
cmd/pretty-print-iface.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* cmd/pretty-print-iface.h
|
||||||
|
* Purpose: interface pretty-printer (/e/n/i style)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IFUPDOWN_CMD_PRETTY_PRINT_IFACE_H__GUARD
|
||||||
|
#define IFUPDOWN_CMD_PRETTY_PRINT_IFACE_H__GUARD
|
||||||
|
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
|
||||||
|
extern void prettyprint_interface_eni(struct lif_interface *iface);
|
||||||
|
|
||||||
|
#endif
|
62
doc/ifparse.scd
Normal file
62
doc/ifparse.scd
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
ifparse(8)
|
||||||
|
|
||||||
|
# NAME
|
||||||
|
|
||||||
|
ifparse - redisplay interface configuration in different formats
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
|
||||||
|
*ifparse* [<_options_>...] <_interfaces_...>
|
||||||
|
|
||||||
|
*ifparse* -A|--all
|
||||||
|
|
||||||
|
# DESCRIPTION
|
||||||
|
|
||||||
|
*ifparse* is used to extract information from the interface configuration
|
||||||
|
file. It is intended to be used to translate the interface configuration
|
||||||
|
stanzas between different formats.
|
||||||
|
|
||||||
|
# OPTIONS
|
||||||
|
|
||||||
|
*-a, --auto*
|
||||||
|
Only match interfaces that are marked as _auto_.
|
||||||
|
|
||||||
|
*-h, --help*
|
||||||
|
Display supported options to ifquery.
|
||||||
|
|
||||||
|
*-i, --interfaces* _FILE_
|
||||||
|
Use _FILE_ as the config database.
|
||||||
|
|
||||||
|
*-F, --format* _FORMAT_
|
||||||
|
Use _FORMAT_ to determine what format to use. *ifupdown* and
|
||||||
|
*yaml-raw* formats are available.
|
||||||
|
|
||||||
|
*-I, --include* _PATTERN_
|
||||||
|
Include _PATTERN_ when matching against the config or state
|
||||||
|
database.
|
||||||
|
|
||||||
|
*-U, --allow-undefined*
|
||||||
|
Create virtual interfaces for any interfaces not explicitly
|
||||||
|
defined in the configuration file. This is primarily useful
|
||||||
|
for property queries.
|
||||||
|
|
||||||
|
*-S, --state-file* _FILE_
|
||||||
|
Use _FILE_ as the state database.
|
||||||
|
|
||||||
|
*-V, --version*
|
||||||
|
Print the ifupdown-ng version and exit.
|
||||||
|
|
||||||
|
*-X, --exclude* _PATTERN_
|
||||||
|
Exclude _PATTERN_ when matching against the config or state
|
||||||
|
database.
|
||||||
|
|
||||||
|
# SEE ALSO
|
||||||
|
|
||||||
|
*ifup*(8)++
|
||||||
|
*ifdown*(8)++
|
||||||
|
*ifquery*(8)++
|
||||||
|
*interfaces*(5)
|
||||||
|
|
||||||
|
# AUTHORS
|
||||||
|
|
||||||
|
Ariadne Conill <ariadne@dereferenced.org>
|
|
@ -40,7 +40,7 @@ extern void lif_node_delete(struct lif_node *node, struct lif_list *list);
|
||||||
for ((iter) = (head); (iter) != NULL; (iter) = (iter)->next)
|
for ((iter) = (head); (iter) != NULL; (iter) = (iter)->next)
|
||||||
|
|
||||||
#define LIF_LIST_FOREACH_SAFE(iter, iter_next, head) \
|
#define LIF_LIST_FOREACH_SAFE(iter, iter_next, head) \
|
||||||
for ((iter) = (head), (iter_next) = (iter)->next; (iter) != NULL; (iter) = (iter_next), (iter_next) = (iter) != NULL ? (iter)->next : NULL)
|
for ((iter) = (head), (iter_next) = (iter) != NULL ? (iter)->next : NULL; (iter) != NULL; (iter) = (iter_next), (iter_next) = (iter) != NULL ? (iter)->next : NULL)
|
||||||
|
|
||||||
#define LIF_LIST_FOREACH_REVERSE(iter, tail) \
|
#define LIF_LIST_FOREACH_REVERSE(iter, tail) \
|
||||||
for ((iter) = (tail); (iter) != NULL; (iter) = (iter)->prev)
|
for ((iter) = (tail); (iter) != NULL; (iter) = (iter)->prev)
|
||||||
|
|
127
libifupdown/yaml-base.c
Normal file
127
libifupdown/yaml-base.c
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* libifupdown/yaml-base.c
|
||||||
|
* Purpose: YAML implementation -- base
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
#include "libifupdown/yaml-base.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
lif_yaml_document_init(struct lif_yaml_node *doc, const char *name)
|
||||||
|
{
|
||||||
|
memset(doc, '\0', sizeof *doc);
|
||||||
|
doc->value_type = LIF_YAML_OBJECT;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
doc->name = strdup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_yaml_node *
|
||||||
|
lif_yaml_document_new(const char *name)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *doc = calloc(1, sizeof *doc);
|
||||||
|
|
||||||
|
lif_yaml_document_init(doc, name);
|
||||||
|
doc->malloced = true;
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_yaml_node *
|
||||||
|
lif_yaml_node_new_boolean(const char *name, bool value)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *node = calloc(1, sizeof *node);
|
||||||
|
|
||||||
|
node->malloced = true;
|
||||||
|
node->value_type = LIF_YAML_BOOLEAN;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
node->name = strdup(name);
|
||||||
|
|
||||||
|
node->value.bool_value = value;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_yaml_node *
|
||||||
|
lif_yaml_node_new_string(const char *name, const char *value)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *node = calloc(1, sizeof *node);
|
||||||
|
|
||||||
|
node->malloced = true;
|
||||||
|
node->value_type = LIF_YAML_STRING;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
node->name = strdup(name);
|
||||||
|
|
||||||
|
if (value != NULL)
|
||||||
|
node->value.str_value = strdup(value);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_yaml_node *
|
||||||
|
lif_yaml_node_new_object(const char *name)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *node = calloc(1, sizeof *node);
|
||||||
|
|
||||||
|
node->malloced = true;
|
||||||
|
node->value_type = LIF_YAML_OBJECT;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
node->name = strdup(name);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lif_yaml_node *
|
||||||
|
lif_yaml_node_new_list(const char *name)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *node = calloc(1, sizeof *node);
|
||||||
|
|
||||||
|
node->malloced = true;
|
||||||
|
node->value_type = LIF_YAML_LIST;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
node->name = strdup(name);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lif_yaml_node_free(struct lif_yaml_node *node)
|
||||||
|
{
|
||||||
|
struct lif_node *iter, *next;
|
||||||
|
|
||||||
|
LIF_LIST_FOREACH_SAFE(iter, next, node->children.head)
|
||||||
|
{
|
||||||
|
struct lif_yaml_node *iter_node = iter->data;
|
||||||
|
|
||||||
|
lif_yaml_node_free(iter_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(node->name);
|
||||||
|
|
||||||
|
if (node->value_type == LIF_YAML_STRING)
|
||||||
|
free(node->value.str_value);
|
||||||
|
|
||||||
|
if (node->malloced)
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lif_yaml_node_append_child(struct lif_yaml_node *parent, struct lif_yaml_node *child)
|
||||||
|
{
|
||||||
|
lif_node_insert_tail(&child->node, child, &parent->children);
|
||||||
|
}
|
52
libifupdown/yaml-base.h
Normal file
52
libifupdown/yaml-base.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* libifupdown/yaml-base.h
|
||||||
|
* Purpose: YAML implementation -- base
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBIFUPDOWN_YAML_BASE_H__GUARD
|
||||||
|
#define LIBIFUPDOWN_YAML_BASE_H__GUARD
|
||||||
|
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
|
||||||
|
/* this is a subset of types supported by our implementation */
|
||||||
|
enum lif_yaml_value {
|
||||||
|
LIF_YAML_STRING,
|
||||||
|
LIF_YAML_LIST,
|
||||||
|
LIF_YAML_OBJECT,
|
||||||
|
LIF_YAML_BOOLEAN
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lif_yaml_node {
|
||||||
|
struct lif_node node;
|
||||||
|
|
||||||
|
bool malloced;
|
||||||
|
char *name;
|
||||||
|
enum lif_yaml_value value_type;
|
||||||
|
union {
|
||||||
|
char *str_value; /* for string nodes */
|
||||||
|
bool bool_value; /* for boolean nodes */
|
||||||
|
} value;
|
||||||
|
struct lif_list children; /* for list and object nodes */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void lif_yaml_document_init(struct lif_yaml_node *doc, const char *name);
|
||||||
|
extern struct lif_yaml_node *lif_yaml_document_new(const char *name);
|
||||||
|
|
||||||
|
extern struct lif_yaml_node *lif_yaml_node_new_boolean(const char *name, bool value);
|
||||||
|
extern struct lif_yaml_node *lif_yaml_node_new_string(const char *name, const char *value);
|
||||||
|
extern struct lif_yaml_node *lif_yaml_node_new_object(const char *name);
|
||||||
|
extern struct lif_yaml_node *lif_yaml_node_new_list(const char *name);
|
||||||
|
extern void lif_yaml_node_free(struct lif_yaml_node *node);
|
||||||
|
extern void lif_yaml_node_append_child(struct lif_yaml_node *parent, struct lif_yaml_node *child);
|
||||||
|
|
||||||
|
#endif
|
66
libifupdown/yaml-writer.c
Normal file
66
libifupdown/yaml-writer.c
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* libifupdown/yaml-writer.c
|
||||||
|
* Purpose: YAML implementation -- writer
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
#include "libifupdown/yaml-base.h"
|
||||||
|
#include "libifupdown/yaml-writer.h"
|
||||||
|
|
||||||
|
static const size_t INDENT_WIDTH = 2;
|
||||||
|
|
||||||
|
static void
|
||||||
|
lif_yaml_write_node(const struct lif_yaml_node *node, FILE *f, size_t indent, bool type_annotations)
|
||||||
|
{
|
||||||
|
const struct lif_node *iter;
|
||||||
|
|
||||||
|
if (node->name != NULL)
|
||||||
|
fprintf(f, "%*s%s: ", (int) indent, "", node->name);
|
||||||
|
|
||||||
|
size_t child_indent = indent + INDENT_WIDTH;
|
||||||
|
|
||||||
|
switch (node->value_type)
|
||||||
|
{
|
||||||
|
case LIF_YAML_BOOLEAN:
|
||||||
|
fprintf(f, "%s%s\n", type_annotations ? "!!bool " : "", node->value.bool_value ? "true" : "false");
|
||||||
|
break;
|
||||||
|
case LIF_YAML_STRING:
|
||||||
|
fprintf(f, "%s%s\n", type_annotations ? "!!str " : "", node->value.str_value);
|
||||||
|
break;
|
||||||
|
case LIF_YAML_OBJECT:
|
||||||
|
fprintf(f, "\n");
|
||||||
|
break;
|
||||||
|
case LIF_YAML_LIST:
|
||||||
|
fprintf(f, "\n");
|
||||||
|
child_indent += INDENT_WIDTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIF_LIST_FOREACH(iter, node->children.head)
|
||||||
|
{
|
||||||
|
const struct lif_yaml_node *iter_node = iter->data;
|
||||||
|
|
||||||
|
if (node->value_type == LIF_YAML_LIST)
|
||||||
|
fprintf(f, "%*s-\n", (int) (child_indent - INDENT_WIDTH), "");
|
||||||
|
|
||||||
|
lif_yaml_write_node(iter_node, f, child_indent, type_annotations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lif_yaml_write(const struct lif_yaml_node *doc, FILE *f, bool type_annotations)
|
||||||
|
{
|
||||||
|
lif_yaml_write_node(doc, f, 0, type_annotations);
|
||||||
|
}
|
24
libifupdown/yaml-writer.h
Normal file
24
libifupdown/yaml-writer.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* libifupdown/yaml-writer.h
|
||||||
|
* Purpose: YAML implementation -- writer
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBIFUPDOWN_YAML_WRITER_H__GUARD
|
||||||
|
#define LIBIFUPDOWN_YAML_WRITER_H__GUARD
|
||||||
|
|
||||||
|
#include "libifupdown/libifupdown.h"
|
||||||
|
#include "libifupdown/yaml-base.h"
|
||||||
|
|
||||||
|
extern void lif_yaml_write(const struct lif_yaml_node *doc, FILE *f, bool type_annotations);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue