/**
 * sload.c
 *
 * Copyright (C) 2015 Huawei Ltd.
 * Witten by:
 *   Hou Pengyang <houpengyang@huawei.com>
 *   Liu Shuoran <liushuoran@huawei.com>
 *   Jaegeuk Kim <jaegeuk@kernel.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#define _GNU_SOURCE
#include "fsck.h"
#include <libgen.h>
#include <dirent.h>
#ifdef HAVE_MNTENT_H
#include <mntent.h>
#endif

#ifdef HAVE_LIBSELINUX
static struct selabel_handle *sehnd = NULL;
#endif

typedef void (*fs_config_f)(const char *path, int dir,
			    const char *target_out_path,
			    unsigned *uid, unsigned *gid,
			    unsigned *mode, uint64_t *capabilities);

static fs_config_f fs_config_func = NULL;

#ifdef WITH_ANDROID
#include <selinux/android.h>
#include <private/android_filesystem_config.h>
#include <private/canned_fs_config.h>
#endif

static int filter_dot(const struct dirent *d)
{
	return (strcmp(d->d_name, "..") && strcmp(d->d_name, "."));
}

static void f2fs_make_directory(struct f2fs_sb_info *sbi,
				int entries, struct dentry *de)
{
	int i = 0;

	for (i = 0; i < entries; i++) {
		if (de[i].file_type == F2FS_FT_DIR)
			f2fs_mkdir(sbi, de + i);
		else if (de[i].file_type == F2FS_FT_REG_FILE)
			f2fs_create(sbi, de + i);
		else if (de[i].file_type == F2FS_FT_SYMLINK)
			f2fs_symlink(sbi, de + i);
	}
}

#ifdef HAVE_LIBSELINUX
static int set_selinux_xattr(struct f2fs_sb_info *sbi, const char *path,
							nid_t ino, int mode)
{
	char *secontext = NULL;
	char *mnt_path = NULL;

	if (!sehnd)
		return 0;

	if (asprintf(&mnt_path, "%s%s", c.mount_point, path) <= 0) {
		ERR_MSG("cannot allocate security path for %s%s\n",
						c.mount_point, path);
		return -ENOMEM;
	}

	/* set root inode selinux context */
	if (selabel_lookup(sehnd, &secontext, mnt_path, mode) < 0) {
		ERR_MSG("cannot lookup security context for %s\n", mnt_path);
		free(mnt_path);
		return -EINVAL;
	}

	if (secontext) {
		MSG(2, "%s (%d) -> SELinux context = %s\n",
						mnt_path, ino, secontext);
		inode_set_selinux(sbi, ino, secontext);
	}
	freecon(secontext);
	free(mnt_path);
	return 0;
}
#else
#define set_selinux_xattr(...)	0
#endif

static int set_perms_and_caps(struct dentry *de)
{
	uint64_t capabilities = 0;
	unsigned int uid = 0, gid = 0, imode = 0;
	char *mnt_path = NULL;

	if (asprintf(&mnt_path, "%s%s", c.mount_point, de->path) <= 0) {
		ERR_MSG("cannot allocate mount path for %s%s\n",
				c.mount_point, de->path);
		return -ENOMEM;
	}

	/* Permissions */
	if (fs_config_func != NULL) {
		fs_config_func(mnt_path, S_ISDIR(de->mode),
				c.target_out_dir, &uid, &gid, &imode,
				&capabilities);
		de->uid = uid & 0xffff;
		de->gid = gid & 0xffff;
		de->mode = (de->mode & S_IFMT) | (imode & 0xffff);
		de->capabilities = capabilities;
	}
	MSG(2, "%s -> mode = 0x%x, uid = 0x%x, gid = 0x%x, "
			"capabilities = 0x%"PRIx64"\n",
		mnt_path, de->mode, de->uid, de->gid, de->capabilities);
	free(mnt_path);
	return 0;
}

