summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/spamdb/spamdb.819
-rw-r--r--usr.sbin/spamdb/spamdb.c188
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");