summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Härdeman2025-10-25 13:32:06 +0000
committerÁlvaro Fernández Rojas2025-10-25 15:31:54 +0000
commitf49574e42e78cff0eeeb4d00e62b875c915e9511 (patch)
treec510d9266cf40c04aa41ad06f329645f6104e0d0
parent0900202c27543f1ae81ce99a18cd3fd145966c0f (diff)
downloadodhcpd-f49574e42e78cff0eeeb4d00e62b875c915e9511.tar.gz
odhcpd: change "-c" cmd line arg to take a dir
After the TZ support was added, odhcpd now reads two cfg files potentially. Instead of adding a separate switch for the system UCI file, I've changed the "-c" argument to take a directory. This is more future-proof and also serves as a preparation for the global DUID PR (which will necessitate reading from the UCI "network" file as well). While I was at it, I also made some tiny improvements to the odhcpd_reload() function to avoid an unnecessary allocation. Signed-off-by: David Härdeman <david@hardeman.nu> Link: https://github.com/openwrt/odhcpd/pull/291 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-rw-r--r--src/config.c25
-rw-r--r--src/odhcpd.c20
-rw-r--r--src/odhcpd.h3
3 files changed, 35 insertions, 13 deletions
diff --git a/src/config.c b/src/config.c
index 3e916ad..7bff307 100644
--- a/src/config.c
+++ b/src/config.c
@@ -41,14 +41,13 @@ struct config config = {
.dhcp_hostsfile = NULL,
.ra_piofolder = NULL,
.ra_piofolder_fd = -1,
- .uci_cfgfile = "dhcp",
+ .uci_cfgdir = NULL,
.log_level = LOG_WARNING,
.log_level_cmdline = false,
.log_syslog = true,
};
struct sys_conf sys_conf = {
- .uci_cfgfile = "system",
.posix_tz = NULL, // "timezone"
.posix_tz_len = 0,
.tzdb_tz = NULL, // "zonename"
@@ -2226,16 +2225,27 @@ void odhcpd_reload(void)
{
struct uci_context *uci = uci_alloc_context();
struct interface *master = NULL, *i, *tmp;
+ char *uci_dhcp_path = "dhcp";
+ char *uci_system_path = "system";
if (!uci)
return;
+ if (config.uci_cfgdir) {
+ size_t dlen = strlen(config.uci_cfgdir);
+
+ uci_dhcp_path = alloca(dlen + sizeof("/dhcp"));
+ sprintf(uci_dhcp_path, "%s/dhcp", config.uci_cfgdir);
+ uci_system_path = alloca(dlen + sizeof("/system"));
+ sprintf(uci_system_path, "%s/system", config.uci_cfgdir);
+ }
+
vlist_update(&leases);
avl_for_each_element(&interfaces, i, avl)
clean_interface(i);
struct uci_package *dhcp = NULL;
- if (!uci_load(uci, config.uci_cfgfile, &dhcp)) {
+ if (!uci_load(uci, uci_dhcp_path, &dhcp)) {
struct uci_element *e;
/* 1. Global settings */
@@ -2268,9 +2278,10 @@ void odhcpd_reload(void)
}
ipv6_pxe_dump();
}
+ uci_unload(uci, dhcp);
struct uci_package *system = NULL;
- if (!uci_load(uci, sys_conf.uci_cfgfile, &system) && config.enable_tz == true) {
+ if (config.enable_tz && !uci_load(uci, uci_system_path, &system)) {
struct uci_element *e;
/* 1. System settings */
@@ -2280,12 +2291,12 @@ void odhcpd_reload(void)
set_timezone_info_from_uci(s);
}
}
+ uci_unload(uci, system);
if (config.dhcp_statefile) {
- char *path = strdup(config.dhcp_statefile);
+ char *path = strdupa(config.dhcp_statefile);
mkdir_p(dirname(path), 0755);
- free(path);
}
if (config.ra_piofolder) {
@@ -2374,8 +2385,6 @@ void odhcpd_reload(void)
close_interface(i);
}
- uci_unload(uci, dhcp);
- uci_unload(uci, system);
uci_free_context(uci);
}
diff --git a/src/odhcpd.c b/src/odhcpd.c
index 0f314bf..38d96fd 100644
--- a/src/odhcpd.c
+++ b/src/odhcpd.c
@@ -91,7 +91,7 @@ static void print_usage(const char *app)
#endif /* EXT_CER_ID */
"\n"
"\n"
- " -c <path> Use an alternative configuration file\n"
+ " -c <dir> Read UCI configuration files from <dir>\n"
" -l <int> Specify log level 0..7 (default %d)\n"
" -f Log to stderr instead of syslog\n"
" -h Print this help text and exit\n",
@@ -117,9 +117,23 @@ int main(int argc, char **argv)
while ((opt = getopt(argc, argv, "c:l:fh")) != -1) {
switch (opt) {
case 'c':
- config.uci_cfgfile = realpath(optarg, NULL);
- fprintf(stderr, "Configuration will be read from %s\n", config.uci_cfgfile);
+ struct stat sb;
+ char *path;
+
+ free(config.uci_cfgdir);
+ config.uci_cfgdir = NULL;
+
+ path = realpath(optarg, NULL);
+ if (!path || stat(path, &sb) || !S_ISDIR(sb.st_mode)) {
+ fprintf(stderr, "%s is not a directory, ignoring\n", optarg);
+ free(path);
+ break;
+ }
+
+ fprintf(stderr, "Configuration will be read from %s\n", path);
+ config.uci_cfgdir = path;
break;
+
case 'l':
config.log_level = (atoi(optarg) & LOG_PRIMASK);
config.log_level_cmdline = true;
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 693da99..f2e2e74 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -194,7 +194,7 @@ struct config {
char *ra_piofolder;
int ra_piofolder_fd;
- char *uci_cfgfile;
+ char *uci_cfgdir;
int log_level;
bool log_level_cmdline;
bool log_syslog;
@@ -203,7 +203,6 @@ struct config {
struct sys_conf {
uint8_t *posix_tz;
size_t posix_tz_len;
- char *uci_cfgfile;
uint8_t *tzdb_tz;
size_t tzdb_tz_len;
};