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));

Reply via email to