1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)mci.c 5.1 (Berkeley) 07/11/92"; 11 #endif /* not lint */ 12 13 #include "sendmail.h" 14 15 /* 16 ** MCI_CACHE -- enter a connection structure into the open connection cache 17 ** 18 ** This may cause something else to be flushed. 19 ** 20 ** Parameters: 21 ** mci -- the connection to cache. 22 ** 23 ** Returns: 24 ** none. 25 */ 26 27 mci_cache(mci) 28 register MCONINFO *mci; 29 { 30 register MCONINFO **mcislot; 31 extern MCONINFO **mci_scan(); 32 33 if (MaxMciCache <= 0) 34 { 35 /* we don't support caching */ 36 return; 37 } 38 39 /* 40 ** Find the best slot. This may cause expired connections 41 ** to be closed. 42 */ 43 44 mcislot = mci_scan(mci); 45 46 /* if this is already cached, we are done */ 47 if (bitset(MCIF_CACHED, mci->mci_flags)) 48 return; 49 50 /* otherwise we may have to clear the slot */ 51 if (*mcislot != NULL) 52 mci_uncache(mcislot); 53 54 *mcislot = mci; 55 mci->mci_flags |= MCIF_CACHED; 56 } 57 /* 58 ** MCI_SCAN -- scan the cache, flush junk, and return best slot 59 ** 60 ** Parameters: 61 ** savemci -- never flush this one. Can be null. 62 ** 63 ** Returns: 64 ** The LRU (or empty) slot. 65 */ 66 67 MCONINFO **MciCache; 68 69 MCONINFO ** 70 mci_scan(savemci) 71 MCONINFO *savemci; 72 { 73 time_t now; 74 register MCONINFO **bestmci; 75 register MCONINFO *mci; 76 register int i; 77 78 if (MciCache == NULL) 79 { 80 /* first call */ 81 MciCache = (MCONINFO **) xalloc(MaxMciCache * sizeof *MciCache); 82 return (&MciCache[0]); 83 } 84 85 now = curtime(); 86 bestmci = &MciCache[0]; 87 for (i = 0; i < MaxMciCache; i++) 88 { 89 mci = MciCache[i]; 90 if (mci == NULL || mci->mci_state == MCIS_CLOSED) 91 { 92 bestmci = &MciCache[i]; 93 continue; 94 } 95 if (mci->mci_lastuse + MciCacheTimeout < now && mci != savemci) 96 { 97 /* connection idle too long -- close it */ 98 bestmci = &MciCache[i]; 99 mci_uncache(bestmci); 100 continue; 101 } 102 if (*bestmci == NULL) 103 continue; 104 if (mci->mci_lastuse < (*bestmci)->mci_lastuse) 105 bestmci = &MciCache[i]; 106 } 107 return bestmci; 108 } 109 /* 110 ** MCI_UNCACHE -- remove a connection from a slot. 111 ** 112 ** May close a connection. 113 ** 114 ** Parameters: 115 ** mcislot -- the slot to empty. 116 ** 117 ** Returns: 118 ** none. 119 */ 120 121 mci_uncache(mcislot) 122 register MCONINFO **mcislot; 123 { 124 register MCONINFO *mci; 125 extern ENVELOPE *BlankEnvelope; 126 127 mci = *mcislot; 128 if (mci == NULL) 129 return; 130 *mcislot = NULL; 131 mci->mci_flags &= ~MCIF_CACHED; 132 133 /* only uses the envelope to flush the transcript file */ 134 if (mci->mci_state != MCIS_CLOSED) 135 smtpquit(mci->mci_mailer, mci, &BlankEnvelope); 136 } 137 /* 138 ** MCI_FLUSH -- flush the entire cache 139 */ 140 141 mci_flush() 142 { 143 register int i; 144 145 if (MciCache == NULL) 146 return; 147 148 for (i = 0; i < MaxMciCache; i++) 149 mci_uncache(&MciCache[i]); 150 } 151 /* 152 ** MCI_GET -- get information about a particular host 153 */ 154 155 MCONINFO * 156 mci_get(host, m) 157 char *host; 158 MAILER *m; 159 { 160 return &(stab(host, ST_MCONINFO + m->m_mno, ST_ENTER))->s_mci; 161 } 162