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

/************************************************************************
*									*
*				Copyright 1984, 1985			*
*			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 chmod call.  Pass the
 * path name to the remote machine.
 *
 * jht 841204-05,07 -- augment EFS with chmod/fchmod.
 * smj 850813	Remove (enable) refs to NET_SUPER_USER.
 */

#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_CHMOD
struct efs_chmodCall {
	int		fmode;		/* Mode a la' chmod(2) for file */
	int		uidCaller;	/* Caller's uid	*/
	int		gidCaller;	/* Caller's gid	*/
	/* Null terminated fname follows this structure */
};

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

/*
 * Client-side support for chmod().
 */
efs_chmod(fnamep, fmode)
	char	*fnamep;
	int	 fmode;		/* Mode to which file is to be set */
{
	register connection_t	*	 conn;
	register struct efs_chmodCall	*params;
	register struct efs_chmodReturn *results;

	if ((conn = efs_uhostLookup()) == NULL) {
		u.u_error = EHOSTUNREACH;
		return;
	}
	params			= efs_makePacket(chmod,EFS_PATHSIZE);
	params->fmode		= fmode;
	params->uidCaller	= u.u_uid;	/* Of the user	*/
	params->gidCaller	= u.u_gid;
	efs_getPathname(efs_data(params));

	efs_incClient(chmods);
	results = (struct efs_chmodReturn *)efs_call(conn,EFS_CHMOD,params);
	if (results == NULL)
		return;
	u.u_error = results->error;
	rpc_freeResults(results);
}

/*
 * Server side.
 */
caddr_t
efs_remoteChmod(clientConn, clientId, operation, params)
	connection_t	*	clientConn;
	u_long			clientId;
	u_short			operation;
	struct	efs_chmodCall *	params;
{
	register struct efs_chmodReturn *results;
	register struct inode		*ip;
	extern	 struct inode		*efs_owner();
	extern	 mbufchar();

	efs_incServer(chmods);
	/*
	 * BUG: Does this subvert the context
	 * set up by prpc?
	 */
	u.u_uid = u.u_ruid = params->uidCaller;
	u.u_gid = u.u_rgid = params->gidCaller;
	efs_checkNetsu();
	u.u_error = 0;
	results   = efs_makeReturnPacket(params,chmod, 0);
	u.u_dirp  = efs_data(params);	/* fname */

	if (ip    = efs_owner(mbufchar, 1/*follow*/)) {
		chmod1(ip, params->fmode);
		iput(ip);
	}
	results->error = u.u_error;
	rpc_freeParams(params);
	return((caddr_t)results);
}
#endif	EFS_X_CHMOD
