Added stdlib.h for malloc() in lib/decode.c
[libtar.git] / lib / decode.c
blob35312be3da928b84525c503a9c5c3309f8f5f99e
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 <stdlib.h>
17 #include <sys/param.h>
18 #include <pwd.h>
19 #include <grp.h>
21 #ifdef STDC_HEADERS
22 # include <string.h>
23 #endif
26 /* determine full path name */
27 char *
28 th_get_pathname(TAR *t)
30 if (t->th_buf.gnu_longname)
31 return t->th_buf.gnu_longname;
33 /* allocate the th_pathname buffer if not already */
34 if (t->th_pathname == NULL)
36 t->th_pathname = malloc(MAXPATHLEN * sizeof(char));
37 if (t->th_pathname == NULL)
38 /* out of memory */
39 return NULL;
42 if (t->th_buf.prefix[0] == '\0')
44 snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name);
46 else
48 snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s",
49 t->th_buf.prefix, t->th_buf.name);
52 /* will be deallocated in tar_close() */
53 return t->th_pathname;
57 uid_t
58 th_get_uid(TAR *t)
60 int uid;
61 struct passwd *pw;
63 pw = getpwnam(t->th_buf.uname);
64 if (pw != NULL)
65 return pw->pw_uid;
67 /* if the password entry doesn't exist */
68 sscanf(t->th_buf.uid, "%o", &uid);
69 return uid;
73 gid_t
74 th_get_gid(TAR *t)
76 int gid;
77 struct group *gr;
79 gr = getgrnam(t->th_buf.gname);
80 if (gr != NULL)
81 return gr->gr_gid;
83 /* if the group entry doesn't exist */
84 sscanf(t->th_buf.gid, "%o", &gid);
85 return gid;
89 mode_t
90 th_get_mode(TAR *t)
92 mode_t mode;
94 mode = (mode_t)oct_to_int(t->th_buf.mode);
95 if (! (mode & S_IFMT))
97 switch (t->th_buf.typeflag)
99 case SYMTYPE:
100 mode |= S_IFLNK;
101 break;
102 case CHRTYPE:
103 mode |= S_IFCHR;
104 break;
105 case BLKTYPE:
106 mode |= S_IFBLK;
107 break;
108 case DIRTYPE:
109 mode |= S_IFDIR;
110 break;
111 case FIFOTYPE:
112 mode |= S_IFIFO;
113 break;
114 case AREGTYPE:
115 if (t->th_buf.name[strlen(t->th_buf.name) - 1] == '/')
117 mode |= S_IFDIR;
118 break;
120 /* FALLTHROUGH */
121 case LNKTYPE:
122 case REGTYPE:
123 default:
124 mode |= S_IFREG;
128 return mode;