comparison dcclib/clnt_init.c @ 0:c7f6b056b673

First import of vendor version
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 13:49:58 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c7f6b056b673
1 /* Distributed Checksum Clearinghouse
2 *
3 * connect to a DCC server for an administrative program
4 *
5 * Copyright (c) 2008 by Rhyolite Software, LLC
6 *
7 * This agreement is not applicable to any entity which sells anti-spam
8 * solutions to others or provides an anti-spam solution as part of a
9 * security solution sold to other entities, or to a private network
10 * which employs the DCC or uses data provided by operation of the DCC
11 * but does not provide corresponding data to other users.
12 *
13 * Permission to use, copy, modify, and distribute this software without
14 * changes for any purpose with or without fee is hereby granted, provided
15 * that the above copyright notice and this permission notice appear in all
16 * copies and any distributed versions or copies are either unchanged
17 * or not called anything similar to "DCC" or "Distributed Checksum
18 * Clearinghouse".
19 *
20 * Parties not eligible to receive a license under this agreement can
21 * obtain a commercial license to use DCC by contacting Rhyolite Software
22 * at sales@rhyolite.com.
23 *
24 * A commercial license would be for Distributed Checksum and Reputation
25 * Clearinghouse software. That software includes additional features. This
26 * free license for Distributed ChecksumClearinghouse Software does not in any
27 * way grant permision to use Distributed Checksum and Reputation Clearinghouse
28 * software
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
31 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
33 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
34 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
35 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
36 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
37 * SOFTWARE.
38 *
39 * Rhyolite Software DCC 1.3.103-1.49 $Revision$
40 */
41
42 #include "dcc_clnt.h"
43 #include "dcc_heap_debug.h"
44
45
46 static DCC_CLNT_CTXT *ctxt_free;
47 static int ctxts_active;
48
49
50 /* this can give the wrong answer if another thread sneaks in and
51 * switches servers */
52 const char *
53 dcc_srvr_nm(u_char grey)
54 {
55 const DCC_SRVR_CLASS *class;
56 SRVR_INX srvr_inx;
57 const DCC_SRVR_ADDR *cur_addr;
58 NAM_INX nam_inx;
59
60 if (!dcc_clnt_info)
61 return "???";
62 class = grey ? &dcc_clnt_info->dcc : &dcc_clnt_info->grey;
63 srvr_inx = class->srvr_inx;
64 if (GOOD_SRVR(class, srvr_inx)) {
65 cur_addr = &class->addrs[srvr_inx];
66 nam_inx = cur_addr->nam_inx;
67 if (GOOD_NAM(nam_inx))
68 return class->nms[nam_inx].hostname;
69 }
70 return grey ? "greylist server" : "DCC server";
71 }
72
73
74
75 /* Create a DCC client context
76 * The contexts must be locked */
77 DCC_CLNT_CTXT * /* 0=failed */
78 dcc_alloc_ctxt(void)
79 {
80 DCC_CLNT_CTXT *ctxt;
81
82 assert_ctxts_locked();
83
84 ctxt = ctxt_free;
85 if (ctxt) {
86 ctxt_free = ctxt->fwd;
87 } else {
88 ctxt = dcc_malloc(sizeof(*ctxt));
89 }
90 memset(ctxt, 0, sizeof(*ctxt));
91 ctxt->soc = INVALID_SOCKET;
92 ++ctxts_active;
93
94 return ctxt;
95 }
96
97
98
99 /* the contexts must be locked */
100 void
101 dcc_rel_ctxt(DCC_CLNT_CTXT *ctxt)
102 {
103 assert_ctxts_locked();
104
105 dcc_clnt_soc_close(ctxt);
106
107 ctxt->fwd = ctxt_free;
108 ctxt_free = ctxt;
109
110 if (--ctxts_active < 0)
111 abort();
112 }
113
114
115
116 /* create a temporary an anonymous map file
117 * The contexts must be locked.
118 * On failure, everything is undone.
119 * On success, the file is initialized and mapped. */
120 u_char /* 0=failed; 1=mapped & locked */
121 dcc_map_tmp_info(DCC_EMSG emsg, /* cleared of stale messages */
122 const DCC_SRVR_NM *nm,
123 const DCC_IP *src,
124 u_char info_flags) /* DCC_INFO_FG_* */
125 {
126 DCC_PATH tmp_info_nm;
127 int fd;
128
129 assert_ctxts_locked();
130
131 fd = dcc_mkstemp(emsg, tmp_info_nm, sizeof(tmp_info_nm), 0, 0, 0,
132 0, "map", 1, 0);
133 if (fd < 0)
134 return 0;
135
136 if (!dcc_create_map(emsg, tmp_info_nm, &fd, nm, 1, nm, 1,
137 src, info_flags | DCC_INFO_FG_TMP))
138 return 0;
139
140 return dcc_map_info(emsg, tmp_info_nm, fd);
141 }
142
143
144
145 /* start to get ready for an operation
146 * on entry, nothing is locked,
147 * on success, the contexts and info are locked
148 * on failure, nothing is locked */
149 DCC_CLNT_CTXT * /* 0=failed */
150 dcc_clnt_start(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
151 const char *new_info_map_nm,
152 DCC_CLNT_FGS clnt_fgs)
153 {
154 if (emsg)
155 *emsg = '\0';
156 dcc_ctxts_lock();
157
158 if (!ctxt)
159 ctxt = dcc_alloc_ctxt();
160
161 if (!dcc_map_info(emsg, new_info_map_nm, -1)) {
162 dcc_rel_ctxt(ctxt);
163 dcc_ctxts_unlock();
164 return 0;
165 }
166
167 if (emsg)
168 *emsg = '\0';
169 if (!dcc_clnt_rdy(emsg, ctxt, clnt_fgs)) {
170 if (!(clnt_fgs & DCC_CLNT_FG_BAD_SRVR_OK)) {
171 dcc_unmap_close_info(0);
172 dcc_rel_ctxt(ctxt);
173 dcc_ctxts_unlock();
174 return 0;
175 }
176 if (emsg && dcc_clnt_debug)
177 dcc_trace_msg("%s", emsg);
178
179 /* lock the shared information since we are not failing */
180 if (!dcc_info_lock(emsg)) {
181 dcc_rel_ctxt(ctxt);
182 dcc_ctxts_unlock();
183 return 0;
184 }
185 }
186
187 return ctxt;
188 }
189
190
191
192 DCC_CLNT_CTXT * /* 0=failed */
193 dcc_clnt_start_fin(DCC_EMSG emsg, /* cleared of stale messages */
194 DCC_CLNT_CTXT *ctxt)
195 {
196 if (!dcc_info_unlock(emsg)) {
197 dcc_unmap_close_info(0);
198 dcc_rel_ctxt(ctxt);
199 dcc_ctxts_unlock();
200 return 0;
201 }
202 dcc_ctxts_unlock();
203 return ctxt;
204 }
205
206
207
208 /* on success the info file is mapped, but nothing is locked
209 * on failure, nothing is mapped or locked */
210 DCC_CLNT_CTXT * /* 0=failed */
211 dcc_clnt_init(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
212 const char *new_info_map_nm,
213 DCC_CLNT_FGS clnt_fgs)
214 {
215 ctxt = dcc_clnt_start(emsg, ctxt, new_info_map_nm, clnt_fgs);
216 if (ctxt)
217 ctxt = dcc_clnt_start_fin(emsg, ctxt);
218 return ctxt;
219 }
220
221
222
223 /* start talking to a DCC server using an temporary parameter file */
224 DCC_CLNT_CTXT * /* 0=failed, 1=ready */
225 dcc_tmp_clnt_init(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
226 const DCC_SRVR_NM *new_srvr,
227 const DCC_IP *src,
228 DCC_CLNT_FGS clnt_fgs,
229 u_char info_flags) /* DCC_INFO_FG_* */
230 {
231 if (emsg)
232 *emsg = '\0';
233
234 dcc_ctxts_lock();
235 if (!dcc_map_tmp_info(emsg, new_srvr, src, info_flags)) {
236 if (ctxt)
237 dcc_rel_ctxt(ctxt);
238 dcc_ctxts_unlock();
239 return 0;
240 }
241 dcc_ctxts_unlock();
242
243 ctxt = dcc_clnt_init(emsg, ctxt, 0, clnt_fgs | DCC_CLNT_FG_NO_FAIL);
244 if (!ctxt) {
245 dcc_ctxts_lock();
246 dcc_unmap_close_info(0);
247 dcc_ctxts_unlock();
248 }
249 return ctxt;
250 }