/*
**  Copyright 1998-2003 University of Illinois Board of Trustees
**  Copyright 1998-2003 Mark D. Roth
**  All rights reserved.
**
**  extract.c - libtar code to extract a file from a tar archive
**
**  Mark D. Roth <roth@uiuc.edu>
**  Campus Information Technologies and Educational Services
**  University of Illinois at Urbana-Champaign
*/

#include <internal.h>

#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <utime.h>

#include <sys/capability.h>
#include <sys/xattr.h>
#include <linux/xattr.h>

#ifdef STDC_HEADERS
# include <stdlib.h>
#endif

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <selinux/selinux.h>

#ifdef USE_FSCRYPT
#include "fscrypt_policy.h"
#endif

#ifdef TW_LIBTAR_DEBUG
#define DEBUG 1
#endif

#include "android_utils.h"

const unsigned long long progress_size = (unsigned long long)(T_BLOCKSIZE);

static int
tar_set_file_perms(TAR *t, const char *realname)
{
	mode_t mode;
	uid_t uid;
	gid_t gid;
	struct utimbuf ut;
	const char *filename;
	char *pn;

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	mode = th_get_mode(t);
	uid = th_get_uid(t);
	gid = th_get_gid(t);
	ut.modtime = ut.actime = th_get_mtime(t);

#ifdef DEBUG
	LOG("tar_set_file_perms(): setting perms: %s (mode %04o, uid %d, gid %d)\n",
		filename, mode, uid, gid);
#endif

	/* change owner/group */
	if (geteuid() == 0)
#ifdef HAVE_LCHOWN
		if (lchown(filename, uid, gid) == -1)
		{
# ifdef DEBUG
			fprintf(stderr, "lchown(\"%s\", %d, %d): %s\n",
				filename, uid, gid, strerror(errno));
# endif
#else /* ! HAVE_LCHOWN */
		if (!TH_ISSYM(t) && chown(filename, uid, gid) == -1)
		{
# ifdef DEBUG
			fprintf(stderr, "chown(\"%s\", %d, %d): %s\n",
				filename, uid, gid, strerror(errno));
# endif
#endif /* HAVE_LCHOWN */
			return -1;
		}

	/* change access/modification time */
	if (!TH_ISSYM(t) && utime(filename, &ut) == -1)
	{
#ifdef DEBUG
		perror("utime()");
#endif
		return -1;
	}

	/* change permissions */
	if (!TH_ISSYM(t) && chmod(filename, mode) == -1)
	{
#ifdef DEBUG
		perror("chmod()");
#endif
		return -1;
	}

	return 0;
}


/* switchboard */
int
tar_extract_file(TAR *t, const char *realname, const char *prefix, const int *progress_fd)
{
	int i;
#ifdef LIBTAR_FILE_HASH
	char *lnp;
	char *pn;
	int pathname_len;
	int realname_len;
#endif

	if (t->options & TAR_NOOVERWRITE)
	{
		struct stat s;

		if (lstat(realname, &s) == 0 || errno != ENOENT)
		{
			errno = EEXIST;
			return -1;
		}
	}

	if (TH_ISDIR(t))
	{
		i = tar_extract_dir(t, realname);
		if (i == 1)
			i = 0;
	}
	else if (TH_ISLNK(t))
		i = tar_extract_hardlink(t, realname, prefix);
	else if (TH_ISSYM(t))
		i = tar_extract_symlink(t, realname);
	else if (TH_ISCHR(t))
		i = tar_extract_chardev(t, realname);
	else if (TH_ISBLK(t))
		i = tar_extract_blockdev(t, realname);
	else if (TH_ISFIFO(t))
		i = tar_extract_fifo(t, realname);
	else /* if (TH_ISREG(t)) */
		i = tar_extract_regfile(t, realname, progress_fd);

	if (i != 0) {
		fprintf(stderr, "tar_extract_file(): failed to extract %s !!!\n", realname);
		return i;
	}

	i = tar_set_file_perms(t, realname);
	if (i != 0) {
		fprintf(stderr, "tar_extract_file(): failed to set permissions on %s !!!\n", realname);
		return i;
	}

	if((t->options & TAR_STORE_SELINUX) && t->th_buf.selinux_context != NULL)
	{
#ifdef DEBUG
		LOG("tar_extract_file(): restoring SELinux context %s to file %s\n", t->th_buf.selinux_context, realname);
#endif
		if (lsetfilecon(realname, t->th_buf.selinux_context) < 0)
			fprintf(stderr, "tar_extract_file(): failed to restore SELinux context %s to file %s !!!\n", t->th_buf.selinux_context, realname);
	}

	if((t->options & TAR_STORE_POSIX_CAP) && t->th_buf.has_cap_data)
	{
#if 1 //def DEBUG
		LOG("tar_extract_file(): restoring posix capabilities to file %s\n", realname);
		print_caps(&t->th_buf.cap_data);
#endif
		if (setxattr(realname, XATTR_NAME_CAPS, &t->th_buf.cap_data, sizeof(struct vfs_cap_data), 0) < 0)
			fprintf(stderr, "tar_extract_file(): failed to restore posix capabilities to file %s !!!\n", realname);
	}

#ifdef LIBTAR_FILE_HASH
	pn = th_get_pathname(t);
	pathname_len = strlen(pn) + 1;
	realname_len = strlen(realname) + 1;
	lnp = (char *)calloc(1, pathname_len + realname_len);
	if (lnp == NULL)
		return -1;
	strcpy(&lnp[0], pn);
	strcpy(&lnp[pathname_len], realname);
#ifdef DEBUG
	LOG("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", "
	       "value=\"%s\"\n", pn, realname);
#endif
	if (libtar_hash_add(t->h, lnp) != 0)
		return -1;
	free(lnp);
#endif

	return 0;
}


/* extract regular file */
int
tar_extract_regfile(TAR *t, const char *realname, const int *progress_fd)
{
	int64_t size, i;
	ssize_t k;
	int fdout;
	char buf[T_BLOCKSIZE];
	const char *filename;
	char *pn;

#ifdef DEBUG
	LOG("  ==> tar_extract_regfile(realname=\"%s\")\n", realname);
#endif

	if (!TH_ISREG(t))
	{
		errno = EINVAL;
		return -1;
	}

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	size = th_get_size(t);

	if (mkdirhier(dirname(filename)) == -1)
		return -1;

	LOG("  ==> extracting: %s (file size %" PRId64 " bytes)\n",
			filename, size);

	fdout = open(filename, O_WRONLY | O_CREAT | O_TRUNC
#ifdef O_BINARY
		     | O_BINARY
#endif
		    , 0666);
	if (fdout == -1)
	{
#ifdef DEBUG
		perror("open()");
#endif
		return -1;
	}

	/* extract the file */
	for (i = size; i > 0; i -= T_BLOCKSIZE)
	{
		k = tar_block_read(t, buf);
		if (k != T_BLOCKSIZE)
		{
			if (k != -1)
				errno = EINVAL;
			close(fdout);
			return -1;
		}

		/* write block to output file */
		if (write(fdout, buf,
			  ((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1)
		{
			close(fdout);
			return -1;
		}
		else
		{
			if (*progress_fd != 0)
				write(*progress_fd, &progress_size, sizeof(progress_size));
		}
	}

	/* close output file */
	if (close(fdout) == -1)
		return -1;

#ifdef DEBUG
	LOG("### done extracting %s\n", filename);
#endif

	return 0;
}


/* skip regfile */
int
tar_skip_regfile(TAR *t)
{
	int64_t size, i;
	ssize_t k;
	char buf[T_BLOCKSIZE];

	if (!TH_ISREG(t))
	{
		errno = EINVAL;
		return -1;
	}

	size = th_get_size(t);
	for (i = size; i > 0; i -= T_BLOCKSIZE)
	{
		k = tar_block_read(t, buf);
		if (k != T_BLOCKSIZE)
		{
			if (k != -1)
				errno = EINVAL;
			return -1;
		}
	}

	return 0;
}


/* hardlink */
int
tar_extract_hardlink(TAR * t, const char *realname, const char *prefix)
{
	const char *filename;
	char *pn;
	char *linktgt = NULL;
	char *newtgt = NULL;
	char *lnp;
	libtar_hashptr_t hp;

	if (!TH_ISLNK(t))
	{
		errno = EINVAL;
		return -1;
	}

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	if (mkdirhier(dirname(filename)) == -1)
		return -1;
	if (unlink(filename) == -1 && errno != ENOENT)
		return -1;
	libtar_hashptr_reset(&hp);
	if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
			       (libtar_matchfunc_t)libtar_str_match) != 0)
	{
		lnp = (char *)libtar_hashptr_data(&hp);
		linktgt = &lnp[strlen(lnp) + 1];
	}
	else
		linktgt = th_get_linkname(t);

	newtgt = strdup(linktgt);
	sprintf(linktgt, "%s/%s", prefix, newtgt);

	LOG("  ==> extracting: %s (link to %s)\n", filename, linktgt);

	if (link(linktgt, filename) == -1)
	{
		fprintf(stderr, "tar_extract_hardlink(): failed restore of hardlink '%s' but returning as if nothing bad happened\n", filename);
		return 0; // Used to be -1
	}

	return 0;
}


/* symlink */
int
tar_extract_symlink(TAR *t, const char *realname)
{
	const char *filename;
	char *pn;

	if (!TH_ISSYM(t))
	{
		errno = EINVAL;
		return -1;
	}

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	if (mkdirhier(dirname(filename)) == -1)
		return -1;

	if (unlink(filename) == -1 && errno != ENOENT)
		return -1;

	LOG("  ==> extracting: %s (symlink to %s)\n",
	       filename, th_get_linkname(t));

	if (symlink(th_get_linkname(t), filename) == -1)
	{
#ifdef DEBUG
		perror("symlink()");
#endif
		return -1;
	}

	return 0;
}


/* character device */
int
tar_extract_chardev(TAR *t, const char *realname)
{
	mode_t mode;
	unsigned long devmaj, devmin;
	const char *filename;
	char *pn;

	if (!TH_ISCHR(t))
	{
		errno = EINVAL;
		return -1;
	}

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	mode = th_get_mode(t);
	devmaj = th_get_devmajor(t);
	devmin = th_get_devminor(t);

	if (mkdirhier(dirname(filename)) == -1)
		return -1;

	LOG("  ==> extracting: %s (character device %ld,%ld)\n",
	       filename, devmaj, devmin);

	if (mknod(filename, mode | S_IFCHR,
		  compat_makedev(devmaj, devmin)) == -1)
	{
		fprintf(stderr, "tar_extract_chardev(): failed restore of character device '%s' but returning as if nothing bad happened\n", filename);
		return 0; // Used to be -1
	}

	return 0;
}


/* block device */
int
tar_extract_blockdev(TAR *t, const char *realname)
{
	mode_t mode;
	unsigned long devmaj, devmin;
	const char *filename;
	char *pn;

	if (!TH_ISBLK(t))
	{
		errno = EINVAL;
		return -1;
	}

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	mode = th_get_mode(t);
	devmaj = th_get_devmajor(t);
	devmin = th_get_devminor(t);

	if (mkdirhier(dirname(filename)) == -1)
		return -1;

	LOG("  ==> extracting: %s (block device %ld,%ld)\n",
	       filename, devmaj, devmin);

	if (mknod(filename, mode | S_IFBLK,
		  compat_makedev(devmaj, devmin)) == -1)
	{
		fprintf(stderr, "tar_extract_blockdev(): failed restore of block device '%s' but returning as if nothing bad happened\n", filename);
		return 0; // Used to be -1
	}

	return 0;
}

/* directory */
int
tar_extract_dir(TAR *t, const char *realname)
{
	mode_t mode;
	const char *filename;
	char *pn;

	if (!TH_ISDIR(t))
	{
		errno = EINVAL;
		return -1;
	}
	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	mode = th_get_mode(t);

	if (mkdirhier(dirname(filename)) == -1)
		return -1;

	LOG("  ==> extracting: %s (mode %04o, directory)\n", filename,
	       mode);

	if (mkdir(filename, mode) == -1)
	{
		if (errno == EEXIST)
		{
			if (chmod(filename, mode) == -1)
			{
#ifdef DEBUG
				perror("chmod()");
#endif
				return -1;
			}
			else
			{
#if 1 //def DEBUG
				puts("  *** using existing directory");
#endif
				return 1;
			}
		}
		else
		{
#ifdef DEBUG
			perror("mkdir()");
#endif
			return -1;
		}
	}

	if (t->options & TAR_STORE_ANDROID_USER_XATTR)
	{
		if (t->th_buf.has_user_default) {
#if 1 //def DEBUG
			LOG("tar_extract_file(): restoring android user.default xattr to %s\n", realname);
#endif
			if (setxattr(realname, "user.default", NULL, 0, 0) < 0) {
				fprintf(stderr, "tar_extract_file(): failed to restore android user.default to file %s !!!\n", realname);
				return -1;
			}
		}
		if (t->th_buf.has_user_cache) {
#if 1 //def DEBUG
			LOG("tar_extract_file(): restoring android user.inode_cache xattr to %s\n", realname);
#endif
			if (write_path_inode(realname, "cache", "user.inode_cache"))
				return -1;
		}
		if (t->th_buf.has_user_code_cache) {
#if 1 //def DEBUG
			LOG("tar_extract_file(): restoring android user.inode_code_cache xattr to %s\n", realname);
#endif
			if (write_path_inode(realname, "code_cache", "user.inode_code_cache"))
				return -1;
		}
	}

#ifdef USE_FSCRYPT
	if(t->th_buf.fep != NULL)
	{
		uint8_t hex_size, size, *descriptor;
		hex_size = get_policy_size(t->th_buf.fep, true);
		size = get_policy_size(t->th_buf.fep, false);
		descriptor = get_policy_descriptor(t->th_buf.fep);
		char policy_hex[hex_size];
#ifdef DEBUG
		bytes_to_hex(descriptor, size, policy_hex);
		LOG("tar_extract_dir(): restoring fscrypt policy %s to dir %s\n", (char *)policy_hex, realname);
#endif
		bool policy_lookup_error = false;
		uint8_t binary_policy[size];
		memset(&binary_policy, 0, size);

		if (!lookup_ref_tar(t->th_buf.fep, &binary_policy[0])) {
			LOG("error looking up fscrypt policy for '%s' - %s\n", realname, descriptor);
			policy_lookup_error = true;
		}
		memcpy(descriptor, binary_policy, size);
		bytes_to_hex(descriptor, size, policy_hex);
		if (!policy_lookup_error)
		{
			LOG("attempting to restore policy: %s\n", policy_hex);
			if (!fscrypt_policy_set_struct(realname, t->th_buf.fep))
			{
				LOG("tar_extract_file(): failed to restore fscrypt policy to dir '%s' '%s'!!!\n", realname, policy_hex);
				//return -1; // This may not be an error in some cases, so log and ignore
			}
		} else
			LOG("No policy was found. Continuing restore.");
	}
	else
		LOG("NULL FSCRYPT\n");
#endif

	return 0;
}


/* FIFO */
int
tar_extract_fifo(TAR *t, const char *realname)
{
	mode_t mode;
	const char *filename;
	char *pn;

	if (!TH_ISFIFO(t))
	{
		errno = EINVAL;
		return -1;
	}

	pn = th_get_pathname(t);
	filename = (realname ? realname : pn);
	mode = th_get_mode(t);

	if (mkdirhier(dirname(filename)) == -1)
		return -1;


	LOG("  ==> extracting: %s (fifo)\n", filename);

	if (mkfifo(filename, mode) == -1)
	{
#ifdef DEBUG
		perror("mkfifo()");
#endif
		return -1;
	}

	return 0;
}

/* extract file contents from a tarchive */
int
tar_extract_file_contents(TAR *t, void *buf, size_t *lenp)
{
	char block[T_BLOCKSIZE];
	int64_t size, i;
	ssize_t k;

#ifdef DEBUG
	LOG("  ==> tar_extract_file_contents\n");
#endif

	if (!TH_ISREG(t))
	{
		errno = EINVAL;
		return -1;
	}

	size = th_get_size(t);
	if ((uint64_t)size > *lenp)
	{
		errno = ENOSPC;
		return -1;
	}

	/* extract the file */
	for (i = size; i >= T_BLOCKSIZE; i -= T_BLOCKSIZE)
	{
		k = tar_block_read(t, buf);
		if (k != T_BLOCKSIZE)
		{
			if (k != -1)
				errno = EINVAL;
			return -1;
		}
		buf = (char *)buf + T_BLOCKSIZE;
	}
	if (i > 0) {
		k = tar_block_read(t, block);
		if (k != T_BLOCKSIZE)
		{
			if (k != -1)
				errno = EINVAL;
			return -1;
		}
		memcpy(buf, block, i);
	}
	*lenp = (size_t)size;

#ifdef DEBUG
	LOG("### done extracting contents\n");
#endif
	return 0;
}
