/*************************************************
*     Exim - an Internet mail transport agent    *
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2009 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions concerned with serialization. */


#include "exim.h"




/*************************************************
*       Test for host or ETRN serialization      *
*************************************************/

/* This function is called when a host is listed for serialization of
connections. It is also called when ETRN is listed for serialization. We open
the misc database and look for a record, which implies an existing connection
or ETRN run. If not found, create one and return TRUE.

Arguments:
  key            string on which to serialize

Returns:         TRUE if OK to proceed; FALSE otherwise
*/


BOOL
enq_start(uschar *key)
{
dbdata_serialize *serial_record;
dbdata_serialize new_record;
open_db dbblock;
open_db *dbm_file;

DEBUG(D_transport) debug_printf("check serialized: %s\n", key);

/* Open and lock the waiting information database. The absence of O_CREAT is
deliberate; the dbfn_open() function - which is an Exim function - always tries
to create if it can't open a read/write file. It expects only O_RDWR or
O_RDONLY as its argument. */

dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE);
if (dbm_file == NULL) return FALSE;

/* See if there is a record for this host or queue run; if there is, we cannot
proceed with the connection unless the record is very old. */

serial_record = dbfn_read(dbm_file, key);
if (serial_record != NULL && time(NULL) - serial_record->time_stamp < 6*60*60)
  {
  dbfn_close(dbm_file);
  DEBUG(D_transport) debug_printf("outstanding serialization record for %s\n",
    key);
  return FALSE;
  }

/* We can proceed - insert a new record or update the old one. At present
the count field is not used; just set it to 1. */

new_record.count = 1;
dbfn_write(dbm_file, key, &new_record, (int)sizeof(dbdata_serialize));
dbfn_close(dbm_file);
return TRUE;
}



/*************************************************
*              Release serialization             *
*************************************************/

/* This function is called when a serialized host's connection or serialized
ETRN queue run ends. We open the relevant database and delete its record.

Arguments:
  key          the serialization key

Returns:       nothing
*/

void
enq_end(uschar *key)
{
open_db dbblock;
open_db *dbm_file;

DEBUG(D_transport) debug_printf("end serialized: %s\n", key);

dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE);
if (dbm_file == NULL) return;
dbfn_delete(dbm_file, key);
dbfn_close(dbm_file);
}

/* End of enq.c */
