Logo Search packages:      
Sourcecode: dcc version File versions  Download package

clnt_init.c

/* Distributed Checksum Clearinghouse
 *
 * connect to a DCC server for an administrative program
 *
 * Copyright (c) 2005 by Rhyolite Software
 *
 * 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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE
 * 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.2.74-1.24 $Revision$
 */

#include "dcc_clnt.h"
#include "dcc_heap_debug.h"
#include "dcc_paths.h"


static DCC_CLNT_CTXT *ctxt_free;
static int ctxts_active;


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 */
u_char                              /* 0=file problems, 1=ok */
dcc_rel_ctxt(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt)
{
      u_char result = 1;

      if (ctxt->soc != INVALID_SOCKET
          && SOCKET_ERROR == closesocket(ctxt->soc)) {
            dcc_pemsg(EX_OSERR, emsg, "close(ctxt): %s", ERROR_STR());
            result = 0;
      }

      ctxt->fwd = ctxt_free;
      ctxt_free = ctxt;

      if (--ctxts_active < 0)
            abort();

      return result;
}



/* 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, u_char flags)
{
      DCC_PATH tmp_info_nm;
      int fd;

      fd = dcc_mkstemp(emsg, tmp_info_nm, sizeof(tmp_info_nm),
                   _PATH_TMP, "map", 1, 0, 0);
      if (fd < 0)
            return 0;

      if (!dcc_create_map(emsg, tmp_info_nm, &fd, nm, 1, nm, 1, flags))
            return 0;

      return dcc_map_lock_info(emsg, tmp_info_nm, fd);
}



DCC_CLNT_CTXT *                     /* 0 failed */
dcc_clnt_init(DCC_EMSG emsg, DCC_CLNT_CTXT *ctxt,
            const char *new_info_map_nm,
            u_char flags)           /* DCC_CLNT_FG_* */
{
      u_char mapped;

      if (emsg)
            *emsg = '\0';
      dcc_ctxts_lock();

      if (!ctxt) {
            ctxt = dcc_alloc_ctxt();
            if (!ctxt) {
                  dcc_ctxts_unlock();
                  return 0;
            }
      }

      mapped = dcc_map_lock_info(emsg, new_info_map_nm, -1);
      if (!mapped) {
            dcc_rel_ctxt(0, ctxt);
            dcc_ctxts_unlock();
            return 0;
      }

      if (!dcc_clnt_rdy(emsg, ctxt, flags)) {
            if (flags & DCC_CLNT_FG_NO_SRVR_OK) {
                  if (emsg && dcc_clnt_debug)
                        dcc_trace_msg("%s", emsg);
            } else {
                  if (mapped > 1)
                        dcc_unmap_info(0);
                  dcc_rel_ctxt(0, ctxt);
                  dcc_ctxts_unlock();
                  return 0;
            }
      }

      if (!dcc_info_unlock(emsg)) {
            if (mapped > 1)
                  dcc_unmap_info(0);
            dcc_rel_ctxt(0, ctxt);
            dcc_ctxts_unlock();
            return 0;
      }

      dcc_ctxts_unlock();
      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,
              u_char grey, u_char lock_flags)
{
      if (emsg)
            *emsg = '\0';

      dcc_ctxts_lock();
      if (!dcc_map_lock_tmp_info(emsg, new_srvr, lock_flags)) {
            if (ctxt)
                  dcc_rel_ctxt(0, ctxt);
            dcc_ctxts_unlock();
            return 0;
      }
      dcc_ctxts_unlock();

      ctxt = dcc_clnt_init(emsg, ctxt, 0,
                       (grey ? DCC_CLNT_FG_GREY : 0)
                       | DCC_CLNT_FG_NO_FAIL);
      if (!ctxt) {
            dcc_unmap_info(0);
            return 0;
      }

      return ctxt;
}

Generated by  Doxygen 1.6.0   Back to index