/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "contents.h"

#include <sys/stat.h>
#include <string.h>
#include <stdio.h>

#include "allocate.h"
#include "ext4_utils/ext4_utils.h"
#include "ext4_utils/make_ext4fs.h"
#include "extent.h"
#include "indirect.h"

#ifdef __ANDROID__
#include <linux/capability.h>
#else
#include <private/android_filesystem_capability.h>
#endif

#define XATTR_SELINUX_SUFFIX "selinux"
#define XATTR_CAPS_SUFFIX "capability"

#ifdef _WIN32
#define S_IFLNK 0  /* used by make_link, not needed under mingw */
#endif

static struct block_allocation* saved_allocation_head = NULL;

struct block_allocation* get_saved_allocation_chain() {
	return saved_allocation_head;
}

static u32 dentry_size(u32 entries, struct dentry *dentries)
{
	u32 len = 24;
	unsigned int i;
	unsigned int dentry_len;

	for (i = 0; i < entries; i++) {
		dentry_len = 8 + EXT4_ALIGN(strlen(dentries[i].filename), 4);
		if (len % info.block_size + dentry_len > info.block_size)
			len += info.block_size - (len % info.block_size);
		len += dentry_len;
	}

	return len;
}

static struct ext4_dir_entry_2 *add_dentry(u8 *data, u32 *offset,
		struct ext4_dir_entry_2 *prev, u32 inode, const char *name,
		u8 file_type)
{
	u8 name_len = strlen(name);
	u16 rec_len = 8 + EXT4_ALIGN(name_len, 4);
	struct ext4_dir_entry_2 *dentry;

	u32 start_block = *offset / info.block_size;
	u32 end_block = (*offset + rec_len - 1) / info.block_size;
	if (start_block != end_block) {
		/* Adding this dentry will cross a block boundary, so pad the previous
		   dentry to the block boundary */
		if (!prev)
			critical_error("no prev");
		prev->rec_len += end_block * info.block_size - *offset;
		*offset = end_block * info.block_size;
	}

	dentry = (struct ext4_dir_entry_2 *)(data + *offset);
	dentry->inode = inode;
	dentry->rec_len = rec_len;
	dentry->name_len = name_len;
	dentry->file_type = file_type;
	memcpy(dentry->name, name, name_len);

	*offset += rec_len;
	return dentry;
}

/* Creates a directory structure for an array of directory entries, dentries,
   and stores the location of the structure in an inode.  The new inode's
   .. link is set to dir_inode_num.  Stores the location of the inode number
   of each directory entry into dentries[i].inode, to be filled in later
   when the inode for the entry is allocated.  Returns the inode number of the
   new directory */
u32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries,
	u32 dirs)
{
	struct ext4_inode *inode;
	u32 blocks;
	u32 len;
	u32 offset = 0;
	u32 inode_num;
	u8 *data;
	unsigned int i;
	struct ext4_dir_entry_2 *dentry;

	blocks = DIV_ROUND_UP(dentry_size(entries, dentries), info.block_size);
	len = blocks * info.block_size;

	if (dir_inode_num) {
		inode_num = allocate_inode(info);
	} else {
		dir_inode_num = EXT4_ROOT_INO;
		inode_num = EXT4_ROOT_INO;
	}

	if (inode_num == EXT4_ALLOCATE_FAILED) {
		error("failed to allocate inode\n");
		return EXT4_ALLOCATE_FAILED;
	}

	add_directory(inode_num);

	inode = get_inode(inode_num);
	if (inode == NULL) {
		error("failed to get inode %u", inode_num);
		return EXT4_ALLOCATE_FAILED;
	}

	data = inode_allocate_data_extents(inode, len, len);
	if (data == NULL) {
		error("failed to allocate %u extents", len);
		return EXT4_ALLOCATE_FAILED;
	}

	inode->i_mode = S_IFDIR;
	inode->i_links_count = dirs + 2;
	inode->i_flags |= aux_info.default_i_flags;

	dentry = NULL;

	dentry = add_dentry(data, &offset, NULL, inode_num, ".", EXT4_FT_DIR);
	if (!dentry) {
		error("failed to add . directory");
		return EXT4_ALLOCATE_FAILED;
	}

	dentry = add_dentry(data, &offset, dentry, dir_inode_num, "..", EXT4_FT_DIR);
	if (!dentry) {
		error("failed to add .. directory");
		return EXT4_ALLOCATE_FAILED;
	}

	for (i = 0; i < entries; i++) {
		dentry = add_dentry(data, &offset, dentry, 0,
				dentries[i].filename, dentries[i].file_type);
		if (offset > len || (offset == len && i != entries - 1))
			critical_error("internal error: dentry for %s ends at %d, past %d\n",
				dentries[i].filename, offset, len);
		dentries[i].inode = &dentry->inode;
		if (!dentry) {
			error("failed to add directory");
			return EXT4_ALLOCATE_FAILED;
		}
	}

	/* pad the last dentry out to the end of the block */
	dentry->rec_len += len - offset;

	return inode_num;
}

