Fix parsing of '*' device and 'all' protocol value
[project/firewall3.git] / utils.c
diff --git a/utils.c b/utils.c
index 1942cbc..e7a2215 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -244,6 +244,7 @@ __fw3_command_pipe(bool silent, const char *command, ...)
                signal(SIGPIPE, SIG_IGN);
                pipe_pid = pid;
                close(pfds[0]);
+               fcntl(pfds[1], F_SETFD, fcntl(pfds[1], F_GETFD) | FD_CLOEXEC);
        }
 
        pipe_fd = fdopen(pfds[1], "w");
@@ -408,6 +409,8 @@ fw3_read_statefile(void *state)
 
                                zone->name = strdup(name);
                                list_add_tail(&zone->list, &s->zones);
+
+                               setbit(flags[0], FW3_FLAG_DELETED);
                        }
 
                        zone->flags[0] = flags[0];
@@ -425,6 +428,8 @@ fw3_read_statefile(void *state)
 
                                ipset->name = strdup(name);
                                list_add_tail(&ipset->list, &s->ipsets);
+
+                               setbit(flags[0], FW3_FLAG_DELETED);
                        }
 
                        ipset->flags[0] = flags[0];
@@ -493,6 +498,9 @@ fw3_write_statefile(void *state)
 
        list_for_each_entry(z, &s->running_zones, running_list)
        {
+               if (hasbit(z->flags[0], FW3_FLAG_DELETED))
+                       continue;
+
                if (fw3_no_table(z->flags[0]) && fw3_no_table(z->flags[1]))
                        continue;
 
@@ -511,6 +519,9 @@ fw3_write_statefile(void *state)
 
        list_for_each_entry(i, &s->running_ipsets, running_list)
        {
+               if (hasbit(z->flags[0], FW3_FLAG_DELETED))
+                       continue;
+
                if (!fw3_no_family(i->flags[0]) || !fw3_no_family(i->flags[1]))
                {
                        fprintf(sf, "%x %s %x %x\n",
@@ -597,3 +608,43 @@ fw3_pr_rulespec(int table, int family, uint32_t *flags, uint32_t mask,
 
        return rv;
 }
+
+
+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->name,       1);
+       setenv("DEVICE",    d->name,                1);
+
+       execl(FW3_HOTPLUG, FW3_HOTPLUG, "firewall", NULL);
+
+       /* unreached */
+       return false;
+}