/*
 * QUOTA    An implementation of the diskquota system for the LINUX
 *          operating system. QUOTA is implemented using the BSD systemcall
 *          interface as the means of communication with the user level.
 *          Should work for all filesystems because of integration into the
 *          VFS layer of the operating system.
 *          This is based on the Melbourne quota system wich uses both user and
 *          group quota files.
 *
 *          This part does the rpc-communication with the rquotad.
 *
 * Author:  Marco van Wieringen <mvw@planets.elm.net>
 *
 *          This program is free software; you can redistribute it and/or
 *          modify it under the terms of the GNU General Public License
 *          as published by the Free Software Foundation; either version
 *          2 of the License, or (at your option) any later version.
 */

#include "config.h"

#include <rpc/rpc.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <stdint.h>

#include "mntopt.h"
#include "rquota.h"
#include "common.h"
#include "quotaio.h"
#include "quotasys.h"

#if defined(RPC)

/* Convert network format of quotas to utils one */
static inline void clinet2utildqblk(struct util_dqblk *u, struct rquota *n)
{
	time_t now;
	
	/* Copy the quota */
	u->dqb_bhardlimit = toqb(((qsize_t)n->rq_bhardlimit) * n->rq_bsize);
	u->dqb_bsoftlimit = toqb(((qsize_t)n->rq_bsoftlimit) * n->rq_bsize);
	u->dqb_ihardlimit = n->rq_fhardlimit;
	u->dqb_isoftlimit = n->rq_fsoftlimit;
	u->dqb_curinodes = n->rq_curfiles;
	u->dqb_curspace = ((qsize_t)n->rq_curblocks) * n->rq_bsize;
	time(&now);
	if (n->rq_btimeleft)
		u->dqb_btime = (int32_t)n->rq_btimeleft + now;
	else
		u->dqb_btime = 0;
	if (n->rq_ftimeleft)
		u->dqb_itime = (int32_t)n->rq_ftimeleft + now;
	else
		u->dqb_itime = 0;
}

/* Convert utils format of quotas to network one */
static inline void cliutil2netdqblk(struct sq_dqblk *n, struct util_dqblk *u)
{
	time_t now;

	time(&now);
	n->rq_bhardlimit = u->dqb_bhardlimit;
	n->rq_bsoftlimit = u->dqb_bsoftlimit;
	n->rq_fhardlimit = u->dqb_ihardlimit;
	n->rq_fsoftlimit = u->dqb_isoftlimit;
	n->rq_curblocks = toqb(u->dqb_curspace);
	n->rq_curfiles = u->dqb_curinodes;
	if (u->dqb_btime)
		n->rq_btimeleft = difftime2net(u->dqb_btime, now);
	else
		n->rq_btimeleft = 0;
	if (u->dqb_itime)
		n->rq_ftimeleft = difftime2net(u->dqb_itime, now);
	else
		n->rq_ftimeleft = 0;
}

/* Write appropriate error message */
static int rquota_err(int stat)
{
	switch (stat) {
		case -1:
			return -ECONNREFUSED;
		case 0:
			return -ENOSYS;
		case Q_NOQUOTA:
			return -ENOENT;
		case Q_OK:
			return 0;
		case Q_EPERM:
			return -EPERM;
		default:
			return -EINVAL;
	}
}

static int split_nfs_mount(char *devname, char **host, char **path)
{
	char *pathname;

	/* NFS server name contained in brackets? */
	if (*devname == '[') {
		*host = devname + 1;
		pathname = strchr(devname, ']');
		if (!pathname || pathname[1] != ':')
			return 0;
		/* Autofs? */
		if (pathname[2] == '(')
			return 0;
		*pathname = 0;
		*path = pathname + 2;
		return 1;
	}
	*host = devname;
	pathname = strchr(devname, ':');
	if (!pathname)
		return 0;
	/* Autofs? */
	if (pathname[1] == '(')
		return 0;
	*pathname = 0;
	*path = pathname + 1;
	return 1;
}

/*
 * Collect the requested quota information from a remote host.
 */
