commit ca4bcfbd9d2233c90080b9ad400bf576db221781 Author: rnhmjoj Date: Sat Sep 13 13:54:00 2025 +0200 wpa_supplicant: allow multiple config files with -I This change allows to load multiple addition configuration files in wpa_supplicant by repeating the -I option. Signed-off-by: Michele Guerini Rocco diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml index df538e332..71195d0d3 100644 --- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml +++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml @@ -358,7 +358,8 @@ -I filename - Path to additional configuration file. + Path to additional configuration file + (can be repeat to add multiple files). diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c index 9229eb51f..ff877f3b9 100644 --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -76,7 +76,7 @@ static void usage(void) " -G = global ctrl_interface group\n" " -h = show this help text\n" " -i = interface name\n" - " -I = additional configuration file\n" + " -I = additional configuration file (can be repeated)\n" " -K = include keys (passwords, etc.) in debug output\n" " -L = show license (BSD)\n" #ifdef CONFIG_P2P @@ -183,7 +183,8 @@ int main(int argc, char *argv[]) { int c, i; struct wpa_interface *ifaces, *iface; - int iface_count, exitcode = -1; + int iface_count, conf_count = 0, exitcode = -1; + size_t path_size; struct wpa_params params; struct wpa_global *global; @@ -253,7 +254,15 @@ int main(int argc, char *argv[]) iface->ifname = optarg; break; case 'I': - iface->confanother = optarg; + if (conf_count >= 15) { + wpa_printf(MSG_ERROR, + "too many additional configuration files"); + goto out; + } + path_size = 1 + os_strlen(optarg); + iface->confanother[conf_count] = os_malloc(path_size); + os_memcpy(iface->confanother[conf_count], optarg, path_size); + conf_count++; break; case 'K': params.wpa_debug_show_keys++; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index d45002fd9..af5836ef5 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -675,8 +675,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) os_free(wpa_s->confname); wpa_s->confname = NULL; - os_free(wpa_s->confanother); - wpa_s->confanother = NULL; + for (i = 0; wpa_s->confanother[i] != NULL; i++) { + os_free(wpa_s->confanother[i]); + wpa_s->confanother[i] = NULL; + } os_free(wpa_s->last_con_fail_realm); wpa_s->last_con_fail_realm = NULL; @@ -1404,6 +1406,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) struct wpa_config *conf; int reconf_ctrl; int old_ap_scan; + int i; if (wpa_s->confname == NULL) return -1; @@ -1413,12 +1416,14 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) "file '%s' - exiting", wpa_s->confname); return -1; } - if (wpa_s->confanother && - !wpa_config_read(wpa_s->confanother, conf, true)) { - wpa_msg(wpa_s, MSG_ERROR, - "Failed to parse the configuration file '%s' - exiting", - wpa_s->confanother); - return -1; + + for (i = 0; wpa_s->confanother[i] != NULL; i++) { + if (!wpa_config_read(wpa_s->confanother[i], conf, true)) { + wpa_msg(wpa_s, MSG_ERROR, + "Failed to parse the configuration file '%s' - exiting", + wpa_s->confanother[i]); + return -1; + } } conf->changed_parameters = (unsigned int) -1; @@ -7658,13 +7663,16 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, "configuration '%s'.", wpa_s->confname); return -1; } - wpa_s->confanother = os_rel2abs_path(iface->confanother); - if (wpa_s->confanother && - !wpa_config_read(wpa_s->confanother, wpa_s->conf, true)) { - wpa_printf(MSG_ERROR, - "Failed to read or parse configuration '%s'.", - wpa_s->confanother); - return -1; + + for (int i = 0; iface->confanother[i] != NULL; i++) { + wpa_s->confanother[i] = os_rel2abs_path(iface->confanother[i]); + if (wpa_s->confanother[i] && + !wpa_config_read(wpa_s->confanother[i], wpa_s->conf, true)) { + wpa_printf(MSG_ERROR, + "Failed to read or parse configuration '%s'.", + wpa_s->confanother[i]); + return -1; + } } /* diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 2f77413d5..84c009e78 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -66,12 +66,12 @@ struct wpa_interface { const char *confname; /** - * confanother - Additional configuration name (file or profile) name + * confanother - Additional configuration names (file or profile) name * * This can also be %NULL when the additional configuration file is not * used. */ - const char *confanother; + char *confanother[16]; /** * ctrl_interface - Control interface parameter @@ -713,7 +713,7 @@ struct wpa_supplicant { char bridge_ifname[16]; char *confname; - char *confanother; + char *confanother[16]; struct wpa_config *conf; int countermeasures;