static void set_inode_metadata(struct dentry *de)
{
	struct stat stat;
	int ret;

	ret = lstat(de->full_path, &stat);
	if (ret < 0) {
		ERR_MSG("lstat failure\n");
		ASSERT(0);
	}

	if (S_ISREG(stat.st_mode)) {
		de->file_type = F2FS_FT_REG_FILE;
	} else if (S_ISDIR(stat.st_mode)) {
		de->file_type = F2FS_FT_DIR;
	} else if (S_ISCHR(stat.st_mode)) {
		de->file_type = F2FS_FT_CHRDEV;
	} else if (S_ISBLK(stat.st_mode)) {
		de->file_type = F2FS_FT_BLKDEV;
	} else if (S_ISFIFO(stat.st_mode)) {
		de->file_type = F2FS_FT_FIFO;
	} else if (S_ISSOCK(stat.st_mode)) {
		de->file_type = F2FS_FT_SOCK;
	} else if (S_ISLNK(stat.st_mode)) {
		de->file_type = F2FS_FT_SYMLINK;
		de->link = calloc(F2FS_BLKSIZE, 1);
		ASSERT(de->link);
		ret = readlink(de->full_path, de->link, F2FS_BLKSIZE - 1);
		ASSERT(ret >= 0);
	} else {
		ERR_MSG("unknown file type on %s", de->path);
		ASSERT(0);
	}

	de->size = stat.st_size;
	de->mode = stat.st_mode &
			(S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
	if (c.fixed_time == -1 && c.from_dir)
		de->mtime = stat.st_mtime;
	else
		de->mtime = c.fixed_time;

	set_perms_and_caps(de);
}

static int build_directory(struct f2fs_sb_info *sbi, const char *full_path,
			const char *dir_path, const char *target_out_dir,
			nid_t dir_ino)
{
	int entries = 0;
	struct dentry *dentries;
	struct dirent **namelist = NULL;
	int i, ret = 0;

	entries = scandir(full_path, &namelist, filter_dot, (void *)alphasort);
	if (entries < 0) {
		ERR_MSG("No entries in %s\n", full_path);
		return -ENOENT;
	}

	dentries = calloc(entries, sizeof(struct dentry));
	if (dentries == NULL)
		return -ENOMEM;

	for (i = 0; i < entries; i++) {
		dentries[i].name = (unsigned char *)strdup(namelist[i]->d_name);
		if (dentries[i].name == NULL) {
			ERR_MSG("Skip: ENOMEM\n");
			continue;
		}
		dentries[i].len = strlen((char *)dentries[i].name);

		ret = asprintf(&dentries[i].path, "%s%s",
					dir_path, namelist[i]->d_name);
		ASSERT(ret > 0);
		ret = asprintf(&dentries[i].full_path, "%s/%s",
					full_path, namelist[i]->d_name);
		ASSERT(ret > 0);
		free(namelist[i]);

		set_inode_metadata(dentries + i);

		dentries[i].pino = dir_ino;
	}

	free(namelist);

	f2fs_make_directory(sbi, entries, dentries);

	for (i = 0; i < entries; i++) {
		if (dentries[i].file_type == F2FS_FT_REG_FILE) {
			f2fs_build_file(sbi, dentries + i);
		} else if (dentries[i].file_type == F2FS_FT_DIR) {
			char *subdir_full_path = NULL;
			char *subdir_dir_path = NULL;

			ret = asprintf(&subdir_full_path, "%s",
							dentries[i].full_path);
			ASSERT(ret > 0);
			ret = asprintf(&subdir_dir_path, "%s/",
							dentries[i].path);
			ASSERT(ret > 0);

			build_directory(sbi, subdir_full_path, subdir_dir_path,
					target_out_dir, dentries[i].ino);
			free(subdir_full_path);
			free(subdir_dir_path);
		} else if (dentries[i].file_type == F2FS_FT_SYMLINK) {
			/*
			 * It is already done in f2fs_make_directory
			 * f2fs_make_symlink(sbi, dir_ino, &dentries[i]);
			 */
		} else {
			MSG(1, "Error unknown file type\n");
		}

		ret = set_selinux_xattr(sbi, dentries[i].path,
					dentries[i].ino, dentries[i].mode);
		if (ret)
			return ret;

		free(dentries[i].path);
		free(dentries[i].full_path);
		free((void *)dentries[i].name);
	}

	free(dentries);
	return 0;
}

static int configure_files(void)
{
#ifdef HAVE_LIBSELINUX
	if (!c.nr_opt)
		goto skip;
#if !defined(__ANDROID__)
	sehnd = selabel_open(SELABEL_CTX_FILE, c.seopt_file, c.nr_opt);
	if (!sehnd) {
		ERR_MSG("Failed to open file contexts \"%s\"",
					c.seopt_file[0].value);
			return -EINVAL;
	}
#else
	sehnd = selinux_android_file_context_handle();
	if (!sehnd) {
		ERR_MSG("Failed to get android file_contexts\n", c.mount_point);
		return -EINVAL;
	}
#endif
skip:
#endif
#ifdef WITH_ANDROID
	/* Load the FS config */
	if (c.fs_config_file) {
		int ret = load_canned_fs_config(c.fs_config_file);

		if (ret < 0) {
			ERR_MSG("Failed to load fs_config \"%s\"",
						c.fs_config_file);
			return ret;
		}
		fs_config_func = canned_fs_config;
	} else {
		fs_config_func = fs_config;
	}
#endif
	return 0;
}

int f2fs_sload(struct f2fs_sb_info *sbi)
{
	int ret = 0;

	ret = configure_files();
	if (ret) {
		ERR_MSG("Failed to configure files\n");
		return ret;
	}

	/* flush NAT/SIT journal entries */
	flush_journal_entries(sbi);

	ret = build_directory(sbi, c.from_dir, "/",
					c.target_out_dir, F2FS_ROOT_INO(sbi));
	if (ret) {
		ERR_MSG("Failed to build due to %d\n", ret);
		return ret;
	}

	ret = set_selinux_xattr(sbi, c.mount_point,
					F2FS_ROOT_INO(sbi), S_IFDIR);
	if (ret) {
		ERR_MSG("Failed to set selinux for root: %d\n", ret);
		return ret;
	}

	/* update curseg info; can update sit->types */
	move_curseg_info(sbi, SM_I(sbi)->main_blkaddr);
	zero_journal_entries(sbi);
	write_curseg_info(sbi);

	/* flush dirty sit entries */
	flush_sit_entries(sbi);

	write_checkpoint(sbi);
	return 0;
}
