static char rcsid[] = "$Header: efs_flock.c,v 820.1 86/12/04 19:47:36 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

/************************************************************************
*									*
*				Copyright 1984				*
*			VALID LOGIC SYSTEMS INCORPORATED		*
*									*
*	This listing contains confidential proprietary information	*
*	which is not to be disclosed to unauthorized persons without	*
*	written consent of an officer of Valid Logic Systems 		*
*	Incorporated.							*
*									*
*	The copyright notice appearing above is included to provide	*
*	statutory protection in the event of unauthorized or 		*
*	unintentional public disclosure.				*
*									*
************************************************************************/

/*
 * Perform an flock() on an open remote file.
 *
 * jht 841205,07 -- augment EFS with flock().
 */

#ifdef	EFS_X_FLOCK
#include "../h/param.h"
#include "../h/dir.h"
#include "../h/file.h"
#include "../h/user.h"
#include "../vnet/vnet.h"
#include "../h/inode.h"

#include "../conn/conn.h"
#include "../rpc/rpc.h"
#include "../efs/efs.h"

/*
 * This code has never been turned on...until now.  We have been having
 * problems at Fluke Mfg, one of which was attributable to a problem in
 * RPC.  It is my belief that the other problem is caused by the
 * fact the that application programs believed the flock() would work
 * over the net when, in fact, flock() was not supported, EFS-wise.
 *
 * Note that I am enforcing the no-block provision of flock() -- to
 * do otherwise would invite the slew of problems that we had with
 * open using lock bits in the 7.x RPC/EFS.
 *
 * sas 861015
 */
 
struct efs_flockCall {
	u_long	rfd;		/* Remote file descriptor */
	int	how;		/* What to do with the locks	*/
};

struct efs_flockReturn {
	int	error;		/* Error number or 0 on success */
};

/*
 * Twiddle with advisory lock on a remote file.
 * This is the client-side.
 */
efs_flock(fp, how)
	register struct file *fp;
	int	how;		/* What to do with the locks */
{
	register struct efs_remoteFile	* remote;
	register struct efs_flockCall	* params;
	register struct efs_flockReturn	* results;
	register struct a {
		int	fd;
		int	how;	/* What to do with the locks */
	} *uap = (struct a *)u.u_ap;

	if (fp == NULL)
		return;
	remote = fp->f_remote;
	if (remote->state == EFS_FILE_CRASHED)
		return(ESERVERCRASHED);
	params			= efs_makePacket(flock, 0);
	params->rfd		= remote->rfd;
	params->how		= uap->how|LOCK_NB;

	efs_incClient(flocks);
	results = (struct efs_flockReturn *)efs_call(remote->conn,EFS_FLOCK,params);
	if (results == NULL)
		return;
	u.u_error = results->error;
	rpc_freeResults(results);
}

/*
 * Server side.
 */
caddr_t
efs_remoteFlock(clientConn, clientId, operation, params)
	connection_t	*	clientConn;
	u_long			clientId;
	u_short			operation;	/* EFS opCode */
	struct	efs_flockCall *	params;
{
	register struct	efs_flockReturn *	results;
	register efs_localFile_t	*	local;
	struct a {
		int	fd;
		int	how;	/* What to do with the locks */
	} efs_fake_u_ap, *uap = (struct a *)&efs_fake_u_ap;

	efs_incServer(flocks);
	results = efs_makeReturnPacket(params,flock, 0);
	if (results == NULL)
		goto bad;
	if ((local = efs_rfdToLocal(params->rfd)) == NULL)
		results->error = EBADF;
	else {
		register struct	file	* fp = local->fp;

		u.u_ap	 = (int *)uap;
		uap->fd  = -1;		/* (Unused -- known/bad state) */
		uap->how = params->how|LOCK_NB;
		flock1(fp);
		results->error = u.u_error;
	}
bad:
	rpc_freeParams(params);
	return((caddr_t)results);
}
#endif	EFS_X_FLOCK
