# else /* DB_VERSION_MAJOR >= 3 */
# error Berkeley DB versions earlier than 3 are not supported */
# endif /* DB_VERSION_MAJOR */
+# else
+# error Berkeley DB version 1 is no longer supported
# endif /* DB_VERSION_STRING */
typedef struct {
GDBM_FILE gdbm; /* Database */
datum lkey; /* Last key, for scans */
-} EXIM_DB;
+} gdbm_db;
+
+#define EXIM_DB gdbm_db
/* Cursor type, not used with gdbm: just set up a dummy */
# define EXIM_CURSOR int
/* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
- { (*(dbpp)) = (EXIM_DB *) malloc(sizeof(EXIM_DB));\
- if (*(dbpp) != NULL) { \
- (*(dbpp))->lkey.dptr = NULL;\
- (*(dbpp))->gdbm = gdbm_open(CS name, 0, (((flags) & O_CREAT))?GDBM_WRCREAT:(((flags) & (O_RDWR|O_WRONLY))?GDBM_WRITER:GDBM_READER), mode, 0);\
- if ((*(dbpp))->gdbm == NULL) {\
- free(*(dbpp));\
- *(dbpp) = NULL;\
+ { EXIM_DB * dbp = malloc(sizeof(EXIM_DB));\
+ if (dbp) { \
+ dbp->lkey.dptr = NULL;\
+ dbp->gdbm = gdbm_open(CS name, 0, (((flags) & O_CREAT))?GDBM_WRCREAT:(((flags) & (O_RDWR|O_WRONLY))?GDBM_WRITER:GDBM_READER), (mode), 0);\
+ if (!dbp->gdbm) {\
+ free(dbp);\
+ dbp = NULL;\
}\
}\
+ *(dbpp) = dbp;\
}
/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
/* Access functions */
/* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
-# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
- *(dbpp) = dbm_open(CS name, flags, mode)
+/* Check that the name given is not present. This catches
+a directory name; otherwise we would create the name.pag and
+name.dir files in the directory's parent. */
+
+# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
+ { \
+ struct stat st; \
+ *(dbpp) = !(flags & O_CREAT) \
+ || lstat(CCS (name), &st) != 0 && errno == ENOENT \
+ ? dbm_open(CS (name), (flags), (mode)) \
+ : (errno = (st.st_mode & S_IFMT) == S_IFDIR ? EISDIR : EEXIST, \
+ NULL); \
+ }
/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
# define EXIM_DBGET(db, key, data) \
: (flags) == O_RDWR ? "O_RDWR" \
: (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT" \
: "??"); \
- if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB file not permitted", name) \
- || is_tainted2(dirname, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB directory not permitted", dirname)) \
+ if (is_tainted(name) || is_tainted(dirname)) \
+ { \
+ log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted"); \
*dbpp = NULL; \
+ } \
else \
{ EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \
DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \