Merge pull request #78 from ifupdown-ng/feature/preferences
config file support
This commit is contained in:
		
						commit
						f10faf953c
					
				
					 10 changed files with 254 additions and 1 deletions
				
			
		
							
								
								
									
										7
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -10,6 +10,7 @@ PACKAGE_BUGREPORT := https://github.com/ifupdown-ng/ifupdown-ng/issues/new | ||||||
| 
 | 
 | ||||||
| INTERFACES_FILE := /etc/network/interfaces | INTERFACES_FILE := /etc/network/interfaces | ||||||
| STATE_FILE := /run/ifstate | STATE_FILE := /run/ifstate | ||||||
|  | CONFIG_FILE := /etc/network/ifupdown-ng.conf | ||||||
| EXECUTOR_PATH := /usr/libexec/ifupdown-ng | EXECUTOR_PATH := /usr/libexec/ifupdown-ng | ||||||
| 
 | 
 | ||||||
| CFLAGS ?= -ggdb3 -Os | CFLAGS ?= -ggdb3 -Os | ||||||
|  | @ -18,6 +19,7 @@ CFLAGS += ${LIBBSD_CFLAGS} | ||||||
| CPPFLAGS = -I. | CPPFLAGS = -I. | ||||||
| CPPFLAGS += -DINTERFACES_FILE=\"${INTERFACES_FILE}\" | CPPFLAGS += -DINTERFACES_FILE=\"${INTERFACES_FILE}\" | ||||||
| CPPFLAGS += -DSTATE_FILE=\"${STATE_FILE}\" | CPPFLAGS += -DSTATE_FILE=\"${STATE_FILE}\" | ||||||
|  | CPPFLAGS += -DCONFIG_FILE=\"${CONFIG_FILE}\" | ||||||
| CPPFLAGS += -DPACKAGE_NAME=\"${PACKAGE_NAME}\" | CPPFLAGS += -DPACKAGE_NAME=\"${PACKAGE_NAME}\" | ||||||
| CPPFLAGS += -DPACKAGE_VERSION=\"${PACKAGE_VERSION}\" | CPPFLAGS += -DPACKAGE_VERSION=\"${PACKAGE_VERSION}\" | ||||||
| CPPFLAGS += -DPACKAGE_BUGREPORT=\"${PACKAGE_BUGREPORT}\" | CPPFLAGS += -DPACKAGE_BUGREPORT=\"${PACKAGE_BUGREPORT}\" | ||||||
|  | @ -34,7 +36,9 @@ LIBIFUPDOWN_SRC = \ | ||||||
| 	libifupdown/state.c \
 | 	libifupdown/state.c \
 | ||||||
| 	libifupdown/environment.c \
 | 	libifupdown/environment.c \
 | ||||||
| 	libifupdown/execute.c \
 | 	libifupdown/execute.c \
 | ||||||
| 	libifupdown/lifecycle.c | 	libifupdown/lifecycle.c \
 | ||||||
|  | 	libifupdown/config-parser.c \
 | ||||||
|  | 	libifupdown/config-file.c | ||||||
| 
 | 
 | ||||||
| LIBIFUPDOWN_OBJ = ${LIBIFUPDOWN_SRC:.c=.o} | LIBIFUPDOWN_OBJ = ${LIBIFUPDOWN_SRC:.c=.o} | ||||||
| LIBIFUPDOWN_LIB = libifupdown.a | LIBIFUPDOWN_LIB = libifupdown.a | ||||||
|  | @ -125,6 +129,7 @@ install: all | ||||||
| 	for i in ${EXECUTOR_SCRIPTS_STUB}; do \
 | 	for i in ${EXECUTOR_SCRIPTS_STUB}; do \
 | ||||||
| 		install -D -m755 executor-scripts/stub/$$i ${DESTDIR}${EXECUTOR_PATH}/$$i; \
 | 		install -D -m755 executor-scripts/stub/$$i ${DESTDIR}${EXECUTOR_PATH}/$$i; \
 | ||||||
