edb218519d3295f3f0137e6c20d48b4cd7dd672d
[libtar.git] / lib / decode.c
blobedb218519d3295f3f0137e6c20d48b4cd7dd672d
1 /*
2 ** Copyright 1998-2003 University of Illinois Board of Trustees
3 ** Copyright 1998-2003 Mark D. Roth
4 ** All rights reserved.
5 **
6 ** decode.c - libtar code to decode tar header blocks
7 **
8 ** Mark D. Roth <roth@uiuc.edu>
9 ** Campus Information Technologies and Educational Services
10 ** University of Illinois at Urbana-Champaign
13 #include <internal.h>
15 #include <stdio.h>
16 #include <sys/param.h>
17 #include <pwd.h>
18 #include <grp.h>
20 #ifdef STDC_HEADERS
21 # include <string.h>
22 #endif
25 /* determine full path name */
26 char *
27 th_get_pathname(TAR *t)
29 if (t->th_buf.gnu_longname)
30 return t->th_buf.gnu_longname;
32 /* allocate the th_pathname buffer if not already */
33 if (t->th_pathname == NULL)
35 t->th_pathname = malloc(MAXPATHLEN * sizeof(char));
36 if (t->th_pathname == NULL)
37 /* out of memory */
38 return NULL;
41 if (t->th_buf.prefix[0] == '\0')
43 snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name);
45 else
47 snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s",
48 t->th_buf.prefix, t->th_buf.name);
51 /* will be deallocated in tar_close() */
52 return t->th_pathname;
56 uid_t
57 th_get_uid(TAR *t)
59 int uid;
60 struct passwd *pw;
62 pw = getpwnam(t->th_buf.uname);
63 if (pw != NULL)
64 return pw->pw_uid;
66 /* if the password entry doesn't exist */
67 sscanf(t->th_buf.uid, "%o", &uid);
68 return uid;
72 gid_t
73 th_get_gid(TAR *t)
75 int gid;
76 struct group *gr;
78 gr = getgrnam(t->th_buf.gname);
79 if (gr != NULL)
80 return gr->gr_gid;
82 /* if the group entry doesn't exist */
83 sscanf(t->th_buf.gid, "%o", &gid);
84 return gid;
88 mode_t
89 th_get_mode(TAR *t)
91 mode_t mode;
93 mode = (mode_t)oct_to_int(t->th_buf.mode);
94 if (! (mode & S_IFMT))
96 switch (t->th_buf.typeflag)
98 case SYMTYPE:
99 mode |= S_IFLNK;
100 break;
101 case CHRTYPE:
102 mode |= S_IFCHR;
103 break;
104 case BLKTYPE:
105 mode |= S_IFBLK;
106 break;
107 case DIRTYPE:
108 mode |= S_IFDIR;
109 break;
110 case FIFOTYPE:
111 mode |= S_IFIFO;
112 break;
113 case AREGTYPE:
114 if (t->th_buf.name[strlen(t->th_buf.name) - 1] == '/')
116 mode |= S_IFDIR;
117 break;
119 /* FALLTHROUGH */
120 case LNKTYPE:
121 case REGTYPE:
122 default:
123 mode |= S_IFREG;
127 return mode;