2 ** Copyright 1998-2003 University of Illinois Board of Trustees
3 ** Copyright 1998-2003 Mark D. Roth
4 ** All rights reserved.
6 ** encode.c - libtar code to encode tar header blocks
8 ** Mark D. Roth <roth@uiuc.edu>
9 ** Campus Information Technologies and Educational Services
10 ** University of Illinois at Urbana-Champaign
18 #include <sys/types.h>
26 /* magic, version, and checksum */
30 if (t
->options
& TAR_GNU
)
32 /* we're aiming for this result, but must do it in
33 * two calls to avoid FORTIFY segfaults on some Linux
35 * strncpy(t->th_buf.magic, "ustar ", 8);
37 strncpy(t
->th_buf
.magic
, "ustar ", 6);
38 strncpy(t
->th_buf
.version
, " ", 2);
42 strncpy(t
->th_buf
.version
, TVERSION
, TVERSLEN
);
43 strncpy(t
->th_buf
.magic
, TMAGIC
, TMAGLEN
);
46 int_to_oct(th_crc_calc(t
), t
->th_buf
.chksum
, 8);
50 /* map a file mode to a typeflag */
52 th_set_type(TAR
*t
, mode_t mode
)
55 t
->th_buf
.typeflag
= SYMTYPE
;
57 t
->th_buf
.typeflag
= REGTYPE
;
59 t
->th_buf
.typeflag
= DIRTYPE
;
61 t
->th_buf
.typeflag
= CHRTYPE
;
63 t
->th_buf
.typeflag
= BLKTYPE
;
64 if (S_ISFIFO(mode
) || S_ISSOCK(mode
))
65 t
->th_buf
.typeflag
= FIFOTYPE
;
69 /* encode file path */
71 th_set_path(TAR
*t
, const char *pathname
)
77 printf("in th_set_path(th, pathname=\"%s\")\n", pathname
);
80 if (t
->th_buf
.gnu_longname
!= NULL
)
81 free(t
->th_buf
.gnu_longname
);
82 t
->th_buf
.gnu_longname
= NULL
;
84 if (pathname
[strlen(pathname
) - 1] != '/' && TH_ISDIR(t
))
87 if (strlen(pathname
) > T_NAMELEN
-1 && (t
->options
& TAR_GNU
))
89 /* GNU-style long name */
90 t
->th_buf
.gnu_longname
= strdup(pathname
);
91 strncpy(t
->th_buf
.name
, t
->th_buf
.gnu_longname
, T_NAMELEN
);
93 else if (strlen(pathname
) > T_NAMELEN
)
95 /* POSIX-style prefix field */
96 tmp
= strchr(&(pathname
[strlen(pathname
) - T_NAMELEN
- 1]), '/');
99 printf("!!! '/' not found in \"%s\"\n", pathname
);
102 snprintf(t
->th_buf
.name
, 100, "%s%s", &(tmp
[1]), suffix
);
103 snprintf(t
->th_buf
.prefix
,
104 ((tmp
- pathname
+ 1) <
105 155 ? (tmp
- pathname
+ 1) : 155), "%s", pathname
);
108 /* classic tar format */
109 snprintf(t
->th_buf
.name
, 100, "%s%s", pathname
, suffix
);
112 puts("returning from th_set_path()...");
117 /* encode link path */
119 th_set_link(TAR
*t
, const char *linkname
)
122 printf("==> th_set_link(th, linkname=\"%s\")\n", linkname
);
125 if (strlen(linkname
) > T_NAMELEN
-1 && (t
->options
& TAR_GNU
))
127 /* GNU longlink format */
128 t
->th_buf
.gnu_longlink
= strdup(linkname
);
129 strcpy(t
->th_buf
.linkname
, "././@LongLink");
133 /* classic tar format */
134 strlcpy(t
->th_buf
.linkname
, linkname
,
135 sizeof(t
->th_buf
.linkname
));
136 if (t
->th_buf
.gnu_longlink
!= NULL
)
137 free(t
->th_buf
.gnu_longlink
);
138 t
->th_buf
.gnu_longlink
= NULL
;
143 /* encode device info */
145 th_set_device(TAR
*t
, dev_t device
)
148 printf("th_set_device(): major = %d, minor = %d\n",
149 major(device
), minor(device
));
151 int_to_oct(major(device
), t
->th_buf
.devmajor
, 8);
152 int_to_oct(minor(device
), t
->th_buf
.devminor
, 8);
156 /* encode user info */
158 th_set_user(TAR
*t
, uid_t uid
)
164 strlcpy(t
->th_buf
.uname
, pw
->pw_name
, sizeof(t
->th_buf
.uname
));
166 int_to_oct(uid
, t
->th_buf
.uid
, 8);
170 /* encode group info */
172 th_set_group(TAR
*t
, gid_t gid
)
178 strlcpy(t
->th_buf
.gname
, gr
->gr_name
, sizeof(t
->th_buf
.gname
));
180 int_to_oct(gid
, t
->th_buf
.gid
, 8);
184 /* encode file mode */
186 th_set_mode(TAR
*t
, mode_t fmode
)
193 int_to_oct(fmode
, (t
)->th_buf
.mode
, 8);
198 th_set_from_stat(TAR
*t
, struct stat
*s
)
200 th_set_type(t
, s
->st_mode
);
201 if (S_ISCHR(s
->st_mode
) || S_ISBLK(s
->st_mode
))
202 th_set_device(t
, s
->st_rdev
);
203 th_set_user(t
, s
->st_uid
);
204 th_set_group(t
, s
->st_gid
);
205 th_set_mode(t
, s
->st_mode
);
206 th_set_mtime(t
, s
->st_mtime
);
207 if (S_ISREG(s
->st_mode
))
208 th_set_size(t
, s
->st_size
);