+
+void
+fw3_free_list(struct list_head *head)
+{
+ struct list_head *entry, *tmp;
+
+ if (!head)
+ return;
+
+ list_for_each_safe(entry, tmp, head)
+ {
+ list_del(entry);
+ free(entry);
+ }
+
+ free(head);
+}
+
+bool
+fw3_hotplug(bool add, void *zone, void *device)
+{
+ struct fw3_zone *z = zone;
+ struct fw3_device *d = device;
+
+ if (!*d->network)
+ return false;
+
+ switch (fork())
+ {
+ case -1:
+ warn("Unable to fork(): %s\n", strerror(errno));
+ return false;
+
+ case 0:
+ break;
+
+ default:
+ return true;
+ }
+
+ close(0);
+ close(1);
+ close(2);
+ chdir("/");
+
+ clearenv();
+ setenv("ACTION", add ? "add" : "remove", 1);
+ setenv("ZONE", z->name, 1);
+ setenv("INTERFACE", d->network, 1);
+ setenv("DEVICE", d->name, 1);
+
+ execl(FW3_HOTPLUG, FW3_HOTPLUG, "firewall", NULL);
+
+ /* unreached */
+ return false;
+}