1
1

* tar.c: Eliminate struct hstat, use stack arguments instead.

Этот коммит содержится в:
Pavel Roskin 2004-06-14 16:04:07 +00:00
родитель 3a0c1187b2
Коммит 8ab694ba2d
2 изменённых файлов: 56 добавлений и 47 удалений

Просмотреть файл

@ -1,3 +1,7 @@
2004-06-14 Pavel Roskin <proski@gnu.org>
* tar.c: Eliminate struct hstat, use stack arguments instead.
2004-03-07 Andrew V. Samoilov <sav@bcs.zp.ua> 2004-03-07 Andrew V. Samoilov <sav@bcs.zp.ua>
* utilvfs.c (vfs_parse_ls_lga): Handle device without whitespace(s) * utilvfs.c (vfs_parse_ls_lga): Handle device without whitespace(s)

Просмотреть файл

@ -187,8 +187,6 @@ static long tar_from_oct (int digs, char *where)
return value; return value;
} }
static struct stat hstat; /* Stat struct corresponding */
static void tar_free_archive (struct vfs_class *me, struct vfs_s_super *archive) static void tar_free_archive (struct vfs_class *me, struct vfs_s_super *archive)
{ {
if (archive->u.arch.fd != -1) if (archive->u.arch.fd != -1)
@ -274,7 +272,8 @@ static void tar_skip_n_records (struct vfs_s_super *archive, int tard, int n)
} }
static void static void
tar_fill_stat (struct vfs_class *me, struct stat *st, union record *header) tar_fill_stat (struct vfs_class *me, struct stat *st, union record *header,
size_t h_size)
{ {
st->st_mode = tar_from_oct (8, header->header.mode); st->st_mode = tar_from_oct (8, header->header.mode);
@ -321,7 +320,7 @@ tar_fill_stat (struct vfs_class *me, struct stat *st, union record *header)
st->st_uid = tar_from_oct (8, header->header.uid); st->st_uid = tar_from_oct (8, header->header.uid);
st->st_gid = tar_from_oct (8, header->header.gid); st->st_gid = tar_from_oct (8, header->header.gid);
} }
st->st_size = hstat.st_size; st->st_size = h_size;
st->st_mtime = tar_from_oct (1 + 12, header->header.mtime); st->st_mtime = tar_from_oct (1 + 12, header->header.mtime);
st->st_atime = tar_from_oct (1 + 12, header->header.atime); st->st_atime = tar_from_oct (1 + 12, header->header.atime);
st->st_ctime = tar_from_oct (1 + 12, header->header.ctime); st->st_ctime = tar_from_oct (1 + 12, header->header.ctime);
@ -340,7 +339,8 @@ typedef enum {
* *
*/ */
static ReadStatus static ReadStatus
tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard) tar_read_header (struct vfs_class *me, struct vfs_s_super *archive,
int tard, size_t *h_size)
{ {
register int i; register int i;
register long sum, signed_sum, recsum; register long sum, signed_sum, recsum;
@ -356,13 +356,14 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard)
recsum = tar_from_oct (8, header->header.chksum); recsum = tar_from_oct (8, header->header.chksum);
sum = 0; signed_sum = 0; sum = 0;
signed_sum = 0;
p = header->charptr; p = header->charptr;
for (i = sizeof (*header); --i >= 0;) { for (i = sizeof (*header); --i >= 0;) {
/* /*
* We can't use unsigned char here because of old compilers, * We can't use unsigned char here because of old compilers,
* e.g. V7. * e.g. V7.
*/ */
signed_sum += *p; signed_sum += *p;
sum += 0xFF & *p++; sum += 0xFF & *p++;
} }
@ -384,22 +385,23 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard)
if (sum != recsum && signed_sum != recsum) if (sum != recsum && signed_sum != recsum)
return STATUS_BADCHECKSUM; return STATUS_BADCHECKSUM;
/* /*
* linkflag on BSDI tar (pax) always '\000' * linkflag on BSDI tar (pax) always '\000'
*/ */
if (header->header.linkflag == '\000' && if (header->header.linkflag == '\000'
(i = strlen(header->header.arch_name)) && && (i = strlen (header->header.arch_name))
header->header.arch_name[i - 1] == '/') && header->header.arch_name[i - 1] == '/')
header->header.linkflag = LF_DIR; header->header.linkflag = LF_DIR;
/* /*
* Good record. Decode file size and return. * Good record. Decode file size and return.
*/ */
if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR) if (header->header.linkflag == LF_LINK
hstat.st_size = 0; /* Links 0 size on tape */ || header->header.linkflag == LF_DIR)
*h_size = 0; /* Links 0 size on tape */
else else
hstat.st_size = tar_from_oct (1 + 12, header->header.size); *h_size = tar_from_oct (1 + 12, header->header.size);
header->header.arch_name[NAMSIZ - 1] = '\0'; header->header.arch_name[NAMSIZ - 1] = '\0';
if (header->header.linkflag == LF_LONGNAME if (header->header.linkflag == LF_LONGNAME
@ -409,19 +411,17 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard)
int size, written; int size, written;
longp = ((header->header.linkflag == LF_LONGNAME) longp = ((header->header.linkflag == LF_LONGNAME)
? &next_long_name ? &next_long_name : &next_long_link);
: &next_long_link);
if (*longp) if (*longp)
g_free (*longp); g_free (*longp);
bp = *longp = g_malloc (hstat.st_size); bp = *longp = g_malloc (*h_size);
for (size = hstat.st_size; for (size = *h_size; size > 0; size -= written) {
size > 0;
size -= written) {
data = tar_get_next_record (archive, tard)->charptr; data = tar_get_next_record (archive, tard)->charptr;
if (data == NULL) { if (data == NULL) {
message (1, MSG_ERROR, _("Unexpected EOF on archive file")); message (1, MSG_ERROR,
_("Unexpected EOF on archive file"));
return STATUS_BADCHECKSUM; return STATUS_BADCHECKSUM;
} }
written = RECORDSIZE; written = RECORDSIZE;
@ -432,8 +432,8 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard)
bp += written; bp += written;
} }
#if 0 #if 0
if (hstat.st_size > 1) if (*h_size > 1)
bp [hstat.st_size - 1] = 0; /* just to make sure */ bp[*h_size - 1] = 0; /* just to make sure */
#endif #endif
goto recurse; goto recurse;
} else { } else {
@ -445,51 +445,54 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard)
int len; int len;
char *current_file_name, *current_link_name; char *current_file_name, *current_link_name;
current_link_name = (next_long_link current_link_name =
? next_long_link (next_long_link ? next_long_link :
: g_strdup (header->header.arch_linkname)); g_strdup (header->header.arch_linkname));
len = strlen (current_link_name); len = strlen (current_link_name);
if (len > 1 && current_link_name [len - 1] == '/') if (len > 1 && current_link_name[len - 1] == '/')
current_link_name[len - 1] = 0; current_link_name[len - 1] = 0;
current_file_name = (next_long_name current_file_name =
? next_long_name (next_long_name ? next_long_name :
: g_strdup (header->header.arch_name)); g_strdup (header->header.arch_name));
len = strlen (current_file_name); len = strlen (current_file_name);
if (current_file_name[len - 1] == '/') { if (current_file_name[len - 1] == '/') {
current_file_name[len - 1] = 0; current_file_name[len - 1] = 0;
} }
data_position = current_tar_position; data_position = current_tar_position;
p = strrchr (current_file_name, '/'); p = strrchr (current_file_name, '/');
if (p == NULL) { if (p == NULL) {
p = current_file_name; p = current_file_name;
q = current_file_name + len; /* "" */ q = current_file_name + len; /* "" */
} else { } else {
*(p++) = 0; *(p++) = 0;
q = current_file_name; q = current_file_name;
} }
parent = vfs_s_find_inode (me, archive, q, LINK_NO_FOLLOW, FL_MKDIR); parent =
vfs_s_find_inode (me, archive, q, LINK_NO_FOLLOW, FL_MKDIR);
if (parent == NULL) { if (parent == NULL) {
message (1, MSG_ERROR, _("Inconsistent tar archive")); message (1, MSG_ERROR, _("Inconsistent tar archive"));
return STATUS_BADCHECKSUM; return STATUS_BADCHECKSUM;
} }
if (header->header.linkflag == LF_LINK) { if (header->header.linkflag == LF_LINK) {
inode = vfs_s_find_inode (me, archive, current_link_name, LINK_NO_FOLLOW, 0); inode =
vfs_s_find_inode (me, archive, current_link_name,
LINK_NO_FOLLOW, 0);
if (inode == NULL) { if (inode == NULL) {
message (1, MSG_ERROR, _("Inconsistent tar archive")); message (1, MSG_ERROR, _("Inconsistent tar archive"));
} else { } else {
entry = vfs_s_new_entry(me, p, inode); entry = vfs_s_new_entry (me, p, inode);
vfs_s_insert_entry(me, parent, entry); vfs_s_insert_entry (me, parent, entry);
g_free (current_link_name); g_free (current_link_name);
goto done; goto done;
} }
} }
tar_fill_stat (me, &st, header); tar_fill_stat (me, &st, header, *h_size);
inode = vfs_s_new_inode (me, archive, &st); inode = vfs_s_new_inode (me, archive, &st);
inode->data_offset = data_position; inode->data_offset = data_position;
@ -503,11 +506,12 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard)
vfs_s_insert_entry (me, parent, entry); vfs_s_insert_entry (me, parent, entry);
g_free (current_file_name); g_free (current_file_name);
done: done:
next_long_link = next_long_name = NULL; next_long_link = next_long_name = NULL;
if (header->header.isextended) { if (header->header.isextended) {
while (tar_get_next_record (archive, tard)->ext_hdr.isextended); while (tar_get_next_record (archive, tard)->ext_hdr.
isextended);
inode->data_offset = current_tar_position; inode->data_offset = current_tar_position;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -533,15 +537,16 @@ tar_open_archive (struct vfs_class *me, struct vfs_s_super *archive,
return -1; return -1;
for (;;) { for (;;) {
prev_status = status; size_t h_size;
status = tar_read_header (me, archive, tard);
prev_status = status;
status = tar_read_header (me, archive, tard, &h_size);
switch (status) { switch (status) {
case STATUS_SUCCESS: case STATUS_SUCCESS:
tar_skip_n_records (archive, tard, tar_skip_n_records (archive, tard,
(hstat.st_size + RECORDSIZE - (h_size + RECORDSIZE -
1) / RECORDSIZE); 1) / RECORDSIZE);
continue; continue;