/* Machine generated file -- Do NOT edit */

#include <afsconfig.h>
#include <afs/param.h>
#include <roken.h>
#include <afs/opr.h>
#ifdef AFS_PTHREAD_ENV
# include <opr/lock.h>
#endif
#include "kauth.h"

#define KAF_SETTABLE_FLAGS (KAFADMIN | KAFNOTGS | KAFNOSEAL | KAFNOCPW | KAFNEWASSOC)
#ifndef NEVERDATE
#define NEVERDATE 037777777777 /* a date that will never come */
#endif
#ifndef Date
#define Date afs_uint32
#endif
#if !defined(AFS_HPUX_ENV) && !defined(AFS_NT40_ENV) && !defined(AFS_LINUX_ENV)
#define AUTH_DBM_LOG
#endif
int KAA_Authenticate_old(struct rx_connection *z_conn,kaname name,kaname instance,afs_uint32 start_time,afs_uint32 end_time,struct ka_CBS * request,struct ka_BBS * answer)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 1;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_uint32(&z_xdrs, &start_time))
	     || (!xdr_afs_uint32(&z_xdrs, &end_time))
	     || (!xdr_ka_CBS(&z_xdrs, request))
	     || (!xdr_ka_BBS(&z_xdrs, answer))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_BBS(&z_xdrs, answer))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAA_STATINDEX,
		0, KAA_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAA_Authenticate_old(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_uint32 start_time,afs_uint32 end_time,struct ka_CBS * request,struct ka_BBS * answer)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAA_Authenticate_old(tc
, name, instance, start_time, end_time, request, answer);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAA_Authenticate(struct rx_connection *z_conn,kaname name,kaname instance,afs_uint32 start_time,afs_uint32 end_time,struct ka_CBS * request,struct ka_BBS * answer)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 21;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_uint32(&z_xdrs, &start_time))
	     || (!xdr_afs_uint32(&z_xdrs, &end_time))
	     || (!xdr_ka_CBS(&z_xdrs, request))
	     || (!xdr_ka_BBS(&z_xdrs, answer))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_BBS(&z_xdrs, answer))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAA_STATINDEX,
		1, KAA_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAA_Authenticate(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_uint32 start_time,afs_uint32 end_time,struct ka_CBS * request,struct ka_BBS * answer)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAA_Authenticate(tc
, name, instance, start_time, end_time, request, answer);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAA_AuthenticateV2(struct rx_connection *z_conn,kaname name,kaname instance,afs_uint32 start_time,afs_uint32 end_time,struct ka_CBS * request,struct ka_BBS * answer)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 22;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_uint32(&z_xdrs, &start_time))
	     || (!xdr_afs_uint32(&z_xdrs, &end_time))
	     || (!xdr_ka_CBS(&z_xdrs, request))
	     || (!xdr_ka_BBS(&z_xdrs, answer))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_BBS(&z_xdrs, answer))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAA_STATINDEX,
		2, KAA_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAA_AuthenticateV2(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_uint32 start_time,afs_uint32 end_time,struct ka_CBS * request,struct ka_BBS * answer)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAA_AuthenticateV2(tc
, name, instance, start_time, end_time, request, answer);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAA_ChangePassword(struct rx_connection *z_conn,kaname name,kaname instance,struct ka_CBS * arequest,struct ka_BBS * oanswer)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 2;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_ka_CBS(&z_xdrs, arequest))
	     || (!xdr_ka_BBS(&z_xdrs, oanswer))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_BBS(&z_xdrs, oanswer))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAA_STATINDEX,
		3, KAA_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAA_ChangePassword(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,struct ka_CBS * arequest,struct ka_BBS * oanswer)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAA_ChangePassword(tc
, name, instance, arequest, oanswer);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAT_GetTicket_old(struct rx_connection *z_conn,afs_int32 kvno,kaname auth_domain,struct ka_CBS * aticket,kaname name,kaname instance,struct ka_CBS * atimes,struct ka_BBS * oanswer)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 3;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_afs_int32(&z_xdrs, &kvno))
	     || (!xdr_kaname(&z_xdrs, &auth_domain))
	     || (!xdr_ka_CBS(&z_xdrs, aticket))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_ka_CBS(&z_xdrs, atimes))
	     || (!xdr_ka_BBS(&z_xdrs, oanswer))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_BBS(&z_xdrs, oanswer))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAT_STATINDEX,
		0, KAT_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAT_GetTicket_old(struct ubik_client *aclient, afs_int32 aflags,afs_int32 kvno,kaname auth_domain,struct ka_CBS * aticket,kaname name,kaname instance,struct ka_CBS * atimes,struct ka_BBS * oanswer)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAT_GetTicket_old(tc
, kvno, auth_domain, aticket, name, instance, atimes, oanswer);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAT_GetTicket(struct rx_connection *z_conn,afs_int32 kvno,kaname auth_domain,struct ka_CBS * aticket,kaname name,kaname instance,struct ka_CBS * atimes,struct ka_BBS * oanswer)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 23;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_afs_int32(&z_xdrs, &kvno))
	     || (!xdr_kaname(&z_xdrs, &auth_domain))
	     || (!xdr_ka_CBS(&z_xdrs, aticket))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_ka_CBS(&z_xdrs, atimes))
	     || (!xdr_ka_BBS(&z_xdrs, oanswer))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_BBS(&z_xdrs, oanswer))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAT_STATINDEX,
		1, KAT_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAT_GetTicket(struct ubik_client *aclient, afs_int32 aflags,afs_int32 kvno,kaname auth_domain,struct ka_CBS * aticket,kaname name,kaname instance,struct ka_CBS * atimes,struct ka_BBS * oanswer)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAT_GetTicket(tc
, kvno, auth_domain, aticket, name, instance, atimes, oanswer);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_SetPassword(struct rx_connection *z_conn,kaname name,kaname instance,afs_int32 kvno,EncryptionKey password)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 4;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_int32(&z_xdrs, &kvno))
	     || (!xdr_EncryptionKey(&z_xdrs, &password))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		0, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_SetPassword(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_int32 kvno,EncryptionKey password)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_SetPassword(tc
, name, instance, kvno, password);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_SetFields(struct rx_connection *z_conn,kaname name,kaname instance,afs_int32 flags,afs_uint32 user_expiration,afs_int32 max_ticket_lifetime,afs_int32 maxAssociates,afs_uint32 misc_auth_bytes,afs_int32 spare2)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 5;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_int32(&z_xdrs, &flags))
	     || (!xdr_afs_uint32(&z_xdrs, &user_expiration))
	     || (!xdr_afs_int32(&z_xdrs, &max_ticket_lifetime))
	     || (!xdr_afs_int32(&z_xdrs, &maxAssociates))
	     || (!xdr_afs_uint32(&z_xdrs, &misc_auth_bytes))
	     || (!xdr_afs_int32(&z_xdrs, &spare2))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		1, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_SetFields(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_int32 flags,afs_uint32 user_expiration,afs_int32 max_ticket_lifetime,afs_int32 maxAssociates,afs_uint32 misc_auth_bytes,afs_int32 spare2)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_SetFields(tc
, name, instance, flags, user_expiration, max_ticket_lifetime, maxAssociates, misc_auth_bytes, spare2);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_CreateUser(struct rx_connection *z_conn,kaname name,kaname instance,EncryptionKey password)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 6;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_EncryptionKey(&z_xdrs, &password))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		2, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_CreateUser(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,EncryptionKey password)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_CreateUser(tc
, name, instance, password);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_DeleteUser(struct rx_connection *z_conn,kaname name,kaname instance)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 7;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		3, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_DeleteUser(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_DeleteUser(tc
, name, instance);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_GetEntry(struct rx_connection *z_conn,kaname name,kaname instance,afs_int32 major_version,struct kaentryinfo * entry)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 8;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_int32(&z_xdrs, &major_version))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_kaentryinfo(&z_xdrs, entry))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		4, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_GetEntry(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_int32 major_version,struct kaentryinfo * entry)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_GetEntry(tc
, name, instance, major_version, entry);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_ListEntry(struct rx_connection *z_conn,afs_int32 previous_index,afs_int32 * index,afs_int32 * count,kaident * name)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 9;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_afs_int32(&z_xdrs, &previous_index))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_afs_int32(&z_xdrs, index))
	     || (!xdr_afs_int32(&z_xdrs, count))
	     || (!xdr_kaident(&z_xdrs, name))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		5, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_ListEntry(struct ubik_client *aclient, afs_int32 aflags,afs_int32 previous_index,afs_int32 * index,afs_int32 * count,kaident * name)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_ListEntry(tc
, previous_index, index, count, name);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_GetStats(struct rx_connection *z_conn,afs_int32 major_version,afs_int32 * admin_accounts,struct kasstats * statics,struct kadstats * dynamics)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 10;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_afs_int32(&z_xdrs, &major_version))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_afs_int32(&z_xdrs, admin_accounts))
	     || (!xdr_kasstats(&z_xdrs, statics))
	     || (!xdr_kadstats(&z_xdrs, dynamics))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		6, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_GetStats(struct ubik_client *aclient, afs_int32 aflags,afs_int32 major_version,afs_int32 * admin_accounts,struct kasstats * statics,struct kadstats * dynamics)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_GetStats(tc
, major_version, admin_accounts, statics, dynamics);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_Debug(struct rx_connection *z_conn,afs_int32 major_version,int checkDB,struct ka_debugInfo * info)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 11;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_afs_int32(&z_xdrs, &major_version))
	     || (!xdr_int(&z_xdrs, &checkDB))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_ka_debugInfo(&z_xdrs, info))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		7, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_Debug(struct ubik_client *aclient, afs_int32 aflags,afs_int32 major_version,int checkDB,struct ka_debugInfo * info)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_Debug(tc
, major_version, checkDB, info);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_GetPassword(struct rx_connection *z_conn,kaname name,EncryptionKey * password)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 12;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_EncryptionKey(&z_xdrs, password))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		8, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_GetPassword(struct ubik_client *aclient, afs_int32 aflags,kaname name,EncryptionKey * password)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_GetPassword(tc
, name, password);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_GetRandomKey(struct rx_connection *z_conn,EncryptionKey * password)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 13;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_EncryptionKey(&z_xdrs, password))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		9, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_GetRandomKey(struct ubik_client *aclient, afs_int32 aflags,EncryptionKey * password)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_GetRandomKey(tc
, password);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_Unlock(struct rx_connection *z_conn,kaname name,kaname instance,afs_int32 spare1,afs_int32 spare2,afs_int32 spare3,afs_int32 spare4)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 14;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_int32(&z_xdrs, &spare1))
	     || (!xdr_afs_int32(&z_xdrs, &spare2))
	     || (!xdr_afs_int32(&z_xdrs, &spare3))
	     || (!xdr_afs_int32(&z_xdrs, &spare4))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		10, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_Unlock(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_int32 spare1,afs_int32 spare2,afs_int32 spare3,afs_int32 spare4)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_Unlock(tc
, name, instance, spare1, spare2, spare3, spare4);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

