diff options
Diffstat (limited to 'libtar/decode.c')
-rw-r--r-- | libtar/decode.c | 47 |
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; |