| 	done | 	done | ||||||
|  | 	install -D -m644 dist/ifupdown-ng.conf.example ${DESTDIR}${CONFIG_FILE}.example | ||||||
| 
 | 
 | ||||||
| .scd.1 .scd.2 .scd.3 .scd.4 .scd.5 .scd.6 .scd.7 .scd.8: | .scd.1 .scd.2 .scd.3 .scd.4 .scd.5 .scd.6 .scd.7 .scd.8: | ||||||
| 	${SCDOC} < $< > $@ | 	${SCDOC} < $< > $@ | ||||||
|  |  | ||||||
|  | @ -72,6 +72,8 @@ main(int argc, char *argv[]) | ||||||
| 	argv0 = basename(argv[0]); | 	argv0 = basename(argv[0]); | ||||||
| 	const struct if_applet **app; | 	const struct if_applet **app; | ||||||
| 
 | 
 | ||||||
|  | 	lif_config_load(CONFIG_FILE); | ||||||
|  | 
 | ||||||
| 	app = bsearch(argv0, applet_table, | 	app = bsearch(argv0, applet_table, | ||||||
| 		      ARRAY_SIZE(applet_table), sizeof(*applet_table), | 		      ARRAY_SIZE(applet_table), sizeof(*applet_table), | ||||||
| 		      applet_cmp); | 		      applet_cmp); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								dist/ifupdown-ng.conf.example
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								dist/ifupdown-ng.conf.example
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | # This is an example configuration file for ifupdown-ng, which allows | ||||||
|  | # the system administrator to configure the behaviour of ifupdown-ng. | ||||||
|  | # | ||||||
|  | # The settings specified here are the defaults of ifupdown-ng. | ||||||
|  | 
 | ||||||
|  | # allow_addon_scripts: | ||||||
|  | # Enable support for /etc/if-X.d addon scripts.  These are used for | ||||||
|  | # compatibility with legacy setups, and may be disabled for performance | ||||||
|  | # improvements in setups where only ifupdown-ng executors are used. | ||||||
|  | allow_addon_scripts = 1 | ||||||
							
								
								
									
										63
									
								
								libifupdown/config-file.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								libifupdown/config-file.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,63 @@ | ||||||
