From 6f57f7c60167b11e0e7769310aa8878d2980a3da Mon Sep 17 00:00:00 2001 From: James Christopher Adduono Date: Tue, 1 Mar 2016 16:01:53 -0500 Subject: Merge code from upstream libtar + bug fixes All updates and fixes applied from upstream libtar as of March 1, 2016. Debug flag is disabled, however non-debug output now provides 1 line of useful output per object extracted. I've also merged some fixes from CyanogenMod's fork of libtar: From: Tom Marshall Date: Thu, 11 Feb 2016 16:24:40 -0800 Subject: libtar: Cleanup, secure, and extend numeric fields Commit: e18b457ea1cbf6be1adc3b75450ed1c737cd82ea From: Tom Marshall Date: Thu, 11 Feb 2016 12:49:30 -0800 Subject: libtar: Make file sizes 64-bit clean Commit: e628c2025549a24018bc568351465130a05daafb From: Tom Marshall Date: Thu, 17 Apr 2014 09:39:25 -0700 Subject: libtar: Add methods for in-memory files Commit: 8ec5627a8ff0a91724c6d5b344f0e887da922527 From: Tom Marshall Date: Wed, 2 Jul 2014 09:34:40 -0700 Subject: libtar: Fix hardlink extract Commit: 166d83a51e0c51abcea37694dbd7df92d03c1f56 From: philz-cwm6 Date: Sat, 26 Apr 2014 01:11:35 +0200 Subject: libtar: Various bug fixes and enhancements Commit: a271d763e94235ccee9ecaabdb52bf4b9b2f8c06 (Some of this was not merged in, as better solutions were available from upstream libtar) From: Tom Marshall Date: Wed, 9 Apr 2014 09:35:54 -0700 Subject: libtar: Add const qualifiers to reduce compile warnings Commit: 0600afa19fe827d06d3fcf24a7aabd52dbf487b4 Change-Id: I6d008cb6fdf950f835bbed63aeb8727cc5c86083 --- libtar/append.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 95 insertions(+), 21 deletions(-) (limited to 'libtar/append.c') diff --git a/libtar/append.c b/libtar/append.c index 1831990be..4be679ccd 100644 --- a/libtar/append.c +++ b/libtar/append.c @@ -13,8 +13,11 @@ #include #include +#include +#include #include #include +#include #include #include @@ -28,7 +31,7 @@ #endif #ifdef HAVE_SELINUX -#include "selinux/selinux.h" +# include "selinux/selinux.h" #endif struct tar_dev @@ -57,7 +60,7 @@ tar_dev_free(tar_dev_t *tdp) /* appends a file to the tar archive */ int -tar_append_file(TAR *t, char *realname, char *savename) +tar_append_file(TAR *t, const char *realname, const char *savename) { struct stat s; int i; @@ -82,38 +85,46 @@ tar_append_file(TAR *t, char *realname, char *savename) /* set header block */ #ifdef DEBUG - puts(" tar_append_file(): setting header block..."); + puts("tar_append_file(): setting header block..."); #endif memset(&(t->th_buf), 0, sizeof(struct tar_header)); th_set_from_stat(t, &s); /* set the header path */ #ifdef DEBUG - puts(" tar_append_file(): setting header path..."); + puts("tar_append_file(): setting header path..."); #endif th_set_path(t, (savename ? savename : realname)); #ifdef HAVE_SELINUX /* get selinux context */ - if(t->options & TAR_STORE_SELINUX) { - if(t->th_buf.selinux_context != NULL) { + if (t->options & TAR_STORE_SELINUX) + { + if (t->th_buf.selinux_context != NULL) + { free(t->th_buf.selinux_context); t->th_buf.selinux_context = NULL; } security_context_t selinux_context = NULL; - if (lgetfilecon(realname, &selinux_context) >= 0) { + if (lgetfilecon(realname, &selinux_context) >= 0) + { t->th_buf.selinux_context = strdup(selinux_context); - printf("setting selinux context: %s\n", selinux_context); + printf(" ==> set selinux context: %s\n", selinux_context); freecon(selinux_context); } else + { +#ifdef DEBUG perror("Failed to get selinux context"); +#endif + } } #endif + /* check if it's a hardlink */ #ifdef DEBUG - puts(" tar_append_file(): checking inode cache for hardlink..."); + puts("tar_append_file(): checking inode cache for hardlink..."); #endif libtar_hashptr_reset(&hp); if (libtar_hash_getkey(t->h, &hp, &(s.st_dev), @@ -171,7 +182,7 @@ tar_append_file(TAR *t, char *realname, char *savename) i = MAXPATHLEN - 1; path[i] = '\0'; #ifdef DEBUG - printf(" tar_append_file(): encoding symlink \"%s\" -> " + printf("tar_append_file(): encoding symlink \"%s\" -> " "\"%s\"...\n", realname, path); #endif th_set_link(t, path); @@ -179,10 +190,10 @@ tar_append_file(TAR *t, char *realname, char *savename) /* print file info */ if (t->options & TAR_VERBOSE) - th_print_long_ls(t); + printf("%s\n", th_get_pathname(t)); #ifdef DEBUG - puts(" tar_append_file(): writing header"); + puts("tar_append_file(): writing header"); #endif /* write header */ if (th_write(t) != 0) @@ -193,7 +204,7 @@ tar_append_file(TAR *t, char *realname, char *savename) return -1; } #ifdef DEBUG - puts(" tar_append_file(): back from th_write()"); + puts("tar_append_file(): back from th_write()"); #endif /* if it's a regular file, write the contents as well */ @@ -229,14 +240,19 @@ tar_append_eof(TAR *t) /* add file contents to a tarchive */ int -tar_append_regfile(TAR *t, char *realname) +tar_append_regfile(TAR *t, const char *realname) { char block[T_BLOCKSIZE]; int filefd; - int j; - size_t size, i; + int64_t i, size; + ssize_t j; + int rv = -1; +#if defined(O_BINARY) + filefd = open(realname, O_RDONLY|O_BINARY); +#else filefd = open(realname, O_RDONLY); +#endif if (filefd == -1) { #ifdef DEBUG @@ -253,25 +269,83 @@ tar_append_regfile(TAR *t, char *realname) { if (j != -1) errno = EINVAL; - return -1; + goto fail; } if (tar_block_write(t, &block) == -1) - return -1; + goto fail; } if (i > 0) { j = read(filefd, &block, i); if (j == -1) - return -1; + goto fail; memset(&(block[i]), 0, T_BLOCKSIZE - i); if (tar_block_write(t, &block) == -1) - return -1; + goto fail; } + /* success! */ + rv = 0; +fail: close(filefd); - return 0; + return rv; } +/* add file contents to a tarchive */ +int +tar_append_file_contents(TAR *t, const char *savename, mode_t mode, + uid_t uid, gid_t gid, void *buf, size_t len) +{ + struct stat st; + + memset(&st, 0, sizeof(st)); + st.st_mode = S_IFREG | mode; + st.st_uid = uid; + st.st_gid = gid; + st.st_mtime = time(NULL); + st.st_size = len; + + th_set_from_stat(t, &st); + th_set_path(t, savename); + + /* write header */ + if (th_write(t) != 0) + { +#ifdef DEBUG + fprintf(stderr, "tar_append_file_contents(): could not write header, t->fd = %d\n", t->fd); +#endif + return -1; + } + + return tar_append_buffer(t, buf, len); +} + +int +tar_append_buffer(TAR *t, void *buf, size_t len) +{ + char block[T_BLOCKSIZE]; + int filefd; + int i, j; + size_t size = len; + + for (i = size; i > T_BLOCKSIZE; i -= T_BLOCKSIZE) + { + if (tar_block_write(t, buf) == -1) + return -1; + buf = (char *)buf + T_BLOCKSIZE; + } + + if (i > 0) + { + memcpy(block, buf, i); + memset(&(block[i]), 0, T_BLOCKSIZE - i); + if (tar_block_write(t, &block) == -1) + return -1; + } + + return 0; +} + -- cgit v1.2.3