/*
 * Copyright (c) 2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * 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.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include <stdbool.h>
#include "command.h"
#include "init.h"
#include "quota.h"

static cmdinfo_t off_cmd;
static cmdinfo_t state_cmd;
static cmdinfo_t enable_cmd;
static cmdinfo_t disable_cmd;
static cmdinfo_t remove_cmd;

static void
off_help(void)
{
	printf(_(
"\n"
" turn filesystem quota off, both accounting and enforcement\n"
"\n"
" Example:\n"
" 'off -uv'  (switch off user quota on the current filesystem)\n"
" This command is the equivalent of the traditional quotaoff command,\n"
" which disables quota completely on a mounted filesystem.\n"
" Note that there is no 'on' command - for XFS filesystems (with the\n"
" exception of the root filesystem on IRIX) quota can only be enabled\n"
" at mount time, through the use of one of the quota mount options.\n"
"\n"
" The state command is useful for displaying the current state.  Using\n"
" the -v (verbose) option with the 'off' command will display the quota\n"
" state for the affected filesystem once the operation is complete.\n"
" The affected quota type is -g (groups), -p (projects) or -u (users)\n"
" and defaults to user quota (multiple types can be specified).\n"
"\n"));
}

static void
state_help(void)
{
	printf(_(
"\n"
" query the state of quota on the current filesystem\n"
"\n"
" This is a verbose status command, reporting whether or not accounting\n"
" and/or enforcement are enabled for a filesystem, which inodes are in\n"
" use as the quota state inodes, and how many extents and blocks are\n"
" presently being used to hold that information.\n"
" The quota type is specified via -g (groups), -p (projects) or -u (users)\n"
" and defaults to user quota (multiple types can be specified).\n"
"\n"));
}

static void
enable_help(void)
{
	printf(_(
"\n"
" enable quota enforcement on a filesystem\n"
"\n"
" If a filesystem is mounted and has quota accounting enabled, but not\n"
" quota enforcement, enforcement can be enabled with this command.\n"
" With the -v (verbose) option, the status of the filesystem will be\n"
" reported after the operation is complete.\n"
" The affected quota type is -g (groups), -p (projects) or -u (users)\n"
" and defaults to user quota (multiple types can be specified).\n"
"\n"));
}

static void
disable_help(void)
{
	printf(_(
"\n"
" disable quota enforcement on a filesystem\n"
"\n"
" If a filesystem is mounted and is currently enforcing quota, this\n"
" provides a mechanism to switch off the enforcement, but continue to\n"
" perform used space (and used inodes) accounting.\n"
" The affected quota type is -g (groups), -p (projects) or -u (users).\n"
"\n"));
}

static void
remove_help(void)
{
	printf(_(
"\n"
" remove any space being used by the quota subsystem\n"
"\n"
" Once quota has been switched 'off' on a filesystem, the space that\n"
" was allocated to holding quota metadata can be freed via this command.\n"
" The affected quota type is -g (groups), -p (projects) or -u (users)\n"
" and defaults to user quota (multiple types can be specified).\n"
"\n"));
}

static void
state_qfilestat(
	FILE			*fp,
	struct fs_path		*mount,
	uint			type,
	struct fs_qfilestatv	*qfs,
	int			accounting,
	int			enforcing)
{
	fprintf(fp, _("%s quota state on %s (%s)\n"), type_to_string(type),
		mount->fs_dir, mount->fs_name);
	fprintf(fp, _("  Accounting: %s\n"), accounting ? _("ON") : _("OFF"));
	fprintf(fp, _("  Enforcement: %s\n"), enforcing ? _("ON") : _("OFF"));
	if (qfs->qfs_ino != (__u64) -1)
		fprintf(fp, _("  Inode: #%llu (%llu blocks, %lu extents)\n"),
			(unsigned long long)qfs->qfs_ino,
			(unsigned long long)qfs->qfs_nblks,
			(unsigned long)qfs->qfs_nextents);
	else
		fprintf(fp, _("  Inode: N/A\n"));
}

static void
state_timelimit(
	FILE		*fp,
	uint		form,
	__uint32_t	timelimit)
{
	fprintf(fp, _("%s grace time: %s\n"),
		form_to_string(form),
		time_to_string(timelimit, VERBOSE_FLAG | ABSOLUTE_FLAG));
}

/*
 * fs_quota_stat holds a subset of fs_quota_statv; this copies
 * the smaller into the larger, leaving any not-present fields
 * empty.  This is so the same reporting function can be used
 * for both XFS_GETQSTAT and XFS_GETQSTATV results.
 */
