diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dcclib/clnt_init.c	Tue Mar 10 13:49:58 2009 +0100
@@ -0,0 +1,250 @@
+/* Distributed Checksum Clearinghouse
+ *
+ * connect to a DCC server for an administrative program
+ *
+ * Copyright (c) 2008 by Rhyolite Software, LLC
+ *
+ * This agreement is not applicable to any entity which sells anti-spam
+ * solutions to others or provides an anti-spam solution as part of a
+ * security solution sold to other entities, or to a private network
+ * which employs the DCC or uses data provided by operation of the DCC
+ * but does not provide corresponding data to other users.
+ *
+ * Permission to use, copy, modify, and distribute this software without
+ * changes for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear in all
+ * copies and any distributed versions or copies are either unchanged
+ * or not called anything similar to "DCC" or "Distributed Checksum
+ * Clearinghouse".
+ *
+ * Parties not eligible to receive a license under this agreement can
+ * obtain a commercial license to use DCC by contacting Rhyolite Software
+ * at sales@rhyolite.com.
+ *
+ * A commercial license would be for Distributed Checksum and Reputation
+ * Clearinghouse software.  That software includes additional features.  This
+ * free license for Distributed ChecksumClearinghouse Software does not in any
+ * way grant permision to use Distributed Checksum and Reputation Clearinghouse
+ * software
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
+ * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Rhyolite Software DCC 1.3.103-1.49 $Revision$
+ */
+
+#include "dcc_clnt.h"
+#include "dcc_heap_debug.h"
+
+
+static DCC_CLNT_CTXT *ctxt_free;
+static int ctxts_active;
+
+
+/* this can give the wrong answer if another thread sneaks in and
+ * switches servers */
+const char *
+dcc_srvr_nm(u_char grey)
+{
+	const DCC_SRVR_CLASS *class;
+	SRVR_INX srvr_inx;
+	const DCC_SRVR_ADDR *cur_addr;
+	NAM_INX nam_inx;
+
+	if (!dcc_clnt_info)
+		return "???";
+	class = grey ? &dcc_clnt_info->dcc : &dcc_clnt_info->grey;
+	srvr_inx = class->srvr_inx;
+	if (GOOD_SRVR(class, srvr_inx)) {
+		cur_addr = &class->addrs[srvr_inx];
+		nam_inx = cur_addr->nam_inx;
+		if (GOOD_NAM(nam_inx))
+			return class->nms[nam_inx].hostname;
+	}
+	return grey ? "greylist server" : "DCC server";
+}
+
+
+
+/* Create a DCC client context
+ *	The contexts must be locked */
+DCC_CLNT_CTXT *				/* 0=failed */
+dcc_alloc_ctxt(void)
+{
+	DCC_CLNT_CTXT *ctxt;
+
+	assert_ctxts_locked();
+
+	ctxt = ctxt_free;
+	if (ctxt) {
+		ctxt_free = ctxt->fwd;
+	} else {
+		ctxt = dcc_malloc(sizeof(*ctxt));
+	}
+	memset(ctxt, 0, sizeof(*ctxt));
+	ctxt->soc = INVALID_SOCKET;
+	++ctxts_active;
+
+	return ctxt;
+}
+
+
+
+/* the contexts must be locked */
+void
+dcc_rel_ctxt(DCC_CLNT_CTXT *ctxt)
+{
+	assert_ctxts_locked();
+
+	dcc_clnt_soc_close(ctxt);
+
+	ctxt->fwd = ctxt_free;
+	ctxt_free = ctxt;
+
+	if (--ctxts_active < 0)
+		abort();
+}
+
+
+
+/* create a temporary an anonymous map file
+ *	The contexts must be locked.
+ *	On failure, everything is undone.
+ *	On success, the file is initialized and mapped. */
+u_char					/* 0=failed; 1=mapped & locked */
+dcc_map_tmp_info(DCC_EMSG emsg,		/* cleared of stale messages */
+		 const DCC_SRVR_NM *nm,
+		 const DCC_IP *src,
+		 u_char info_flags)	/* DCC_INFO_FG_* */
+{
+	DCC_PATH tmp_info_nm;
+	int fd;
+
+	assert_ctxts_locked();
+
+	fd = dcc_mkstemp(emsg, tmp_info_nm, sizeof(tmp_info_nm), 0, 0, 0,
+			 0, "map", 1, 0);
+	if (fd < 0)
+		return 0;
+
+	if (!dcc_create_map(emsg, tmp_info_nm, &fd, nm, 1, nm, 1,
+			    src, info_flags | DCC_INFO_FG_TMP))
+		return 0;
+
+	return dcc_map_info(emsg, tmp_info_nm, fd);
+}
+
+
+
+/* start to get ready for an operation
+ *	on entry, nothing is locked,
+ *	on success, the contexts and info are locked
+ *	on failure, nothing is locked */
+DCC_CLNT_CTXT *				/* 0=failed */
+dcc_clnt_start(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
+	       const char *new_info_map_nm,
+	       DCC_CLNT_FGS clnt_fgs)
+{
+	if (emsg)
+		*emsg = '\0';
+	dcc_ctxts_lock();
+
+	if (!ctxt)
+		ctxt = dcc_alloc_ctxt();
+
+	if (!dcc_map_info(emsg, new_info_map_nm, -1)) {
+		dcc_rel_ctxt(ctxt);
+		dcc_ctxts_unlock();
+		return 0;
+	}
+
+	if (emsg)
+		*emsg = '\0';
+	if (!dcc_clnt_rdy(emsg, ctxt, clnt_fgs)) {
+		if (!(clnt_fgs & DCC_CLNT_FG_BAD_SRVR_OK)) {
+			dcc_unmap_close_info(0);
+			dcc_rel_ctxt(ctxt);
+			dcc_ctxts_unlock();
+			return 0;
+		}
+		if (emsg && dcc_clnt_debug)
+			dcc_trace_msg("%s", emsg);
+
+		/* lock the shared information since we are not failing */
+		if (!dcc_info_lock(emsg)) {
+			dcc_rel_ctxt(ctxt);
+			dcc_ctxts_unlock();
+			return 0;
+		}
+	}
+
+	return ctxt;
+}
+
+
+
+DCC_CLNT_CTXT *				/* 0=failed */
+dcc_clnt_start_fin(DCC_EMSG emsg,	/* cleared of stale messages */
+		   DCC_CLNT_CTXT *ctxt)
+{
+	if (!dcc_info_unlock(emsg)) {
+		dcc_unmap_close_info(0);
+		dcc_rel_ctxt(ctxt);
+		dcc_ctxts_unlock();
+		return 0;
+	}
+	dcc_ctxts_unlock();
+	return ctxt;
+}
+
+
+
+/* on success the info file is mapped, but nothing is locked
+ * on failure, nothing is mapped or locked */
+DCC_CLNT_CTXT *				/* 0=failed */
+dcc_clnt_init(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
+	      const char *new_info_map_nm,
+	      DCC_CLNT_FGS clnt_fgs)
+{
+	ctxt = dcc_clnt_start(emsg, ctxt, new_info_map_nm, clnt_fgs);
+	if (ctxt)
+		ctxt = dcc_clnt_start_fin(emsg, ctxt);
+	return ctxt;
+}
+
+
+
+/* start talking to a DCC server using an temporary parameter file */
+DCC_CLNT_CTXT *				/* 0=failed, 1=ready */
+dcc_tmp_clnt_init(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
+		  const DCC_SRVR_NM *new_srvr,
+		  const DCC_IP *src,
+		  DCC_CLNT_FGS clnt_fgs,
+		  u_char info_flags)	/* DCC_INFO_FG_* */
+{
+	if (emsg)
+		*emsg = '\0';
+
+	dcc_ctxts_lock();
+	if (!dcc_map_tmp_info(emsg, new_srvr, src, info_flags)) {
+		if (ctxt)
+			dcc_rel_ctxt(ctxt);
+		dcc_ctxts_unlock();
+		return 0;
+	}
+	dcc_ctxts_unlock();
+
+	ctxt = dcc_clnt_init(emsg, ctxt, 0, clnt_fgs | DCC_CLNT_FG_NO_FAIL);
+	if (!ctxt) {
+		dcc_ctxts_lock();
+		dcc_unmap_close_info(0);
+		dcc_ctxts_unlock();
+	}
+	return ctxt;
+}