diff options
-rw-r--r-- | usr.sbin/spamdb/spamdb.8 | 19 | ||||
-rw-r--r-- | usr.sbin/spamdb/spamdb.c | 188 |
2 files changed, 127 insertions, 80 deletions
diff --git a/usr.sbin/spamdb/spamdb.8 b/usr.sbin/spamdb/spamdb.8 index 9feb07a7cb5..3d622cd32b3 100644 --- a/usr.sbin/spamdb/spamdb.8 +++ b/usr.sbin/spamdb/spamdb.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: spamdb.8,v 1.19 2017/10/11 18:25:07 millert Exp $ +.\" $OpenBSD: spamdb.8,v 1.20 2017/10/29 19:11:34 millert Exp $ .\" .\" Copyright (c) 2004 Bob Beck. All rights reserved. .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 11 2017 $ +.Dd $Mdocdate: October 29 2017 $ .Dt SPAMDB 8 .Os .Sh NAME @@ -22,10 +22,8 @@ .Nd spamd database tool .Sh SYNOPSIS .Nm spamdb -.Oo Oo Fl Tt Oc -.Fl a Ar keys Oc -.Oo Oo Fl GTt Oc -.Fl d Ar keys Oc +.Op Fl adGTt +.Op Ar keys ... .Sh DESCRIPTION .Nm manipulates the spamd database in @@ -35,7 +33,7 @@ used for .Pp The options are as follows: .Bl -tag -width Ds -.It Fl a Ar keys +.It Fl a Add or update the entries for .Ar keys . This can be used to whitelist one or more IP addresses @@ -46,7 +44,7 @@ If any specified match entries already in the spamd database, .Nm updates the entry's time last seen to now. -.It Fl d Ar keys +.It Fl d Delete entries for .Ar keys . .It Fl G @@ -90,9 +88,12 @@ Otherwise .Ar keys must be numerical IP addresses. .Ss DATABASE OUTPUT FORMAT -If invoked without any arguments, +If invoked without any options, .Nm lists the contents of the database in a text format. +If one or more +.Ar keys +are specified, only matching entries will be printed. .Pp For SPAMTRAP entries the format is: .Pp diff --git a/usr.sbin/spamdb/spamdb.c b/usr.sbin/spamdb/spamdb.c index fb23337fd8d..f1766db50c5 100644 --- a/usr.sbin/spamdb/spamdb.c +++ b/usr.sbin/spamdb/spamdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spamdb.c,v 1.33 2017/10/12 09:28:56 jmc Exp $ */ +/* $OpenBSD: spamdb.c,v 1.34 2017/10/29 19:11:34 millert Exp $ */ /* * Copyright (c) 2004 Bob Beck. All rights reserved. @@ -186,10 +186,81 @@ dbupdate(DB *db, char *ip, int add, int type) } int +print_entry(DBT *dbk, DBT *dbd) +{ + struct gdata gd; + char *a, *cp; + + if ((dbk->size < 1) || gdcopyin(dbd, &gd) == -1) { + warnx("bogus size db entry - bad db file?"); + return (1); + } + a = malloc(dbk->size + 1); + if (a == NULL) + err(1, "malloc"); + memcpy(a, dbk->data, dbk->size); + a[dbk->size]='\0'; + cp = strchr(a, '\n'); + if (cp == NULL) { + /* this is a non-greylist entry */ + switch (gd.pcount) { + case -1: /* spamtrap hit, with expiry time */ + printf("TRAPPED|%s|%lld\n", a, + (long long)gd.expire); + break; + case -2: /* spamtrap address */ + printf("SPAMTRAP|%s\n", a); + break; + default: /* whitelist */ + printf("WHITE|%s|||%lld|%lld|%lld|%d|%d\n", a, + (long long)gd.first, (long long)gd.pass, + (long long)gd.expire, gd.bcount, + gd.pcount); + break; + } + } else { + char *helo, *from, *to; + + /* greylist entry */ + *cp = '\0'; + helo = cp + 1; + from = strchr(helo, '\n'); + if (from == NULL) { + warnx("No from part in grey key %s", a); + free(a); + return (1); + } + *from = '\0'; + from++; + to = strchr(from, '\n'); + if (to == NULL) { + /* probably old format - print it the + * with an empty HELO field instead + * of erroring out. + */ + printf("GREY|%s|%s|%s|%s|%lld|%lld|%lld|%d|%d\n", + a, "", helo, from, (long long)gd.first, + (long long)gd.pass, (long long)gd.expire, + gd.bcount, gd.pcount); + + } else { + *to = '\0'; + to++; + printf("GREY|%s|%s|%s|%s|%lld|%lld|%lld|%d|%d\n", + a, helo, from, to, (long long)gd.first, + (long long)gd.pass, (long long)gd.expire, + gd.bcount, gd.pcount); + } + } + free(a); + + return (0); +} + +int dblist(DB *db) { DBT dbk, dbd; - struct gdata gd; int r; /* walk db, list in text format */ @@ -197,80 +268,52 @@ dblist(DB *db) memset(&dbd, 0, sizeof(dbd)); for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r; r = db->seq(db, &dbk, &dbd, R_NEXT)) { - char *a, *cp; - - if ((dbk.size < 1) || gdcopyin(&dbd, &gd) == -1) { - db->close(db); - errx(1, "bogus size db entry - bad db file?"); + if (print_entry(&dbk, &dbd) != 0) { + r = -1; + break; } - a = malloc(dbk.size + 1); - if (a == NULL) - err(1, "malloc"); - memcpy(a, dbk.data, dbk.size); - a[dbk.size]='\0'; - cp = strchr(a, '\n'); - if (cp == NULL) { - /* this is a non-greylist entry */ - switch (gd.pcount) { - case -1: /* spamtrap hit, with expiry time */ - printf("TRAPPED|%s|%lld\n", a, - (long long)gd.expire); - break; - case -2: /* spamtrap address */ - printf("SPAMTRAP|%s\n", a); - break; - default: /* whitelist */ - printf("WHITE|%s|||%lld|%lld|%lld|%d|%d\n", a, - (long long)gd.first, (long long)gd.pass, - (long long)gd.expire, gd.bcount, - gd.pcount); - break; - } - } else { - char *helo, *from, *to; + } + db->close(db); + db = NULL; + return (r == -1); +} - /* greylist entry */ - *cp = '\0'; - helo = cp + 1; - from = strchr(helo, '\n'); - if (from == NULL) { - warnx("No from part in grey key %s", a); - free(a); - goto bad; - } - *from = '\0'; - from++; - to = strchr(from, '\n'); - if (to == NULL) { - /* probably old format - print it the - * with an empty HELO field instead - * of erroring out. - */ - printf("GREY|%s|%s|%s|%s|%lld|%lld|%lld|%d|%d\n", - a, "", helo, from, (long long)gd.first, - (long long)gd.pass, (long long)gd.expire, - gd.bcount, gd.pcount); - - } else { - *to = '\0'; - to++; - printf("GREY|%s|%s|%s|%s|%lld|%lld|%lld|%d|%d\n", - a, helo, from, to, (long long)gd.first, - (long long)gd.pass, (long long)gd.expire, - gd.bcount, gd.pcount); +int +dbshow(DB *db, char **addrs) +{ + DBT dbk, dbd; + int errors = 0; + char *a; + + /* look up each addr */ + while ((a = *addrs) != NULL) { + memset(&dbk, 0, sizeof(dbk)); + dbk.size = strlen(a); + dbk.data = a; + memset(&dbd, 0, sizeof(dbd)); + switch (db->get(db, &dbk, &dbd, 0)) { + case -1: + warn("db->get failed"); + errors++; + goto done; + case 0: + if (print_entry(&dbk, &dbd) != 0) { + errors++; + goto done; } + break; + case 1: + default: + /* not found */ + errors++; + break; } - free(a); + addrs++; } + done: db->close(db); db = NULL; - return (0); - bad: - db->close(db); - db = NULL; - errx(1, "incorrect db format entry"); - /* NOTREACHED */ - return (1); + return (errors); } extern char *__progname; @@ -278,7 +321,7 @@ extern char *__progname; static int usage(void) { - fprintf(stderr, "usage: %s [[-Tt] -a keys] [[-GTt] -d keys]\n", __progname); + fprintf(stderr, "usage: %s [-adGTt] [keys ...]\n", __progname); exit(1); /* NOTREACHED */ } @@ -335,7 +378,10 @@ main(int argc, char **argv) switch (action) { case 0: - return dblist(db); + if (argc) + return dbshow(db, argv); + else + return dblist(db); case 1: if (type == GREY) errx(2, "cannot add GREY entries"); |