/* Creates a file on disk.  Returns the inode number of the new file */
u32 make_file(const char *filename, u64 len)
{
	struct ext4_inode *inode;
	u32 inode_num;

	inode_num = allocate_inode(info);
	if (inode_num == EXT4_ALLOCATE_FAILED) {
		error("failed to allocate inode\n");
		return EXT4_ALLOCATE_FAILED;
	}

	inode = get_inode(inode_num);
	if (inode == NULL) {
		error("failed to get inode %u", inode_num);
		return EXT4_ALLOCATE_FAILED;
	}

	if (len > 0) {
		struct block_allocation* alloc = inode_allocate_file_extents(inode, len, filename);
		if (alloc) {
			alloc->filename = strdup(filename);
			alloc->next = saved_allocation_head;
			saved_allocation_head = alloc;
		}
	}

	inode->i_mode = S_IFREG;
	inode->i_links_count = 1;
	inode->i_flags |= aux_info.default_i_flags;

	return inode_num;
}

/* Creates a file on disk.  Returns the inode number of the new file */
u32 make_link(const char *link)
{
	struct ext4_inode *inode;
	u32 inode_num;
	u32 len = strlen(link);

	inode_num = allocate_inode(info);
	if (inode_num == EXT4_ALLOCATE_FAILED) {
		error("failed to allocate inode\n");
		return EXT4_ALLOCATE_FAILED;
	}

	inode = get_inode(inode_num);
	if (inode == NULL) {
		error("failed to get inode %u", inode_num);
		return EXT4_ALLOCATE_FAILED;
	}

	inode->i_mode = S_IFLNK;
	inode->i_links_count = 1;
	inode->i_flags |= aux_info.default_i_flags;
	inode->i_size_lo = len;

	if (len + 1 <= sizeof(inode->i_block)) {
		/* Fast symlink */
		memcpy((char*)inode->i_block, link, len);
	} else {
		u8 *data = inode_allocate_data_indirect(inode, info.block_size, info.block_size);
		memcpy(data, link, len);
		inode->i_blocks_lo = info.block_size / 512;
	}

	return inode_num;
}

int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime)
{
	struct ext4_inode *inode = get_inode(inode_num);

	if (!inode)
		return -1;

	inode->i_mode |= mode;
	inode->i_uid = uid;
	inode->i_gid = gid;
	inode->i_mtime = mtime;
	inode->i_atime = mtime;
	inode->i_ctime = mtime;

	return 0;
}

/*
 * Returns the amount of free space available in the specified
 * xattr region
 */
static size_t xattr_free_space(struct ext4_xattr_entry *entry, char *end)
{
        end -= sizeof(uint32_t); /* Required four null bytes */
	while(!IS_LAST_ENTRY(entry) && (((char *) entry) < end)) {
		end   -= EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
		entry  = EXT4_XATTR_NEXT(entry);
	}

	if (((char *) entry) > end) {
		error("unexpected read beyond end of xattr space");
		return 0;
	}

	return end - ((char *) entry);
}

/*
 * Returns a pointer to the free space immediately after the
 * last xattr element
 */
static struct ext4_xattr_entry* xattr_get_last(struct ext4_xattr_entry *entry)
{
	for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
		// skip entry
	}
	return entry;
}

/*
 * assert that the elements in the ext4 xattr section are in sorted order
 *
 * The ext4 filesystem requires extended attributes to be sorted when
 * they're not stored in the inode. The kernel ext4 code uses the following
 * sorting algorithm:
 *
 * 1) First sort extended attributes by their name_index. For example,
 *    EXT4_XATTR_INDEX_USER (1) comes before EXT4_XATTR_INDEX_SECURITY (6).
 * 2) If the name_indexes are equal, then sorting is based on the length
 *    of the name. For example, XATTR_SELINUX_SUFFIX ("selinux") comes before
 *    XATTR_CAPS_SUFFIX ("capability") because "selinux" is shorter than "capability"
 * 3) If the name_index and name_length are equal, then memcmp() is used to determine
 *    which name comes first. For example, "selinux" would come before "yelinux".
 *
 * This method is intended to implement the sorting function defined in
 * the Linux kernel file fs/ext4/xattr.c function ext4_xattr_find_entry().
 */
static void xattr_assert_sane(struct ext4_xattr_entry *entry)
{
	for( ; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
		struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(entry);
		if (IS_LAST_ENTRY(next)) {
			return;
		}

		int cmp = next->e_name_index - entry->e_name_index;
		if (cmp == 0)
			cmp = next->e_name_len - entry->e_name_len;
		if (cmp == 0)
			cmp = memcmp(next->e_name, entry->e_name, next->e_name_len);
		if (cmp < 0) {
			error("BUG: extended attributes are not sorted\n");
			return;
		}
		if (cmp == 0) {
			error("BUG: duplicate extended attributes detected\n");
			return;
		}
	}
}

#define NAME_HASH_SHIFT 5
#define VALUE_HASH_SHIFT 16