static void
state_stat_to_statv(
	struct fs_quota_stat	*s,
	struct fs_quota_statv	*sv)
{
	memset(sv, 0, sizeof(struct fs_quota_statv));

	/* shared information */
	sv->qs_version = s->qs_version;
	sv->qs_flags = s->qs_flags;
	sv->qs_incoredqs = s->qs_incoredqs;
	sv->qs_btimelimit = s->qs_btimelimit;
	sv->qs_itimelimit = s->qs_itimelimit;
	sv->qs_rtbtimelimit = s->qs_rtbtimelimit;
	sv->qs_bwarnlimit = s->qs_bwarnlimit;
	sv->qs_iwarnlimit = s->qs_iwarnlimit;

	/* Always room for uquota */
	sv->qs_uquota.qfs_ino = s->qs_uquota.qfs_ino;
	sv->qs_uquota.qfs_nblks = s->qs_uquota.qfs_nblks;
	sv->qs_uquota.qfs_nextents = s->qs_uquota.qfs_nextents;

	/*
	 * If we are here, XFS_GETQSTATV failed and XFS_GETQSTAT passed;
	 * that is a very strong hint that we're on a kernel which predates
	 * the on-disk pquota inode; both were added in v3.12.  So, we do
	 * some tricksy determination here.
	 * gs_gquota may hold either group quota inode info, or project
	 * quota if that is used instead; which one it actually holds depends
	 * on the quota flags.  (If neither is set, neither is used)
	 */
	if (s->qs_flags & XFS_QUOTA_GDQ_ACCT) {
		/* gs_gquota holds group quota info */
		sv->qs_gquota.qfs_ino = s->qs_gquota.qfs_ino;
		sv->qs_gquota.qfs_nblks = s->qs_gquota.qfs_nblks;
		sv->qs_gquota.qfs_nextents = s->qs_gquota.qfs_nextents;
	} else if (s->qs_flags & XFS_QUOTA_PDQ_ACCT) {
		/* gs_gquota actually holds project quota info */
		sv->qs_pquota.qfs_ino = s->qs_gquota.qfs_ino;
		sv->qs_pquota.qfs_nblks = s->qs_gquota.qfs_nblks;
		sv->qs_pquota.qfs_nextents = s->qs_gquota.qfs_nextents;
	}
}

