diff options
| author | David Härdeman | 2025-10-25 13:32:06 +0000 |
|---|---|---|
| committer | Álvaro Fernández Rojas | 2025-10-25 15:31:54 +0000 |
| commit | f49574e42e78cff0eeeb4d00e62b875c915e9511 (patch) | |
| tree | c510d9266cf40c04aa41ad06f329645f6104e0d0 | |
| parent | 0900202c27543f1ae81ce99a18cd3fd145966c0f (diff) | |
| download | odhcpd-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.c | 25 | ||||
| -rw-r--r-- | src/odhcpd.c | 20 | ||||
| -rw-r--r-- | src/odhcpd.h | 3 |
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; }; |