int rpc_rquota_get(struct dquot *dquot)
{
	CLIENT *clnt;
	getquota_rslt *result;
	union {
		getquota_args arg;
		ext_getquota_args ext_arg;
	} args;
	char *fsname_tmp, *host, *pathname;
	struct timeval timeout = { 2, 0 };
	int rquotaprog_not_registered = 0;
	int ret;

	/*
	 * Initialize with NULL.
	 */
	memset(&dquot->dq_dqb, 0, sizeof(dquot->dq_dqb));

	/*
	 * Convert host:pathname to seperate host and pathname.
	 */
	fsname_tmp = (char *)smalloc(strlen(dquot->dq_h->qh_quotadev) + 1);
	strcpy(fsname_tmp, dquot->dq_h->qh_quotadev);
	if (!split_nfs_mount(fsname_tmp, &host, &pathname)) {
		free(fsname_tmp);
		return -ENOENT;
	}

	/* For NFSv4, we send the filesystem path without initial /. Server prepends proper
	 * NFS pseudoroot automatically and uses this for detection of NFSv4 mounts. */
	if ((dquot->dq_h->qh_io_flags & IOFL_NFS_MIXED_PATHS) &&
	    !strcmp(dquot->dq_h->qh_fstype, MNTTYPE_NFS4)) {
		while (*pathname == '/')
			pathname++;
	}

	/*
	 * First try EXT_RQUOTAPROG (Extended (LINUX) RPC quota program)
	 */
	args.ext_arg.gqa_pathp = pathname;
	args.ext_arg.gqa_id = dquot->dq_id;
	args.ext_arg.gqa_type = dquot->dq_h->qh_type;

	/*
	 * Create a RPC client.
	 */
	if ((clnt = clnt_create(host, RQUOTAPROG, EXT_RQUOTAVERS, "udp")) != NULL) {
		/*
		 * Initialize unix authentication
		 */
		clnt->cl_auth = authunix_create_default();

		/*
		 * Setup protocol timeout.
		 */
		clnt_control(clnt, CLSET_TIMEOUT, (caddr_t) & timeout);

		/*
		 * Do RPC call and check result.
		 */
		result = rquotaproc_getquota_2(&args.ext_arg, clnt);
		if (result != NULL && result->status == Q_OK)
			clinet2utildqblk(&dquot->dq_dqb, &result->getquota_rslt_u.gqr_rquota);

		/*
		 * Destroy unix authentication and RPC client structure.
		 */
		auth_destroy(clnt->cl_auth);
		clnt_destroy(clnt);
	}
	else {
		result = NULL;
		if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
			rquotaprog_not_registered = 1;
	}

	if (result == NULL || !result->status) {
		if (dquot->dq_h->qh_type == USRQUOTA) {
			/*
			 * Try RQUOTAPROG because server doesn't seem to understand EXT_RQUOTAPROG. (NON-LINUX servers.)
			 */
			args.arg.gqa_pathp = pathname;
			args.arg.gqa_uid = dquot->dq_id;

			/*
			 * Create a RPC client.
			 */
			if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) != NULL) {
				/*
				 * Initialize unix authentication
				 */
				clnt->cl_auth = authunix_create_default();

				/*
				 * Setup protocol timeout.
				 */
				clnt_control(clnt, CLSET_TIMEOUT, (caddr_t) & timeout);

				/*
				 * Do RPC call and check result.
				 */
				result = rquotaproc_getquota_1(&args.arg, clnt);
				if (result != NULL && result->status == Q_OK)
					clinet2utildqblk(&dquot->dq_dqb,
							 &result->getquota_rslt_u.gqr_rquota);

				/*
				 * Destroy unix authentication and RPC client structure.
				 */
				auth_destroy(clnt->cl_auth);
				clnt_destroy(clnt);
			} else {
				result = NULL;
				if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
					    rquotaprog_not_registered = 1;
			}
		}
	}
	free(fsname_tmp);
	if (result)
		ret = result->status;
	else if (rquotaprog_not_registered)
		ret = Q_NOQUOTA;
	else
		ret = -1;
	return rquota_err(ret);
}

/*
 * Set the requested quota information on a remote host.
 */
