/*
 * quota.c --- debugfs quota commands
 *
 * Copyright (C) 2014 Theodore Ts'o.  This file may be redistributed
 * under the terms of the GNU Public License.
 */

#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif

#include "debugfs.h"

const char *quota_type[] = { "user", "group", "project", NULL };

static int load_quota_ctx(char *progname)
{
	errcode_t	retval;

	if (check_fs_open(progname))
		return 1;

	if (!ext2fs_has_feature_quota(current_fs->super)) {
		com_err(progname, 0, "quota feature not enabled");
		return 1;
	}

	if (current_qctx)
		return 0;

	retval = quota_init_context(&current_qctx, current_fs, 0);
	if (retval) {
		com_err(current_fs->device_name, retval,
			"while trying to load quota information");
		return 1;
	}
	return 0;
}

static int parse_quota_type(const char *cmdname, const char *str)
{
	errcode_t	retval;
	char		*t;
	int		flags = 0;
	int		i;

	for (i = 0; i < MAXQUOTAS; i++) {
		if (strcasecmp(str, quota_type[i]) == 0)
			break;
	}
	if (i >= MAXQUOTAS) {
		i = strtol(str, &t, 0);
		if (*t)
			i = -1;
	}
	if (i < 0 || i >= MAXQUOTAS) {
		com_err(0, 0, "Invalid quota type: %s", str);
		printf("Valid quota types are: ");
		for (i = 0; i < MAXQUOTAS; i++)
			printf("%s ", quota_type[i]);
		printf("\n");
		return -1;
	}

	if (current_fs->flags & EXT2_FLAG_RW)
		flags |= EXT2_FILE_WRITE;

	retval = quota_file_open(current_qctx, NULL, 0, i, -1, flags);
	if (retval) {
		com_err(cmdname, retval,
			"while opening quota inode (type %d)", i);
		return -1;
	}
	return i;
}


static int list_quota_callback(struct dquot *dq,
			       void *cb_data EXT2FS_ATTR((unused)))
{
	printf("%10u   %8lld %8lld %8lld    %8lld %8lld %8lld\n",
	       dq->dq_id, (long long)dq->dq_dqb.dqb_curspace,
	       (long long)dq->dq_dqb.dqb_bsoftlimit,
	       (long long)dq->dq_dqb.dqb_bhardlimit,
	       (long long)dq->dq_dqb.dqb_curinodes,
	       (long long)dq->dq_dqb.dqb_isoftlimit,
	       (long long)dq->dq_dqb.dqb_ihardlimit);
	return 0;
}

void do_list_quota(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
		   void *infop EXT2FS_ATTR((unused)))
{
	errcode_t	retval;
	int		type;
	struct quota_handle *qh;

	if (load_quota_ctx(argv[0]))
		return;

	if (argc != 2) {
		com_err(0, 0, "Usage: list_quota <quota_type>\n");
		return;
	}

	type = parse_quota_type(argv[0], argv[1]);
	if (type < 0)
		return;

	printf("%7s %2s   %8s %8s %8s    %8s %8s %8s\n",
	       quota_type[type], "id",
	       "blocks", "quota", "limit", "inodes", "quota", "limit");
	qh = current_qctx->quota_file[type];
	retval = qh->qh_ops->scan_dquots(qh, list_quota_callback, NULL);
	if (retval) {
		com_err(argv[0], retval, "while scanning dquots");
		return;
	}
}

void do_get_quota(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
		  void *infop EXT2FS_ATTR((unused)))
{
	int		err, type;
	struct quota_handle *qh;
	struct dquot	*dq;
	qid_t		id;

	if (load_quota_ctx(argv[0]))
		return;

	if (argc != 3) {
		com_err(0, 0, "Usage: get_quota <quota_type> <id>\n");
		return;
	}

	type = parse_quota_type(argv[0], argv[1]);
	if (type < 0)
		return;

	id = parse_ulong(argv[2], argv[0], "id", &err);
	if (err)
		return;

	printf("%7s %2s   %8s %8s %8s    %8s %8s %8s\n",
	       quota_type[type], "id",
	       "blocks", "quota", "limit", "inodes", "quota", "limit");

	qh = current_qctx->quota_file[type];

	dq = qh->qh_ops->read_dquot(qh, id);
	if (dq) {
		list_quota_callback(dq, NULL);
		ext2fs_free_mem(&dq);
	} else {
		com_err(argv[0], 0, "couldn't read quota record");
	}
}