static void
state_quotafile_mount(
	FILE			*fp,
	uint			type,
	struct fs_path		*mount,
	uint			flags)
{
	struct fs_quota_stat	s;
	struct fs_quota_statv	sv;
	char			*dev = mount->fs_name;

	sv.qs_version = FS_QSTATV_VERSION1;

	if (xfsquotactl(XFS_GETQSTATV, dev, type, 0, (void *)&sv) < 0) {
		if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)&s) < 0) {
			if (flags & VERBOSE_FLAG)
				fprintf(fp,
					_("%s quota are not enabled on %s\n"),
					type_to_string(type), dev);
			return;
		}
		state_stat_to_statv(&s, &sv);
	}

	if (type & XFS_USER_QUOTA)
		state_qfilestat(fp, mount, XFS_USER_QUOTA, &sv.qs_uquota,
				sv.qs_flags & XFS_QUOTA_UDQ_ACCT,
				sv.qs_flags & XFS_QUOTA_UDQ_ENFD);
	if (type & XFS_GROUP_QUOTA)
		state_qfilestat(fp, mount, XFS_GROUP_QUOTA, &sv.qs_gquota,
				sv.qs_flags & XFS_QUOTA_GDQ_ACCT,
				sv.qs_flags & XFS_QUOTA_GDQ_ENFD);
	if (type & XFS_PROJ_QUOTA)
		state_qfilestat(fp, mount, XFS_PROJ_QUOTA, &sv.qs_pquota,
				sv.qs_flags & XFS_QUOTA_PDQ_ACCT,
				sv.qs_flags & XFS_QUOTA_PDQ_ENFD);

	state_timelimit(fp, XFS_BLOCK_QUOTA, sv.qs_btimelimit);
	state_timelimit(fp, XFS_INODE_QUOTA, sv.qs_itimelimit);
	state_timelimit(fp, XFS_RTBLOCK_QUOTA, sv.qs_rtbtimelimit);
}

static void
state_quotafile(
	FILE		*fp,
	uint		type,
	char		*dir,
	uint		flags)
{
	fs_cursor_t	cursor;
	fs_path_t	*mount;

	fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
	while ((mount = fs_cursor_next_entry(&cursor)))
		state_quotafile_mount(fp, type, mount, flags);
}

static int
state_f(
	int		argc,
	char		**argv)
{
	FILE		*fp = NULL;
	char		*fname = NULL;
	int		c, flags = 0, type = 0;

	while ((c = getopt(argc, argv, "af:gpuv")) != EOF) {
		switch (c) {
		case 'a':
			flags |= ALL_MOUNTS_FLAG;
			break;
		case 'f':
			fname = optarg;
			break;
		case 'g':
			type |= XFS_GROUP_QUOTA;
			break;
		case 'p':
			type |= XFS_PROJ_QUOTA;
			break;
		case 'u':
			type |= XFS_USER_QUOTA;
			break;
		case 'v':
			flags |= VERBOSE_FLAG;
			break;
		default:
			return command_usage(&state_cmd);
		}
	}

	if (argc != optind)
		return command_usage(&state_cmd);

	if ((fp = fopen_write_secure(fname)) == NULL)
		return 0;

	if (!type)
		type = XFS_USER_QUOTA | XFS_GROUP_QUOTA | XFS_PROJ_QUOTA;

	if (flags & ALL_MOUNTS_FLAG)
		state_quotafile(fp, type, NULL, flags);
	else if (fs_path && fs_path->fs_flags & FS_MOUNT_POINT)
		state_quotafile(fp, type, fs_path->fs_dir, flags);

	if (fname)
		fclose(fp);
	return 0;
}

static void
enable_enforcement(
	char		*dir,
	uint		type,
	uint		qflags,
	uint		flags)
{
	fs_path_t	*mount;

	mount = fs_table_lookup(dir, FS_MOUNT_POINT);
	if (!mount) {
		exitcode = 1;
		fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
		return;
	}
	dir = mount->fs_name;
	if (xfsquotactl(XFS_QUOTAON, dir, type, 0, (void *)&qflags) < 0)
		perror("XFS_QUOTAON");
	else if (flags & VERBOSE_FLAG)
		state_quotafile_mount(stdout, type, mount, flags);
}

static void
disable_enforcement(
	char		*dir,
	uint		type,
	uint		qflags,
	uint		flags)
{
	fs_path_t	*mount;

	mount = fs_table_lookup(dir, FS_MOUNT_POINT);
	if (!mount) {
		exitcode = 1;
		fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
		return;
	}
	dir = mount->fs_name;
	if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0)
		perror("XFS_QUOTAOFF");
	else if (flags & VERBOSE_FLAG)
		state_quotafile_mount(stdout, type, mount, flags);
}

