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 */
32 if (t
->options
& TAR_GNU
)
34 /* we're aiming for this result, but must do it in
35 * two calls to avoid FORTIFY segfaults on some Linux
37 * strncpy(t->th_buf.magic, "ustar ", 8);
39 strncpy(t
->th_buf
.magic
, "ustar ", 6);
40 strncpy(t
->th_buf
.version
, " ", 2);
44 strncpy(t
->th_buf
.version
, TVERSION
, TVERSLEN
);
45 strncpy(t
->th_buf
.magic
, TMAGIC
, TMAGLEN
);
48 for (i
= 0; i
< T_BLOCKSIZE
; i
++)
49 sum
+= ((char *)(&(t
->th_buf
)))[i
];
50 for (i
= 0; i
< 8; i
++)
51 sum
+= (' ' - t
->th_buf
.chksum
[i
]);
52 int_to_oct(sum
, t
->th_buf
.chksum
, 8);
56 /* map a file mode to a typeflag */
58 th_set_type(TAR
*t
, mode_t mode
)
61 t
->th_buf
.typeflag
= SYMTYPE
;
63 t
->th_buf
.typeflag
= REGTYPE
;
65 t
->th_buf
.typeflag
= DIRTYPE
;
67 t
->th_buf
.typeflag
= CHRTYPE
;
69 t
->th_buf
.typeflag
= BLKTYPE
;
70 if (S_ISFIFO(mode
) || S_ISSOCK(mode
))
71 t
->th_buf
.typeflag
= FIFOTYPE
;
75 /* encode file path */
77 th_set_path(TAR
*t
, char *pathname
)
83 printf("in th_set_path(th, pathname=\"%s\")\n", pathname
);
86 if (t
->th_buf
.gnu_longname
!= NULL
)
87 free(t
->th_buf
.gnu_longname
);
88 t
->th_buf
.gnu_longname
= NULL
;
90 if (pathname
[strlen(pathname
) - 1] != '/' && TH_ISDIR(t
))
93 if (strlen(pathname
) > T_NAMELEN
-1 && (t
->options
& TAR_GNU
))
95 /* GNU-style long name */
96 t
->th_buf
.gnu_longname
= strdup(pathname
);
97 strncpy(t
->th_buf
.name
, t
->th_buf
.gnu_longname
, T_NAMELEN
);
99 else if (strlen(pathname
) > T_NAMELEN
)
101 /* POSIX-style prefix field */
102 tmp
= strchr(&(pathname
[strlen(pathname
) - T_NAMELEN
- 1]), '/');
105 printf("!!! '/' not found in \"%s\"\n", pathname
);
108 snprintf(t
->th_buf
.name
, 100, "%s%s", &(tmp
[1]), suffix
);
109 snprintf(t
->th_buf
.prefix
,
110 ((tmp
- pathname
+ 1) <
111 155 ? (tmp
- pathname
+ 1) : 155), "%s", pathname
);
114 /* classic tar format */
115 snprintf(t
->th_buf
.name
, 100, "%s%s", pathname
, suffix
);
118 puts("returning from th_set_path()...");
123 /* encode link path */
125 th_set_link(TAR
*t
, char *linkname
)
128 printf("==> th_set_link(th, linkname=\"%s\")\n", linkname
);
131 if (strlen(linkname
) > T_NAMELEN
-1 && (t
->options
& TAR_GNU
))
133 /* GNU longlink format */
134 t
->th_buf
.gnu_longlink
= strdup(linkname
);
135 strcpy(t
->th_buf
.linkname
, "././@LongLink");
139 /* classic tar format */
140 strlcpy(t
->th_buf
.linkname
, linkname
,
141 sizeof(t
->th_buf
.linkname
));
142 if (t
->th_buf
.gnu_longlink
!= NULL
)
143 free(t
->th_buf
.gnu_longlink
);
144 t
->th_buf
.gnu_longlink
= NULL
;
149 /* encode device info */
151 th_set_device(TAR
*t
, dev_t device
)
154 printf("th_set_device(): major = %d, minor = %d\n",
155 major(device
), minor(device
));
157 int_to_oct(major(device
), t
->th_buf
.devmajor
, 8);
158 int_to_oct(minor(device
), t
->th_buf
.devminor
, 8);
162 /* encode user info */
164 th_set_user(TAR
*t
, uid_t uid
)
170 strlcpy(t
->th_buf
.uname
, pw
->pw_name
, sizeof(t
->th_buf
.uname
));
172 int_to_oct(uid
, t
->th_buf
.uid
, 8);
176 /* encode group info */
178 th_set_group(TAR
*t
, gid_t gid
)
184 strlcpy(t
->th_buf
.gname
, gr
->gr_name
, sizeof(t
->th_buf
.gname
));
186 int_to_oct(gid
, t
->th_buf
.gid
, 8);
190 /* encode file mode */
192 th_set_mode(TAR
*t
, mode_t fmode
)
199 int_to_oct(fmode
, (t
)->th_buf
.mode
, 8);
204 th_set_from_stat(TAR
*t
, struct stat
*s
)
206 th_set_type(t
, s
->st_mode
);
207 if (S_ISCHR(s
->st_mode
) || S_ISBLK(s
->st_mode
))
208 th_set_device(t
, s
->st_rdev
);
209 th_set_user(t
, s
->st_uid
);
210 th_set_group(t
, s
->st_gid
);
211 th_set_mode(t
, s
->st_mode
);
212 th_set_mtime(t
, s
->st_mtime
);
213 if (S_ISREG(s
->st_mode
))
214 th_set_size(t
, s
->st_size
);