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