static void
quotaoff(
	char		*dir,
	uint		type,
	uint		qflags,
	uint		flags)
{
	fs_path_t	*mount;

	mount = fs_table_lookup(dir, FS_MOUNT_POINT);
	if (!mount) {
		exitcode = 1;
		fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
		return;
	}
	dir = mount->fs_name;
	if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0)
		perror("XFS_QUOTAOFF");
	else if (flags & VERBOSE_FLAG)
		state_quotafile_mount(stdout, type, mount, flags);
}

static int
remove_qtype_extents(
	char		*dir,
	uint		type)
{
	int	error = 0;

	if ((error = xfsquotactl(XFS_QUOTARM, dir, type, 0, (void *)&type)) < 0)
		perror("XFS_QUOTARM");
	return error;
}

static void
remove_extents(
	char		*dir,
	uint		type,
	uint		flags)
{
	fs_path_t	*mount;

	mount = fs_table_lookup(dir, FS_MOUNT_POINT);
	if (!mount) {
		exitcode = 1;
		fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
		return;
	}
	dir = mount->fs_name;
	if (type & XFS_USER_QUOTA) {
		if (remove_qtype_extents(dir, XFS_USER_QUOTA) < 0)
			return;
	}
	if (type & XFS_GROUP_QUOTA) {
		if (remove_qtype_extents(dir, XFS_GROUP_QUOTA) < 0)
			return;
	} else if (type & XFS_PROJ_QUOTA) {
		if (remove_qtype_extents(dir, XFS_PROJ_QUOTA) < 0)
			return;
	}
	if (flags & VERBOSE_FLAG)
		state_quotafile_mount(stdout, type, mount, flags);
}

static int
enable_f(
	int		argc,
	char		**argv)
{
	int		c, flags = 0, qflags = 0, type = 0;

	while ((c = getopt(argc, argv, "gpuv")) != EOF) {
		switch (c) {
		case 'g':
			type |= XFS_GROUP_QUOTA;
			qflags |= XFS_QUOTA_GDQ_ACCT | XFS_QUOTA_GDQ_ENFD;
			break;
		case 'p':
			type |= XFS_PROJ_QUOTA;
			qflags |= XFS_QUOTA_PDQ_ACCT | XFS_QUOTA_PDQ_ENFD;
			break;
		case 'u':
			type |= XFS_USER_QUOTA;
			qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
			break;
		case 'v':
			flags |= VERBOSE_FLAG;
			break;
		default:
			return command_usage(&enable_cmd);
		}
	}

	if (argc != optind)
		return command_usage(&enable_cmd);

	if (!type) {
		type |= XFS_USER_QUOTA;
		qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
	}

	if (fs_path->fs_flags & FS_MOUNT_POINT)
		enable_enforcement(fs_path->fs_dir, type, qflags, flags);
	return 0;
}

static int
disable_f(
	int		argc,
	char		**argv)
{
	int		c, flags = 0, qflags = 0, type = 0;

	while ((c = getopt(argc, argv, "gpuv")) != EOF) {
		switch (c) {
		case 'g':
			type |= XFS_GROUP_QUOTA;
			qflags |= XFS_QUOTA_GDQ_ENFD;
			break;
		case 'p':
			type |= XFS_PROJ_QUOTA;
			qflags |= XFS_QUOTA_PDQ_ENFD;
			break;
		case 'u':
			type |= XFS_USER_QUOTA;
			qflags |= XFS_QUOTA_UDQ_ENFD;
			break;
		case 'v':
			flags |= VERBOSE_FLAG;
			break;
		default:
			return command_usage(&disable_cmd);
		}
	}

	if (argc != optind)
		return command_usage(&disable_cmd);

	if (!type) {
		type |= XFS_USER_QUOTA;
		qflags |= XFS_QUOTA_UDQ_ENFD;
	}

	if (fs_path->fs_flags & FS_MOUNT_POINT)
		disable_enforcement(fs_path->fs_dir, type, qflags, flags);
	return 0;
}

