name The single-component name of one of Exim's database files.
flags Either O_RDONLY or O_RDWR, indicating the type of open required;
O_RDWR implies "create if necessary"
-XXX this is a mess. hintsdb.h has grown lots of code expecting O_CREAT
-XXX with the obvious semantics, and not that described above.
dbblock Points to an open_db block to be filled in.
lof If TRUE, write to the log for actual open failures (locking failures
are always logged).
On success, dbblock is returned. This contains the dbm pointer and
the fd of the locked lock file.
-
-There are some calls that use O_RDWR|O_CREAT for the flags. Having discovered
-this in December 2005, I'm not sure if this is correct or not, but for the
-moment I haven't changed them.
*/
open_db *
-dbfn_open(uschar *name, int flags, open_db *dbblock, BOOL lof, BOOL panic)
+dbfn_open(const uschar * name, int flags, open_db * dbblock,
+ BOOL lof, BOOL panic)
{
int rc, save_errno;
-BOOL read_only = flags == O_RDONLY;
+BOOL read_only = flags & O_RDONLY;
flock_t lock_data;
uschar dirname[PATHLEN], filename[PATHLEN];
it easy to pin this down, there are now debug statements on either side of the
open call. */
+flags &= O_RDONLY | O_RDWR;
snprintf(CS filename, sizeof(filename), "%s/%s", dirname, name);
priv_drop_temp(exim_uid, exim_gid);
debug_printf_indent("opened hints database %s: flags=%s\n", filename,
flags == O_RDONLY ? "O_RDONLY"
: flags == O_RDWR ? "O_RDWR"
- : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
: "??");
/* Pass back the block containing the opened database handle and the open fd
void dbfn_close(open_db *);
int dbfn_delete(open_db *, const uschar *);
-open_db *dbfn_open(uschar *, int, open_db *, BOOL, BOOL);
+open_db *dbfn_open(const uschar *, int, open_db *, BOOL, BOOL);
void *dbfn_read_with_length(open_db *, const uschar *, int *);
void *dbfn_read_enforce_length(open_db *, const uschar *, size_t);
uschar *dbfn_scan(open_db *, BOOL, EXIM_CURSOR **);
*/
BOOL
-directory_make(const uschar *parent, const uschar *name,
+directory_make(const uschar * parent, const uschar * name,
int mode, BOOL panic)
{
BOOL use_chown = parent == spool_directory && geteuid() == root_uid;
*/
open_db *
-dbfn_open(uschar *name, int flags, open_db *dbblock, BOOL lof, BOOL panic)
+dbfn_open(const uschar * name, int flags, open_db * dbblock,
+ BOOL lof, BOOL panic)
{
int rc;
struct flock lock_data;
-BOOL read_only = flags == O_RDONLY;
+BOOL read_only = flags & O_RDONLY;
uschar * dirname, * filename;
/* The first thing to do is to open a separate file on which to lock. This
ensures that Exim has exclusive use of the database before it even tries to
open it. If there is a database, there should be a lock file in existence. */
-#ifdef COMPILE_UTILITY
if ( asprintf(CSS &dirname, "%s/db", spool_directory) < 0
|| asprintf(CSS &filename, "%s/%s.lockfile", dirname, name) < 0)
return NULL;
-#else
-dirname = string_sprintf("%s/db", spool_directory);
-filename = string_sprintf("%s/%s.lockfile", dirname, name);
-#endif
-dbblock->lockfd = Uopen(filename, flags, 0);
-if (dbblock->lockfd < 0)
+if ((dbblock->lockfd = Uopen(filename, O_RDWR|O_CREAT, 0)) < 0)
{
printf("** Failed to open database lock file %s: %s\n", filename,
strerror(errno));
if (rc < 0)
{
printf("** Failed to get %s lock for %s: %s",
- flags & O_WRONLY ? "write" : "read",
+ read_only ? "read" : "write",
filename,
errno == ETIMEDOUT ? "timed out" : strerror(errno));
(void)close(dbblock->lockfd);
/* At this point we have an opened and locked separate lock file, that is,
exclusive access to the database, so we can go ahead and open it. */
-#ifdef COMPILE_UTILITY
if (asprintf(CSS &filename, "%s/%s", dirname, name) < 0) return NULL;
-#else
-filename = string_sprintf("%s/%s", dirname, name);
-#endif
-dbblock->dbptr = exim_dbopen(filename, dirname, flags, 0);
-if (!dbblock->dbptr)
+if (flags & O_RDWR) flags |= O_CREAT;
+
+if (!(dbblock->dbptr = exim_dbopen(filename, dirname, flags, 0)))
{
printf("** Failed to open DBM file %s for %s:\n %s%s\n", filename,
read_only? "reading" : "writing", strerror(errno),
#endif /* EXIM_TIDYDB */
/* End of exim_dbutil.c */
+/* vi: aw ai sw=2
+*/
The API is:
Functions:
- exim_dbopen
+ exim_dbopen O_RDONLY/O_RDWR, optionally OR'd with O_CREAT
exim_dbclose
exim_dbget
exim_dbput
{
dbp->app_private = b;
if (b->open(b, NULL, CS name, NULL,
- flags == O_RDONLY ? DB_UNKNOWN : DB_HASH,
- flags == O_RDONLY ? DB_RDONLY : DB_CREATE,
+ flags & O_CREAT ? DB_HASH : DB_UNKNOWN,
+ flags & O_CREAT ? DB_CREATE
+ : flags & O_RDONLY ? DB_RDONLY
+ : 0, /*XXX is there a writeable if exists option? */
mode) == 0
)
return dbp;
return db_create(&dbp, NULL, 0) == 0
&& ( dbp->set_errcall(dbp, dbfn_bdb_error_callback),
dbp->open(dbp, CS name, NULL,
- flags == O_RDONLY ? DB_UNKNOWN : DB_HASH,
- flags == O_RDONLY ? DB_RDONLY : DB_CREATE,
+ flags & O_CREAT ? DB_HASH : DB_UNKNOWN,
+ flags & O_CREAT ? DB_CREATE
+ : flags & O_RDONLY ? DB_RDONLY
+ : 0, /*XXX*/
mode)
) == 0
? dbp : NULL;
Otherwise the value is ccache_accept, ccache_reject, or ccache_reject_mfnull. */
if (dom_rec->result != ccache_unknown)
- if (!(dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE)))
+ if (!(dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE, TRUE)))
{
HDEBUG(D_verify) debug_printf_indent("callout cache: not available\n");
}
if (done && addr_rec->result != ccache_unknown)
{
if (!dbm_file)
- dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE);
+ dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE, TRUE);
if (!dbm_file)
{
HDEBUG(D_verify) debug_printf_indent("no callout cache available\n");
if (!pos_cache && !neg_cache)
return;
-if (!(dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE)))
+if (!(dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE, TRUE)))
{
HDEBUG(D_verify) debug_printf_indent("quota cache: not available\n");
return;