]>
Commit | Line | Data |
---|---|---|
b8db2713 MT |
1 | /*############################################################################# |
2 | # # | |
3 | # IPFire.org - A linux based firewall # | |
4 | # Copyright (C) 2023 IPFire Network Development Team # | |
5 | # # | |
6 | # This program is free software: you can redistribute it and/or modify # | |
7 | # it under the terms of the GNU General Public License as published by # | |
8 | # the Free Software Foundation, either version 3 of the License, or # | |
9 | # (at your option) any later version. # | |
10 | # # | |
11 | # This program is distributed in the hope that it will be useful, # | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
14 | # GNU General Public License for more details. # | |
15 | # # | |
16 | # You should have received a copy of the GNU General Public License # | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
18 | # # | |
19 | #############################################################################*/ | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <string.h> | |
23 | #include <sys/queue.h> | |
c791afc8 | 24 | #include <sys/stat.h> |
b8db2713 MT |
25 | |
26 | #include "logging.h" | |
27 | #include "port.h" | |
28 | #include "ports.h" | |
c791afc8 MT |
29 | #include "string.h" |
30 | #include "util.h" | |
b8db2713 MT |
31 | |
32 | struct nw_ports_entry { | |
2361667e | 33 | nw_port* port; |
b8db2713 MT |
34 | |
35 | // Link to the other entries | |
36 | STAILQ_ENTRY(nw_ports_entry) nodes; | |
37 | }; | |
38 | ||
39 | struct nw_ports { | |
2361667e | 40 | nw_daemon* daemon; |
b8db2713 MT |
41 | int nrefs; |
42 | ||
43 | // Port Entries | |
44 | STAILQ_HEAD(entries, nw_ports_entry) entries; | |
45 | ||
46 | // A counter of the port entries | |
47 | unsigned int num; | |
48 | }; | |
49 | ||
2361667e MT |
50 | int nw_ports_create(nw_ports** ports, nw_daemon* daemon) { |
51 | nw_ports* p = calloc(1, sizeof(*p)); | |
b8db2713 MT |
52 | if (!p) |
53 | return 1; | |
54 | ||
55 | // Store a reference to the daemon | |
56 | p->daemon = nw_daemon_ref(daemon); | |
57 | ||
58 | // Initialize the reference counter | |
59 | p->nrefs = 1; | |
60 | ||
61 | // Initialize entries | |
62 | STAILQ_INIT(&p->entries); | |
63 | ||
64 | // Reference the pointer | |
65 | *ports = p; | |
66 | ||
67 | return 0; | |
68 | } | |
69 | ||
2361667e | 70 | static void nw_ports_free(nw_ports* ports) { |
b8db2713 MT |
71 | struct nw_ports_entry* entry = NULL; |
72 | ||
73 | while (!STAILQ_EMPTY(&ports->entries)) { | |
74 | entry = STAILQ_FIRST(&ports->entries); | |
75 | ||
76 | // Dereference the port | |
77 | nw_port_unref(entry->port); | |
78 | ||
79 | // Remove the entry from the list | |
80 | STAILQ_REMOVE_HEAD(&ports->entries, nodes); | |
81 | ||
82 | // Free the entry | |
83 | free(entry); | |
84 | } | |
85 | } | |
86 | ||
2361667e | 87 | nw_ports* nw_ports_ref(nw_ports* ports) { |
b8db2713 MT |
88 | ports->nrefs++; |
89 | ||
90 | return ports; | |
91 | } | |
92 | ||
2361667e | 93 | nw_ports* nw_ports_unref(nw_ports* ports) { |
b8db2713 MT |
94 | if (--ports->nrefs > 0) |
95 | return ports; | |
96 | ||
97 | nw_ports_free(ports); | |
98 | return NULL; | |
99 | } | |
100 | ||
605e975f MT |
101 | int nw_ports_save(nw_ports* ports) { |
102 | struct nw_ports_entry* entry = NULL; | |
103 | int r; | |
104 | ||
105 | STAILQ_FOREACH(entry, &ports->entries, nodes) { | |
106 | r = nw_port_save(entry->port); | |
107 | if (r) | |
108 | return r; | |
109 | } | |
110 | ||
111 | return 0; | |
112 | } | |
113 | ||
2361667e | 114 | static int nw_ports_add_port(nw_ports* ports, nw_port* port) { |
c791afc8 MT |
115 | // Allocate a new entry |
116 | struct nw_ports_entry* entry = calloc(1, sizeof(*entry)); | |
117 | if (!entry) | |
118 | return 1; | |
119 | ||
120 | // Reference the port | |
121 | entry->port = nw_port_ref(port); | |
122 | ||
123 | // Add it to the list | |
124 | STAILQ_INSERT_TAIL(&ports->entries, entry, nodes); | |
125 | ||
126 | // Increment the counter | |
127 | ports->num++; | |
128 | ||
129 | return 0; | |
130 | } | |
131 | ||
132 | static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) { | |
2361667e | 133 | nw_port* port = NULL; |
c791afc8 MT |
134 | int r; |
135 | ||
2361667e | 136 | nw_ports* ports = (nw_ports*)data; |
c791afc8 MT |
137 | |
138 | // Skip anything that isn't a regular file | |
139 | if (!S_ISREG(s->st_mode)) | |
140 | return 0; | |
141 | ||
142 | // Find the basename of the file | |
143 | const char* name = nw_path_basename(path); | |
144 | ||
145 | // Break on invalid paths | |
146 | if (!name) | |
147 | return 0; | |
148 | ||
149 | // Skip any hidden files | |
150 | if (*name == '.') | |
151 | return 0; | |
152 | ||
153 | // Create a new port | |
06bc93d3 | 154 | r = nw_port_create_from_config(&port, ports->daemon, name, path); |
c791afc8 MT |
155 | if (r) |
156 | goto ERROR; | |
157 | ||
158 | // Add the port to the list | |
159 | r = nw_ports_add_port(ports, port); | |
160 | if (r) | |
161 | goto ERROR; | |
162 | ||
163 | ERROR: | |
164 | if (port) | |
165 | nw_port_unref(port); | |
166 | ||
167 | return r; | |
168 | } | |
169 | ||
2361667e | 170 | int nw_ports_enumerate(nw_ports* ports) { |
c791afc8 | 171 | return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); |
b8db2713 | 172 | } |
7297ba7f | 173 | |
2361667e | 174 | nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name) { |
7297ba7f MT |
175 | struct nw_ports_entry* entry = NULL; |
176 | ||
177 | STAILQ_FOREACH(entry, &ports->entries, nodes) { | |
178 | const char* __name = nw_port_name(entry->port); | |
179 | ||
180 | // If the name matches, return a reference to the zone | |
181 | if (strcmp(name, __name) == 0) | |
182 | return nw_port_ref(entry->port); | |
183 | } | |
184 | ||
185 | // No match found | |
186 | return NULL; | |
187 | } | |
188 | ||
2361667e | 189 | int nw_ports_bus_paths(nw_ports* ports, char*** paths) { |
7297ba7f MT |
190 | struct nw_ports_entry* entry = NULL; |
191 | char* path = NULL; | |
192 | ||
193 | // Allocate an array for all paths | |
194 | char** p = calloc(ports->num + 1, sizeof(*p)); | |
195 | if (!p) | |
196 | return 1; | |
197 | ||
198 | unsigned int i = 0; | |
199 | ||
200 | // Walk through all ports | |
201 | STAILQ_FOREACH(entry, &ports->entries, nodes) { | |
202 | // Generate the bus path | |
203 | path = nw_port_bus_path(entry->port); | |
204 | if (!path) | |
205 | goto ERROR; | |
206 | ||
207 | // Append the bus path to the array | |
208 | p[i++] = path; | |
209 | } | |
210 | ||
211 | // Return pointer | |
212 | *paths = p; | |
213 | ||
214 | return 0; | |
215 | ||
216 | ERROR: | |
217 | if (p) { | |
218 | for (char** e = p; *e; e++) | |
219 | free(*e); | |
220 | free(p); | |
221 | } | |
222 | ||
223 | return 1; | |
224 | } | |
b9769b09 MT |
225 | |
226 | int nw_ports_walk(nw_ports* ports, nw_ports_walk_callback callback, void* data) { | |
227 | struct nw_ports_entry* entry = NULL; | |
228 | int r; | |
229 | ||
230 | STAILQ_FOREACH(entry, &ports->entries, nodes) { | |
231 | r = callback(ports->daemon, entry->port, data); | |
232 | if (r) | |
233 | return r; | |
234 | } | |
235 | ||
236 | return 0; | |
237 | } | |
238 | ||
239 | static int __nw_ports_reconfigure(nw_daemon* daemon, nw_port* port, void* data) { | |
240 | return nw_port_reconfigure(port); | |
241 | } | |
242 | ||
243 | int nw_ports_reconfigure(nw_ports* ports) { | |
244 | return nw_ports_walk(ports, __nw_ports_reconfigure, NULL); | |
245 | } |