static void ext4_xattr_hash_entry(struct ext4_xattr_header *header,
		struct ext4_xattr_entry *entry)
{
	u32 hash = 0;
	char *name = entry->e_name;
	int n;

	for (n = 0; n < entry->e_name_len; n++) {
		hash = (hash << NAME_HASH_SHIFT) ^
			(hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
			*name++;
	}

	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
		u32 *value = (u32 *)((char *)header +
			le16_to_cpu(entry->e_value_offs));
		for (n = (le32_to_cpu(entry->e_value_size) +
			EXT4_XATTR_ROUND) >> EXT4_XATTR_PAD_BITS; n; n--) {
			hash = (hash << VALUE_HASH_SHIFT) ^
				(hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
				le32_to_cpu(*value++);
		}
	}
	entry->e_hash = cpu_to_le32(hash);
}

#undef NAME_HASH_SHIFT
#undef VALUE_HASH_SHIFT

static struct ext4_xattr_entry* xattr_addto_range(
		void *block_start,
		void *block_end,
		struct ext4_xattr_entry *first,
		int name_index,
		const char *name,
		const void *value,
		size_t value_len)
{
	size_t name_len = strlen(name);
	if (name_len > 255)
		return NULL;

	size_t available_size = xattr_free_space(first, block_end);
	size_t needed_size = EXT4_XATTR_LEN(name_len) + EXT4_XATTR_SIZE(value_len);

	if (needed_size > available_size)
		return NULL;

	struct ext4_xattr_entry *new_entry = xattr_get_last(first);
	memset(new_entry, 0, EXT4_XATTR_LEN(name_len));

	new_entry->e_name_len = name_len;
	new_entry->e_name_index = name_index;
	memcpy(new_entry->e_name, name, name_len);
	new_entry->e_value_block = 0;
	new_entry->e_value_size = cpu_to_le32(value_len);

	char *val = (char *) new_entry + available_size - EXT4_XATTR_SIZE(value_len);
	size_t e_value_offs = val - (char *) block_start;

	new_entry->e_value_offs = cpu_to_le16(e_value_offs);
	memset(val, 0, EXT4_XATTR_SIZE(value_len));
	memcpy(val, value, value_len);

	xattr_assert_sane(first);
	return new_entry;
}

static int xattr_addto_inode(struct ext4_inode *inode, int name_index,
		const char *name, const void *value, size_t value_len)
{
	struct ext4_xattr_ibody_header *hdr = (struct ext4_xattr_ibody_header *) (inode + 1);
	struct ext4_xattr_entry *first = (struct ext4_xattr_entry *) (hdr + 1);
	char *block_end = ((char *) inode) + info.inode_size;

	struct ext4_xattr_entry *result =
		xattr_addto_range(first, block_end, first, name_index, name, value, value_len);

	if (result == NULL)
		return -1;

	hdr->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
	inode->i_extra_isize = cpu_to_le16(sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE);

	return 0;
}

static int xattr_addto_block(struct ext4_inode *inode, int name_index,
		const char *name, const void *value, size_t value_len)
{
	struct ext4_xattr_header *header = get_xattr_block_for_inode(inode);
	if (!header)
		return -1;

	struct ext4_xattr_entry *first = (struct ext4_xattr_entry *) (header + 1);
	char *block_end = ((char *) header) + info.block_size;

	struct ext4_xattr_entry *result =
		xattr_addto_range(header, block_end, first, name_index, name, value, value_len);

	if (result == NULL)
		return -1;

	ext4_xattr_hash_entry(header, result);
	return 0;
}


static int xattr_add(u32 inode_num, int name_index, const char *name,
		const void *value, size_t value_len)
{
	if (!value)
		return 0;

	struct ext4_inode *inode = get_inode(inode_num);

	if (!inode)
		return -1;

	int result = xattr_addto_inode(inode, name_index, name, value, value_len);
	if (result != 0) {
		result = xattr_addto_block(inode, name_index, name, value, value_len);
	}
	return result;
}

int inode_set_selinux(u32 inode_num, const char *secon)
{
	if (!secon)
		return 0;

	return xattr_add(inode_num, EXT4_XATTR_INDEX_SECURITY,
		XATTR_SELINUX_SUFFIX, secon, strlen(secon) + 1);
}

int inode_set_capabilities(u32 inode_num, uint64_t capabilities) {
	if (capabilities == 0)
		return 0;

	struct vfs_cap_data cap_data;
	memset(&cap_data, 0, sizeof(cap_data));

	cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE;
	cap_data.data[0].permitted = (uint32_t) (capabilities & 0xffffffff);
	cap_data.data[0].inheritable = 0;
	cap_data.data[1].permitted = (uint32_t) (capabilities >> 32);
	cap_data.data[1].inheritable = 0;

	return xattr_add(inode_num, EXT4_XATTR_INDEX_SECURITY,
		XATTR_CAPS_SUFFIX, &cap_data, sizeof(cap_data));
}
