/* Distributed Checksum Clearinghouse * * connect to a DCC server for an administrative program * * Copyright (c) 2006 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 for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * Parties not eligible to receive a license under this agreement can * obtain a commercial license to use DCC and permission to use * U.S. Patent 6,330,590 by contacting Commtouch at http://www.commtouch.com/ * or by email to nospam@commtouch.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.50-1.37 $Revision$ */ #include "dcc_clnt.h" #include "dcc_heap_debug.h" #include "dcc_paths.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(void) { int inx; DCC_SRVR_ADDR *cur_addr; inx = dcc_clnt_info->dcc.act_inx; if (inx >= dcc_clnt_info->dcc.num_addrs) return "server"; cur_addr = &dcc_clnt_info->dcc.addrs[inx]; return dcc_clnt_info->dcc.nms[cur_addr->nm_inx].hostname; } /* Create a DCC client context * The contexts must be locked */ DCC_CLNT_CTXT * /* 0=failed */ dcc_alloc_ctxt(void) { DCC_CLNT_CTXT *ctxt; 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) { 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_lock_tmp_info(DCC_EMSG emsg, const DCC_SRVR_NM *nm, const DCC_IP *src, u_char info_flags) /* DCC_INFO_FG_* */ { DCC_PATH tmp_info_nm; int fd; fd = dcc_mkstemp(emsg, tmp_info_nm, sizeof(tmp_info_nm), 0, 0, _PATH_TMP, "map", 1, 0, 0); if (fd < 0) return 0; if (!dcc_create_map(emsg, tmp_info_nm, &fd, nm, 1, nm, 1, src, info_flags)) return 0; return dcc_map_lock_info(emsg, tmp_info_nm, fd); } DCC_CLNT_CTXT * /* 0=failed */ dcc_clnt_start(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt, const char *new_info_map_nm, u_char clnt_flags) /* DCC_CLNT_FG_* */ { if (emsg) *emsg = '\0'; dcc_ctxts_lock(); if (!ctxt) ctxt = dcc_alloc_ctxt(); if (!dcc_map_lock_info(emsg, new_info_map_nm, -1)) { dcc_rel_ctxt(ctxt); dcc_ctxts_unlock(); return 0; } if (!dcc_clnt_rdy(emsg, ctxt, clnt_flags)) { if (clnt_flags & DCC_CLNT_FG_NO_SRVR_OK) { if (emsg && dcc_clnt_debug) dcc_trace_msg("%s", emsg); } else { dcc_unmap_info(0); dcc_rel_ctxt(ctxt); dcc_ctxts_unlock(); return 0; } } return ctxt; } DCC_CLNT_CTXT * /* 0=failed */ dcc_clnt_start_fin(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt) { if (!dcc_info_unlock(emsg)) { dcc_unmap_info(0); dcc_rel_ctxt(ctxt); dcc_ctxts_unlock(); return 0; } dcc_ctxts_unlock(); return ctxt; } DCC_CLNT_CTXT * /* 0=failed */ dcc_clnt_init(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt, const char *new_info_map_nm, u_char clnt_flags) /* DCC_CLNT_FG_* */ { ctxt = dcc_clnt_start(emsg, ctxt, new_info_map_nm, clnt_flags); 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, u_char clnt_flags, /* DCC_CLNT_FG_* */ u_char info_flags) /* DCC_INFO_FG_* */ { if (emsg) *emsg = '\0'; dcc_ctxts_lock(); if (!dcc_map_lock_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_flags | DCC_CLNT_FG_NO_FAIL); if (!ctxt) dcc_unmap_info(0); return ctxt; }