static int
off_f(
	int		argc,
	char		**argv)
{
	int		c, flags = 0, qflags = 0, type = 0;

	while ((c = getopt(argc, argv, "gpuv")) != EOF) {
		switch (c) {
		case 'g':
			type |= XFS_GROUP_QUOTA;
			qflags |= XFS_QUOTA_GDQ_ACCT | XFS_QUOTA_GDQ_ENFD;
			break;
		case 'p':
			type |= XFS_PROJ_QUOTA;
			qflags |= XFS_QUOTA_PDQ_ACCT | XFS_QUOTA_PDQ_ENFD;
			break;
		case 'u':
			type |= XFS_USER_QUOTA;
			qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
			break;
		case 'v':
			flags |= VERBOSE_FLAG;
			break;
		default:
			return command_usage(&off_cmd);
		}
	}

	if (argc != optind)
		return command_usage(&off_cmd);

	if (!type) {
		type |= XFS_USER_QUOTA;
		qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
	}

	if (fs_path->fs_flags & FS_MOUNT_POINT)
		quotaoff(fs_path->fs_dir, type, qflags, flags);
	return 0;
}

static int
remove_f(
	int		argc,
	char		**argv)
{
	int		c, flags = 0, type = 0;

	while ((c = getopt(argc, argv, "gpuv")) != EOF) {
		switch (c) {
		case 'g':
			type |= XFS_GROUP_QUOTA;
			break;
		case 'p':
			type |= XFS_PROJ_QUOTA;
			break;
		case 'u':
			type |= XFS_USER_QUOTA;
			break;
		case 'v':
			flags |= VERBOSE_FLAG;
			break;
		default:
			return command_usage(&remove_cmd);
		}
	}

	if (argc != optind)
		return command_usage(&remove_cmd);

	if (!type) {
		type |= XFS_USER_QUOTA;
	}

	if (fs_path->fs_flags & FS_MOUNT_POINT)
		remove_extents(fs_path->fs_dir, type, flags);
	return 0;
}

void
state_init(void)
{
	off_cmd.name = "off";
	off_cmd.cfunc = off_f;
	off_cmd.argmin = 0;
	off_cmd.argmax = -1;
	off_cmd.args = _("[-gpu] [-v]");
	off_cmd.oneline = _("permanently switch quota off for a path");
	off_cmd.help = off_help;

	state_cmd.name = "state";
	state_cmd.cfunc = state_f;
	state_cmd.argmin = 0;
	state_cmd.argmax = -1;
	state_cmd.args = _("[-gpu] [-a] [-v] [-f file]");
	state_cmd.oneline = _("get overall quota state information");
	state_cmd.help = state_help;
	state_cmd.flags = CMD_FLAG_FOREIGN_OK;

	enable_cmd.name = "enable";
	enable_cmd.cfunc = enable_f;
	enable_cmd.argmin = 0;
	enable_cmd.argmax = -1;
	enable_cmd.args = _("[-gpu] [-v]");
	enable_cmd.oneline = _("enable quota enforcement");
	enable_cmd.help = enable_help;

	disable_cmd.name = "disable";
	disable_cmd.cfunc = disable_f;
	disable_cmd.argmin = 0;
	disable_cmd.argmax = -1;
	disable_cmd.args = _("[-gpu] [-v]");
	disable_cmd.oneline = _("disable quota enforcement");
	disable_cmd.help = disable_help;

	remove_cmd.name = "remove";
	remove_cmd.cfunc = remove_f;
	remove_cmd.argmin = 0;
	remove_cmd.argmax = -1;
	remove_cmd.args = _("[-gpu] [-v]");
	remove_cmd.oneline = _("remove quota extents from a filesystem");
	remove_cmd.help = remove_help;

	if (expert) {
		add_command(&off_cmd);
		add_command(&state_cmd);
		add_command(&enable_cmd);
		add_command(&disable_cmd);
		add_command(&remove_cmd);
	}
}
