| 1 | /* $Cambridge: exim/src/src/enq.c,v 1.3 2006/02/07 11:19:00 ph10 Exp $ */ |
| 2 | |
| 3 | /************************************************* |
| 4 | * Exim - an Internet mail transport agent * |
| 5 | *************************************************/ |
| 6 | |
| 7 | /* Copyright (c) University of Cambridge 1995 - 2006 */ |
| 8 | /* See the file NOTICE for conditions of use and distribution. */ |
| 9 | |
| 10 | /* Functions concerned with serialization. */ |
| 11 | |
| 12 | |
| 13 | #include "exim.h" |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | /************************************************* |
| 19 | * Test for host or ETRN serialization * |
| 20 | *************************************************/ |
| 21 | |
| 22 | /* This function is called when a host is listed for serialization of |
| 23 | connections. It is also called when ETRN is listed for serialization. We open |
| 24 | the misc database and look for a record, which implies an existing connection |
| 25 | or ETRN run. If not found, create one and return TRUE. |
| 26 | |
| 27 | Arguments: |
| 28 | key string on which to serialize |
| 29 | |
| 30 | Returns: TRUE if OK to proceed; FALSE otherwise |
| 31 | */ |
| 32 | |
| 33 | |
| 34 | BOOL |
| 35 | enq_start(uschar *key) |
| 36 | { |
| 37 | dbdata_serialize *serial_record; |
| 38 | dbdata_serialize new_record; |
| 39 | open_db dbblock; |
| 40 | open_db *dbm_file; |
| 41 | |
| 42 | DEBUG(D_transport) debug_printf("check serialized: %s\n", key); |
| 43 | |
| 44 | /* Open and lock the waiting information database. The absence of O_CREAT is |
| 45 | deliberate; the dbfn_open() function - which is an Exim function - always tries |
| 46 | to create if it can't open a read/write file. It expects only O_RDWR or |
| 47 | O_RDONLY as its argument. */ |
| 48 | |
| 49 | dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE); |
| 50 | if (dbm_file == NULL) return FALSE; |
| 51 | |
| 52 | /* See if there is a record for this host or queue run; if there is, we cannot |
| 53 | proceed with the connection unless the record is very old. */ |
| 54 | |
| 55 | serial_record = dbfn_read(dbm_file, key); |
| 56 | if (serial_record != NULL && time(NULL) - serial_record->time_stamp < 6*60*60) |
| 57 | { |
| 58 | dbfn_close(dbm_file); |
| 59 | DEBUG(D_transport) debug_printf("outstanding serialization record for %s\n", |
| 60 | key); |
| 61 | return FALSE; |
| 62 | } |
| 63 | |
| 64 | /* We can proceed - insert a new record or update the old one. At present |
| 65 | the count field is not used; just set it to 1. */ |
| 66 | |
| 67 | new_record.count = 1; |
| 68 | dbfn_write(dbm_file, key, &new_record, (int)sizeof(dbdata_serialize)); |
| 69 | dbfn_close(dbm_file); |
| 70 | return TRUE; |
| 71 | } |
| 72 | |
| 73 | |
| 74 | |
| 75 | /************************************************* |
| 76 | * Release serialization * |
| 77 | *************************************************/ |
| 78 | |
| 79 | /* This function is called when a serialized host's connection or serialized |
| 80 | ETRN queue run ends. We open the relevant database and delete its record. |
| 81 | |
| 82 | Arguments: |
| 83 | key the serialization key |
| 84 | |
| 85 | Returns: nothing |
| 86 | */ |
| 87 | |
| 88 | void |
| 89 | enq_end(uschar *key) |
| 90 | { |
| 91 | open_db dbblock; |
| 92 | open_db *dbm_file; |
| 93 | |
| 94 | DEBUG(D_transport) debug_printf("end serialized: %s\n", key); |
| 95 | |
| 96 | dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE); |
| 97 | if (dbm_file == NULL) return; |
| 98 | dbfn_delete(dbm_file, key); |
| 99 | dbfn_close(dbm_file); |
| 100 | } |
| 101 | |
| 102 | /* End of enq.c */ |