summaryrefslogtreecommitdiffstats
path: root/libtar/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtar/decode.c')
-rw-r--r--libtar/decode.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/libtar/decode.c b/libtar/decode.c
index 383306d64..1a3d0ee56 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;
+
+ /* allocate the th_pathname buffer if not already */
+ if (t->th_pathname == NULL)
+ {
+ t->th_pathname = malloc(MAXPATHLEN * sizeof(char));
+ if (t->th_pathname == NULL)
+ /* out of memory */
+ return NULL;
}
- if (t->th_buf.prefix[0] != '\0')
+ if (t->th_buf.prefix[0] == '\0')
{
- snprintf(filename, sizeof(filename), "%.155s/%.100s",
+ 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);
- return strdup(filename);
}
- snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name);
- return strdup(filename);
+ /* will be deallocated in tar_close() */
+ return t->th_pathname;
}
@@ -51,9 +60,11 @@ th_get_uid(TAR *t)
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 @@ th_get_gid(TAR *t)
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 @@ th_get_mode(TAR *t)
{
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 @@ th_get_mode(TAR *t)
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;