|  | /*
 | ||||||
|  |  * libifupdown/config-file.c | ||||||
|  |  * Purpose: config file loading | ||||||
|  |  * | ||||||
|  |  * 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 <errno.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "libifupdown/libifupdown.h" | ||||||
|  | 
 | ||||||
|  | struct lif_config_file lif_config = { | ||||||
|  | 	.allow_addon_scripts = true, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static bool | ||||||
|  | set_bool_value(const char *key, const char *value, void *opaque) | ||||||
|  | { | ||||||
|  | 	(void) key; | ||||||
|  | 
 | ||||||
|  | 	if (*value == '1' || | ||||||
|  | 		*value == 'Y' || *value == 'y' ||  | ||||||
|  | 		*value == 'T' || *value == 't') | ||||||
|  | 		*(bool *) opaque = true; | ||||||
|  | 	else if (*value == '0' || | ||||||
|  | 		*value == 'N' || *value == 'n' || | ||||||
|  | 		*value == 'F' || *value == 'f') | ||||||
|  | 		*(bool *) opaque = false; | ||||||
|  | 	else | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static struct lif_config_handler handlers[] = { | ||||||
|  | 	{"allow_addon_scripts", set_bool_value, &lif_config.allow_addon_scripts}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | bool | ||||||
|  | lif_config_load(const char *filename) | ||||||
|  | { | ||||||
|  | 	FILE *fd = fopen(filename, "r"); | ||||||
|  | 
 | ||||||
|  | 	if (fd == NULL) | ||||||
|  | 	{ | ||||||
|  | #if 0 | ||||||
|  | 		fprintf(stderr, "ifupdown-ng: cannot open config %s: %s\n", | ||||||
|  | 			filename, strerror(errno)); | ||||||
|  | #endif | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return lif_config_parse_file(fd, filename, handlers, ARRAY_SIZE(handlers)); | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								libifupdown/config-file.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								libifupdown/config-file.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | /*
 | ||||||
|  |  * libifupdown/config-file.h | ||||||
|  |  * Purpose: config file loading | ||||||
|  |  * | ||||||
|  |  * 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__CONFIG_FILE_H | ||||||
|  | #define LIBIFUPDOWN__CONFIG_FILE_H | ||||||
|  | 
 | ||||||
|  | #include <stdbool.h> | ||||||
|  | 
 | ||||||
|  | struct lif_config_file { | ||||||
|  | 	bool allow_addon_scripts; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | extern struct lif_config_file lif_config; | ||||||
|  | 
 | ||||||
|  | extern bool lif_config_load(const char *filename); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										87
									
								
								libifupdown/config-parser.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								libifupdown/config-parser.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | ||||||
|  | /*
 | ||||||
|  |  * libifupdown/config-parser.c | ||||||
|  |  * Purpose: config parsing | ||||||
|  |  * | ||||||
|  |  * 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 <errno.h> | ||||||
|  | #include <stddef.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "libifupdown/config-parser.h" | ||||||
|  | #include "libifupdown/fgetline.h" | ||||||
|  | #include "libifupdown/tokenize.h" | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | handler_cmp(const void *a, const void *b) | ||||||
|  | { | ||||||
|  | 	const char *key = a; | ||||||
|  | 	const struct lif_config_handler *hdl = b; | ||||||
|  | 
 | ||||||
|  | 	return strcmp(key, hdl->key); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool | ||||||
|  | lif_config_parse_file(FILE *fd, const char *filename, struct lif_config_handler *handlers, size_t handler_count) | ||||||
|  | { | ||||||
|  | 	char linebuf[4096]; | ||||||
|  | 	size_t lineno = 0; | ||||||
|  | 
 | ||||||
|  | 	while (lif_fgetline(linebuf, sizeof linebuf, fd)) | ||||||
|  | 	{ | ||||||
|  | 		char *bufp = linebuf; | ||||||
|  | 		char *key = lif_next_token_eq(&bufp); | ||||||
|  | 		char *value = lif_next_token_eq(&bufp); | ||||||
|  | 
 | ||||||
|  | 		lineno++; | ||||||
|  | 
 | ||||||
|  | 		if (!*key || !*value) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if (*key == '#') | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		struct lif_config_handler *hdl = bsearch(key, handlers, handler_count, sizeof(*handlers), | ||||||
|  | 			handler_cmp); | ||||||
|  | 
 | ||||||
|  | 		if (hdl == NULL) | ||||||
|  | 		{ | ||||||
|  | 			fprintf(stderr, "ifupdown-ng: %s:%zu: warning: unknown config setting %s\n", | ||||||
|  | 				filename, lineno, key); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!hdl->handle(key, value, hdl->opaque)) | ||||||
|  | 		{ | ||||||
|  | 			fclose(fd); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fclose(fd); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool | ||||||
|  | lif_config_parse(const char *filename, struct lif_config_handler *handlers, size_t handler_count) | ||||||
|  | { | ||||||
|  | 	FILE *f = fopen(filename, "r"); | ||||||
|  | 
 | ||||||
|  | 	if (f == NULL) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "ifupdown-ng: unable to parse %s: %s\n", filename, strerror(errno)); | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return lif_config_parse_file(f, filename, handlers, handler_count); | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								libifupdown/config-parser.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								libifupdown/config-parser.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | /*
 | ||||||
|  |  * libifupdown/config-parser.h | ||||||
|  |  * Purpose: config parsing | ||||||
|  |  * | ||||||
|  |  * 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__CONFIG_PARSER_H | ||||||
|  | #define LIBIFUPDOWN__CONFIG_PARSER_H | ||||||
|  | 
 | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stddef.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | struct lif_config_handler { | ||||||
|  | 	const char *key; | ||||||
|  | 	bool (*handle)(const char *key, const char *value, void *opaque); | ||||||
|  | 	void *opaque; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | extern bool lif_config_parse_file(FILE *f, const char *filename, struct lif_config_handler *handlers, size_t handler_count); | ||||||
|  | extern bool lif_config_parse(const char *filename, struct lif_config_handler *handlers, size_t handler_count); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -27,6 +27,8 @@ | ||||||
| #include "libifupdown/execute.h" | #include "libifupdown/execute.h" | ||||||
| #include "libifupdown/lifecycle.h" | #include "libifupdown/lifecycle.h" | ||||||
| #include "libifupdown/tokenize.h" | #include "libifupdown/tokenize.h" | ||||||
|  | #include "libifupdown/config-file.h" | ||||||
|  | #include "libifupdown/config-parser.h" | ||||||
| 
 | 
 | ||||||
| #ifndef ARRAY_SIZE | #ifndef ARRAY_SIZE | ||||||
| # define ARRAY_SIZE(x)   (sizeof(x) / sizeof(*x)) | # define ARRAY_SIZE(x)   (sizeof(x) / sizeof(*x)) | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ | ||||||
| #include "libifupdown/lifecycle.h" | #include "libifupdown/lifecycle.h" | ||||||
| #include "libifupdown/state.h" | #include "libifupdown/state.h" | ||||||
| #include "libifupdown/tokenize.h" | #include "libifupdown/tokenize.h" | ||||||
|  | #include "libifupdown/config-file.h" | ||||||
| 
 | 
 | ||||||
| static bool | static bool | ||||||
| handle_commands_for_phase(const struct lif_execute_opts *opts, char *const envp[], const struct lif_interface *iface, const char *phase) | handle_commands_for_phase(const struct lif_execute_opts *opts, char *const envp[], const struct lif_interface *iface, const char *phase) | ||||||
|  | @ -240,6 +241,10 @@ lif_lifecycle_run_phase(const struct lif_execute_opts *opts, struct lif_interfac | ||||||
| 	if (!handle_commands_for_phase(opts, envp, iface, phase)) | 	if (!handle_commands_for_phase(opts, envp, iface, phase)) | ||||||
| 		goto handle_error; | 		goto handle_error; | ||||||
| 
 | 
 | ||||||
|  | 	/* if we don't need to support /etc/if-X.d we're done here */ | ||||||
|  | 	if (!lif_config.allow_addon_scripts) | ||||||
|  | 		goto out_free; | ||||||
|  | 
 | ||||||
