static char rcsid[] = "$Header: efs_readlink.c,v 820.1 86/12/04 19:47:47 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.				*
*									*
************************************************************************/

/*
 * Handle a remote readlink call.  Pass the
 * path name to the remote machine.
 *
 * jht 850806-07 -- augment EFS with readlink.
 */

#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 "../h/nami.h"

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

#ifdef	EFS_X_READLINK
struct	efs_readlinkCall {
	int		buflen;	/* Size of caller's receiving buffer */
	/* Null terminated filename follows this structure */
};

struct efs_readlinkReturn {
	int		error;		/* Error number or 0 on success */
	/* Null terminated synlink follows this structure */
};

/*
 * Client-side Support for readlink().
 */
efs_readlink(fnamep, bufp, buflen)
	char	*fnamep;
	char	*bufp;
	int	 buflen;
{
	register connection_t	*	 	 conn;
	register struct efs_readlinkCall	*params;
	register struct efs_readlinkReturn	*results;

	if ((conn = efs_uhostLookup()) == NULL) {
		u.u_error = EHOSTUNREACH;
		return;
	}
	params			= efs_makePacket(readlink,EFS_PATHSIZE);
	params->buflen		= buflen;	/* For the caller's buffer */
	efs_getPathname(efs_data(params));	/* fname */

	efs_incClient(readlinks);
	results = (struct efs_readlinkReturn *)efs_call(conn,EFS_READLINK,params);
	if (results == NULL)
		return;
	u.u_error = results->error;
	rpc_freeResults(results);
}

/*
 * Server side.
 */
caddr_t
efs_remoteReadlink(clientConn, clientId, operation, params)
	connection_t	*		clientConn;
	u_long				clientId;
	u_short				operation;
	struct	efs_readlinkCall *	params;
{
	register struct efs_readlinkReturn *results;
	register struct inode		   *ip;
	extern	 struct inode		   *efs_owner();
	extern	 mbufchar();
	struct a {		/* Pretended context for readlink1() */
		char	*name;		/* Filename			*/
		char	*buf;		/* Receiving buffer		*/
		int	count;		/* Length of receiving buffer	*/
	} *uap = (struct a *)u.u_ap;


	efs_incServer(readlinks);
	u.u_error = 0;

	/*
	 * Get return packet to hold the symlink.
	 */
	results   = efs_makeReturnPacket(params,readlink, params->buflen);

	/*
	 * Simulate a context for readlink()
	 */
	uap.name  = (char *)
	u.u_dirp  = efs_data(params);		/* Filename for uchar()      */
	uap.buf   = (char *) efs_data(results);	/* Passback buffer	     */
	uap.count = buflen;			/* Length of passback buffer */

	/*
	 * Hunt up the symbolic link
	 */
	results->resid = readlink1(mbufchar, uap->name, uap.buf, uap.count);

	/*
	 * Return the results to the client-side
	 */
	results->error = u.u_error;
	rpc_freeParams(params);
	return((caddr_t)results);
}
#endif	EFS_X_READLINK
