/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program 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
 * 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 to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <fcntl.h>
#include <unistd.h>

#include "ctree.h"
#include "commands.h"
#include "utils.h"
#include "props.h"

#define XATTR_BTRFS_PREFIX     "btrfs."
#define XATTR_BTRFS_PREFIX_LEN (sizeof(XATTR_BTRFS_PREFIX) - 1)

/*
 * Defined as synonyms in attr/xattr.h
 */
#ifndef ENOATTR
#define ENOATTR ENODATA
#endif

static int prop_read_only(enum prop_object_type type,
			  const char *object,
			  const char *name,
			  const char *value)
{
	int ret = 0;
	int fd = -1;
	u64 flags = 0;

	fd = open(object, O_RDONLY);
	if (fd < 0) {
		ret = -errno;
		fprintf(stderr, "ERROR: open %s failed. %s\n",
				object, strerror(-ret));
		goto out;
	}

	ret = ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags);
	if (ret < 0) {
		ret = -errno;
		fprintf(stderr, "ERROR: failed to get flags for %s. %s\n",
				object, strerror(-ret));
		goto out;
	}

	if (!value) {
		if (flags & BTRFS_SUBVOL_RDONLY)
			fprintf(stdout, "ro=true\n");
		else
			fprintf(stdout, "ro=false\n");
		ret = 0;
		goto out;
	}

	if (!strcmp(value, "true")) {
		flags |= BTRFS_SUBVOL_RDONLY;
	} else if (!strcmp(value, "false")) {
		flags = flags & ~BTRFS_SUBVOL_RDONLY;
	} else {
		ret = -EINVAL;
		fprintf(stderr, "ERROR: invalid value for property.\n");
		goto out;
	}

	ret = ioctl(fd, BTRFS_IOC_SUBVOL_SETFLAGS, &flags);
	if (ret < 0) {
		ret = -errno;
		fprintf(stderr, "ERROR: failed to set flags for %s. %s\n",
				object, strerror(-ret));
		goto out;
	}

out:
	if (fd != -1)
		close(fd);
	return ret;
}

static int prop_label(enum prop_object_type type,
		      const char *object,
		      const char *name,
		      const char *value)
{
	int ret;

	if (value) {
		ret = set_label((char *) object, (char *) value);
	} else {
		char label[BTRFS_LABEL_SIZE];

		ret = get_label((char *) object, label);
		if (!ret)
			fprintf(stdout, "label=%s\n", label);
	}

	return ret;
}

static int prop_compression(enum prop_object_type type,
			    const char *object,
			    const char *name,
			    const char *value)
{
	int ret;
	ssize_t sret;
	int fd = -1;
	DIR *dirstream = NULL;
	char *buf = NULL;
	char *xattr_name = NULL;
	int open_flags = value ? O_RDWR : O_RDONLY;

	fd = open_file_or_dir3(object, &dirstream, open_flags);
	if (fd == -1) {
		ret = -errno;
		fprintf(stderr, "ERROR: open %s failed. %s\n",
			object, strerror(-ret));
		goto out;
	}

	xattr_name = malloc(XATTR_BTRFS_PREFIX_LEN + strlen(name) + 1);
	if (!xattr_name) {
		ret = -ENOMEM;
		goto out;
	}
	memcpy(xattr_name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN);
	memcpy(xattr_name + XATTR_BTRFS_PREFIX_LEN, name, strlen(name));
	xattr_name[XATTR_BTRFS_PREFIX_LEN + strlen(name)] = '\0';

	if (value)
		sret = fsetxattr(fd, xattr_name, value, strlen(value), 0);
	else
		sret = fgetxattr(fd, xattr_name, NULL, 0);
	if (sret < 0) {
		ret = -errno;
		if (ret != -ENOATTR)
			fprintf(stderr,
				"ERROR: failed to %s compression for %s. %s\n",
				value ? "set" : "get", object, strerror(-ret));
		else
			ret = 0;
		goto out;
	}
	if (!value) {
		size_t len = sret;

		buf = malloc(len);
		if (!buf) {
			ret = -ENOMEM;
			goto out;
		}
		sret = fgetxattr(fd, xattr_name, buf, len);
		if (sret < 0) {
			ret = -errno;
			fprintf(stderr,
				"ERROR: failed to get compression for %s. %s\n",
				object, strerror(-ret));
			goto out;
		}
		fprintf(stdout, "compression=%.*s\n", (int)len, buf);
	}

	ret = 0;
out:
	free(xattr_name);
	free(buf);
	if (fd >= 0)
		close_file_or_dir(fd, dirstream);

	return ret;
}

const struct prop_handler prop_handlers[] = {
	{"ro", "Set/get read-only flag of subvolume.", 0, prop_object_subvol,
	 prop_read_only},
	{"label", "Set/get label of device.", 0,
	 prop_object_dev | prop_object_root, prop_label},
	{"compression", "Set/get compression for a file or directory", 0,
	 prop_object_inode, prop_compression},
	{0, 0, 0, 0, 0}
};
