aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive/data_extract_all.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/libunarchive/data_extract_all.c')
-rw-r--r--archival/libunarchive/data_extract_all.c200
1 files changed, 0 insertions, 200 deletions
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c
deleted file mode 100644
index 5fb1ab2ae..000000000
--- a/archival/libunarchive/data_extract_all.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * Licensed under GPLv2 or later, see file LICENSE in this source tree.
- */
-
-#include "libbb.h"
-#include "unarchive.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;
-
-#if ENABLE_FEATURE_TAR_SELINUX
- char *sctx = archive_handle->tar__next_file_sctx;
- if (!sctx)
- sctx = archive_handle->tar__global_sctx;
- if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
- setfscreatecon(sctx);
- free(archive_handle->tar__next_file_sctx);
- archive_handle->tar__next_file_sctx = NULL;
- }
-#endif
-
- if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
- char *slash = strrchr(file_header->name, '/');
- if (slash) {
- *slash = '\0';
- bb_make_directory(file_header->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)) {
- /* Is it hardlink?
- * We encode hard links as regular files of size 0 with a symlink */
- if (S_ISREG(file_header->mode)
- && file_header->link_target
- && file_header->size == 0
- ) {
- /* Ugly special case:
- * tar cf t.tar hardlink1 hardlink2 hardlink1
- * results in this tarball structure:
- * hardlink1
- * hardlink2 -> hardlink1
- * hardlink1 -> hardlink1 <== !!!
- */
- if (strcmp(file_header->link_target, file_header->name) == 0)
- goto ret;
- }
- /* Proceed with deleting */
- if (unlink(file_header->name) == -1
- && errno != ENOENT
- ) {
- bb_perror_msg_and_die("can't remove old file %s",
- file_header->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(file_header->name, &existing_sb) == -1) {
- if (errno != ENOENT) {
- bb_perror_msg_and_die("can't stat old file");
- }
- }
- else if (existing_sb.st_mtime >= file_header->mtime) {
- if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
- && !S_ISDIR(file_header->mode)
- ) {
- bb_error_msg("%s not created: newer or "
- "same age file exists", file_header->name);
- }
- data_skip(archive_handle);
- goto ret;
- }
- else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
- bb_perror_msg_and_die("can't remove old file %s",
- file_header->name);
- }
- }
-
- /* Handle hard links separately
- * We encode hard links as regular files of size 0 with a symlink */
- if (S_ISREG(file_header->mode)
- && file_header->link_target
- && file_header->size == 0
- ) {
- /* hard link */
- res = link(file_header->link_target, file_header->name);
- if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
- bb_perror_msg("can't create %slink "
- "from %s to %s", "hard",
- file_header->name,
- file_header->link_target);
- }
- /* 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 */
- int flags = O_WRONLY | O_CREAT | O_EXCL;
- if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
- flags = O_WRONLY | O_CREAT | O_TRUNC;
- dst_fd = xopen3(file_header->name,
- flags,
- file_header->mode
- );
- bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
- close(dst_fd);
- break;
- }
- case S_IFDIR:
- res = mkdir(file_header->name, file_header->mode);
- if ((res == -1)
- && (errno != EISDIR) /* btw, Linux doesn't return this */
- && (errno != EEXIST)
- && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
- ) {
- bb_perror_msg("can't make dir %s", file_header->name);
- }
- break;
- case S_IFLNK:
- /* Symlink */
-//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
- res = symlink(file_header->link_target, file_header->name);
- if ((res == -1)
- && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
- ) {
- bb_perror_msg("can't create %slink "
- "from %s to %s", "sym",
- file_header->name,
- file_header->link_target);
- }
- break;
- case S_IFSOCK:
- case S_IFBLK:
- case S_IFCHR:
- case S_IFIFO:
- res = mknod(file_header->name, file_header->mode, file_header->device);
- if ((res == -1)
- && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
- ) {
- bb_perror_msg("can't create node %s", file_header->name);
- }
- break;
- default:
- bb_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(file_header->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(file_header->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(file_header->name, t);
- }
- }
-
- ret: ;
-#if ENABLE_FEATURE_TAR_SELINUX
- if (sctx) {
- /* reset the context after creating an entry */
- setfscreatecon(NULL);
- }
-#endif
-}