int rpc_rquota_set(int qcmd, struct dquot *dquot)
{
#if defined(RPC_SETQUOTA)
	CLIENT *clnt;
	setquota_rslt *result;
	union {
		setquota_args arg;
		ext_setquota_args ext_arg;
	} args;
	char *fsname_tmp, *host, *pathname;
	struct timeval timeout = { 2, 0 };
	int rquotaprog_not_registered = 0;
	int ret;

	/* RPC limits values to 32b variables. Prevent value wrapping. */
	if (check_dquot_range(dquot) < 0)
		return -ERANGE;

	/*
	 * Convert host:pathname to seperate host and pathname.
	 */
	fsname_tmp = (char *)smalloc(strlen(dquot->dq_h->qh_quotadev) + 1);
	strcpy(fsname_tmp, dquot->dq_h->qh_quotadev);
	if (!split_nfs_mount(fsname_tmp, &host, &pathname)) {
		free(fsname_tmp);
		return -ENOENT;
	}

	/* For NFSv4, we send the filesystem path without initial /. Server prepends proper
	 * NFS pseudoroot automatically and uses this for detection of NFSv4 mounts. */
	if ((dquot->dq_h->qh_io_flags & IOFL_NFS_MIXED_PATHS) &&
	    !strcmp(dquot->dq_h->qh_fstype, MNTTYPE_NFS4)) {
		while (*pathname == '/')
			pathname++;
	}

	/*
	 * First try EXT_RQUOTAPROG (Extended (LINUX) RPC quota program)
	 */
	args.ext_arg.sqa_qcmd = qcmd;
	args.ext_arg.sqa_pathp = pathname;
	args.ext_arg.sqa_id = dquot->dq_id;
	args.ext_arg.sqa_type = dquot->dq_h->qh_type;
	cliutil2netdqblk(&args.ext_arg.sqa_dqblk, &dquot->dq_dqb);

	if ((clnt = clnt_create(host, RQUOTAPROG, EXT_RQUOTAVERS, "udp")) != NULL) {
		/*
		 * Initialize unix authentication
		 */
		clnt->cl_auth = authunix_create_default();

		/*
		 * Setup protocol timeout.
		 */
		clnt_control(clnt, CLSET_TIMEOUT, (caddr_t) & timeout);

		/*
		 * Do RPC call and check result.
		 */
		result = rquotaproc_setquota_2(&args.ext_arg, clnt);
		if (result != NULL && result->status == Q_OK)
			clinet2utildqblk(&dquot->dq_dqb, &result->setquota_rslt_u.sqr_rquota);

		/*
		 * Destroy unix authentication and RPC client structure.
		 */
		auth_destroy(clnt->cl_auth);
		clnt_destroy(clnt);
	}
	else {
		result = NULL;
		if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
			rquotaprog_not_registered = 1;
	}

	if (result == NULL || !result->status) {
		if (dquot->dq_h->qh_type == USRQUOTA) {
			/*
			 * Try RQUOTAPROG because server doesn't seem to understand EXT_RQUOTAPROG. (NON-LINUX servers.)
			 */
			args.arg.sqa_qcmd = qcmd;
			args.arg.sqa_pathp = pathname;
			args.arg.sqa_id = dquot->dq_id;
			cliutil2netdqblk(&args.arg.sqa_dqblk, &dquot->dq_dqb);

			/*
			 * Create a RPC client.
			 */
			if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) != NULL) {
				/*
				 * Initialize unix authentication
				 */
				clnt->cl_auth = authunix_create_default();

				/*
				 * Setup protocol timeout.
				 */
				clnt_control(clnt, CLSET_TIMEOUT, (caddr_t) & timeout);

				/*
				 * Do RPC call and check result.
				 */
				result = rquotaproc_setquota_1(&args.arg, clnt);
				if (result != NULL && result->status == Q_OK)
					clinet2utildqblk(&dquot->dq_dqb,
							 &result->setquota_rslt_u.sqr_rquota);

				/*
				 * Destroy unix authentication and RPC client structure.
				 */
				auth_destroy(clnt->cl_auth);
				clnt_destroy(clnt);
			} else {
				result = NULL;
				if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
					rquotaprog_not_registered = 1;
			}
		}
	}
	free(fsname_tmp);
	if (result)
		ret = result->status;
	else if (rquotaprog_not_registered)
		ret = Q_NOQUOTA;
	else
		ret = -1;
	return rquota_err(ret);
#endif
	return -1;
}
#endif
