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
13 #include <libtarint/internal.h>
20 #include <sys/types.h>
28 /* magic, version, and checksum */
34 if (t
->options
& TAR_GNU
)
35 strncpy(t
->th_buf
.magic
, "ustar ", 8);
38 strncpy(t
->th_buf
.version
, TVERSION
, TVERSLEN
);
39 strncpy(t
->th_buf
.magic
, TMAGIC
, TMAGLEN
);
42 for (i
= 0; i
< T_BLOCKSIZE
; i
++)
43 sum
+= ((char *)(&(t
->th_buf
)))[i
];
44 for (i
= 0; i
< 8; i
++)
45 sum
+= (' ' - t
->th_buf
.chksum
[i
]);
46 int_to_oct(sum
, t
->th_buf
.chksum
, 8);
50 /* map a file mode to a typeflag */
52 th_set_type(TAR
*t
, mode_t mode
)
56 t
->th_buf
.typeflag
= SYMTYPE
;
59 t
->th_buf
.typeflag
= REGTYPE
;
61 t
->th_buf
.typeflag
= DIRTYPE
;
64 t
->th_buf
.typeflag
= CHRTYPE
;
67 t
->th_buf
.typeflag
= BLKTYPE
;
74 t
->th_buf
.typeflag
= FIFOTYPE
;
78 /* encode file path */
80 th_set_path(TAR
*t
, char *pathname
)
86 printf("in th_set_path(th, pathname=\"%s\")\n", pathname
);
89 if (t
->th_buf
.gnu_longname
!= NULL
)
90 free(t
->th_buf
.gnu_longname
);
91 t
->th_buf
.gnu_longname
= NULL
;
93 if (pathname
[strlen(pathname
) - 1] != '/' && TH_ISDIR(t
))
96 if (strlen(pathname
)+strlen(suffix
) >= T_NAMELEN
&& (t
->options
& TAR_GNU
))
98 /* GNU-style long name */
99 t
->th_buf
.gnu_longname
= strdup(pathname
);
100 strncpy(t
->th_buf
.name
, t
->th_buf
.gnu_longname
, T_NAMELEN
);
102 else if (strlen(pathname
)+ strlen(suffix
) >= T_NAMELEN
)
104 /* POSIX-style prefix field */
105 tmp
= strrchr(pathname
, '/');
108 printf("!!! '/' not found in \"%s\"\n", pathname
);
111 snprintf(t
->th_buf
.name
, 100, "%s%s", &(tmp
[1]), suffix
);
112 snprintf(t
->th_buf
.prefix
,
113 ((tmp
- pathname
+ 1) <
114 155 ? (tmp
- pathname
+ 1) : 155), "%s", pathname
);
117 /* classic tar format */
118 snprintf(t
->th_buf
.name
, 100, "%s%s", pathname
, suffix
);
121 puts("returning from th_set_path()...");
126 /* encode link path */
128 th_set_link(TAR
*t
, char *linkname
)
131 printf("==> th_set_link(th, linkname=\"%s\")\n", linkname
);
134 if (strlen(linkname
) > T_NAMELEN
&& (t
->options
& TAR_GNU
))
136 /* GNU longlink format */
137 t
->th_buf
.gnu_longlink
= strdup(linkname
);
138 strcpy(t
->th_buf
.linkname
, "././@LongLink");
142 /* classic tar format */
143 strlcpy(t
->th_buf
.linkname
, linkname
,
144 sizeof(t
->th_buf
.linkname
));
145 if (t
->th_buf
.gnu_longlink
!= NULL
)
146 free(t
->th_buf
.gnu_longlink
);
147 t
->th_buf
.gnu_longlink
= NULL
;
152 /* encode device info */
154 th_set_device(TAR
*t
, dev_t device
)
157 printf("th_set_device(): major = %d, minor = %d\n",
158 major(device
), minor(device
));
160 int_to_oct(major(device
), t
->th_buf
.devmajor
, 8);
161 int_to_oct(minor(device
), t
->th_buf
.devminor
, 8);
165 /* encode user info */
167 th_set_user(TAR
*t
, uid_t uid
)
174 strlcpy(t
->th_buf
.uname
, pw
->pw_name
, sizeof(t
->th_buf
.uname
));
176 int_to_oct(uid
, t
->th_buf
.uid
, 8);
180 /* encode group info */
182 th_set_group(TAR
*t
, gid_t gid
)
189 strlcpy(t
->th_buf
.gname
, gr
->gr_name
, sizeof(t
->th_buf
.gname
));
191 int_to_oct(gid
, t
->th_buf
.gid
, 8);
195 /* encode file mode */
197 th_set_mode(TAR
*t
, mode_t fmode
)
208 /* Looks like on windows the st_mode is longer than 8 characters. */
209 int_to_oct(fmode
& 07777777, (t
)->th_buf
.mode
, 8);
214 th_set_from_stat(TAR
*t
, struct stat
*s
)
216 th_set_type(t
, s
->st_mode
);
218 if (S_ISCHR(s
->st_mode
) || S_ISBLK(s
->st_mode
))
219 th_set_device(t
, s
->st_rdev
);
221 th_set_user(t
, s
->st_uid
);
222 th_set_group(t
, s
->st_gid
);
223 th_set_mode(t
, s
->st_mode
);
224 th_set_mtime(t
, s
->st_mtime
);
225 if (S_ISREG(s
->st_mode
))
226 th_set_size(t
, s
->st_size
);