summaryrefslogtreecommitdiffstats
path: root/libtar/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtar/decode.c')
-rw-r--r--libtar/decode.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/libtar/decode.c b/libtar/decode.c
new file mode 100644
index 000000000..1a3d0ee56
--- /dev/null
+++ b/libtar/decode.c
@@ -0,0 +1,135 @@
+/*
+** Copyright 1998-2003 University of Illinois Board of Trustees
+** Copyright 1998-2003 Mark D. Roth
+** All rights reserved.
+**
+** decode.c - libtar code to decode tar header blocks
+**
+** Mark D. Roth <roth@uiuc.edu>
+** Campus Information Technologies and Educational Services
+** University of Illinois at Urbana-Champaign
+*/
+
+#include <internal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include <grp.h>
+
+#ifdef STDC_HEADERS
+# include <string.h>
+#endif
+
+
+/* determine full path name */
+char *
+th_get_pathname(TAR *t)
+{
+ 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')
+ {
+ 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;
+}
+
+
+uid_t
+th_get_uid(TAR *t)
+{
+ int uid;
+ struct passwd *pw;
+
+ 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);
+ return uid;
+}
+
+
+gid_t
+th_get_gid(TAR *t)
+{
+ int gid;
+ struct group *gr;
+
+ 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);
+ return gid;
+}
+
+
+mode_t
+th_get_mode(TAR *t)
+{
+ mode_t 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)
+ {
+ case SYMTYPE:
+ mode |= S_IFLNK;
+ break;
+ case CHRTYPE:
+ mode |= S_IFCHR;
+ break;
+ case BLKTYPE:
+ mode |= S_IFBLK;
+ break;
+ case DIRTYPE:
+ mode |= S_IFDIR;
+ break;
+ case FIFOTYPE:
+ mode |= S_IFIFO;
+ break;
+ case AREGTYPE:
+ if (t->th_buf.name[strnlen(t->th_buf.name, T_NAMELEN) - 1] == '/')
+ {
+ mode |= S_IFDIR;
+ break;
+ }
+ /* FALLTHROUGH */
+ case LNKTYPE:
+ case REGTYPE:
+ default:
+ mode |= S_IFREG;
+ }
+ }
+
+ return mode;
+}
+
+