lol
1commit ca4bcfbd9d2233c90080b9ad400bf576db221781
2Author: rnhmjoj <rnhmjoj@inventati.org>
3Date: Sat Sep 13 13:54:00 2025 +0200
4
5 wpa_supplicant: allow multiple config files with -I
6
7 This change allows to load multiple addition configuration files in
8 wpa_supplicant by repeating the -I option.
9
10 Signed-off-by: Michele Guerini Rocco <rnhmjoj@inventati.org>
11
12diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
13index df538e332..71195d0d3 100644
14--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
15+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
16@@ -358,7 +358,8 @@
17 <varlistentry>
18 <term>-I filename</term>
19 <listitem>
20- <para>Path to additional configuration file.</para>
21+ <para>Path to additional configuration file
22+ (can be repeat to add multiple files).</para>
23 </listitem>
24 </varlistentry>
25
26diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
27index 9229eb51f..ff877f3b9 100644
28--- a/wpa_supplicant/main.c
29+++ b/wpa_supplicant/main.c
30@@ -76,7 +76,7 @@ static void usage(void)
31 " -G = global ctrl_interface group\n"
32 " -h = show this help text\n"
33 " -i = interface name\n"
34- " -I = additional configuration file\n"
35+ " -I = additional configuration file (can be repeated)\n"
36 " -K = include keys (passwords, etc.) in debug output\n"
37 " -L = show license (BSD)\n"
38 #ifdef CONFIG_P2P
39@@ -183,7 +183,8 @@ int main(int argc, char *argv[])
40 {
41 int c, i;
42 struct wpa_interface *ifaces, *iface;
43- int iface_count, exitcode = -1;
44+ int iface_count, conf_count = 0, exitcode = -1;
45+ size_t path_size;
46 struct wpa_params params;
47 struct wpa_global *global;
48
49@@ -253,7 +254,15 @@ int main(int argc, char *argv[])
50 iface->ifname = optarg;
51 break;
52 case 'I':
53- iface->confanother = optarg;
54+ if (conf_count >= 15) {
55+ wpa_printf(MSG_ERROR,
56+ "too many additional configuration files");
57+ goto out;
58+ }
59+ path_size = 1 + os_strlen(optarg);
60+ iface->confanother[conf_count] = os_malloc(path_size);
61+ os_memcpy(iface->confanother[conf_count], optarg, path_size);
62+ conf_count++;
63 break;
64 case 'K':
65 params.wpa_debug_show_keys++;
66diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
67index d45002fd9..af5836ef5 100644
68--- a/wpa_supplicant/wpa_supplicant.c
69+++ b/wpa_supplicant/wpa_supplicant.c
70@@ -675,8 +675,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
71 os_free(wpa_s->confname);
72 wpa_s->confname = NULL;
73
74- os_free(wpa_s->confanother);
75- wpa_s->confanother = NULL;
76+ for (i = 0; wpa_s->confanother[i] != NULL; i++) {
77+ os_free(wpa_s->confanother[i]);
78+ wpa_s->confanother[i] = NULL;
79+ }
80
81 os_free(wpa_s->last_con_fail_realm);
82 wpa_s->last_con_fail_realm = NULL;
83@@ -1404,6 +1406,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
84 struct wpa_config *conf;
85 int reconf_ctrl;
86 int old_ap_scan;
87+ int i;
88
89 if (wpa_s->confname == NULL)
90 return -1;
91@@ -1413,12 +1416,14 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
92 "file '%s' - exiting", wpa_s->confname);
93 return -1;
94 }
95- if (wpa_s->confanother &&
96- !wpa_config_read(wpa_s->confanother, conf, true)) {
97- wpa_msg(wpa_s, MSG_ERROR,
98- "Failed to parse the configuration file '%s' - exiting",
99- wpa_s->confanother);
100- return -1;
101+
102+ for (i = 0; wpa_s->confanother[i] != NULL; i++) {
103+ if (!wpa_config_read(wpa_s->confanother[i], conf, true)) {
104+ wpa_msg(wpa_s, MSG_ERROR,
105+ "Failed to parse the configuration file '%s' - exiting",
106+ wpa_s->confanother[i]);
107+ return -1;
108+ }
109 }
110
111 conf->changed_parameters = (unsigned int) -1;
112@@ -7658,13 +7663,16 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
113 "configuration '%s'.", wpa_s->confname);
114 return -1;
115 }
116- wpa_s->confanother = os_rel2abs_path(iface->confanother);
117- if (wpa_s->confanother &&
118- !wpa_config_read(wpa_s->confanother, wpa_s->conf, true)) {
119- wpa_printf(MSG_ERROR,
120- "Failed to read or parse configuration '%s'.",
121- wpa_s->confanother);
122- return -1;
123+
124+ for (int i = 0; iface->confanother[i] != NULL; i++) {
125+ wpa_s->confanother[i] = os_rel2abs_path(iface->confanother[i]);
126+ if (wpa_s->confanother[i] &&
127+ !wpa_config_read(wpa_s->confanother[i], wpa_s->conf, true)) {
128+ wpa_printf(MSG_ERROR,
129+ "Failed to read or parse configuration '%s'.",
130+ wpa_s->confanother[i]);
131+ return -1;
132+ }
133 }
134
135 /*
136diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
137index 2f77413d5..84c009e78 100644
138--- a/wpa_supplicant/wpa_supplicant_i.h
139+++ b/wpa_supplicant/wpa_supplicant_i.h
140@@ -66,12 +66,12 @@ struct wpa_interface {
141 const char *confname;
142
143 /**
144- * confanother - Additional configuration name (file or profile) name
145+ * confanother - Additional configuration names (file or profile) name
146 *
147 * This can also be %NULL when the additional configuration file is not
148 * used.
149 */
150- const char *confanother;
151+ char *confanother[16];
152
153 /**
154 * ctrl_interface - Control interface parameter
155@@ -713,7 +713,7 @@ struct wpa_supplicant {
156 char bridge_ifname[16];
157
158 char *confname;
159- char *confanother;
160+ char *confanother[16];
161
162 struct wpa_config *conf;
163 int countermeasures;