]>
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 | ||
2361667e | 101 | static int nw_ports_add_port(nw_ports* ports, nw_port* port) { |
c791afc8 MT |
102 | // Allocate a new entry |
103 | struct nw_ports_entry* entry = calloc(1, sizeof(*entry)); | |
104 | if (!entry) | |
105 | return 1; | |
106 | ||
107 | // Reference the port | |
108 | entry->port = nw_port_ref(port); | |
109 | ||
110 | // Add it to the list | |
111 | STAILQ_INSERT_TAIL(&ports->entries, entry, nodes); | |
112 | ||
113 | // Increment the counter | |
114 | ports->num++; | |
115 | ||
116 | return 0; | |
117 | } | |
118 | ||
119 | static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) { | |
2361667e | 120 | nw_port* port = NULL; |
c791afc8 MT |
121 | int r; |
122 | ||
2361667e | 123 | nw_ports* ports = (nw_ports*)data; |
c791afc8 MT |
124 | |
125 | // Skip anything that isn't a regular file | |
126 | if (!S_ISREG(s->st_mode)) | |
127 | return 0; | |
128 | ||
129 | // Find the basename of the file | |
130 | const char* name = nw_path_basename(path); | |
131 | ||
132 | // Break on invalid paths | |
133 | if (!name) | |
134 | return 0; | |
135 | ||
136 | // Skip any hidden files | |
137 | if (*name == '.') | |
138 | return 0; | |
139 | ||
140 | // Create a new port | |
30d4ab67 | 141 | r = nw_port_create(&port, ports->daemon, name); |
c791afc8 MT |
142 | if (r) |
143 | goto ERROR; | |
144 | ||
145 | // Add the port to the list | |
146 | r = nw_ports_add_port(ports, port); | |
147 | if (r) | |
148 | goto ERROR; | |
149 | ||
150 | ERROR: | |
151 | if (port) | |
152 | nw_port_unref(port); | |
153 | ||
154 | return r; | |
155 | } | |
156 | ||
2361667e | 157 | int nw_ports_enumerate(nw_ports* ports) { |
c791afc8 | 158 | return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); |
b8db2713 | 159 | } |
7297ba7f | 160 | |
2361667e | 161 | nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name) { |
7297ba7f MT |
162 | struct nw_ports_entry* entry = NULL; |
163 | ||
164 | STAILQ_FOREACH(entry, &ports->entries, nodes) { | |
165 | const char* __name = nw_port_name(entry->port); | |
166 | ||
167 | // If the name matches, return a reference to the zone | |
168 | if (strcmp(name, __name) == 0) | |
169 | return nw_port_ref(entry->port); | |
170 | } | |
171 | ||
172 | // No match found | |
173 | return NULL; | |
174 | } | |
175 | ||
2361667e | 176 | int nw_ports_bus_paths(nw_ports* ports, char*** paths) { |
7297ba7f MT |
177 | struct nw_ports_entry* entry = NULL; |
178 | char* path = NULL; | |
179 | ||
180 | // Allocate an array for all paths | |
181 | char** p = calloc(ports->num + 1, sizeof(*p)); | |
182 | if (!p) | |
183 | return 1; | |
184 | ||
185 | unsigned int i = 0; | |
186 | ||
187 | // Walk through all ports | |
188 | STAILQ_FOREACH(entry, &ports->entries, nodes) { | |
189 | // Generate the bus path | |
190 | path = nw_port_bus_path(entry->port); | |
191 | if (!path) | |
192 | goto ERROR; | |
193 | ||
194 | // Append the bus path to the array | |
195 | p[i++] = path; | |
196 | } | |
197 | ||
198 | // Return pointer | |
199 | *paths = p; | |
200 | ||
201 | return 0; | |
202 | ||
203 | ERROR: | |
204 | if (p) { | |
205 | for (char** e = p; *e; e++) | |
206 | free(*e); | |
207 | free(p); | |
208 | } | |
209 | ||
210 | return 1; | |
211 | } |