Speaking of spamd, I've been running the following diff for five months or so. It removes the use of time_t in the greylist db file and provides backwards compat for 32-bit times.
- todd Index: usr.sbin/spamdb/Makefile =================================================================== RCS file: /home/cvs/openbsd/src/usr.sbin/spamdb/Makefile,v retrieving revision 1.3 diff -u -p -u -r1.3 Makefile --- usr.sbin/spamdb/Makefile 24 May 2005 22:23:05 -0000 1.3 +++ usr.sbin/spamdb/Makefile 22 Apr 2013 20:03:45 -0000 @@ -1,9 +1,11 @@ # $OpenBSD: Makefile,v 1.3 2005/05/24 22:23:05 millert Exp $ PROG= spamdb -SRCS= spamdb.c +SRCS= spamdb.c gdcopy.c MAN= spamdb.8 CFLAGS+= -Wall -Wstrict-prototypes -I${.CURDIR}/../../libexec/spamd + +.PATH: ${.CURDIR}/../../libexec/spamd .include <bsd.prog.mk> Index: usr.sbin/spamdb/spamdb.c =================================================================== RCS file: /home/cvs/openbsd/src/usr.sbin/spamdb/spamdb.c,v retrieving revision 1.26 diff -u -p -u -r1.26 spamdb.c --- usr.sbin/spamdb/spamdb.c 22 Apr 2013 19:49:36 -0000 1.26 +++ usr.sbin/spamdb/spamdb.c 22 Apr 2013 20:03:45 -0000 @@ -129,12 +129,11 @@ dbupdate(DB *db, char *ip, int add, int goto bad; } } else { - if (dbd.size != sizeof(gd)) { + if (gdcopyin(&dbd, &gd) == -1) { /* whatever this is, it doesn't belong */ db->del(db, &dbk, 0); goto bad; } - memcpy(&gd, dbd.data, sizeof(gd)); gd.pcount++; switch (type) { case WHITE: @@ -185,11 +184,10 @@ dblist(DB *db) r = db->seq(db, &dbk, &dbd, R_NEXT)) { char *a, *cp; - if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) { + if ((dbk.size < 1) || gdcopyin(&dbd, &gd) == -1) { db->close(db); errx(1, "bogus size db entry - bad db file?"); } - memcpy(&gd, dbd.data, sizeof(gd)); a = malloc(dbk.size + 1); if (a == NULL) err(1, "malloc"); Index: libexec/spamd/Makefile =================================================================== RCS file: /home/cvs/openbsd/src/libexec/spamd/Makefile,v retrieving revision 1.9 diff -u -p -u -r1.9 Makefile --- libexec/spamd/Makefile 4 Mar 2007 03:19:41 -0000 1.9 +++ libexec/spamd/Makefile 22 Apr 2013 20:03:45 -0000 @@ -1,7 +1,7 @@ # $OpenBSD: Makefile,v 1.9 2007/03/04 03:19:41 beck Exp $ PROG= spamd -SRCS= spamd.c sdl.c grey.c sync.c +SRCS= spamd.c sdl.c gdcopy.c grey.c sync.c MAN= spamd.8 CFLAGS+= -Wall -Wstrict-prototypes Index: libexec/spamd/gdcopy.c =================================================================== RCS file: libexec/spamd/gdcopy.c diff -N libexec/spamd/gdcopy.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ libexec/spamd/gdcopy.c 22 Apr 2013 20:03:45 -0000 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 Todd C. Miller <todd.mil...@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <db.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "grey.h" + +/* Fill in struct gdata from DBT, converting from obsolete format as needed. */ +int +gdcopyin(const void *v, struct gdata *gd) +{ + const DBT *dbd = v; + int rc = 0; + + if (dbd->size == sizeof(struct gdata)) { + /* Current grey data format. */ + memcpy(gd, dbd->data, sizeof(struct gdata)); + } else if (dbd->size == sizeof(struct ogdata)) { + /* Backwards compat for obsolete grey data format. */ + struct ogdata ogd; + memcpy(&ogd, dbd->data, sizeof(struct ogdata)); + gd->first = ogd.first; + gd->pass = ogd.pass; + gd->expire = ogd.expire; + gd->bcount = ogd.bcount; + gd->pcount = ogd.pcount; + } else { + /* Unsupported grey data format. */ + rc = -1; + } + return (rc); +} Index: libexec/spamd/grey.c =================================================================== RCS file: /home/cvs/openbsd/src/libexec/spamd/grey.c,v retrieving revision 1.52 diff -u -p -u -r1.52 grey.c --- libexec/spamd/grey.c 2 Oct 2012 15:26:17 -0000 1.52 +++ libexec/spamd/grey.c 22 Apr 2013 20:03:45 -0000 @@ -540,7 +540,6 @@ do_changes(DB *db) int db_addrstate(DB *db, char *key) { - int i; DBT dbk, dbd; struct gdata gd; @@ -548,14 +547,18 @@ db_addrstate(DB *db, char *key) dbk.size = strlen(key); dbk.data = key; memset(&dbd, 0, sizeof(dbd)); - i = db->get(db, &dbk, &dbd, 0); - if (i == -1) - return (-1); - if (i) - /* not in the database */ + switch (db->get(db, &dbk, &dbd, 0)) { + case 1: + /* not found */ return (0); - memcpy(&gd, dbd.data, sizeof(gd)); - return gd.pcount == -1 ? 1 : 2; + case 0: + if (gdcopyin(&dbd, &gd) != -1) + return (gd.pcount == -1 ? 1 : 2); + /* FALLTHROUGH */ + default: + /* error */ + return (-1); + } } @@ -582,7 +585,7 @@ greyscan(char *dbname) memset(&dbd, 0, sizeof(dbd)); for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r; r = db->seq(db, &dbk, &dbd, R_NEXT)) { - if ((dbk.size < 1) || dbd.size != sizeof(struct gdata)) { + if ((dbk.size < 1) || gdcopyin(&dbd, &gd) == -1) { syslog_r(LOG_ERR, &sdata, "bogus entry in spamd database"); goto bad; } @@ -597,7 +600,6 @@ greyscan(char *dbname) } memset(a, 0, asiz); memcpy(a, dbk.data, dbk.size); - memcpy(&gd, dbd.data, sizeof(gd)); if (gd.expire <= now && gd.pcount != -2) { /* get rid of entry */ if (queue_change(a, NULL, 0, DBC_DEL) == -1) @@ -719,7 +721,7 @@ twupdate(char *dbname, char *what, char now = time(NULL); /* expiry times have to be in the future */ - expire = strtonum(expires, now, INT_MAX, NULL); + expire = strtonum(expires, now, sizeof(time_t) == sizeof(int) ? INT_MAX : LLONG_MAX, NULL); if (expire == 0) return(-1); @@ -766,13 +768,12 @@ twupdate(char *dbname, char *what, char expires); } else { /* existing entry */ - if (dbd.size != sizeof(gd)) { + if (gdcopyin(&dbd, &gd) == -1) { /* whatever this is, it doesn't belong */ db->del(db, &dbk, 0); db->sync(db, 0); goto bad; } - memcpy(&gd, dbd.data, sizeof(gd)); if (spamtrap) { gd.pcount = -1; gd.bcount++; @@ -889,13 +890,12 @@ greyupdate(char *dbname, char *helo, cha spamtrap ? "greytrap " : "", ip, from, to, helo); } else { /* existing entry */ - if (dbd.size != sizeof(gd)) { + if (gdcopyin(&dbd, &gd) == -1) { /* whatever this is, it doesn't belong */ db->del(db, &dbk, 0); db->sync(db, 0); goto bad; } - memcpy(&gd, dbd.data, sizeof(gd)); gd.bcount++; gd.pcount = spamtrap ? -1 : 0; if (gd.first + passtime < now) @@ -979,7 +979,7 @@ greyreader(void) sync = 1; if (grey == NULL) { syslog_r(LOG_ERR, &sdata, "No greylist pipe stream!\n"); - exit(1); + return (-1); } /* grab trap suffixes */ @@ -1140,10 +1140,11 @@ greywatcher(void) */ close(pfdev); setproctitle("(%s update)", PATH_SPAMD_DB); - greyreader(); - syslog_r(LOG_ERR, &sdata, "greyreader failed (%m)"); - /* NOTREACHED */ - _exit(1); + if (greyreader() == -1) { + syslog_r(LOG_ERR, &sdata, "greyreader failed (%m)"); + _exit(1); + } + _exit(0); } Index: libexec/spamd/grey.h =================================================================== RCS file: /home/cvs/openbsd/src/libexec/spamd/grey.h,v retrieving revision 1.9 diff -u -p -u -r1.9 grey.h --- libexec/spamd/grey.h 6 Mar 2007 23:38:36 -0000 1.9 +++ libexec/spamd/grey.h 22 Apr 2013 20:03:45 -0000 @@ -27,13 +27,23 @@ #define DB_TRAP_INTERVAL 60 * 10 #define PATH_SPAMD_DB "/var/db/spamd" +/* Obsolete grey data format. */ +struct ogdata { + int32_t first; /* when did we see it first */ + int32_t pass; /* when was it whitelisted */ + int32_t expire; /* when will we get rid of this entry */ + int bcount; /* how many times have we blocked it */ + int pcount; /* how many times passed, or -1 for spamtrap */ +}; + struct gdata { - time_t first; /* when did we see it first */ - time_t pass; /* when was it whitelisted */ - time_t expire; /* when will we get rid of this entry */ - int bcount; /* how many times have we blocked it */ - int pcount; /* how many times passed, or -1 for spamtrap */ + int64_t first; /* when did we see it first */ + int64_t pass; /* when was it whitelisted */ + int64_t expire; /* when will we get rid of this entry */ + int bcount; /* how many times have we blocked it */ + int pcount; /* how many times passed, or -1 for spamtrap */ }; extern int greywatcher(void); extern int greyupdate(char *, char *, char *, char *, char *, int, char *); +extern int gdcopyin(const void *, struct gdata *); Index: libexec/spamlogd/Makefile =================================================================== RCS file: /home/cvs/openbsd/src/libexec/spamlogd/Makefile,v retrieving revision 1.6 diff -u -p -u -r1.6 Makefile --- libexec/spamlogd/Makefile 4 Mar 2007 03:19:41 -0000 1.6 +++ libexec/spamlogd/Makefile 22 Apr 2013 20:03:45 -0000 @@ -1,7 +1,7 @@ # $OpenBSD: Makefile,v 1.6 2007/03/04 03:19:41 beck Exp $ PROG= spamlogd -SRCS= spamlogd.c sync.c +SRCS= spamlogd.c sync.c gdcopy.c MAN= spamlogd.8 CFLAGS+= -Wall -Wstrict-prototypes -I${.CURDIR}/../spamd Index: libexec/spamlogd/spamlogd.c =================================================================== RCS file: /home/cvs/openbsd/src/libexec/spamlogd/spamlogd.c,v retrieving revision 1.21 diff -u -p -u -r1.21 spamlogd.c --- libexec/spamlogd/spamlogd.c 18 Mar 2011 22:37:06 -0000 1.21 +++ libexec/spamlogd/spamlogd.c 22 Apr 2013 20:03:45 -0000 @@ -250,12 +250,12 @@ dbupdate(char *dbname, char *ip) goto bad; } } else { - if (dbd.size != sizeof(gd)) { + /* XXX - backwards compat */ + if (gdcopyin(&dbd, &gd) == -1) { /* whatever this is, it doesn't belong */ db->del(db, &dbk, 0); goto bad; } - memcpy(&gd, dbd.data, sizeof(gd)); gd.pcount++; gd.expire = now + whiteexp; memset(&dbk, 0, sizeof(dbk));