I think this would be the way to go.

On Wed, Aug 21, 2013 at 9:14 AM, Todd C. Miller
<todd.mil...@courtesan.com> wrote:
> 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