| 	/* Check if scripts dir for this phase is present and bail out if it isn't */ | 	/* Check if scripts dir for this phase is present and bail out if it isn't */ | ||||||
| 	struct stat dir_stat; | 	struct stat dir_stat; | ||||||
| 	char dir_path[4096]; | 	char dir_path[4096]; | ||||||
|  |  | ||||||
|  | @ -18,6 +18,24 @@ | ||||||
| 
 | 
 | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| 
 | 
 | ||||||
|  | static inline char * | ||||||
|  | lif_next_token_eq(char **buf) | ||||||
|  | { | ||||||
|  | 	char *out = *buf; | ||||||
|  | 
 | ||||||
|  | 	while (*out && (isspace(*out) || *out == '=')) | ||||||
|  | 		out++; | ||||||
|  | 
 | ||||||
|  | 	char *end = out; | ||||||
|  | 	while (*end && !isspace(*end) && *end != '=') | ||||||
|  | 		end++; | ||||||
|  | 
 | ||||||
|  | 	*end++ = '\0'; | ||||||
|  | 	*buf = end; | ||||||
|  | 
 | ||||||
|  | 	return out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static inline char * | static inline char * | ||||||
| lif_next_token(char **buf) | lif_next_token(char **buf) | ||||||
| { | { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue