From 39c9fc70c3395b3163e8882ebf120288f45d5bc5 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 18 Feb 2022 19:55:27 +0000 Subject: [PATCH 1/1] Parameteraizable retry DB record size limit. Bug 2535 --- src/src/dbstuff.h | 362 +++++++++++++++++++++++++--------------------- src/src/retry.c | 2 +- 2 files changed, 196 insertions(+), 168 deletions(-) diff --git a/src/src/dbstuff.h b/src/src/dbstuff.h index ce3272c4a..ee49d818d 100644 --- a/src/src/dbstuff.h +++ b/src/src/dbstuff.h @@ -18,80 +18,87 @@ databases are also kept in this file, which is used by the maintenance utilities as well as the main Exim binary. */ -# ifdef USE_TDB +#ifdef USE_TDB /* ************************* tdb interface ************************ */ -#include +# include /* Basic DB type */ -#define EXIM_DB TDB_CONTEXT +# define EXIM_DB TDB_CONTEXT /* Cursor type: tdb uses the previous "key" in _nextkey() (really it wants tdb_traverse to be called) */ -#define EXIM_CURSOR TDB_DATA +# define EXIM_CURSOR TDB_DATA /* The datum type used for queries */ -#define EXIM_DATUM TDB_DATA +# define EXIM_DATUM TDB_DATA /* Some text for messages */ -#define EXIM_DBTYPE "tdb" +# define EXIM_DBTYPE "tdb" /* Access functions */ /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */ -#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ *(dbpp) = tdb_open(CS name, 0, TDB_DEFAULT, flags, mode) /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -#define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ (data = tdb_fetch(db, key), data.dptr != NULL) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -#define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ tdb_store(db, key, data, TDB_REPLACE) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -#define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ tdb_store(db, key, data, TDB_INSERT) /* Returns from EXIM_DBPUTB */ -#define EXIM_DBPUTB_OK 0 -#define EXIM_DBPUTB_DUP (-1) +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP (-1) /* EXIM_DBDEL */ -#define EXIM_DBDEL(db, key) tdb_delete(db, key) +# define EXIM_DBDEL(db, key) tdb_delete(db, key) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */ -#define EXIM_DBCREATE_CURSOR(db, cursor) { \ +# define EXIM_DBCREATE_CURSOR(db, cursor) { \ *(cursor) = store_malloc(sizeof(TDB_DATA)); (*(cursor))->dptr = NULL; } /* EXIM_DBSCAN - This is complicated because we have to free the last datum free() must not die when passed NULL */ -#define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ (key = (first ? tdb_firstkey(db) : tdb_nextkey(db, *(cursor))), \ free((cursor)->dptr), *(cursor) = key, \ key.dptr != NULL) /* EXIM_DBDELETE_CURSOR - terminate scanning operation. */ -#define EXIM_DBDELETE_CURSOR(cursor) store_free(cursor) +# define EXIM_DBDELETE_CURSOR(cursor) store_free(cursor) /* EXIM_DBCLOSE */ -#define EXIM_DBCLOSE__(db) tdb_close(db) +# define EXIM_DBCLOSE__(db) tdb_close(db) /* Datum access types - these are intended to be assignable */ -#define EXIM_DATUM_SIZE(datum) (datum).dsize -#define EXIM_DATUM_DATA(datum) (datum).dptr +# define EXIM_DATUM_SIZE(datum) (datum).dsize +# define EXIM_DATUM_DATA(datum) (datum).dptr /* Free the stuff inside the datum. */ -#define EXIM_DATUM_FREE(datum) (free((datum).dptr), (datum).dptr = NULL) +# define EXIM_DATUM_FREE(datum) (free((datum).dptr), (datum).dptr = NULL) /* No initialization is needed. */ -#define EXIM_DATUM_INIT(datum) +# define EXIM_DATUM_INIT(datum) + +/* size limit */ + +# define EXIM_DB_RLIMIT 150 + + + @@ -99,40 +106,40 @@ free() must not die when passed NULL */ #elif defined USE_DB -#include +# include /* We can distinguish between versions 1.x and 2.x/3.x by looking for a definition of DB_VERSION_STRING, which is present in versions 2.x onwards. */ -#ifdef DB_VERSION_STRING +# ifdef DB_VERSION_STRING -# if DB_VERSION_MAJOR >= 6 -# error Version 6 and later BDB API is not supported -# endif +# if DB_VERSION_MAJOR >= 6 +# error Version 6 and later BDB API is not supported +# endif /* The API changed (again!) between the 2.x and 3.x versions */ -#if DB_VERSION_MAJOR >= 3 +# if DB_VERSION_MAJOR >= 3 /***************** Berkeley db 3.x/4.x native definitions ******************/ /* Basic DB type */ -# if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) -# define EXIM_DB DB_ENV +# if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) +# define EXIM_DB DB_ENV /* Cursor type, for scanning */ -# define EXIM_CURSOR DBC +# define EXIM_CURSOR DBC /* The datum type used for queries */ -# define EXIM_DATUM DBT +# define EXIM_DATUM DBT /* Some text for messages */ -# define EXIM_DBTYPE "db (v4.1+)" +# define EXIM_DBTYPE "db (v4.1+)" /* Only more-recent versions. 5+ ? */ -# ifndef DB_FORCESYNC -# define DB_FORCESYNC 0 -# endif +# ifndef DB_FORCESYNC +# define DB_FORCESYNC 0 +# endif /* Access functions */ @@ -141,9 +148,9 @@ definition of DB_VERSION_STRING, which is present in versions 2.x onwards. */ API changed for DB 4.1. - and we also starting using the "env" with a specified working dir, to avoid the DBCONFIG file trap. */ -# define ENV_TO_DB(env) ((DB *)((env)->app_private)) +# define ENV_TO_DB(env) ((DB *)((env)->app_private)) -# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ if ( db_env_create(dbpp, 0) != 0 \ || ((*dbpp)->set_errcall(*dbpp, dbfn_bdb_error_callback), 0) \ || (*dbpp)->open(*dbpp, CS dirname, DB_CREATE|DB_INIT_MPOOL|DB_PRIVATE, 0) != 0\ @@ -166,72 +173,72 @@ specified working dir, to avoid the DBCONFIG file trap. */ } /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -# define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ (ENV_TO_DB(db)->get(ENV_TO_DB(db), NULL, &key, &data, 0) == 0) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -# define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ ENV_TO_DB(db)->put(ENV_TO_DB(db), NULL, &key, &data, 0) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -# define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ ENV_TO_DB(db)->put(ENV_TO_DB(db), NULL, &key, &data, DB_NOOVERWRITE) /* Return values from EXIM_DBPUTB */ -# define EXIM_DBPUTB_OK 0 -# define EXIM_DBPUTB_DUP DB_KEYEXIST +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP DB_KEYEXIST /* EXIM_DBDEL */ -# define EXIM_DBDEL(db, key) ENV_TO_DB(db)->del(ENV_TO_DB(db), NULL, &key, 0) +# define EXIM_DBDEL(db, key) ENV_TO_DB(db)->del(ENV_TO_DB(db), NULL, &key, 0) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */ -# define EXIM_DBCREATE_CURSOR(db, cursor) \ +# define EXIM_DBCREATE_CURSOR(db, cursor) \ ENV_TO_DB(db)->cursor(ENV_TO_DB(db), NULL, cursor, 0) /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */ -# define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ ((cursor)->c_get(cursor, &key, &data, \ (first? DB_FIRST : DB_NEXT)) == 0) /* EXIM_DBDELETE_CURSOR - terminate scanning operation */ -# define EXIM_DBDELETE_CURSOR(cursor) \ +# define EXIM_DBDELETE_CURSOR(cursor) \ (cursor)->c_close(cursor) /* EXIM_DBCLOSE */ -# define EXIM_DBCLOSE__(db) \ +# define EXIM_DBCLOSE__(db) \ (ENV_TO_DB(db)->close(ENV_TO_DB(db), 0) , ((DB_ENV *)(db))->close((DB_ENV *)(db), DB_FORCESYNC)) /* Datum access types - these are intended to be assignable. */ -# define EXIM_DATUM_SIZE(datum) (datum).size -# define EXIM_DATUM_DATA(datum) (datum).data +# define EXIM_DATUM_SIZE(datum) (datum).size +# define EXIM_DATUM_DATA(datum) (datum).data /* The whole datum structure contains other fields that must be cleared before use, but we don't have to free anything after reading data. */ -# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum)) -# define EXIM_DATUM_FREE(datum) +# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum)) +# define EXIM_DATUM_FREE(datum) -# else /* pre- 4.1 */ +# else /* pre- 4.1 */ -# define EXIM_DB DB +# define EXIM_DB DB /* Cursor type, for scanning */ -# define EXIM_CURSOR DBC +# define EXIM_CURSOR DBC /* The datum type used for queries */ -# define EXIM_DATUM DBT +# define EXIM_DATUM DBT /* Some text for messages */ -# define EXIM_DBTYPE "db (v3/4)" +# define EXIM_DBTYPE "db (v3/4)" /* Access functions */ /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. */ -# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ if (db_create(dbpp, NULL, 0) != 0 || \ ((*dbpp)->set_errcall(*dbpp, dbfn_bdb_error_callback), \ ((*dbpp)->open)(*dbpp, CS name, NULL, \ @@ -240,99 +247,99 @@ before use, but we don't have to free anything after reading data. */ mode)) != 0) *(dbpp) = NULL /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -# define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ ((db)->get(db, NULL, &key, &data, 0) == 0) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -# define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ (db)->put(db, NULL, &key, &data, 0) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -# define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ (db)->put(db, NULL, &key, &data, DB_NOOVERWRITE) /* Return values from EXIM_DBPUTB */ -# define EXIM_DBPUTB_OK 0 -# define EXIM_DBPUTB_DUP DB_KEYEXIST +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP DB_KEYEXIST /* EXIM_DBDEL */ -# define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0) +# define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */ -# define EXIM_DBCREATE_CURSOR(db, cursor) \ +# define EXIM_DBCREATE_CURSOR(db, cursor) \ (db)->cursor(db, NULL, cursor, 0) /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */ -# define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ ((cursor)->c_get(cursor, &key, &data, \ (first? DB_FIRST : DB_NEXT)) == 0) /* EXIM_DBDELETE_CURSOR - terminate scanning operation */ -# define EXIM_DBDELETE_CURSOR(cursor) \ +# define EXIM_DBDELETE_CURSOR(cursor) \ (cursor)->c_close(cursor) /* EXIM_DBCLOSE */ -# define EXIM_DBCLOSE__(db) (db)->close(db, 0) +# define EXIM_DBCLOSE__(db) (db)->close(db, 0) /* Datum access types - these are intended to be assignable. */ -# define EXIM_DATUM_SIZE(datum) (datum).size -# define EXIM_DATUM_DATA(datum) (datum).data +# define EXIM_DATUM_SIZE(datum) (datum).size +# define EXIM_DATUM_DATA(datum) (datum).data /* The whole datum structure contains other fields that must be cleared before use, but we don't have to free anything after reading data. */ -# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum)) -# define EXIM_DATUM_FREE(datum) +# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum)) +# define EXIM_DATUM_FREE(datum) -# endif +# endif -#else /* DB_VERSION_MAJOR >= 3 */ +# else /* DB_VERSION_MAJOR >= 3 */ /******************* Berkeley db 2.x native definitions ********************/ /* Basic DB type */ -#define EXIM_DB DB +# define EXIM_DB DB /* Cursor type, for scanning */ -#define EXIM_CURSOR DBC +# define EXIM_CURSOR DBC /* The datum type used for queries */ -#define EXIM_DATUM DBT +# define EXIM_DATUM DBT /* Some text for messages */ -#define EXIM_DBTYPE "db (v2)" +# define EXIM_DBTYPE "db (v2)" /* Access functions */ /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */ -#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ if ((errno = db_open(CS name, DB_HASH, \ ((flags) == O_RDONLY)? DB_RDONLY : DB_CREATE, \ mode, NULL, NULL, dbpp)) != 0) *(dbpp) = NULL /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -#define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ ((db)->get(db, NULL, &key, &data, 0) == 0) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -#define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ (db)->put(db, NULL, &key, &data, 0) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -#define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ (db)->put(db, NULL, &key, &data, DB_NOOVERWRITE) /* Return values from EXIM_DBPUTB */ -#define EXIM_DBPUTB_OK 0 -#define EXIM_DBPUTB_DUP DB_KEYEXIST +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP DB_KEYEXIST /* EXIM_DBDEL */ -#define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0) +# define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */ @@ -340,57 +347,57 @@ before use, but we don't have to free anything after reading data. */ not know exactly where the change happened, but the Change Log for 2.5.9 lists the new option that is available, so I guess that it happened at 2.5.x. */ -#if DB_VERSION_MINOR >= 5 -#define EXIM_DBCREATE_CURSOR(db, cursor) \ +# if DB_VERSION_MINOR >= 5 +# define EXIM_DBCREATE_CURSOR(db, cursor) \ (db)->cursor(db, NULL, cursor, 0) -#else -#define EXIM_DBCREATE_CURSOR(db, cursor) \ +# else +# define EXIM_DBCREATE_CURSOR(db, cursor) \ (db)->cursor(db, NULL, cursor) -#endif +# endif /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */ -#define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ ((cursor)->c_get(cursor, &key, &data, \ (first? DB_FIRST : DB_NEXT)) == 0) /* EXIM_DBDELETE_CURSOR - terminate scanning operation */ -#define EXIM_DBDELETE_CURSOR(cursor) \ +# define EXIM_DBDELETE_CURSOR(cursor) \ (cursor)->c_close(cursor) /* EXIM_DBCLOSE */ -#define EXIM_DBCLOSE__(db) (db)->close(db, 0) +# define EXIM_DBCLOSE__(db) (db)->close(db, 0) /* Datum access types - these are intended to be assignable. */ -#define EXIM_DATUM_SIZE(datum) (datum).size -#define EXIM_DATUM_DATA(datum) (datum).data +# define EXIM_DATUM_SIZE(datum) (datum).size +# define EXIM_DATUM_DATA(datum) (datum).data /* The whole datum structure contains other fields that must be cleared before use, but we don't have to free anything after reading data. */ -#define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum)) -#define EXIM_DATUM_FREE(datum) +# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum)) +# define EXIM_DATUM_FREE(datum) -#endif /* DB_VERSION_MAJOR >= 3 */ +# endif /* DB_VERSION_MAJOR >= 3 */ /* If DB_VERSION_TYPE is not defined, we have version 1.x */ -#else /* DB_VERSION_TYPE */ +# else /* DB_VERSION_TYPE */ /******************* Berkeley db 1.x native definitions ********************/ /* Basic DB type */ -#define EXIM_DB DB +# define EXIM_DB DB /* Cursor type, not used with DB 1.x: just set up a dummy */ -#define EXIM_CURSOR int +# define EXIM_CURSOR int /* The datum type used for queries */ -#define EXIM_DATUM DBT +# define EXIM_DATUM DBT /* Some text for messages */ -#define EXIM_DBTYPE "db (v1)" +# define EXIM_DBTYPE "db (v1)" /* When scanning, for the non-first case we historically just passed 0 as the flags field and it worked. On FreeBSD 8 it no longer works and @@ -399,61 +406,70 @@ R_NEXT, but this 1.x is a historical fallback and I've no idea how portable the use of that flag is; so the solution is to define R_NEXT here if it's not already defined, with a default value of 0 because that's what we've always before been able to pass successfully. */ -#ifndef R_NEXT -#define R_NEXT 0 -#endif +# ifndef R_NEXT +# define R_NEXT 0 +# endif /* Access functions */ /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */ -#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ *(dbpp) = dbopen(CS name, flags, mode, DB_HASH, NULL) /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -#define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ ((db)->get(db, &key, &data, 0) == 0) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -#define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ (db)->put(db, &key, &data, 0) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -#define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ (db)->put(db, &key, &data, R_NOOVERWRITE) /* Returns from EXIM_DBPUTB */ -#define EXIM_DBPUTB_OK 0 -#define EXIM_DBPUTB_DUP 1 +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP 1 /* EXIM_DBDEL */ -#define EXIM_DBDEL(db, key) (db)->del(db, &key, 0) +# define EXIM_DBDEL(db, key) (db)->del(db, &key, 0) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */ -#define EXIM_DBCREATE_CURSOR(db, cursor) {} +# define EXIM_DBCREATE_CURSOR(db, cursor) {} /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */ -#define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ ((db)->seq(db, &key, &data, (first? R_FIRST : R_NEXT)) == 0) /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). */ -#define EXIM_DBDELETE_CURSOR(cursor) { } +# define EXIM_DBDELETE_CURSOR(cursor) { } /* EXIM_DBCLOSE */ -#define EXIM_DBCLOSE__(db) (db)->close(db) +# define EXIM_DBCLOSE__(db) (db)->close(db) /* Datum access types - these are intended to be assignable */ -#define EXIM_DATUM_SIZE(datum) (datum).size -#define EXIM_DATUM_DATA(datum) (datum).data +# define EXIM_DATUM_SIZE(datum) (datum).size +# define EXIM_DATUM_DATA(datum) (datum).data /* There's no clearing required before use, and we don't have to free anything after reading data. */ -#define EXIM_DATUM_INIT(datum) -#define EXIM_DATUM_FREE(datum) +# define EXIM_DATUM_INIT(datum) +# define EXIM_DATUM_FREE(datum) + +# endif /* DB_VERSION_STRING */ + + +/* all BDB versions */ +/* size limit */ + +# define EXIM_DB_RLIMIT 150 + + -#endif /* DB_VERSION_STRING */ @@ -461,7 +477,7 @@ after reading data. */ #elif defined USE_GDBM -#include +# include /* Basic DB type */ typedef struct { @@ -470,19 +486,19 @@ typedef struct { } EXIM_DB; /* Cursor type, not used with gdbm: just set up a dummy */ -#define EXIM_CURSOR int +# define EXIM_CURSOR int /* The datum type used for queries */ -#define EXIM_DATUM datum +# define EXIM_DATUM datum /* Some text for messages */ -#define EXIM_DBTYPE "gdbm" +# define EXIM_DBTYPE "gdbm" /* Access functions */ /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */ -#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ { (*(dbpp)) = (EXIM_DB *) malloc(sizeof(EXIM_DB));\ if (*(dbpp) != NULL) { \ (*(dbpp))->lkey.dptr = NULL;\ @@ -495,127 +511,139 @@ typedef struct { } /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -#define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ (data = gdbm_fetch(db->gdbm, key), data.dptr != NULL) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -#define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ gdbm_store(db->gdbm, key, data, GDBM_REPLACE) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -#define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ gdbm_store(db->gdbm, key, data, GDBM_INSERT) /* Returns from EXIM_DBPUTB */ -#define EXIM_DBPUTB_OK 0 -#define EXIM_DBPUTB_DUP 1 +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP 1 /* EXIM_DBDEL */ -#define EXIM_DBDEL(db, key) gdbm_delete(db->gdbm, key) +# define EXIM_DBDEL(db, key) gdbm_delete(db->gdbm, key) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */ -#define EXIM_DBCREATE_CURSOR(db, cursor) {} +# define EXIM_DBCREATE_CURSOR(db, cursor) {} /* EXIM_DBSCAN */ -#define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ ( key = ((first)? gdbm_firstkey(db->gdbm) : gdbm_nextkey(db->gdbm, db->lkey)), \ (((db)->lkey.dptr != NULL)? (free((db)->lkey.dptr),1) : 1),\ db->lkey = key, key.dptr != NULL) /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). */ -#define EXIM_DBDELETE_CURSOR(cursor) { } +# define EXIM_DBDELETE_CURSOR(cursor) { } /* EXIM_DBCLOSE */ -#define EXIM_DBCLOSE__(db) \ +# define EXIM_DBCLOSE__(db) \ { gdbm_close((db)->gdbm);\ if ((db)->lkey.dptr != NULL) free((db)->lkey.dptr);\ free(db); } /* Datum access types - these are intended to be assignable */ -#define EXIM_DATUM_SIZE(datum) (datum).dsize -#define EXIM_DATUM_DATA(datum) (datum).dptr +# define EXIM_DATUM_SIZE(datum) (datum).dsize +# define EXIM_DATUM_DATA(datum) (datum).dptr /* There's no clearing required before use, but we have to free the dptr after reading data. */ -#define EXIM_DATUM_INIT(datum) -#define EXIM_DATUM_FREE(datum) free(datum.dptr) +# define EXIM_DATUM_INIT(datum) +# define EXIM_DATUM_FREE(datum) free(datum.dptr) + +/* size limit */ + +# define EXIM_DB_RLIMIT 150 #else /* USE_GDBM */ + + + + /* If none of USE_DB, USG_GDBM, or USE_TDB are set, the default is the NDBM interface */ /********************* ndbm interface definitions **********************/ -#include +# include /* Basic DB type */ -#define EXIM_DB DBM +# define EXIM_DB DBM /* Cursor type, not used with ndbm: just set up a dummy */ -#define EXIM_CURSOR int +# define EXIM_CURSOR int /* The datum type used for queries */ -#define EXIM_DATUM datum +# define EXIM_DATUM datum /* Some text for messages */ -#define EXIM_DBTYPE "ndbm" +# define EXIM_DBTYPE "ndbm" /* Access functions */ /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */ -#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \ *(dbpp) = dbm_open(CS name, flags, mode) /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */ -#define EXIM_DBGET(db, key, data) \ +# define EXIM_DBGET(db, key, data) \ (data = dbm_fetch(db, key), data.dptr != NULL) /* EXIM_DBPUT - returns nothing useful, assumes replace mode */ -#define EXIM_DBPUT(db, key, data) \ +# define EXIM_DBPUT(db, key, data) \ dbm_store(db, key, data, DBM_REPLACE) /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */ -#define EXIM_DBPUTB(db, key, data) \ +# define EXIM_DBPUTB(db, key, data) \ dbm_store(db, key, data, DBM_INSERT) /* Returns from EXIM_DBPUTB */ -#define EXIM_DBPUTB_OK 0 -#define EXIM_DBPUTB_DUP 1 +# define EXIM_DBPUTB_OK 0 +# define EXIM_DBPUTB_DUP 1 /* EXIM_DBDEL */ -#define EXIM_DBDEL(db, key) dbm_delete(db, key) +# define EXIM_DBDEL(db, key) dbm_delete(db, key) /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */ -#define EXIM_DBCREATE_CURSOR(db, cursor) {} +# define EXIM_DBCREATE_CURSOR(db, cursor) {} /* EXIM_DBSCAN */ -#define EXIM_DBSCAN(db, key, data, first, cursor) \ +# define EXIM_DBSCAN(db, key, data, first, cursor) \ (key = (first? dbm_firstkey(db) : dbm_nextkey(db)), key.dptr != NULL) /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). */ -#define EXIM_DBDELETE_CURSOR(cursor) { } +# define EXIM_DBDELETE_CURSOR(cursor) { } /* EXIM_DBCLOSE */ -#define EXIM_DBCLOSE__(db) dbm_close(db) +# define EXIM_DBCLOSE__(db) dbm_close(db) /* Datum access types - these are intended to be assignable */ -#define EXIM_DATUM_SIZE(datum) (datum).dsize -#define EXIM_DATUM_DATA(datum) (datum).dptr +# define EXIM_DATUM_SIZE(datum) (datum).dsize +# define EXIM_DATUM_DATA(datum) (datum).dptr /* There's no clearing required before use, and we don't have to free anything after reading data. */ -#define EXIM_DATUM_INIT(datum) -#define EXIM_DATUM_FREE(datum) +# define EXIM_DATUM_INIT(datum) +# define EXIM_DATUM_FREE(datum) + +/* size limit */ + +# define EXIM_DB_RLIMIT 150 #endif /* USE_GDBM */ @@ -623,15 +651,15 @@ after reading data. */ -# ifdef COMPILE_UTILITY +#ifdef COMPILE_UTILITY -# define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \ EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) -# define EXIM_DBCLOSE(db) EXIM_DBCLOSE__(db) +# define EXIM_DBCLOSE(db) EXIM_DBCLOSE__(db) -# else +#else -# define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \ +# define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \ do { \ DEBUG(D_hints_lookup) \ debug_printf_indent("EXIM_DBOPEN: file <%s> dir <%s> flags=%s\n", \ @@ -647,13 +675,13 @@ after reading data. */ { EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \ DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \ } while(0) -# define EXIM_DBCLOSE(db) \ +# define EXIM_DBCLOSE(db) \ do { \ DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE(%p)\n", db); \ EXIM_DBCLOSE__(db); \ } while(0) -# endif +# endif /********************* End of dbm library definitions **********************/ diff --git a/src/src/retry.c b/src/src/retry.c index 30b308fe3..1993b7768 100644 --- a/src/src/retry.c +++ b/src/src/retry.c @@ -655,7 +655,7 @@ for (int i = 0; i < 3; i++) ? US string_printing(rti->message) : US"unknown error"; message_length = Ustrlen(message); - if (message_length > 150) message_length = 150; + if (message_length > EXIM_DB_RLIMIT) message_length = EXIM_DB_RLIMIT; /* Read a retry record from the database or construct a new one. Ignore an old one if it is too old since it was last updated. */ -- 2.30.2