/*
 * 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 <sys/stat.h>
#include <string.h>
#include <stdio.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"

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

#ifdef USE_MINGW
#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));
}
