/* vi: set sw=4 ts=4: */
/*
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
#include "libbb.h"
#include "bb_archive.h"

void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
{
	file_header_t *file_header = archive_handle->file_header;
	int dst_fd;
	int res;
	char *hard_link;
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
	char *dst_name;
#else
# define dst_name (file_header->name)
#endif

#if ENABLE_FEATURE_TAR_SELINUX
	char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
	if (!sctx)
		sctx = archive_handle->tar__sctx[PAX_GLOBAL];
	if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
		setfscreatecon(sctx);
		free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
		archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
	}
#endif

	/* Hard links are encoded as regular files of size 0
	 * with a nonempty link field */
	hard_link = NULL;
	if (S_ISREG(file_header->mode) && file_header->size == 0)
		hard_link = file_header->link_target;

#if ENABLE_FEATURE_TAR_LONG_OPTIONS
	dst_name = file_header->name;
	if (archive_handle->tar__strip_components) {
		unsigned n = archive_handle->tar__strip_components;
		do {
			dst_name = strchr(dst_name, '/');
			if (!dst_name || dst_name[1] == '\0') {
				data_skip(archive_handle);
				goto ret;
			}
			dst_name++;
			/*
			 * Link target is shortened only for hardlinks:
			 * softlinks restored unchanged.
			 */
			if (hard_link) {
// GNU tar 1.26 does not check that we reached end of link name:
// if "dir/hardlink" is hardlinked to "file",
// tar xvf a.tar --strip-components=1 says:
//  tar: hardlink: Cannot hard link to '': No such file or directory
// and continues processing. We silently skip such entries.
				hard_link = strchr(hard_link, '/');
				if (!hard_link || hard_link[1] == '\0') {
					data_skip(archive_handle);
					goto ret;
				}
				hard_link++;
			}
		} while (--n != 0);
	}
#endif

	if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
		char *slash = strrchr(dst_name, '/');
		if (slash) {
			*slash = '\0';
			bb_make_directory(dst_name, -1, FILEUTILS_RECUR);
			*slash = '/';
		}
	}

	if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
		/* Remove the entry if it exists */
		if (!S_ISDIR(file_header->mode)) {
			if (hard_link) {
				/* Ugly special case:
				 * tar cf t.tar hardlink1 hardlink2 hardlink1
				 * results in this tarball structure:
				 * hardlink1
				 * hardlink2 -> hardlink1
				 * hardlink1 -> hardlink1 <== !!!
				 */
				if (strcmp(hard_link, dst_name) == 0)
					goto ret;
			}
			/* Proceed with deleting */
			if (unlink(dst_name) == -1
			 && errno != ENOENT
			) {
				bb_perror_msg_and_die("can't remove old file %s",
						dst_name);
			}
		}
	}
	else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
		/* Remove the existing entry if its older than the extracted entry */
		struct stat existing_sb;
		if (lstat(dst_name, &existing_sb) == -1) {
			if (errno != ENOENT) {
				bb_simple_perror_msg_and_die("can't stat old file");
			}
		}
		else if (existing_sb.st_mtime >= file_header->mtime) {
			if (!S_ISDIR(file_header->mode)) {
				bb_error_msg("%s not created: newer or "
					"same age file exists", dst_name);
			}
			data_skip(archive_handle);
			goto ret;
		}
		else if ((unlink(dst_name) == -1) && (errno != EISDIR)) {
			bb_perror_msg_and_die("can't remove old file %s",
					dst_name);
		}
	}

	/* Handle hard links separately */
	if (hard_link) {
		create_or_remember_link(&archive_handle->link_placeholders,
				hard_link,
				dst_name,
				1);
		/* Hardlinks have no separate mode/ownership, skip chown/chmod */
		goto ret;
	}

	/* Create the filesystem entry */
	switch (file_header->mode & S_IFMT) {
	case S_IFREG: {
		/* Regular file */
		char *dst_nameN;
		int flags = O_WRONLY | O_CREAT | O_EXCL;
		if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
			flags = O_WRONLY | O_CREAT | O_TRUNC;
		dst_nameN = dst_name;
#ifdef ARCHIVE_REPLACE_VIA_RENAME
		if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME)
			/* rpm-style temp file name */
			dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid());
#endif
		dst_fd = xopen3(dst_nameN,
			flags,
			file_header->mode
			);
		bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
		close(dst_fd);
#ifdef ARCHIVE_REPLACE_VIA_RENAME
		if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) {
			xrename(dst_nameN, dst_name);
			free(dst_nameN);
		}
#endif
		break;
	}
	case S_IFDIR:
		res = mkdir(dst_name, file_header->mode);
		if ((res != 0)
		 && (errno != EISDIR) /* btw, Linux doesn't return this */
		 && (errno != EEXIST)
		) {
			bb_perror_msg("can't make dir %s", dst_name);
		}
		break;
	case S_IFLNK:
		/* Symlink */
//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)

		/* To avoid a directory traversal attack via symlinks,
		 * do not restore symlinks with ".." components
		 * or symlinks starting with "/", unless a magic
		 * envvar is set.
		 *
		 * For example, consider a .tar created via:
		 *  $ tar cvf bug.tar anything.txt
		 *  $ ln -s /tmp symlink
		 *  $ tar --append -f bug.tar symlink
		 *  $ rm symlink
		 *  $ mkdir symlink
		 *  $ tar --append -f bug.tar symlink/evil.py
		 *
		 * This will result in an archive that contains:
		 *  $ tar --list -f bug.tar
		 *  anything.txt
		 *  symlink [-> /tmp]
		 *  symlink/evil.py
		 *
		 * Untarring bug.tar would otherwise place evil.py in '/tmp'.
		 */
		create_or_remember_link(&archive_handle->link_placeholders,
				file_header->link_target,
				dst_name,
				0);
		break;
	case S_IFSOCK:
	case S_IFBLK:
	case S_IFCHR:
	case S_IFIFO:
		res = mknod(dst_name, file_header->mode, file_header->device);
		if (res != 0) {
			bb_perror_msg("can't create node %s", dst_name);
		}
		break;
	default:
		bb_simple_error_msg_and_die("unrecognized file type");
	}

	if (!S_ISLNK(file_header->mode)) {
		if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) {
			uid_t uid = file_header->uid;
			gid_t gid = file_header->gid;
#if ENABLE_FEATURE_TAR_UNAME_GNAME
			if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) {
				if (file_header->tar__uname) {
//TODO: cache last name/id pair?
					struct passwd *pwd = getpwnam(file_header->tar__uname);
					if (pwd) uid = pwd->pw_uid;
				}
				if (file_header->tar__gname) {
					struct group *grp = getgrnam(file_header->tar__gname);
					if (grp) gid = grp->gr_gid;
				}
			}
#endif
			/* GNU tar 1.15.1 uses chown, not lchown */
			chown(dst_name, uid, gid);
		}
		/* uclibc has no lchmod, glibc is even stranger -
		 * it has lchmod which seems to do nothing!
		 * so we use chmod... */
		if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
			chmod(dst_name, file_header->mode);
		}
		if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
			struct timeval t[2];

			t[1].tv_sec = t[0].tv_sec = file_header->mtime;
			t[1].tv_usec = t[0].tv_usec = 0;
			utimes(dst_name, t);
		}
	}

 ret: ;
#if ENABLE_FEATURE_TAR_SELINUX
	if (sctx) {
		/* reset the context after creating an entry */
		setfscreatecon(NULL);
	}
#endif
}
