[systemd-devel] [RFC 2/6] proxy-discoveryd: Add the basics for parsing the default configuration
Tomasz Bursztyka
tomasz.bursztyka at linux.intel.com
Fri Apr 10 05:17:39 PDT 2015
The config file will be in /etc/systemd/proxy/<filename>.conf
It currently only load "Proxy" parts, with the key PAC. Rest is ignored.
The PAC keyword is a path to a .pac file (a specific js script for proxy
configuration).
Only one PAC based proxy configuration will be loaded at a time.
---
Makefile.am | 6 +-
src/proxy-discovery/.gitignore | 1 +
src/proxy-discovery/proxy-discoveryd-manager.c | 46 +++++++++++++
.../proxy-discoveryd-proxy-gperf.gperf | 17 +++++
src/proxy-discovery/proxy-discoveryd-proxy.c | 77 ++++++++++++++++++++++
src/proxy-discovery/proxy-discoveryd.c | 6 ++
src/proxy-discovery/proxy-discoveryd.h | 27 ++++++++
7 files changed, 179 insertions(+), 1 deletion(-)
create mode 100644 src/proxy-discovery/.gitignore
create mode 100644 src/proxy-discovery/proxy-discoveryd-proxy-gperf.gperf
create mode 100644 src/proxy-discovery/proxy-discoveryd-proxy.c
diff --git a/Makefile.am b/Makefile.am
index 3f4e4d3..6e839b9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5897,19 +5897,23 @@ rootlibexec_PROGRAMS += \
systemd_proxy_discoveryd_SOURCES = \
src/proxy-discovery/proxy-discoveryd.c \
src/proxy-discovery/proxy-discoveryd.h \
- src/proxy-discovery/proxy-discoveryd-manager.c
+ src/proxy-discovery/proxy-discoveryd-manager.c \
+ src/proxy-discovery/proxy-discoveryd-proxy.c \
+ src/proxy-discovery/proxy-discoveryd-proxy-gperf.c
systemd_proxy_discoveryd_LDADD = \
libsystemd-internal.la \
libsystemd-shared.la
nodist_systemunit_DATA += \
+ src/proxy-discovery/proxy-discoveryd-proxy-gperf.gperf \
units/systemd-proxy-discoveryd.service
EXTRA_DIST += \
units/systemd-proxy-discoveryd.service.in
CLEANFILES += \
+ src/proxy-discovery/proxy-discoveryd-proxy-gperf.c \
units/systemd-proxy-discoveryd.service
endif
diff --git a/src/proxy-discovery/.gitignore b/src/proxy-discovery/.gitignore
new file mode 100644
index 0000000..5a67f7f
--- /dev/null
+++ b/src/proxy-discovery/.gitignore
@@ -0,0 +1 @@
+/proxy-discoveryd-proxy-gperf.c
diff --git a/src/proxy-discovery/proxy-discoveryd-manager.c b/src/proxy-discovery/proxy-discoveryd-manager.c
index 3aaec68..62fcc23 100644
--- a/src/proxy-discovery/proxy-discoveryd-manager.c
+++ b/src/proxy-discovery/proxy-discoveryd-manager.c
@@ -19,8 +19,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "conf-parser.h"
+#include "conf-files.h"
+#include "strv.h"
+
#include "proxy-discoveryd.h"
+static const char *proxy_discoveryd_dir = "/etc/systemd/proxy/";
+
int manager_new(Manager **ret) {
_cleanup_manager_free_ Manager *m = NULL;
int r;
@@ -47,6 +53,8 @@ int manager_new(Manager **ret) {
if (r < 0)
return r;
+ LIST_HEAD_INIT(m->default_proxies);
+
*ret = m;
m = NULL;
@@ -54,12 +62,50 @@ int manager_new(Manager **ret) {
}
Manager *manager_free(Manager *m) {
+ Proxy *proxy;
+
if (!m)
return NULL;
sd_event_unref(m->event);
+ while((proxy = m->default_proxies))
+ proxy_free(proxy);
+
free(m);
return NULL;
}
+
+int manager_load_config(Manager *m) {
+ _cleanup_strv_free_ char **files = NULL;
+ Proxy *proxy;
+ char **file;
+ int r;
+
+ assert(m);
+
+ while ((proxy = m->default_proxies))
+ proxy_free(proxy);
+
+ r = conf_files_list(&files, ".proxy", NULL, proxy_discoveryd_dir, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enumerate proxy files: %m");
+
+ STRV_FOREACH_BACKWARDS(file, files) {
+ r = proxy_load(m, *file, &proxy);
+ if (r < 0)
+ log_error_errno(r, "Failed to load file %s: %m", *file);
+
+ if (!proxy)
+ continue;
+
+ LIST_PREPEND(proxy_next, m->default_proxies, proxy);
+
+ /* Only one PAC file */
+ if (proxy->pac_path)
+ break;
+ }
+
+ return 0;
+}
diff --git a/src/proxy-discovery/proxy-discoveryd-proxy-gperf.gperf b/src/proxy-discovery/proxy-discoveryd-proxy-gperf.gperf
new file mode 100644
index 0000000..0d42b3c
--- /dev/null
+++ b/src/proxy-discovery/proxy-discoveryd-proxy-gperf.gperf
@@ -0,0 +1,17 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "proxy-discoveryd.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name proxy_discoveryd_proxy_gperf_hash
+%define lookup-function-name proxy_discoveryd_proxy_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Proxy.PAC, config_parse_path, 0, offsetof(Proxy, pac_path)
diff --git a/src/proxy-discovery/proxy-discoveryd-proxy.c b/src/proxy-discovery/proxy-discoveryd-proxy.c
new file mode 100644
index 0000000..d18395b
--- /dev/null
+++ b/src/proxy-discovery/proxy-discoveryd-proxy.c
@@ -0,0 +1,77 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2015 Intel Corporation. All rights reserved.
+
+ systemd 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.1 of the License, or
+ (at your option) any later version.
+
+ systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "proxy-discoveryd.h"
+
+#include "conf-parser.h"
+
+void proxy_free(Proxy *proxy) {
+ if (!proxy)
+ return;
+
+ if (proxy->manager)
+ LIST_REMOVE(proxy_next, proxy->manager->default_proxies, proxy);
+
+ free(proxy);
+}
+
+int proxy_load(Manager *manager, const char *filename, Proxy **ret) {
+ _cleanup_proxy_free_ Proxy *proxy = NULL;
+ _cleanup_fclose_ FILE *file = NULL;
+ int r;
+
+ assert(manager);
+ assert(filename);
+ assert(ret);
+
+ *ret = NULL;
+
+ file = fopen(filename, "re");
+ if (!file) {
+ if (errno == ENOENT)
+ return 0;
+ else
+ return -errno;
+ }
+
+ if (null_or_empty_fd(fileno(file))) {
+ log_debug("Skipping empty file: %s", filename);
+ return 0;
+ }
+
+ proxy = new0(Proxy, 1);
+ if (!proxy)
+ return log_oom();
+
+ proxy->manager = manager;
+
+ r = config_parse(NULL, filename, file, "Proxy\0",
+ config_item_perf_lookup,
+ proxy_discoveryd_proxy_gperf_lookup,
+ false, false, true, proxy);
+ if (r < 0)
+ return r;
+
+ *ret = proxy;
+ proxy = NULL;
+
+ return 0;
+}
diff --git a/src/proxy-discovery/proxy-discoveryd.c b/src/proxy-discovery/proxy-discoveryd.c
index f023312..b4789d1 100644
--- a/src/proxy-discovery/proxy-discoveryd.c
+++ b/src/proxy-discovery/proxy-discoveryd.c
@@ -44,6 +44,12 @@ int main(int argc, char *argv[]) {
goto out;
}
+ r = manager_load_config(m);
+ if (r < 0) {
+ log_error_errno(r, "Could not load configuration files: %m");
+ goto out;
+ }
+
sd_notify(false,
"READY=1\n"
"STATUS=Processing requests...");
diff --git a/src/proxy-discovery/proxy-discoveryd.h b/src/proxy-discovery/proxy-discoveryd.h
index 125abc0..f51fca5 100644
--- a/src/proxy-discovery/proxy-discoveryd.h
+++ b/src/proxy-discovery/proxy-discoveryd.h
@@ -24,15 +24,42 @@
#include "sd-event.h"
#include "util.h"
+#include "list.h"
typedef struct Manager Manager;
+typedef struct Proxy Proxy;
struct Manager {
sd_event *event;
+
+ LIST_HEAD(Proxy, default_proxies);
+};
+
+struct Proxy {
+ Manager *manager;
+
+ char *pac_path;
+
+ LIST_FIELDS(Proxy, proxy_next);
};
+/* Manager */
+
int manager_new(Manager **ret);
Manager *manager_free(Manager *m);
+int manager_load_config(Manager *m);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
#define _cleanup_manager_free_ _cleanup_(manager_freep)
+
+/* Proxy */
+
+void proxy_free(Proxy *proxy);
+
+int proxy_load(Manager *manager, const char *filename, Proxy **ret);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Proxy*, proxy_free);
+#define _cleanup_proxy_free_ _cleanup_(proxy_freep)
+
+const struct ConfigPerfItem* proxy_discoveryd_proxy_gperf_lookup(const char *key, unsigned length);
--
2.0.5
More information about the systemd-devel
mailing list