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
)
33 strncpy(t
->th_buf
.magic
, "ustar ", 8);
36 strncpy(t
->th_buf
.version
, TVERSION
, TVERSLEN
);
37 strncpy(t
->th_buf
.magic
, TMAGIC
, TMAGLEN
);
40 for (i
= 0; i
< T_BLOCKSIZE
; i
++)
41 sum
+= ((char *)(&(t
->th_buf
)))[i
];
42 for (i
= 0; i
< 8; i
++)
43 sum
+= (' ' - t
->th_buf
.chksum
[i
]);
44 int_to_oct(sum
, t
->th_buf
.chksum
, 8);
48 /* map a file mode to a typeflag */
50 th_set_type(TAR
*t
, mode_t mode
)
53 t
->th_buf
.typeflag
= SYMTYPE
;
55 t
->th_buf
.typeflag
= REGTYPE
;
57 t
->th_buf
.typeflag
= DIRTYPE
;
59 t
->th_buf
.typeflag
= CHRTYPE
;
61 t
->th_buf
.typeflag
= BLKTYPE
;
62 if (S_ISFIFO(mode
) || S_ISSOCK(mode
))
63 t
->th_buf
.typeflag
= FIFOTYPE
;
67 /* encode file path */
69 th_set_path(TAR
*t
, char *pathname
)
75 printf("in th_set_path(th, pathname=\"%s\")\n", pathname
);
78 if (t
->th_buf
.gnu_longname
!= NULL
)
79 free(t
->th_buf
.gnu_longname
);
80 t
->th_buf
.gnu_longname
= NULL
;
82 if (pathname
[strlen(pathname
) - 1] != '/' && TH_ISDIR(t
))
85 if (strlen(pathname
) > T_NAMELEN
&& (t
->options
& TAR_GNU
))
87 /* GNU-style long name */
88 t
->th_buf
.gnu_longname
= strdup(pathname
);
89 strncpy(t
->th_buf
.name
, t
->th_buf
.gnu_longname
, T_NAMELEN
);
91 else if (strlen(pathname
) > T_NAMELEN
)
93 /* POSIX-style prefix field */
94 tmp
= strchr(&(pathname
[strlen(pathname
) - T_NAMELEN
- 1]), '/');
97 printf("!!! '/' not found in \"%s\"\n", pathname
);
100 snprintf(t
->th_buf
.name
, 100, "%s%s", &(tmp
[1]), suffix
);
101 snprintf(t
->th_buf
.prefix
,
102 ((tmp
- pathname
+ 1) <
103 155 ? (tmp
- pathname
+ 1) : 155), "%s", pathname
);
106 /* classic tar format */
107 snprintf(t
->th_buf
.name
, 100, "%s%s", pathname
, suffix
);
110 puts("returning from th_set_path()...");
115 /* encode link path */
117 th_set_link(TAR
*t
, char *linkname
)
120 printf("==> th_set_link(th, linkname=\"%s\")\n", linkname
);
123 if (strlen(linkname
) > T_NAMELEN
&& (t
->options
& TAR_GNU
))
125 /* GNU longlink format */
126 t
->th_buf
.gnu_longlink
= strdup(linkname
);
127 strcpy(t
->th_buf
.linkname
, "././@LongLink");
131 /* classic tar format */
132 strlcpy(t
->th_buf
.linkname
, linkname
,
133 sizeof(t
->th_buf
.linkname
));
134 if (t
->th_buf
.gnu_longlink
!= NULL
)
135 free(t
->th_buf
.gnu_longlink
);
136 t
->th_buf
.gnu_longlink
= NULL
;
141 /* encode device info */
143 th_set_device(TAR
*t
, dev_t device
)
146 printf("th_set_device(): major = %d, minor = %d\n",
147 major(device
), minor(device
));
149 int_to_oct(major(device
), t
->th_buf
.devmajor
, 8);
150 int_to_oct(minor(device
), t
->th_buf
.devminor
, 8);
154 /* encode user info */
156 th_set_user(TAR
*t
, uid_t uid
)
162 strlcpy(t
->th_buf
.uname
, pw
->pw_name
, sizeof(t
->th_buf
.uname
));
164 int_to_oct(uid
, t
->th_buf
.uid
, 8);
168 /* encode group info */
170 th_set_group(TAR
*t
, gid_t gid
)
176 strlcpy(t
->th_buf
.gname
, gr
->gr_name
, sizeof(t
->th_buf
.gname
));
178 int_to_oct(gid
, t
->th_buf
.gid
, 8);
182 /* encode file mode */
184 th_set_mode(TAR
*t
, mode_t fmode
)
191 int_to_oct(fmode
, (t
)->th_buf
.mode
, 8);
196 th_set_from_stat(TAR
*t
, struct stat
*s
)
198 th_set_type(t
, s
->st_mode
);
199 if (S_ISCHR(s
->st_mode
) || S_ISBLK(s
->st_mode
))
200 th_set_device(t
, s
->st_rdev
);
201 th_set_user(t
, s
->st_uid
);
202 th_set_group(t
, s
->st_gid
);
203 th_set_mode(t
, s
->st_mode
);
204 th_set_mtime(t
, s
->st_mtime
);
205 if (S_ISREG(s
->st_mode
))
206 th_set_size(t
, s
->st_size
);