diff options
author | Kjell Wooding <kjell@cvs.openbsd.org> | 2001-06-29 21:11:25 +0000 |
---|---|---|
committer | Kjell Wooding <kjell@cvs.openbsd.org> | 2001-06-29 21:11:25 +0000 |
commit | bde108150a758535a27eb83964b07988bf438e25 (patch) | |
tree | 20a474f19043406c6f684de163ae7aec879285c8 /sbin/pfctl/pfctl.c | |
parent | e4fc2085e569fcdd453f419d76a2aee5f81d6291 (diff) |
change load_file implementation so we can accept input on
stdin. Rewrite NAT processing loop to accomodate this fact
(we can only read the rules file once). ok theo
Diffstat (limited to 'sbin/pfctl/pfctl.c')
-rw-r--r-- | sbin/pfctl/pfctl.c | 104 |
1 files changed, 65 insertions, 39 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index a76fd5db68b..36ebeca9c7e 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.23 2001/06/28 20:30:53 dhartmei Exp $ */ +/* $OpenBSD: pfctl.c,v 1.24 2001/06/29 21:11:24 kjell Exp $ */ /* * Copyright (c) 2001, Daniel Hartmeier @@ -88,8 +88,14 @@ usage() char * load_file(char *name, size_t *len) { - FILE *file = fopen(name, "r"); - char *buf = 0; + FILE *file; + char *buf = 0, *buf2 = 0; + u_int32_t i; + + if (!strcmp(name, "-")) + file = stdin; + else + file = fopen(name, "r"); *len = 0; if (file == NULL) { @@ -97,22 +103,52 @@ load_file(char *name, size_t *len) name, strerror(errno)); return (0); } - fseek(file, 0, SEEK_END); - *len = ftell(file); - fseek(file, 0, SEEK_SET); - buf = malloc(*len); - if (buf == NULL) { - fclose(file); - fprintf(stderr, "ERROR: malloc() failed\n"); + + i = 512; /* Start with this. Grow it as req'd */ + *len = 0; + if ((buf = malloc(i)) == NULL) { + fprintf(stderr, "ERROR: could not allocate space " + "for rules file\n"); return (0); } - if (fread(buf, 1, *len, file) != *len) { - free(buf); + while (!feof(file)) { + *len += fread((buf + *len), 1, (i - *len), file); + if (*len == i) { + /* Out of space - realloc time */ + i *= 2; + if ((buf2 = realloc(buf, i)) == NULL) { + if (buf) + free(buf); + buf = NULL; + fprintf(stderr, "ERROR: realloc of " + "stdin buffer failed\n"); + return (0); + } + buf = buf2; + } + } + if (*len == i) { + /* + * file is exactly the size of our buffer. + * grow ours one so we can null terminate it + */ + if ((buf2 = realloc(buf, i+1)) == NULL) { + if (buf) + free(buf); + buf = NULL; + fprintf(stderr, "ERROR: realloc of " + "stdin buffer failed\n"); + return (0); + } + buf = buf2; + } + if (file != stdin) fclose(file); - fprintf(stderr, "ERROR: fread() failed\n"); - return (0); + buf[*len]='\0'; + if (strlen(buf) != *len) { + fprintf(stderr, "WARNING: nulls embedded in rules file\n"); + *len = strlen(buf); } - fclose(file); return (buf); } @@ -310,16 +346,21 @@ pfctl_nat(int dev, char *filename, int opts) struct pfioc_rdr pr; char *buf, *s; size_t len; - unsigned n, nr; + unsigned n, r, nr; - if ((opts & PF_OPT_NOACTION) == 0) + if ((opts & PF_OPT_NOACTION) == 0) { if (ioctl(dev, DIOCBEGINNATS, &pn.ticket)) err(1, "DIOCBEGINNATS"); + + if (ioctl(dev, DIOCBEGINRDRS, &pr.ticket)) + err(1, "DIOCBEGINRDRS"); + } buf = load_file(filename, &len); if (buf == NULL) return (1); n = 0; + r = 0; nr = 0; s = buf; do { @@ -334,25 +375,6 @@ pfctl_nat(int dev, char *filename, int opts) print_nat(&pn.nat); n++; } - } while (s < (buf + len)); - free(buf); - if ((opts & PF_OPT_NOACTION) == 0) { - if (ioctl(dev, DIOCCOMMITNATS, &pn.ticket)) - err(1, "DIOCCOMMITNATS"); - printf("%u nat entries loaded\n", n); - - if (ioctl(dev, DIOCBEGINRDRS, &pr.ticket)) - err(1, "DIOCBEGINRDRS"); - } - buf = load_file(filename, &len); - if (buf == NULL) - return (1); - n = 0; - nr = 0; - s = buf; - do { - char *line = next_line(&s); - nr++; if (*line && (*line == 'r')) if (parse_rdr(nr, line, &pr.rdr)) { if ((opts & PF_OPT_NOACTION) == 0) @@ -360,15 +382,19 @@ pfctl_nat(int dev, char *filename, int opts) err(1, "DIOCADDRDR"); if (opts & PF_OPT_VERBOSE) print_rdr(&pr.rdr); - n++; + r++; } } while (s < (buf + len)); - free(buf); + if ((opts & PF_OPT_NOACTION) == 0) { + if (ioctl(dev, DIOCCOMMITNATS, &pn.ticket)) + err(1, "DIOCCOMMITNATS"); if (ioctl(dev, DIOCCOMMITRDRS, &pr.ticket)) err(1, "DIOCCOMMITRDRS"); - printf("%u rdr entries loaded\n", n); + printf("%u nat entries loaded\n", n); + printf("%u rdr entries loaded\n", r); } + free(buf); return (0); } |