int KAM_LockStatus(struct rx_connection *z_conn,kaname name,kaname instance,afs_int32 * lockeduntil,afs_int32 spare1,afs_int32 spare2,afs_int32 spare3,afs_int32 spare4)
{
	struct rx_call *z_call = rx_NewCall(z_conn);
	static int z_op = 15;
	int z_result;
	XDR z_xdrs;
	xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

	/* Marshal the arguments */
	if ((!xdr_int(&z_xdrs, &z_op))
	     || (!xdr_kaname(&z_xdrs, &name))
	     || (!xdr_kaname(&z_xdrs, &instance))
	     || (!xdr_afs_int32(&z_xdrs, &spare1))
	     || (!xdr_afs_int32(&z_xdrs, &spare2))
	     || (!xdr_afs_int32(&z_xdrs, &spare3))
	     || (!xdr_afs_int32(&z_xdrs, &spare4))) {
		z_result = RXGEN_CC_MARSHAL;
		goto fail;
	}

	/* Un-marshal the reply arguments */
	z_xdrs.x_op = XDR_DECODE;
	if ((!xdr_afs_int32(&z_xdrs, lockeduntil))) {
		z_result = RXGEN_CC_UNMARSHAL;
		goto fail;
	}

	z_result = RXGEN_SUCCESS;
fail:
	z_result = rx_EndCall(z_call, z_result);
	if (rx_enable_stats) {
	    rx_RecordCallStatistics(z_call, KAM_STATINDEX,
		11, KAM_NO_OF_STAT_FUNCS, 1);
	}

	return z_result;
}

