/*
 * quota.c library interface for Quota API calls
 *
 */

/*
 *    SAM-QFS_notice_begin
 *
 *      Solaris 2.x Sun Storage & Archiving Management File System
 *
 *		Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
 *
 *		U.S. Government Rights - Commercial software. Government users are
 *	subject to the Sun Microsystems, Inc. standard license agreement and applicable
 *	provisions of the FAR and its supplements.
 *
 *      	Use is subject to license terms. Sun, Sun Microsystems and the Sun logo
 *	are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S.
 *	and other countries.
 *
 *    SAM-QFS_notice_end
 */

/*
 *	LGPL NOTICE
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#pragma ident "$Revision$"

/* Feature test switches. */
	/* None. */

/* ANSI C headers. */
#include <string.h>

/* POSIX headers. */
#include <sys/types.h>

/* Solaris headers. */

/*
 * SAM-FS headers.
 */
#include <sam/types.h>
#include <sam/param.h>
#define	__QUOTA_DEFS
#include "sam/quota.h"
#include "sam/syscall.h"
#include "sam/lib.h"

/* Local headers. */
	/* None. */

/* Macros. */
	/* None. */

/* Types. */
	/* None. */

/* Structures. */
	/* None. */

/* Private data. */
	/* None. */

/* Private functions. */
	/* None. */

/* Public data. */
	/* None. */

/* Function macros. */
	/* None. */

int
sam_get_quota_entry_by_fd(int fd, int type, int *index, struct sam_dquot *dq)
{
	int err;
	struct sam_quota_arg arg;

	memset(&arg, 0, sizeof (arg));

	arg.qcmd = SAM_QOP_GET;
	arg.qflags = 0;
	arg.qsize = sizeof (struct sam_quota_arg);
	arg.qtype = type;
	arg.qindex = 0;
	arg.qfd = fd;
	arg.qp.ptr = dq;

	err = sam_syscall(SC_quota, &arg, sizeof (arg));
	if (!err && index != NULL) {
		*index = arg.qindex;
	}
	return (err);
}

int
sam_get_quota_entry_by_index(int fd, int type, int index, struct sam_dquot *dq)
{
	struct sam_quota_arg arg;

	memset(&arg, 0, sizeof (arg));

	arg.qcmd = SAM_QOP_GET;
	arg.qflags = SAM_QFL_INDEX;
	arg.qsize = sizeof (struct sam_quota_arg);
	arg.qtype = type;
	arg.qindex = index;
	arg.qfd = fd;
	arg.qp.ptr = dq;

	return (sam_syscall(SC_quota, &arg, sizeof (arg)));
}

int
sam_put_quota_entry(int fd, int type, int index, struct sam_dquot *dq)
{
	struct sam_quota_arg arg;

	memset(&arg, 0, sizeof (arg));

	arg.qcmd = SAM_QOP_PUT;
	arg.qflags = SAM_QFL_INDEX;
	arg.qsize = sizeof (struct sam_quota_arg);
	arg.qtype = type;
	arg.qindex = index;
	arg.qfd = fd;
	arg.qp.ptr = dq;

	return (sam_syscall(SC_quota_priv, &arg, sizeof (arg)));
}


int
sam_putall_quota_entry(int fd, int type, int index, struct sam_dquot *dq)
{
	struct sam_quota_arg arg;

	memset(&arg, 0, sizeof (arg));

	arg.qcmd = SAM_QOP_PUTALL;
	arg.qflags = SAM_QFL_INDEX;
	arg.qsize = sizeof (struct sam_quota_arg);
	arg.qtype = type;
	arg.qindex = index;
	arg.qfd = fd;
	arg.qp.ptr = dq;

	return (sam_syscall(SC_quota_priv, &arg, sizeof (arg)));
}

int
sam_get_quota_stat(int fd, int *mask)
{
	int r;
	struct sam_quota_arg arg;

	arg.qcmd = SAM_QOP_QSTAT;
	arg.qflags = 0;
	arg.qsize = sizeof (struct sam_quota_arg);
	arg.qtype = 0;
	arg.qindex = 0;
	arg.qfd = fd;
	arg.qp.ptr = NULL;

	r = sam_syscall(SC_quota, &arg, sizeof (arg));
	if (r < 0)
		return (r);
	if (mask)
		*mask = arg.qflags;
	return (0);
}


/*
 * Change file's admin-ID
 */
int
sam_chaid(const char *path, int aid)
{
	struct sam_chaid_arg arg;

	arg.path.ptr = path;
	arg.admin_id = aid;
	arg.follow = 1;
	return (sam_syscall(SC_chaid, &arg, sizeof (arg)));
}

/*
 * Same thing, but if the target is a symbolic link,
 * don't follow it.
 */
int
sam_lchaid(const char *path, int aid)
{
	struct sam_chaid_arg arg;

	arg.path.ptr = path;
	arg.admin_id = aid;
	arg.follow = 0;
	return (sam_syscall(SC_chaid, &arg, sizeof (arg)));
}
