#include "bus.h"
#include "daemon.h"
#include "logging.h"
+#include "zone-bus.h"
static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* error) {
struct nw_daemon* daemon = (struct nw_daemon*)data;
.path = "/org/ipfire/network1",
.interface = "org.ipfire.network1",
.vtables = BUS_VTABLES(daemon_vtable),
+ .children = BUS_IMPLEMENTATIONS(&zone_bus_impl),
};
static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) {
}
}
+ // Register the node enumerator
+ if (impl->node_enumerator) {
+ r = sd_bus_add_node_enumerator(bus, NULL, impl->path, impl->node_enumerator, data);
+ if (r < 0) {
+ ERROR("Could not add the node enumerator for %s: %m\n", impl->path);
+ return 1;
+ }
+ }
+
+ // Register any child implementations
+ for (int i = 0; impl->children && impl->children[i]; i++) {
+ r = nw_bus_register_implementation(bus, impl->children[i], data);
+ if (r)
+ return r;
+ }
+
return 0;
}
const char* interface;
const sd_bus_vtable** vtables;
+ sd_bus_node_enumerator_t node_enumerator;
+ const struct nw_bus_implementation** children;
};
+#define BUS_IMPLEMENTATIONS(...) ((const struct nw_bus_implementation* []) { __VA_ARGS__, NULL })
#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
int nw_bus_register_implementation(sd_bus* bus,
#############################################################################*/
#include "bus.h"
+#include "daemon.h"
+#include "logging.h"
+#include "zone.h"
#include "zone-bus.h"
+#include "zones.h"
+
+static int nw_zone_node_enumerator(sd_bus* bus, const char* path, void* data,
+ char*** nodes, sd_bus_error* error) {
+ int r;
+
+ DEBUG("Enumerating zones...\n");
+
+ // Fetch a reference to the daemon
+ struct nw_daemon* daemon = (struct nw_daemon*)data;
+
+ // Fetch zones
+ struct nw_zones* zones = nw_daemon_zones(daemon);
+
+ // Make bus paths for all zones
+ r = nw_zones_bus_paths(zones, nodes);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ nw_zones_unref(zones);
+
+ return r;
+}
const struct nw_bus_implementation zone_bus_impl = {
"/org/ipfire/network1/zone",
"org.ipfire.network1.Zone",
+ //.fallback_vtables = BUS_FALLBACK_VTABLES({zone_bus_vtable, nw_zone_object_find}),
+ .node_enumerator = nw_zone_node_enumerator,
};
#include <limits.h>
#include <stdlib.h>
+#include <systemd/sd-bus.h>
+
#include "config.h"
#include "string.h"
#include "zone.h"
const char* nw_zone_name(struct nw_zone* zone) {
return zone->name;
}
+
+char* nw_zone_bus_path(struct nw_zone* zone) {
+ char* p = NULL;
+ int r;
+
+ // Encode the bus path
+ r = sd_bus_path_encode("/org/ipfire/network1/zone", zone->name, &p);
+ if (r < 0)
+ return NULL;
+
+ return p;
+}
const char* nw_zone_name(struct nw_zone* zone);
+char* nw_zone_bus_path(struct nw_zone* zone);
+
#endif /* NETWORKD_ZONE_H */
struct nw_zones {
int nrefs;
+ // Zone Entries
STAILQ_HEAD(entries, nw_zones_entry) entries;
+
+ // A counter of the zone entries
+ unsigned int num;
};
static int nw_zones_create(struct nw_zones** zones) {
// Add it to the list
STAILQ_INSERT_TAIL(&zones->entries, entry, nodes);
+ // Increment the counter
+ zones->num++;
+
return 0;
}
// No match found
return NULL;
}
+
+int nw_zones_bus_paths(struct nw_zones* zones, char*** paths) {
+ struct nw_zones_entry* entry = NULL;
+ char* path = NULL;
+
+ // Allocate an array for all paths
+ char** p = calloc(zones->num + 1, sizeof(*p));
+ if (!p)
+ return 1;
+
+ unsigned int i = 0;
+
+ // Walk through all zones
+ STAILQ_FOREACH(entry, &zones->entries, nodes) {
+ // Generate the bus path
+ path = nw_zone_bus_path(entry->zone);
+ if (!path)
+ goto ERROR;
+
+ // Append the bus path to the array
+ p[i++] = path;
+ }
+
+ // Return pointer
+ *paths = p;
+
+ return 0;
+
+ERROR:
+ if (p) {
+ for (char** e = p; *e; e++)
+ free(*e);
+ free(p);
+ }
+
+ return 1;
+}
struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name);
+int nw_zones_bus_paths(struct nw_zones* zones, char*** paths);
+
#endif /* NETWORKD_ZONES_H */