/*-
 * customsMaster.c --
 *	Find the location of the current master
 *
 * Copyright (c) 1988, 1989 by the Regents of the University of California
 * Copyright (c) 1988, 1989 by Adam de Boor
 * Copyright (c) 1989 by Berkeley Softworks
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any non-commercial purpose
 * and without fee is hereby granted, provided that the above copyright
 * notice appears in all copies.  The University of California,
 * Berkeley Softworks and Adam de Boor make no representations about
 * the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 */
#ifndef lint
static char *rcsid =
"$Id: customsMaster.c,v 1.2 1994/09/05 21:28:12 stolcke Exp $ ICSI (Berkeley)";
#endif /* not lint */

#include    "customs.h"


/*-
 *-----------------------------------------------------------------------
 * Customs_Master --
 *	Find the location of the current master customs agent.
 *
 * Results:
 *	The status of the call. If the call succeeds, the passed
 *	sockaddr_in is filled with address of the current master.
 *
 * Side Effects:
 *	None.
 *
 *-----------------------------------------------------------------------
 */
Rpc_Stat
Customs_Master(masterAddrPtr)
    struct sockaddr_in	*masterAddrPtr;
{
    return Customs_MasterForHost(&customs_AgentAddr, masterAddrPtr);
}

/*-
 *-----------------------------------------------------------------------
 * Customs_MasterForHost --
 *	Find the location of the current master customs agent for
 *	another host.
 *
 * Results:
 *	The status of the call. If the call succeeds, the passed
 *	sockaddr_in is filled with address of the current master.
 *
 * Side Effects:
 *	None.
 *
 *-----------------------------------------------------------------------
 */
Rpc_Stat
Customs_MasterForHost(hostAddrPtr, masterAddrPtr)
    struct sockaddr_in	*hostAddrPtr;
    struct sockaddr_in	*masterAddrPtr;
{
    SockAddr address;

    if (customs_Socket == -1) {
	Customs_Init();
    }
    customs_Status = Rpc_Call(customs_Socket, hostAddrPtr,
			  (Rpc_Proc)CUSTOMS_MASTER,
			  0, (Rpc_Opaque)0,
			  sizeof(address), (Rpc_Opaque)&address,
			  CUSTOMS_NRETRY, &customs_RetryTimeOut);

    /*
     * Reassemble sin_addr structure from portable representation.
     * As a special case, if the master returned CUSTOMS_FROMADDR as its
     * address, use the from address, since that is guaranteed to actually
     * be reachable from our side.
     */
    if (customs_Status == RPC_SUCCESS) {
	if (address.addr == CUSTOMS_FROMADDR) {
	    *masterAddrPtr = *hostAddrPtr;
	} else {
	    memset (masterAddrPtr, 0, sizeof(*masterAddrPtr));
#ifdef HAVE_SA_LEN
	    masterAddrPtr->sin_len = sizeof(*masterAddrPtr);
#endif
	    masterAddrPtr->sin_family = address.family;
	    masterAddrPtr->sin_port = address.port;
	    masterAddrPtr->sin_addr.s_addr = address.addr;
	}
    }

    return(customs_Status);
}