int ubik_KAM_LockStatus(struct ubik_client *aclient, afs_int32 aflags,kaname name,kaname instance,afs_int32 * lockeduntil,afs_int32 spare1,afs_int32 spare2,afs_int32 spare3,afs_int32 spare4)
{	afs_int32 rcode, code, newHost, thisHost, i, _ucount;
	int chaseCount, pass, needsync;
	struct rx_connection *tc;
	struct rx_peer *rxp;
	short origLevel;

	if (!aclient)
		return UNOENT;
	LOCK_UBIK_CLIENT(aclient);

	 restart:
	origLevel = aclient->initializationState;
	rcode = UNOSERVERS;
	chaseCount = needsync = 0;

	/* 
	* First  pass, we try all servers that are up.
	* Second pass, we try all servers.
	*/
	for (pass = 0; pass < 2; pass++) {  /*p */
		/* For each entry in our servers list */
		for (_ucount = 0;; _ucount++) {     /*s */

		if (needsync) {
			/* Need a sync site. Lets try to quickly find it */
			if (aclient->syncSite) {
				newHost = aclient->syncSite;        /* already in network order */
				aclient->syncSite = 0;      /* Will reset if it works */
			} else if (aclient->conns[3]) {
				/* If there are fewer than four db servers in a cell,
				* there's no point in making the GetSyncSite call.
				* At best, it's a wash. At worst, it results in more
				* RPCs than you would otherwise make.
				*/
				tc = aclient->conns[_ucount];
				if (tc && rx_ConnError(tc)) {
					aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
				}
				if (!tc)
					break;
				code = VOTE_GetSyncSite(tc, &newHost);
				if (aclient->initializationState != origLevel)
					goto restart;   /* somebody did a ubik_ClientInit */
				if (code)
					newHost = 0;
				newHost = htonl(newHost);   /* convert to network order */
			} else {
				newHost = 0;
			}
			if (newHost) {
				/* position count at the appropriate slot in the client
				* structure and retry. If we can't find in slot, we'll
				* just continue through the whole list 
				*/
				for (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {
					rxp = rx_PeerOf(aclient->conns[i]);
					thisHost = rx_HostOf(rxp);
					if (!thisHost)
						break;
					if (thisHost == newHost) {
						if (chaseCount++ > 2)
							break;  /* avoid loop asking */
						_ucount = i;  /* this index is the sync site */
						break;
					}
				}
			}
		}
		/*needsync */
		tc = aclient->conns[_ucount];
		if (tc && rx_ConnError(tc)) {
			aclient->conns[_ucount] = tc = ubik_RefreshConn(tc);
		}
		if (!tc)
			break;

		if ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {
			continue;       /* this guy's down */
		}
		rcode = KAM_LockStatus(tc
, name, instance, lockeduntil, spare1, spare2, spare3, spare4);
		if (aclient->initializationState != origLevel) {
			/* somebody did a ubik_ClientInit */
			if (rcode)
				goto restart;       /* call failed */
			else
				goto done;  /* call suceeded */
		}
		if (rcode < 0) {    /* network errors */
			aclient->states[_ucount] |= CFLastFailed; /* Mark server down */
		} else if (rcode == UNOTSYNC) {
			needsync = 1;
		} else if (rcode != UNOQUORUM) {
			/* either misc ubik code, or misc appl code, or success. */
			aclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/
			goto done;      /* all done */
		}
		}                       /*s */
	}                           /*p */

	done:
	if (needsync) {
		if (!rcode) {           /* Remember the sync site - cmd successful */
			rxp = rx_PeerOf(aclient->conns[_ucount]);
			aclient->syncSite = rx_HostOf(rxp);
		}
	}
	UNLOCK_UBIK_CLIENT(aclient);
	return rcode;
}

