/*
 * 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>

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

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

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 + 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 + 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)
		inode_allocate_file_extents(inode, len, filename);

	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;
}

#define XATTR_SELINUX_SUFFIX "selinux"

/* XXX */
#define cpu_to_le32(x) (x)
#define cpu_to_le16(x) (x)

int inode_set_selinux(u32 inode_num, const char *secon)
{
	struct ext4_inode *inode = get_inode(inode_num);
	u32 *hdr;
	struct ext4_xattr_entry *entry;
	size_t name_len = strlen(XATTR_SELINUX_SUFFIX);
	size_t value_len;
	size_t size, min_offs;
	char *val;

	if (!secon)
		return 0;

	if (!inode)
		return -1;

	hdr = (u32 *) (inode + 1);
	*hdr = cpu_to_le32(EXT4_XATTR_MAGIC);
	entry = (struct ext4_xattr_entry *) (hdr+1);
	memset(entry, 0, EXT4_XATTR_LEN(name_len));
	entry->e_name_index = EXT4_XATTR_INDEX_SECURITY;
	entry->e_name_len = name_len;
	memcpy(entry->e_name, XATTR_SELINUX_SUFFIX, name_len);
	value_len = strlen(secon)+1;
	entry->e_value_size = cpu_to_le32(value_len);
	min_offs = (char *)inode + info.inode_size - (char*) entry;
	size = EXT4_XATTR_SIZE(value_len);
	val = (char *)entry + min_offs - size;
	entry->e_value_offs = cpu_to_le16(min_offs - size);
	memset(val + size - EXT4_XATTR_PAD, 0, EXT4_XATTR_PAD);
	memcpy(val, secon, value_len);
	inode->i_extra_isize = cpu_to_le16(sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE);

	return 0;
}
