xref: /csrg-svn/usr.sbin/sendmail/src/mci.c (revision 54963)
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