1 /* Virtual File System: GNU Tar file system.
2 Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007 Free Software Foundation, Inc.
5 Written by: 1995 Jakub Jelinek
6 Rewritten by: 1998 Pavel Machek
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public License
10 as published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
22 /* Namespace: init_tarfs */
25 #include <sys/types.h>
30 /* major() and minor() macros (among other things) defined here for hpux */
31 #include <sys/mknod.h>
34 #include "../src/global.h"
35 #include "../src/tty.h" /* enable/disable interrupt key */
36 #include "../src/wtools.h" /* message() */
37 #include "../src/main.h" /* print_vfs_message */
39 #include "gc.h" /* vfs_rmstamp */
40 #include "xdirentry.h"
42 static struct vfs_class vfs_tarfs_ops
;
53 * Header block on tape.
55 * I'm going to use traditional DP naming conventions here.
56 * A "block" is a big chunk of stuff that we do I/O on.
57 * A "record" is a piece of info that we care about.
58 * Typically many "record"s fit into a "block".
60 #define RECORDSIZE 512
62 #define PREFIX_SIZE 155
65 #define SPARSE_EXT_HDR 21
66 #define SPARSE_IN_HDR 4
79 char charptr
[RECORDSIZE
];
81 char arch_name
[NAMSIZ
];
89 char arch_linkname
[NAMSIZ
];
95 /* The following bytes of the tar header record were originally unused.
97 Archives following the ustar specification use almost all of those
98 bytes to support pathnames of 256 characters in length.
100 GNU tar archives use the "unused" space to support incremental
101 archives and sparse files. */
103 char prefix
[PREFIX_SIZE
];
104 /* GNU extensions to the ustar (POSIX.1-1988) archive format. */
111 struct sparse sp
[SPARSE_IN_HDR
];
113 char realsize
[12]; /* true size of the sparse file */
117 struct extended_header
{
118 struct sparse sp
[21];
123 /* The checksum field is filled with this while the checksum is computed. */
124 #define CHKBLANKS " " /* 8 blanks, no null */
126 /* The magic field is filled with this if uname and gname are valid. */
127 #define TMAGIC "ustar" /* ustar and a null */
128 #define OLDGNU_MAGIC "ustar " /* 7 chars and a null */
130 /* The linkflag defines the type of file */
131 #define LF_OLDNORMAL '\0' /* Normal disk file, Unix compat */
132 #define LF_NORMAL '0' /* Normal disk file */
133 #define LF_LINK '1' /* Link to previously dumped file */
134 #define LF_SYMLINK '2' /* Symbolic link */
135 #define LF_CHR '3' /* Character special file */
136 #define LF_BLK '4' /* Block special file */
137 #define LF_DIR '5' /* Directory */
138 #define LF_FIFO '6' /* FIFO special file */
139 #define LF_CONTIG '7' /* Contiguous file */
140 #define LF_EXTHDR 'x' /* pax Extended Header */
141 #define LF_GLOBAL_EXTHDR 'g' /* pax Global Extended Header */
142 /* Further link types may be defined later. */
144 /* Note that the standards committee allows only capital A through
145 capital Z for user-defined expansion. This means that defining something
146 as, say '8' is a *bad* idea. */
147 #define LF_DUMPDIR 'D' /* This is a dir entry that contains
148 the names of files that were in
149 the dir at the time the dump
151 #define LF_LONGLINK 'K' /* Identifies the NEXT file on the tape
152 as having a long linkname */
153 #define LF_LONGNAME 'L' /* Identifies the NEXT file on the tape
154 as having a long name. */
155 #define LF_MULTIVOL 'M' /* This is the continuation
156 of a file that began on another
158 #define LF_NAMES 'N' /* For storing filenames that didn't
159 fit in 100 characters */
160 #define LF_SPARSE 'S' /* This is for sparse files */
161 #define LF_VOLHDR 'V' /* This file is a tape/volume header */
162 /* Ignore it on extraction */
165 * Exit codes from the "tar" program
167 #define EX_SUCCESS 0 /* success! */
168 #define EX_ARGSBAD 1 /* invalid args */
169 #define EX_BADFILE 2 /* invalid filename */
170 #define EX_BADARCH 3 /* bad archive */
171 #define EX_SYSTEM 4 /* system gave unexpected error */
172 #define EX_BADVOL 5 /* Special error code means
173 Tape volume doesn't match the one
174 specified on the command line */
176 #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
179 * Quick and dirty octal conversion.
181 * Result is -1 if the field is invalid (all blank, or nonoctal).
183 static long tar_from_oct (int digs
, char *where
)
187 while (isspace ((unsigned char) *where
)) { /* Skip spaces */
190 return -1; /* All blank field */
193 while (digs
> 0 && isodigit (*where
)) { /* Scan till nonoctal */
194 value
= (value
<< 3) | (*where
++ - '0');
198 if (digs
> 0 && *where
&& !isspace ((unsigned char) *where
))
199 return -1; /* Ended on non-space/nul */
204 static void tar_free_archive (struct vfs_class
*me
, struct vfs_s_super
*archive
)
208 if (archive
->u
.arch
.fd
!= -1)
209 mc_close(archive
->u
.arch
.fd
);
212 /* As we open one archive at a time, it is safe to have this static */
213 static int current_tar_position
= 0;
215 /* Returns fd of the open tar file */
217 tar_open_archive_int (struct vfs_class
*me
, const char *name
,
218 struct vfs_s_super
*archive
)
222 struct vfs_s_inode
*root
;
224 result
= mc_open (name
, O_RDONLY
);
226 message (D_ERROR
, MSG_ERROR
, _("Cannot open tar archive\n%s"), name
);
230 archive
->name
= g_strdup (name
);
231 mc_stat (name
, &(archive
->u
.arch
.st
));
232 archive
->u
.arch
.fd
= -1;
233 archive
->u
.arch
.type
= TAR_UNKNOWN
;
235 /* Find out the method to handle this tar file */
236 type
= get_compression_type (result
);
237 mc_lseek (result
, 0, SEEK_SET
);
238 if (type
!= COMPRESSION_NONE
) {
241 s
= g_strconcat (archive
->name
, decompress_extension (type
), (char *) NULL
);
242 result
= mc_open (s
, O_RDONLY
);
244 message (D_ERROR
, MSG_ERROR
, _("Cannot open tar archive\n%s"), s
);
250 archive
->u
.arch
.fd
= result
;
251 mode
= archive
->u
.arch
.st
.st_mode
& 07777;
260 root
= vfs_s_new_inode (me
, archive
, &archive
->u
.arch
.st
);
261 root
->st
.st_mode
= mode
;
262 root
->data_offset
= -1;
264 root
->st
.st_dev
= MEDATA
->rdev
++;
266 archive
->root
= root
;
271 static union record rec_buf
;
273 static union record
*
274 tar_get_next_record (struct vfs_s_super
*archive
, int tard
)
280 n
= mc_read (tard
, rec_buf
.charptr
, RECORDSIZE
);
282 return NULL
; /* An error has occurred */
283 current_tar_position
+= RECORDSIZE
;
287 static void tar_skip_n_records (struct vfs_s_super
*archive
, int tard
, int n
)
291 mc_lseek (tard
, n
* RECORDSIZE
, SEEK_CUR
);
292 current_tar_position
+= n
* RECORDSIZE
;
296 tar_fill_stat (struct vfs_s_super
*archive
, struct stat
*st
, union record
*header
,
299 st
->st_mode
= tar_from_oct (8, header
->header
.mode
);
301 /* Adjust st->st_mode because there are tar-files with
302 * linkflag==LF_SYMLINK and S_ISLNK(mod)==0. I don't
303 * know about the other modes but I think I cause no new
304 * problem when I adjust them, too. -- Norbert.
306 if (header
->header
.linkflag
== LF_DIR
) {
307 st
->st_mode
|= S_IFDIR
;
308 } else if (header
->header
.linkflag
== LF_SYMLINK
) {
309 st
->st_mode
|= S_IFLNK
;
310 } else if (header
->header
.linkflag
== LF_CHR
) {
311 st
->st_mode
|= S_IFCHR
;
312 } else if (header
->header
.linkflag
== LF_BLK
) {
313 st
->st_mode
|= S_IFBLK
;
314 } else if (header
->header
.linkflag
== LF_FIFO
) {
315 st
->st_mode
|= S_IFIFO
;
317 st
->st_mode
|= S_IFREG
;
320 switch (archive
->u
.arch
.type
) {
325 *header
->header
.uname
? vfs_finduid (header
->header
.
326 uname
) : tar_from_oct (8,
331 *header
->header
.gname
? vfs_findgid (header
->header
.
332 gname
) : tar_from_oct (8,
336 switch (header
->header
.linkflag
) {
340 (tar_from_oct (8, header
->header
.devmajor
) << 8) |
341 tar_from_oct (8, header
->header
.devminor
);
344 st
->st_uid
= tar_from_oct (8, header
->header
.uid
);
345 st
->st_gid
= tar_from_oct (8, header
->header
.gid
);
347 st
->st_size
= h_size
;
348 st
->st_mtime
= tar_from_oct (1 + 12, header
->header
.mtime
);
351 if (archive
->u
.arch
.type
== TAR_GNU
) {
352 st
->st_atime
= tar_from_oct (1 + 12,
353 header
->header
.unused
.oldgnu
.atime
);
354 st
->st_ctime
= tar_from_oct (1 + 12,
355 header
->header
.unused
.oldgnu
.ctime
);
367 * Return 1 for success, 0 if the checksum is bad, EOF on eof,
368 * 2 for a record full of zeros (EOF marker).
372 tar_read_header (struct vfs_class
*me
, struct vfs_s_super
*archive
,
373 int tard
, size_t *h_size
)
376 register long sum
, signed_sum
, recsum
;
378 register union record
*header
;
379 static char *next_long_name
= NULL
, *next_long_link
= NULL
;
383 header
= tar_get_next_record (archive
, tard
);
387 recsum
= tar_from_oct (8, header
->header
.chksum
);
392 for (i
= sizeof (*header
); --i
>= 0;) {
394 * We can't use unsigned char here because of old compilers,
401 /* Adjust checksum to count the "chksum" field as blanks. */
402 for (i
= sizeof (header
->header
.chksum
); --i
>= 0;) {
403 sum
-= 0xFF & header
->header
.chksum
[i
];
404 signed_sum
-= (char) header
->header
.chksum
[i
];
406 sum
+= ' ' * sizeof header
->header
.chksum
;
407 signed_sum
+= ' ' * sizeof header
->header
.chksum
;
410 * This is a zeroed record...whole record is 0's except
411 * for the 8 blanks we faked for the checksum field.
414 return STATUS_EOFMARK
;
416 if (sum
!= recsum
&& signed_sum
!= recsum
)
417 return STATUS_BADCHECKSUM
;
420 * Try to determine the archive format.
422 if (archive
->u
.arch
.type
== TAR_UNKNOWN
) {
423 if (!strcmp (header
->header
.magic
, TMAGIC
)) {
424 if (header
->header
.linkflag
== LF_GLOBAL_EXTHDR
)
425 archive
->u
.arch
.type
= TAR_POSIX
;
427 archive
->u
.arch
.type
= TAR_USTAR
;
428 } else if (!strcmp (header
->header
.magic
, OLDGNU_MAGIC
)) {
429 archive
->u
.arch
.type
= TAR_GNU
;
434 * linkflag on BSDI tar (pax) always '\000'
436 if (header
->header
.linkflag
== '\000') {
437 if (header
->header
.arch_name
[NAMSIZ
- 1] != '\0')
440 i
= strlen (header
->header
.arch_name
);
442 if (i
&& header
->header
.arch_name
[i
- 1] == '/')
443 header
->header
.linkflag
= LF_DIR
;
447 * Good record. Decode file size and return.
449 if (header
->header
.linkflag
== LF_LINK
450 || header
->header
.linkflag
== LF_DIR
)
451 *h_size
= 0; /* Links 0 size on tape */
453 *h_size
= tar_from_oct (1 + 12, header
->header
.size
);
456 * Skip over directory snapshot info records that
457 * are stored in incremental tar archives.
459 if (header
->header
.linkflag
== LF_DUMPDIR
) {
460 if (archive
->u
.arch
.type
== TAR_UNKNOWN
)
461 archive
->u
.arch
.type
= TAR_GNU
;
462 return STATUS_SUCCESS
;
466 * Skip over pax extended header and global extended
469 if (header
->header
.linkflag
== LF_EXTHDR
||
470 header
->header
.linkflag
== LF_GLOBAL_EXTHDR
) {
471 if (archive
->u
.arch
.type
== TAR_UNKNOWN
)
472 archive
->u
.arch
.type
= TAR_POSIX
;
473 return STATUS_SUCCESS
;
476 if (header
->header
.linkflag
== LF_LONGNAME
477 || header
->header
.linkflag
== LF_LONGLINK
) {
482 if (archive
->u
.arch
.type
== TAR_UNKNOWN
)
483 archive
->u
.arch
.type
= TAR_GNU
;
485 if (*h_size
> MC_MAXPATHLEN
) {
486 message (D_ERROR
, MSG_ERROR
, _("Inconsistent tar archive"));
487 return STATUS_BADCHECKSUM
;
490 longp
= ((header
->header
.linkflag
== LF_LONGNAME
)
491 ? &next_long_name
: &next_long_link
);
494 bp
= *longp
= g_malloc (*h_size
+ 1);
496 for (size
= *h_size
; size
> 0; size
-= written
) {
497 data
= tar_get_next_record (archive
, tard
)->charptr
;
501 message (D_ERROR
, MSG_ERROR
,
502 _("Unexpected EOF on archive file"));
503 return STATUS_BADCHECKSUM
;
505 written
= RECORDSIZE
;
509 memcpy (bp
, data
, written
);
513 if (bp
- *longp
== MC_MAXPATHLEN
&& bp
[-1] != '\0') {
516 message (D_ERROR
, MSG_ERROR
, _("Inconsistent tar archive"));
517 return STATUS_BADCHECKSUM
;
523 struct vfs_s_entry
*entry
;
524 struct vfs_s_inode
*inode
, *parent
;
528 char *current_file_name
, *current_link_name
;
531 (next_long_link
? next_long_link
:
532 g_strndup (header
->header
.arch_linkname
, NAMSIZ
));
533 len
= strlen (current_link_name
);
534 if (len
> 1 && current_link_name
[len
- 1] == '/')
535 current_link_name
[len
- 1] = 0;
537 current_file_name
= NULL
;
538 switch (archive
->u
.arch
.type
) {
541 /* The ustar archive format supports pathnames of upto 256
542 * characters in length. This is achieved by concatenating
543 * the contents of the `prefix' and `arch_name' fields like
546 * prefix + path_separator + arch_name
548 * If the `prefix' field contains an empty string i.e. its
549 * first characters is '\0' the prefix field is ignored.
551 if (header
->header
.unused
.prefix
[0] != '\0') {
552 char *temp_name
, *temp_prefix
;
554 temp_name
= g_strndup (header
->header
.arch_name
, NAMSIZ
);
555 temp_prefix
= g_strndup (header
->header
.unused
.prefix
,
557 current_file_name
= g_strconcat (temp_prefix
, PATH_SEP_STR
,
558 temp_name
, (char *) NULL
);
560 g_free (temp_prefix
);
564 if (next_long_name
!= NULL
)
565 current_file_name
= next_long_name
;
571 if (current_file_name
== NULL
)
572 current_file_name
= g_strndup (header
->header
.arch_name
, NAMSIZ
);
574 canonicalize_pathname (current_file_name
);
575 len
= strlen (current_file_name
);
577 data_position
= current_tar_position
;
579 p
= strrchr (current_file_name
, '/');
581 p
= current_file_name
;
582 q
= current_file_name
+ len
; /* "" */
585 q
= current_file_name
;
589 vfs_s_find_inode (me
, archive
, q
, LINK_NO_FOLLOW
, FL_MKDIR
);
590 if (parent
== NULL
) {
591 message (D_ERROR
, MSG_ERROR
, _("Inconsistent tar archive"));
592 return STATUS_BADCHECKSUM
;
595 if (header
->header
.linkflag
== LF_LINK
) {
597 vfs_s_find_inode (me
, archive
, current_link_name
,
600 message (D_ERROR
, MSG_ERROR
, _("Inconsistent tar archive"));
602 entry
= vfs_s_new_entry (me
, p
, inode
);
603 vfs_s_insert_entry (me
, parent
, entry
);
604 g_free (current_link_name
);
609 tar_fill_stat (archive
, &st
, header
, *h_size
);
610 inode
= vfs_s_new_inode (me
, archive
, &st
);
612 inode
->data_offset
= data_position
;
613 if (*current_link_name
) {
614 inode
->linkname
= current_link_name
;
615 } else if (current_link_name
!= next_long_link
) {
616 g_free (current_link_name
);
618 entry
= vfs_s_new_entry (me
, p
, inode
);
620 vfs_s_insert_entry (me
, parent
, entry
);
621 g_free (current_file_name
);
624 next_long_link
= next_long_name
= NULL
;
626 if (archive
->u
.arch
.type
== TAR_GNU
&&
627 header
->header
.unused
.oldgnu
.isextended
) {
628 while (tar_get_next_record (archive
, tard
)->ext_hdr
.
630 inode
->data_offset
= current_tar_position
;
632 return STATUS_SUCCESS
;
637 * Main loop for reading an archive.
638 * Returns 0 on success, -1 on error.
641 tar_open_archive (struct vfs_class
*me
, struct vfs_s_super
*archive
,
642 const char *name
, char *op
)
644 /* Initial status at start of archive */
645 ReadStatus status
= STATUS_EOFMARK
;
646 ReadStatus prev_status
;
651 current_tar_position
= 0;
652 /* Open for reading */
653 if ((tard
= tar_open_archive_int (me
, name
, archive
)) == -1)
659 prev_status
= status
;
660 status
= tar_read_header (me
, archive
, tard
, &h_size
);
665 tar_skip_n_records (archive
, tard
,
666 (h_size
+ RECORDSIZE
-
673 * If the previous header was good, tell them
674 * that we are skipping bad ones.
676 case STATUS_BADCHECKSUM
:
677 switch (prev_status
) {
679 /* Error on first record */
681 message (D_ERROR
, MSG_ERROR
,
683 ("Hmm,...\n%s\ndoesn't look like a tar archive."),
687 /* Error after header rec */
689 /* Error after error */
691 case STATUS_BADCHECKSUM
:
698 /* Record of zeroes */
700 status
= prev_status
; /* If error after 0's */
703 case STATUS_EOF
: /* End of archive */
712 tar_super_check (struct vfs_class
*me
, const char *archive_name
, char *op
)
714 static struct stat stat_buf
;
719 if (mc_stat (archive_name
, &stat_buf
))
725 tar_super_same (struct vfs_class
*me
, struct vfs_s_super
*parc
,
726 const char *archive_name
, char *op
, void *cookie
)
728 struct stat
*archive_stat
= cookie
; /* stat of main archive */
733 if (strcmp (parc
->name
, archive_name
))
736 /* Has the cached archive been changed on the disk? */
737 if (parc
->u
.arch
.st
.st_mtime
< archive_stat
->st_mtime
) {
739 (*vfs_tarfs_ops
.free
) ((vfsid
) parc
);
740 vfs_rmstamp (&vfs_tarfs_ops
, (vfsid
) parc
);
743 /* Hasn't been modified, give it a new timeout */
744 vfs_stamp (&vfs_tarfs_ops
, (vfsid
) parc
);
748 static ssize_t
tar_read (void *fh
, char *buffer
, int count
)
750 off_t begin
= FH
->ino
->data_offset
;
751 int fd
= FH_SUPER
->u
.arch
.fd
;
752 struct vfs_class
*me
= FH_SUPER
->me
;
754 if (mc_lseek (fd
, begin
+ FH
->pos
, SEEK_SET
) !=
755 begin
+ FH
->pos
) ERRNOR (EIO
, -1);
757 count
= MIN(count
, FH
->ino
->st
.st_size
- FH
->pos
);
759 if ((count
= mc_read (fd
, buffer
, count
)) == -1) ERRNOR (errno
, -1);
765 static int tar_fh_open (struct vfs_class
*me
, struct vfs_s_fh
*fh
, int flags
, int mode
)
770 if ((flags
& O_ACCMODE
) != O_RDONLY
) ERRNOR (EROFS
, -1);
777 static struct vfs_s_subclass tarfs_subclass
;
779 tarfs_subclass
.flags
= VFS_S_READONLY
;
780 tarfs_subclass
.archive_check
= tar_super_check
;
781 tarfs_subclass
.archive_same
= tar_super_same
;
782 tarfs_subclass
.open_archive
= tar_open_archive
;
783 tarfs_subclass
.free_archive
= tar_free_archive
;
784 tarfs_subclass
.fh_open
= tar_fh_open
;
786 vfs_s_init_class (&vfs_tarfs_ops
, &tarfs_subclass
);
787 vfs_tarfs_ops
.name
= "tarfs";
788 vfs_tarfs_ops
.prefix
= "utar";
789 vfs_tarfs_ops
.read
= tar_read
;
790 vfs_tarfs_ops
.setctl
= NULL
;
791 vfs_register_class (&vfs_tarfs_ops
);