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 <tdm@cyngn.com>
Date: Thu, 11 Feb 2016 16:24:40 -0800
Subject: libtar: Cleanup, secure, and extend numeric fields
Commit: e18b457ea1cbf6be1adc3b75450ed1c737cd82ea
From: Tom Marshall <tdm@cyngn.com>
Date: Thu, 11 Feb 2016 12:49:30 -0800
Subject: libtar: Make file sizes 64-bit clean
Commit: e628c2025549a24018bc568351465130a05daafb
From: Tom Marshall <tdm@cyngn.com>
Date: Thu, 17 Apr 2014 09:39:25 -0700
Subject: libtar: Add methods for in-memory files
Commit: 8ec5627a8ff0a91724c6d5b344f0e887da922527
From: Tom Marshall <tdm@cyngn.com>
Date: Wed, 2 Jul 2014 09:34:40 -0700
Subject: libtar: Fix hardlink extract
Commit: 166d83a51e0c51abcea37694dbd7df92d03c1f56
From: philz-cwm6 <phytowardt@gmail.com>
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 <tdm@cyngn.com>
Date: Wed, 9 Apr 2014 09:35:54 -0700
Subject: libtar: Add const qualifiers to reduce compile warnings
Commit: 0600afa19fe827d06d3fcf24a7aabd52dbf487b4
Change-Id: I6d008cb6fdf950f835bbed63aeb8727cc5c86083
diff --git a/libtar/decode.c b/libtar/decode.c
index 383306d..1a3d0ee 100644
--- a/libtar/decode.c
+++ b/libtar/decode.c
@@ -13,6 +13,7 @@
#include <internal.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
@@ -26,22 +27,30 @@
char *
th_get_pathname(TAR *t)
{
- char filename[MAXPATHLEN];
-
- if (t->th_buf.gnu_longname) {
- printf("returning gnu longname\n");
+ if (t->th_buf.gnu_longname)
return t->th_buf.gnu_longname;
- }
- if (t->th_buf.prefix[0] != '\0')
+ /* allocate the th_pathname buffer if not already */
+ if (t->th_pathname == NULL)
{
- snprintf(filename, sizeof(filename), "%.155s/%.100s",
- t->th_buf.prefix, t->th_buf.name);
- return strdup(filename);
+ t->th_pathname = malloc(MAXPATHLEN * sizeof(char));
+ if (t->th_pathname == NULL)
+ /* out of memory */
+ return NULL;
}
- snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name);
- return strdup(filename);
+ if (t->th_buf.prefix[0] == '\0')
+ {
+ snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name);
+ }
+ else
+ {
+ snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s",
+ t->th_buf.prefix, t->th_buf.name);
+ }
+
+ /* will be deallocated in tar_close() */
+ return t->th_pathname;
}
@@ -51,9 +60,11 @@
int uid;
struct passwd *pw;
- pw = getpwnam(t->th_buf.uname);
- if (pw != NULL)
- return pw->pw_uid;
+ if (!(t->options & TAR_USE_NUMERIC_ID)) {
+ pw = getpwnam(t->th_buf.uname);
+ if (pw != NULL)
+ return pw->pw_uid;
+ }
/* if the password entry doesn't exist */
sscanf(t->th_buf.uid, "%o", &uid);
@@ -67,9 +78,11 @@
int gid;
struct group *gr;
- gr = getgrnam(t->th_buf.gname);
- if (gr != NULL)
- return gr->gr_gid;
+ if (!(t->options & TAR_USE_NUMERIC_ID)) {
+ gr = getgrnam(t->th_buf.gname);
+ if (gr != NULL)
+ return gr->gr_gid;
+ }
/* if the group entry doesn't exist */
sscanf(t->th_buf.gid, "%o", &gid);
@@ -82,7 +95,7 @@
{
mode_t mode;
- mode = (mode_t)oct_to_int(t->th_buf.mode);
+ mode = (mode_t)oct_to_int(t->th_buf.mode, sizeof(t->th_buf.mode));
if (! (mode & S_IFMT))
{
switch (t->th_buf.typeflag)
@@ -103,7 +116,7 @@
mode |= S_IFIFO;
break;
case AREGTYPE:
- if (t->th_buf.name[strlen(t->th_buf.name) - 1] == '/')
+ if (t->th_buf.name[strnlen(t->th_buf.name, T_NAMELEN) - 1] == '/')
{
mode |= S_IFDIR;
break;