Home | History | Annotate | Line # | Download | only in tar
write.c revision 1.1.1.1
      1  1.1  joerg /*-
      2  1.1  joerg  * Copyright (c) 2003-2007 Tim Kientzle
      3  1.1  joerg  * All rights reserved.
      4  1.1  joerg  *
      5  1.1  joerg  * Redistribution and use in source and binary forms, with or without
      6  1.1  joerg  * modification, are permitted provided that the following conditions
      7  1.1  joerg  * are met:
      8  1.1  joerg  * 1. Redistributions of source code must retain the above copyright
      9  1.1  joerg  *    notice, this list of conditions and the following disclaimer.
     10  1.1  joerg  * 2. Redistributions in binary form must reproduce the above copyright
     11  1.1  joerg  *    notice, this list of conditions and the following disclaimer in the
     12  1.1  joerg  *    documentation and/or other materials provided with the distribution.
     13  1.1  joerg  *
     14  1.1  joerg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     15  1.1  joerg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     16  1.1  joerg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     17  1.1  joerg  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     18  1.1  joerg  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     19  1.1  joerg  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     20  1.1  joerg  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     21  1.1  joerg  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  1.1  joerg  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  1.1  joerg  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  1.1  joerg  */
     25  1.1  joerg 
     26  1.1  joerg #include "bsdtar_platform.h"
     27  1.1  joerg __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.70 2008/05/26 17:10:10 kientzle Exp $");
     28  1.1  joerg 
     29  1.1  joerg #ifdef HAVE_SYS_TYPES_H
     30  1.1  joerg #include <sys/types.h>
     31  1.1  joerg #endif
     32  1.1  joerg #ifdef HAVE_SYS_ACL_H
     33  1.1  joerg #include <sys/acl.h>
     34  1.1  joerg #endif
     35  1.1  joerg #ifdef HAVE_SYS_IOCTL_H
     36  1.1  joerg #include <sys/ioctl.h>
     37  1.1  joerg #endif
     38  1.1  joerg #ifdef HAVE_SYS_STAT_H
     39  1.1  joerg #include <sys/stat.h>
     40  1.1  joerg #endif
     41  1.1  joerg #ifdef HAVE_ATTR_XATTR_H
     42  1.1  joerg #include <attr/xattr.h>
     43  1.1  joerg #endif
     44  1.1  joerg #ifdef HAVE_ERRNO_H
     45  1.1  joerg #include <errno.h>
     46  1.1  joerg #endif
     47  1.1  joerg #ifdef HAVE_EXT2FS_EXT2_FS_H
     48  1.1  joerg #include <ext2fs/ext2_fs.h>
     49  1.1  joerg #endif
     50  1.1  joerg #ifdef HAVE_FCNTL_H
     51  1.1  joerg #include <fcntl.h>
     52  1.1  joerg #endif
     53  1.1  joerg #ifdef HAVE_FNMATCH_H
     54  1.1  joerg #include <fnmatch.h>
     55  1.1  joerg #endif
     56  1.1  joerg #ifdef HAVE_GRP_H
     57  1.1  joerg #include <grp.h>
     58  1.1  joerg #endif
     59  1.1  joerg #ifdef HAVE_LIMITS_H
     60  1.1  joerg #include <limits.h>
     61  1.1  joerg #endif
     62  1.1  joerg #ifdef HAVE_LINUX_FS_H
     63  1.1  joerg #include <linux/fs.h>	/* for Linux file flags */
     64  1.1  joerg #endif
     65  1.1  joerg #ifdef HAVE_PWD_H
     66  1.1  joerg #include <pwd.h>
     67  1.1  joerg #endif
     68  1.1  joerg #include <stdio.h>
     69  1.1  joerg #ifdef HAVE_STDLIB_H
     70  1.1  joerg #include <stdlib.h>
     71  1.1  joerg #endif
     72  1.1  joerg #ifdef HAVE_STRING_H
     73  1.1  joerg #include <string.h>
     74  1.1  joerg #endif
     75  1.1  joerg #ifdef HAVE_UNISTD_H
     76  1.1  joerg #include <unistd.h>
     77  1.1  joerg #endif
     78  1.1  joerg 
     79  1.1  joerg #include "bsdtar.h"
     80  1.1  joerg #include "tree.h"
     81  1.1  joerg 
     82  1.1  joerg /* Fixed size of uname/gname caches. */
     83  1.1  joerg #define	name_cache_size 101
     84  1.1  joerg 
     85  1.1  joerg static const char * const NO_NAME = "(noname)";
     86  1.1  joerg 
     87  1.1  joerg struct archive_dir_entry {
     88  1.1  joerg 	struct archive_dir_entry	*next;
     89  1.1  joerg 	time_t			 mtime_sec;
     90  1.1  joerg 	int			 mtime_nsec;
     91  1.1  joerg 	char			*name;
     92  1.1  joerg };
     93  1.1  joerg 
     94  1.1  joerg struct archive_dir {
     95  1.1  joerg 	struct archive_dir_entry *head, *tail;
     96  1.1  joerg };
     97  1.1  joerg 
     98  1.1  joerg struct name_cache {
     99  1.1  joerg 	int	probes;
    100  1.1  joerg 	int	hits;
    101  1.1  joerg 	size_t	size;
    102  1.1  joerg 	struct {
    103  1.1  joerg 		id_t id;
    104  1.1  joerg 		const char *name;
    105  1.1  joerg 	} cache[name_cache_size];
    106  1.1  joerg };
    107  1.1  joerg 
    108  1.1  joerg static void		 add_dir_list(struct bsdtar *bsdtar, const char *path,
    109  1.1  joerg 			     time_t mtime_sec, int mtime_nsec);
    110  1.1  joerg static int		 append_archive(struct bsdtar *, struct archive *,
    111  1.1  joerg 			     struct archive *ina);
    112  1.1  joerg static int		 append_archive_filename(struct bsdtar *,
    113  1.1  joerg 			     struct archive *, const char *fname);
    114  1.1  joerg static void		 archive_names_from_file(struct bsdtar *bsdtar,
    115  1.1  joerg 			     struct archive *a);
    116  1.1  joerg static int		 archive_names_from_file_helper(struct bsdtar *bsdtar,
    117  1.1  joerg 			     const char *line);
    118  1.1  joerg static int		 copy_file_data(struct bsdtar *bsdtar,
    119  1.1  joerg 			     struct archive *a, struct archive *ina);
    120  1.1  joerg static void		 create_cleanup(struct bsdtar *);
    121  1.1  joerg static void		 free_cache(struct name_cache *cache);
    122  1.1  joerg static const char *	 lookup_gname(struct bsdtar *bsdtar, gid_t gid);
    123  1.1  joerg static int		 lookup_gname_helper(struct bsdtar *bsdtar,
    124  1.1  joerg 			     const char **name, id_t gid);
    125  1.1  joerg static const char *	 lookup_uname(struct bsdtar *bsdtar, uid_t uid);
    126  1.1  joerg static int		 lookup_uname_helper(struct bsdtar *bsdtar,
    127  1.1  joerg 			     const char **name, id_t uid);
    128  1.1  joerg static int		 new_enough(struct bsdtar *, const char *path,
    129  1.1  joerg 			     const struct stat *);
    130  1.1  joerg static void		 setup_acls(struct bsdtar *, struct archive_entry *,
    131  1.1  joerg 			     const char *path);
    132  1.1  joerg static void		 setup_xattrs(struct bsdtar *, struct archive_entry *,
    133  1.1  joerg 			     const char *path);
    134  1.1  joerg static void		 test_for_append(struct bsdtar *);
    135  1.1  joerg static void		 write_archive(struct archive *, struct bsdtar *);
    136  1.1  joerg static void		 write_entry(struct bsdtar *, struct archive *,
    137  1.1  joerg 			     const struct stat *, const char *pathname,
    138  1.1  joerg 			     const char *accpath);
    139  1.1  joerg static void		 write_entry_backend(struct bsdtar *, struct archive *,
    140  1.1  joerg 			     struct archive_entry *, int);
    141  1.1  joerg static int		 write_file_data(struct bsdtar *, struct archive *,
    142  1.1  joerg 			     int fd);
    143  1.1  joerg static void		 write_hierarchy(struct bsdtar *, struct archive *,
    144  1.1  joerg 			     const char *);
    145  1.1  joerg 
    146  1.1  joerg void
    147  1.1  joerg tar_mode_c(struct bsdtar *bsdtar)
    148  1.1  joerg {
    149  1.1  joerg 	struct archive *a;
    150  1.1  joerg 	int r;
    151  1.1  joerg 
    152  1.1  joerg 	if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
    153  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0, "no files or directories specified");
    154  1.1  joerg 
    155  1.1  joerg 	/* We want to catch SIGINFO and SIGUSR1. */
    156  1.1  joerg 	siginfo_init(bsdtar);
    157  1.1  joerg 
    158  1.1  joerg 	a = archive_write_new();
    159  1.1  joerg 
    160  1.1  joerg 	/* Support any format that the library supports. */
    161  1.1  joerg 	if (bsdtar->create_format == NULL) {
    162  1.1  joerg 		r = archive_write_set_format_pax_restricted(a);
    163  1.1  joerg 		bsdtar->create_format = "pax restricted";
    164  1.1  joerg 	} else {
    165  1.1  joerg 		r = archive_write_set_format_by_name(a, bsdtar->create_format);
    166  1.1  joerg 	}
    167  1.1  joerg 	if (r != ARCHIVE_OK) {
    168  1.1  joerg 		fprintf(stderr, "Can't use format %s: %s\n",
    169  1.1  joerg 		    bsdtar->create_format,
    170  1.1  joerg 		    archive_error_string(a));
    171  1.1  joerg 		usage(bsdtar);
    172  1.1  joerg 	}
    173  1.1  joerg 
    174  1.1  joerg 	/*
    175  1.1  joerg 	 * If user explicitly set the block size, then assume they
    176  1.1  joerg 	 * want the last block padded as well.  Otherwise, use the
    177  1.1  joerg 	 * default block size and accept archive_write_open_file()'s
    178  1.1  joerg 	 * default padding decisions.
    179  1.1  joerg 	 */
    180  1.1  joerg 	if (bsdtar->bytes_per_block != 0) {
    181  1.1  joerg 		archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
    182  1.1  joerg 		archive_write_set_bytes_in_last_block(a,
    183  1.1  joerg 		    bsdtar->bytes_per_block);
    184  1.1  joerg 	} else
    185  1.1  joerg 		archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
    186  1.1  joerg 
    187  1.1  joerg 	if (bsdtar->compress_program) {
    188  1.1  joerg 		archive_write_set_compression_program(a, bsdtar->compress_program);
    189  1.1  joerg 	} else {
    190  1.1  joerg 		switch (bsdtar->create_compression) {
    191  1.1  joerg 		case 0:
    192  1.1  joerg 			archive_write_set_compression_none(a);
    193  1.1  joerg 			break;
    194  1.1  joerg #ifdef HAVE_LIBBZ2
    195  1.1  joerg 		case 'j': case 'y':
    196  1.1  joerg 			archive_write_set_compression_bzip2(a);
    197  1.1  joerg 			break;
    198  1.1  joerg #endif
    199  1.1  joerg #ifdef HAVE_LIBZ
    200  1.1  joerg 		case 'z':
    201  1.1  joerg 			archive_write_set_compression_gzip(a);
    202  1.1  joerg 			break;
    203  1.1  joerg #endif
    204  1.1  joerg 		case 'Z':
    205  1.1  joerg 			archive_write_set_compression_compress(a);
    206  1.1  joerg 			break;
    207  1.1  joerg 		default:
    208  1.1  joerg 			bsdtar_errc(bsdtar, 1, 0,
    209  1.1  joerg 			    "Unrecognized compression option -%c",
    210  1.1  joerg 			    bsdtar->create_compression);
    211  1.1  joerg 		}
    212  1.1  joerg 	}
    213  1.1  joerg 
    214  1.1  joerg 	r = archive_write_open_file(a, bsdtar->filename);
    215  1.1  joerg 	if (r != ARCHIVE_OK)
    216  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));
    217  1.1  joerg 
    218  1.1  joerg 	write_archive(a, bsdtar);
    219  1.1  joerg 
    220  1.1  joerg 	if (bsdtar->option_totals) {
    221  1.1  joerg 		fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
    222  1.1  joerg 		    (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
    223  1.1  joerg 	}
    224  1.1  joerg 
    225  1.1  joerg 	archive_write_finish(a);
    226  1.1  joerg 
    227  1.1  joerg 	/* Restore old SIGINFO + SIGUSR1 handlers. */
    228  1.1  joerg 	siginfo_done(bsdtar);
    229  1.1  joerg }
    230  1.1  joerg 
    231  1.1  joerg /*
    232  1.1  joerg  * Same as 'c', except we only support tar or empty formats in
    233  1.1  joerg  * uncompressed files on disk.
    234  1.1  joerg  */
    235  1.1  joerg void
    236  1.1  joerg tar_mode_r(struct bsdtar *bsdtar)
    237  1.1  joerg {
    238  1.1  joerg 	off_t	end_offset;
    239  1.1  joerg 	int	format;
    240  1.1  joerg 	struct archive *a;
    241  1.1  joerg 	struct archive_entry *entry;
    242  1.1  joerg 	int	r;
    243  1.1  joerg 
    244  1.1  joerg 	/* Sanity-test some arguments and the file. */
    245  1.1  joerg 	test_for_append(bsdtar);
    246  1.1  joerg 
    247  1.1  joerg 	/* We want to catch SIGINFO and SIGUSR1. */
    248  1.1  joerg 	siginfo_init(bsdtar);
    249  1.1  joerg 
    250  1.1  joerg 	format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
    251  1.1  joerg 
    252  1.1  joerg 	bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666);
    253  1.1  joerg 	if (bsdtar->fd < 0)
    254  1.1  joerg 		bsdtar_errc(bsdtar, 1, errno,
    255  1.1  joerg 		    "Cannot open %s", bsdtar->filename);
    256  1.1  joerg 
    257  1.1  joerg 	a = archive_read_new();
    258  1.1  joerg 	archive_read_support_compression_all(a);
    259  1.1  joerg 	archive_read_support_format_tar(a);
    260  1.1  joerg 	archive_read_support_format_gnutar(a);
    261  1.1  joerg 	r = archive_read_open_fd(a, bsdtar->fd, 10240);
    262  1.1  joerg 	if (r != ARCHIVE_OK)
    263  1.1  joerg 		bsdtar_errc(bsdtar, 1, archive_errno(a),
    264  1.1  joerg 		    "Can't read archive %s: %s", bsdtar->filename,
    265  1.1  joerg 		    archive_error_string(a));
    266  1.1  joerg 	while (0 == archive_read_next_header(a, &entry)) {
    267  1.1  joerg 		if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
    268  1.1  joerg 			archive_read_finish(a);
    269  1.1  joerg 			close(bsdtar->fd);
    270  1.1  joerg 			bsdtar_errc(bsdtar, 1, 0,
    271  1.1  joerg 			    "Cannot append to compressed archive.");
    272  1.1  joerg 		}
    273  1.1  joerg 		/* Keep going until we hit end-of-archive */
    274  1.1  joerg 		format = archive_format(a);
    275  1.1  joerg 	}
    276  1.1  joerg 
    277  1.1  joerg 	end_offset = archive_read_header_position(a);
    278  1.1  joerg 	archive_read_finish(a);
    279  1.1  joerg 
    280  1.1  joerg 	/* Re-open archive for writing */
    281  1.1  joerg 	a = archive_write_new();
    282  1.1  joerg 	archive_write_set_compression_none(a);
    283  1.1  joerg 	/*
    284  1.1  joerg 	 * Set the format to be used for writing.  To allow people to
    285  1.1  joerg 	 * extend empty files, we need to allow them to specify the format,
    286  1.1  joerg 	 * which opens the possibility that they will specify a format that
    287  1.1  joerg 	 * doesn't match the existing format.  Hence, the following bit
    288  1.1  joerg 	 * of arcane ugliness.
    289  1.1  joerg 	 */
    290  1.1  joerg 
    291  1.1  joerg 	if (bsdtar->create_format != NULL) {
    292  1.1  joerg 		/* If the user requested a format, use that, but ... */
    293  1.1  joerg 		archive_write_set_format_by_name(a,
    294  1.1  joerg 		    bsdtar->create_format);
    295  1.1  joerg 		/* ... complain if it's not compatible. */
    296  1.1  joerg 		format &= ARCHIVE_FORMAT_BASE_MASK;
    297  1.1  joerg 		if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK)
    298  1.1  joerg 		    && format != ARCHIVE_FORMAT_EMPTY) {
    299  1.1  joerg 			bsdtar_errc(bsdtar, 1, 0,
    300  1.1  joerg 			    "Format %s is incompatible with the archive %s.",
    301  1.1  joerg 			    bsdtar->create_format, bsdtar->filename);
    302  1.1  joerg 		}
    303  1.1  joerg 	} else {
    304  1.1  joerg 		/*
    305  1.1  joerg 		 * Just preserve the current format, with a little care
    306  1.1  joerg 		 * for formats that libarchive can't write.
    307  1.1  joerg 		 */
    308  1.1  joerg 		if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
    309  1.1  joerg 			/* TODO: When gtar supports pax, use pax restricted. */
    310  1.1  joerg 			format = ARCHIVE_FORMAT_TAR_USTAR;
    311  1.1  joerg 		if (format == ARCHIVE_FORMAT_EMPTY)
    312  1.1  joerg 			format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
    313  1.1  joerg 		archive_write_set_format(a, format);
    314  1.1  joerg 	}
    315  1.1  joerg 	lseek(bsdtar->fd, end_offset, SEEK_SET); /* XXX check return val XXX */
    316  1.1  joerg 	archive_write_open_fd(a, bsdtar->fd); /* XXX check return val XXX */
    317  1.1  joerg 
    318  1.1  joerg 	write_archive(a, bsdtar); /* XXX check return val XXX */
    319  1.1  joerg 
    320  1.1  joerg 	if (bsdtar->option_totals) {
    321  1.1  joerg 		fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
    322  1.1  joerg 		    (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
    323  1.1  joerg 	}
    324  1.1  joerg 
    325  1.1  joerg 	archive_write_finish(a);
    326  1.1  joerg 	close(bsdtar->fd);
    327  1.1  joerg 	bsdtar->fd = -1;
    328  1.1  joerg }
    329  1.1  joerg 
    330  1.1  joerg void
    331  1.1  joerg tar_mode_u(struct bsdtar *bsdtar)
    332  1.1  joerg {
    333  1.1  joerg 	off_t			 end_offset;
    334  1.1  joerg 	struct archive		*a;
    335  1.1  joerg 	struct archive_entry	*entry;
    336  1.1  joerg 	int			 format;
    337  1.1  joerg 	struct archive_dir_entry	*p;
    338  1.1  joerg 	struct archive_dir	 archive_dir;
    339  1.1  joerg 
    340  1.1  joerg 	bsdtar->archive_dir = &archive_dir;
    341  1.1  joerg 	memset(&archive_dir, 0, sizeof(archive_dir));
    342  1.1  joerg 
    343  1.1  joerg 	format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
    344  1.1  joerg 
    345  1.1  joerg 	/* Sanity-test some arguments and the file. */
    346  1.1  joerg 	test_for_append(bsdtar);
    347  1.1  joerg 
    348  1.1  joerg 	/* We want to catch SIGINFO and SIGUSR1. */
    349  1.1  joerg 	siginfo_init(bsdtar);
    350  1.1  joerg 
    351  1.1  joerg 	bsdtar->fd = open(bsdtar->filename, O_RDWR);
    352  1.1  joerg 	if (bsdtar->fd < 0)
    353  1.1  joerg 		bsdtar_errc(bsdtar, 1, errno,
    354  1.1  joerg 		    "Cannot open %s", bsdtar->filename);
    355  1.1  joerg 
    356  1.1  joerg 	a = archive_read_new();
    357  1.1  joerg 	archive_read_support_compression_all(a);
    358  1.1  joerg 	archive_read_support_format_tar(a);
    359  1.1  joerg 	archive_read_support_format_gnutar(a);
    360  1.1  joerg 	if (archive_read_open_fd(a, bsdtar->fd,
    361  1.1  joerg 	    bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
    362  1.1  joerg 		DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
    363  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0,
    364  1.1  joerg 		    "Can't open %s: %s", bsdtar->filename,
    365  1.1  joerg 		    archive_error_string(a));
    366  1.1  joerg 	}
    367  1.1  joerg 
    368  1.1  joerg 	/* Build a list of all entries and their recorded mod times. */
    369  1.1  joerg 	while (0 == archive_read_next_header(a, &entry)) {
    370  1.1  joerg 		if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
    371  1.1  joerg 			archive_read_finish(a);
    372  1.1  joerg 			close(bsdtar->fd);
    373  1.1  joerg 			bsdtar_errc(bsdtar, 1, 0,
    374  1.1  joerg 			    "Cannot append to compressed archive.");
    375  1.1  joerg 		}
    376  1.1  joerg 		add_dir_list(bsdtar, archive_entry_pathname(entry),
    377  1.1  joerg 		    archive_entry_mtime(entry),
    378  1.1  joerg 		    archive_entry_mtime_nsec(entry));
    379  1.1  joerg 		/* Record the last format determination we see */
    380  1.1  joerg 		format = archive_format(a);
    381  1.1  joerg 		/* Keep going until we hit end-of-archive */
    382  1.1  joerg 	}
    383  1.1  joerg 
    384  1.1  joerg 	end_offset = archive_read_header_position(a);
    385  1.1  joerg 	archive_read_finish(a);
    386  1.1  joerg 
    387  1.1  joerg 	/* Re-open archive for writing. */
    388  1.1  joerg 	a = archive_write_new();
    389  1.1  joerg 	archive_write_set_compression_none(a);
    390  1.1  joerg 	/*
    391  1.1  joerg 	 * Set format to same one auto-detected above, except that
    392  1.1  joerg 	 * we don't write GNU tar format, so use ustar instead.
    393  1.1  joerg 	 */
    394  1.1  joerg 	if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
    395  1.1  joerg 		format = ARCHIVE_FORMAT_TAR_USTAR;
    396  1.1  joerg 	archive_write_set_format(a, format);
    397  1.1  joerg 	if (bsdtar->bytes_per_block != 0) {
    398  1.1  joerg 		archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
    399  1.1  joerg 		archive_write_set_bytes_in_last_block(a,
    400  1.1  joerg 		    bsdtar->bytes_per_block);
    401  1.1  joerg 	} else
    402  1.1  joerg 		archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
    403  1.1  joerg 	lseek(bsdtar->fd, end_offset, SEEK_SET);
    404  1.1  joerg 	ftruncate(bsdtar->fd, end_offset);
    405  1.1  joerg 	archive_write_open_fd(a, bsdtar->fd);
    406  1.1  joerg 
    407  1.1  joerg 	write_archive(a, bsdtar);
    408  1.1  joerg 
    409  1.1  joerg 	if (bsdtar->option_totals) {
    410  1.1  joerg 		fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
    411  1.1  joerg 		    (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
    412  1.1  joerg 	}
    413  1.1  joerg 
    414  1.1  joerg 	archive_write_finish(a);
    415  1.1  joerg 	close(bsdtar->fd);
    416  1.1  joerg 	bsdtar->fd = -1;
    417  1.1  joerg 
    418  1.1  joerg 	while (bsdtar->archive_dir->head != NULL) {
    419  1.1  joerg 		p = bsdtar->archive_dir->head->next;
    420  1.1  joerg 		free(bsdtar->archive_dir->head->name);
    421  1.1  joerg 		free(bsdtar->archive_dir->head);
    422  1.1  joerg 		bsdtar->archive_dir->head = p;
    423  1.1  joerg 	}
    424  1.1  joerg 	bsdtar->archive_dir->tail = NULL;
    425  1.1  joerg }
    426  1.1  joerg 
    427  1.1  joerg 
    428  1.1  joerg /*
    429  1.1  joerg  * Write user-specified files/dirs to opened archive.
    430  1.1  joerg  */
    431  1.1  joerg static void
    432  1.1  joerg write_archive(struct archive *a, struct bsdtar *bsdtar)
    433  1.1  joerg {
    434  1.1  joerg 	const char *arg;
    435  1.1  joerg 	struct archive_entry *entry, *sparse_entry;
    436  1.1  joerg 
    437  1.1  joerg 	if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
    438  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver");
    439  1.1  joerg 	archive_entry_linkresolver_set_strategy(bsdtar->resolver,
    440  1.1  joerg 	    archive_format(a));
    441  1.1  joerg 
    442  1.1  joerg 	if (bsdtar->names_from_file != NULL)
    443  1.1  joerg 		archive_names_from_file(bsdtar, a);
    444  1.1  joerg 
    445  1.1  joerg 	while (*bsdtar->argv) {
    446  1.1  joerg 		arg = *bsdtar->argv;
    447  1.1  joerg 		if (arg[0] == '-' && arg[1] == 'C') {
    448  1.1  joerg 			arg += 2;
    449  1.1  joerg 			if (*arg == '\0') {
    450  1.1  joerg 				bsdtar->argv++;
    451  1.1  joerg 				arg = *bsdtar->argv;
    452  1.1  joerg 				if (arg == NULL) {
    453  1.1  joerg 					bsdtar_warnc(bsdtar, 1, 0,
    454  1.1  joerg 					    "Missing argument for -C");
    455  1.1  joerg 					bsdtar->return_value = 1;
    456  1.1  joerg 					return;
    457  1.1  joerg 				}
    458  1.1  joerg 			}
    459  1.1  joerg 			set_chdir(bsdtar, arg);
    460  1.1  joerg 		} else {
    461  1.1  joerg 			if (*arg != '/' && (arg[0] != '@' || arg[1] != '/'))
    462  1.1  joerg 				do_chdir(bsdtar); /* Handle a deferred -C */
    463  1.1  joerg 			if (*arg == '@') {
    464  1.1  joerg 				if (append_archive_filename(bsdtar, a,
    465  1.1  joerg 				    arg + 1) != 0)
    466  1.1  joerg 					break;
    467  1.1  joerg 			} else
    468  1.1  joerg 				write_hierarchy(bsdtar, a, arg);
    469  1.1  joerg 		}
    470  1.1  joerg 		bsdtar->argv++;
    471  1.1  joerg 	}
    472  1.1  joerg 
    473  1.1  joerg 	entry = NULL;
    474  1.1  joerg 	archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
    475  1.1  joerg 	while (entry != NULL) {
    476  1.1  joerg 		int fd = -1;
    477  1.1  joerg 		write_entry_backend(bsdtar, a, entry, fd);
    478  1.1  joerg 		archive_entry_free(entry);
    479  1.1  joerg 		entry = NULL;
    480  1.1  joerg 		archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
    481  1.1  joerg 	}
    482  1.1  joerg 
    483  1.1  joerg 	create_cleanup(bsdtar);
    484  1.1  joerg 	if (archive_write_close(a)) {
    485  1.1  joerg 		bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
    486  1.1  joerg 		bsdtar->return_value = 1;
    487  1.1  joerg 	}
    488  1.1  joerg }
    489  1.1  joerg 
    490  1.1  joerg /*
    491  1.1  joerg  * Archive names specified in file.
    492  1.1  joerg  *
    493  1.1  joerg  * Unless --null was specified, a line containing exactly "-C" will
    494  1.1  joerg  * cause the next line to be a directory to pass to chdir().  If
    495  1.1  joerg  * --null is specified, then a line "-C" is just another filename.
    496  1.1  joerg  */
    497  1.1  joerg void
    498  1.1  joerg archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
    499  1.1  joerg {
    500  1.1  joerg 	bsdtar->archive = a;
    501  1.1  joerg 
    502  1.1  joerg 	bsdtar->next_line_is_dir = 0;
    503  1.1  joerg 	process_lines(bsdtar, bsdtar->names_from_file,
    504  1.1  joerg 	    archive_names_from_file_helper);
    505  1.1  joerg 	if (bsdtar->next_line_is_dir)
    506  1.1  joerg 		bsdtar_errc(bsdtar, 1, errno,
    507  1.1  joerg 		    "Unexpected end of filename list; "
    508  1.1  joerg 		    "directory expected after -C");
    509  1.1  joerg }
    510  1.1  joerg 
    511  1.1  joerg static int
    512  1.1  joerg archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line)
    513  1.1  joerg {
    514  1.1  joerg 	if (bsdtar->next_line_is_dir) {
    515  1.1  joerg 		set_chdir(bsdtar, line);
    516  1.1  joerg 		bsdtar->next_line_is_dir = 0;
    517  1.1  joerg 	} else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
    518  1.1  joerg 		bsdtar->next_line_is_dir = 1;
    519  1.1  joerg 	else {
    520  1.1  joerg 		if (*line != '/')
    521  1.1  joerg 			do_chdir(bsdtar); /* Handle a deferred -C */
    522  1.1  joerg 		write_hierarchy(bsdtar, bsdtar->archive, line);
    523  1.1  joerg 	}
    524  1.1  joerg 	return (0);
    525  1.1  joerg }
    526  1.1  joerg 
    527  1.1  joerg /*
    528  1.1  joerg  * Copy from specified archive to current archive.  Returns non-zero
    529  1.1  joerg  * for write errors (which force us to terminate the entire archiving
    530  1.1  joerg  * operation).  If there are errors reading the input archive, we set
    531  1.1  joerg  * bsdtar->return_value but return zero, so the overall archiving
    532  1.1  joerg  * operation will complete and return non-zero.
    533  1.1  joerg  */
    534  1.1  joerg static int
    535  1.1  joerg append_archive_filename(struct bsdtar *bsdtar, struct archive *a,
    536  1.1  joerg     const char *filename)
    537  1.1  joerg {
    538  1.1  joerg 	struct archive *ina;
    539  1.1  joerg 	int rc;
    540  1.1  joerg 
    541  1.1  joerg 	if (strcmp(filename, "-") == 0)
    542  1.1  joerg 		filename = NULL; /* Library uses NULL for stdio. */
    543  1.1  joerg 
    544  1.1  joerg 	ina = archive_read_new();
    545  1.1  joerg 	archive_read_support_format_all(ina);
    546  1.1  joerg 	archive_read_support_compression_all(ina);
    547  1.1  joerg 	if (archive_read_open_file(ina, filename, 10240)) {
    548  1.1  joerg 		bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(ina));
    549  1.1  joerg 		bsdtar->return_value = 1;
    550  1.1  joerg 		return (0);
    551  1.1  joerg 	}
    552  1.1  joerg 
    553  1.1  joerg 	rc = append_archive(bsdtar, a, ina);
    554  1.1  joerg 
    555  1.1  joerg 	if (archive_errno(ina)) {
    556  1.1  joerg 		bsdtar_warnc(bsdtar, 0, "Error reading archive %s: %s",
    557  1.1  joerg 		    filename, archive_error_string(ina));
    558  1.1  joerg 		bsdtar->return_value = 1;
    559  1.1  joerg 	}
    560  1.1  joerg 	archive_read_finish(ina);
    561  1.1  joerg 
    562  1.1  joerg 	return (rc);
    563  1.1  joerg }
    564  1.1  joerg 
    565  1.1  joerg static int
    566  1.1  joerg append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
    567  1.1  joerg {
    568  1.1  joerg 	struct archive_entry *in_entry;
    569  1.1  joerg 	int e;
    570  1.1  joerg 
    571  1.1  joerg 	while (0 == archive_read_next_header(ina, &in_entry)) {
    572  1.1  joerg 		if (!new_enough(bsdtar, archive_entry_pathname(in_entry),
    573  1.1  joerg 			archive_entry_stat(in_entry)))
    574  1.1  joerg 			continue;
    575  1.1  joerg 		if (excluded(bsdtar, archive_entry_pathname(in_entry)))
    576  1.1  joerg 			continue;
    577  1.1  joerg 		if (bsdtar->option_interactive &&
    578  1.1  joerg 		    !yes("copy '%s'", archive_entry_pathname(in_entry)))
    579  1.1  joerg 			continue;
    580  1.1  joerg 		if (bsdtar->verbose)
    581  1.1  joerg 			safe_fprintf(stderr, "a %s",
    582  1.1  joerg 			    archive_entry_pathname(in_entry));
    583  1.1  joerg 		siginfo_setinfo(bsdtar, "copying",
    584  1.1  joerg 		    archive_entry_pathname(in_entry),
    585  1.1  joerg 		    archive_entry_size(in_entry));
    586  1.1  joerg 		siginfo_printinfo(bsdtar, 0);
    587  1.1  joerg 
    588  1.1  joerg 		e = archive_write_header(a, in_entry);
    589  1.1  joerg 		if (e != ARCHIVE_OK) {
    590  1.1  joerg 			if (!bsdtar->verbose)
    591  1.1  joerg 				bsdtar_warnc(bsdtar, 0, "%s: %s",
    592  1.1  joerg 				    archive_entry_pathname(in_entry),
    593  1.1  joerg 				    archive_error_string(a));
    594  1.1  joerg 			else
    595  1.1  joerg 				fprintf(stderr, ": %s", archive_error_string(a));
    596  1.1  joerg 		}
    597  1.1  joerg 		if (e == ARCHIVE_FATAL)
    598  1.1  joerg 			exit(1);
    599  1.1  joerg 
    600  1.1  joerg 		if (e >= ARCHIVE_WARN) {
    601  1.1  joerg 			if (archive_entry_size(in_entry) == 0)
    602  1.1  joerg 				archive_read_data_skip(ina);
    603  1.1  joerg 			else if (copy_file_data(bsdtar, a, ina))
    604  1.1  joerg 				exit(1);
    605  1.1  joerg 		}
    606  1.1  joerg 
    607  1.1  joerg 		if (bsdtar->verbose)
    608  1.1  joerg 			fprintf(stderr, "\n");
    609  1.1  joerg 	}
    610  1.1  joerg 
    611  1.1  joerg 	/* Note: If we got here, we saw no write errors, so return success. */
    612  1.1  joerg 	return (0);
    613  1.1  joerg }
    614  1.1  joerg 
    615  1.1  joerg /* Helper function to copy data between archives. */
    616  1.1  joerg static int
    617  1.1  joerg copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
    618  1.1  joerg {
    619  1.1  joerg 	char	buff[64*1024];
    620  1.1  joerg 	ssize_t	bytes_read;
    621  1.1  joerg 	ssize_t	bytes_written;
    622  1.1  joerg 	off_t	progress = 0;
    623  1.1  joerg 
    624  1.1  joerg 	bytes_read = archive_read_data(ina, buff, sizeof(buff));
    625  1.1  joerg 	while (bytes_read > 0) {
    626  1.1  joerg 		siginfo_printinfo(bsdtar, progress);
    627  1.1  joerg 
    628  1.1  joerg 		bytes_written = archive_write_data(a, buff, bytes_read);
    629  1.1  joerg 		if (bytes_written < bytes_read) {
    630  1.1  joerg 			bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
    631  1.1  joerg 			return (-1);
    632  1.1  joerg 		}
    633  1.1  joerg 		progress += bytes_written;
    634  1.1  joerg 		bytes_read = archive_read_data(ina, buff, sizeof(buff));
    635  1.1  joerg 	}
    636  1.1  joerg 
    637  1.1  joerg 	return (0);
    638  1.1  joerg }
    639  1.1  joerg 
    640  1.1  joerg /*
    641  1.1  joerg  * Add the file or dir hierarchy named by 'path' to the archive
    642  1.1  joerg  */
    643  1.1  joerg static void
    644  1.1  joerg write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
    645  1.1  joerg {
    646  1.1  joerg 	struct tree *tree;
    647  1.1  joerg 	char symlink_mode = bsdtar->symlink_mode;
    648  1.1  joerg 	dev_t first_dev = 0;
    649  1.1  joerg 	int dev_recorded = 0;
    650  1.1  joerg 	int tree_ret;
    651  1.1  joerg #ifdef __linux
    652  1.1  joerg 	int	 fd, r;
    653  1.1  joerg 	unsigned long fflags;
    654  1.1  joerg #endif
    655  1.1  joerg 
    656  1.1  joerg 	tree = tree_open(path);
    657  1.1  joerg 
    658  1.1  joerg 	if (!tree) {
    659  1.1  joerg 		bsdtar_warnc(bsdtar, errno, "%s: Cannot open", path);
    660  1.1  joerg 		bsdtar->return_value = 1;
    661  1.1  joerg 		return;
    662  1.1  joerg 	}
    663  1.1  joerg 
    664  1.1  joerg 	while ((tree_ret = tree_next(tree))) {
    665  1.1  joerg 		const char *name = tree_current_path(tree);
    666  1.1  joerg 		const struct stat *st = NULL, *lst = NULL;
    667  1.1  joerg 		int descend;
    668  1.1  joerg 
    669  1.1  joerg 		if (tree_ret == TREE_ERROR_DIR)
    670  1.1  joerg 			bsdtar_warnc(bsdtar, errno, "%s: Couldn't visit directory", name);
    671  1.1  joerg 		if (tree_ret != TREE_REGULAR)
    672  1.1  joerg 			continue;
    673  1.1  joerg 		lst = tree_current_lstat(tree);
    674  1.1  joerg 		if (lst == NULL) {
    675  1.1  joerg 			/* Couldn't lstat(); must not exist. */
    676  1.1  joerg 			bsdtar_warnc(bsdtar, errno, "%s: Cannot stat", name);
    677  1.1  joerg 
    678  1.1  joerg 			/*
    679  1.1  joerg 			 * Report an error via the exit code if the failed
    680  1.1  joerg 			 * path is a prefix of what the user provided via
    681  1.1  joerg 			 * the command line.  (Testing for string equality
    682  1.1  joerg 			 * here won't work due to trailing '/' characters.)
    683  1.1  joerg 			 */
    684  1.1  joerg 			if (memcmp(name, path, strlen(name)) == 0)
    685  1.1  joerg 				bsdtar->return_value = 1;
    686  1.1  joerg 
    687  1.1  joerg 			continue;
    688  1.1  joerg 		}
    689  1.1  joerg 		if (S_ISLNK(lst->st_mode))
    690  1.1  joerg 			st = tree_current_stat(tree);
    691  1.1  joerg 		/* Default: descend into any dir or symlink to dir. */
    692  1.1  joerg 		/* We'll adjust this later on. */
    693  1.1  joerg 		descend = 0;
    694  1.1  joerg 		if ((st != NULL) && S_ISDIR(st->st_mode))
    695  1.1  joerg 			descend = 1;
    696  1.1  joerg 		if ((lst != NULL) && S_ISDIR(lst->st_mode))
    697  1.1  joerg 			descend = 1;
    698  1.1  joerg 
    699  1.1  joerg 		/*
    700  1.1  joerg 		 * If user has asked us not to cross mount points,
    701  1.1  joerg 		 * then don't descend into into a dir on a different
    702  1.1  joerg 		 * device.
    703  1.1  joerg 		 */
    704  1.1  joerg 		if (!dev_recorded) {
    705  1.1  joerg 			first_dev = lst->st_dev;
    706  1.1  joerg 			dev_recorded = 1;
    707  1.1  joerg 		}
    708  1.1  joerg 		if (bsdtar->option_dont_traverse_mounts) {
    709  1.1  joerg 			if (lst != NULL && lst->st_dev != first_dev)
    710  1.1  joerg 				descend = 0;
    711  1.1  joerg 		}
    712  1.1  joerg 
    713  1.1  joerg 		/*
    714  1.1  joerg 		 * If this file/dir is flagged "nodump" and we're
    715  1.1  joerg 		 * honoring such flags, skip this file/dir.
    716  1.1  joerg 		 */
    717  1.1  joerg #ifdef HAVE_CHFLAGS
    718  1.1  joerg 		if (bsdtar->option_honor_nodump &&
    719  1.1  joerg 		    (lst->st_flags & UF_NODUMP))
    720  1.1  joerg 			continue;
    721  1.1  joerg #endif
    722  1.1  joerg 
    723  1.1  joerg #ifdef __linux
    724  1.1  joerg 		/*
    725  1.1  joerg 		 * Linux has a nodump flag too but to read it
    726  1.1  joerg 		 * we have to open() the file/dir and do an ioctl on it...
    727  1.1  joerg 		 */
    728  1.1  joerg 		if (bsdtar->option_honor_nodump &&
    729  1.1  joerg 		    ((fd = open(name, O_RDONLY|O_NONBLOCK)) >= 0) &&
    730  1.1  joerg 		    ((r = ioctl(fd, EXT2_IOC_GETFLAGS, &fflags)),
    731  1.1  joerg 			close(fd), r) >= 0 &&
    732  1.1  joerg 		    (fflags & EXT2_NODUMP_FL))
    733  1.1  joerg 			continue;
    734  1.1  joerg #endif
    735  1.1  joerg 
    736  1.1  joerg 		/*
    737  1.1  joerg 		 * If this file/dir is excluded by a filename
    738  1.1  joerg 		 * pattern, skip it.
    739  1.1  joerg 		 */
    740  1.1  joerg 		if (excluded(bsdtar, name))
    741  1.1  joerg 			continue;
    742  1.1  joerg 
    743  1.1  joerg 		/*
    744  1.1  joerg 		 * If the user vetoes this file/directory, skip it.
    745  1.1  joerg 		 */
    746  1.1  joerg 		if (bsdtar->option_interactive &&
    747  1.1  joerg 		    !yes("add '%s'", name))
    748  1.1  joerg 			continue;
    749  1.1  joerg 
    750  1.1  joerg 		/*
    751  1.1  joerg 		 * If this is a dir, decide whether or not to recurse.
    752  1.1  joerg 		 */
    753  1.1  joerg 		if (bsdtar->option_no_subdirs)
    754  1.1  joerg 			descend = 0;
    755  1.1  joerg 
    756  1.1  joerg 		/*
    757  1.1  joerg 		 * Distinguish 'L'/'P'/'H' symlink following.
    758  1.1  joerg 		 */
    759  1.1  joerg 		switch(symlink_mode) {
    760  1.1  joerg 		case 'H':
    761  1.1  joerg 			/* 'H': After the first item, rest like 'P'. */
    762  1.1  joerg 			symlink_mode = 'P';
    763  1.1  joerg 			/* 'H': First item (from command line) like 'L'. */
    764  1.1  joerg 			/* FALLTHROUGH */
    765  1.1  joerg 		case 'L':
    766  1.1  joerg 			/* 'L': Do descend through a symlink to dir. */
    767  1.1  joerg 			/* 'L': Archive symlink to file as file. */
    768  1.1  joerg 			lst = tree_current_stat(tree);
    769  1.1  joerg 			/* If stat fails, we have a broken symlink;
    770  1.1  joerg 			 * in that case, archive the link as such. */
    771  1.1  joerg 			if (lst == NULL)
    772  1.1  joerg 				lst = tree_current_lstat(tree);
    773  1.1  joerg 			break;
    774  1.1  joerg 		default:
    775  1.1  joerg 			/* 'P': Don't descend through a symlink to dir. */
    776  1.1  joerg 			if (!S_ISDIR(lst->st_mode))
    777  1.1  joerg 				descend = 0;
    778  1.1  joerg 			/* 'P': Archive symlink to file as symlink. */
    779  1.1  joerg 			/* lst = tree_current_lstat(tree); */
    780  1.1  joerg 			break;
    781  1.1  joerg 		}
    782  1.1  joerg 
    783  1.1  joerg 		if (descend)
    784  1.1  joerg 			tree_descend(tree);
    785  1.1  joerg 
    786  1.1  joerg 		/*
    787  1.1  joerg 		 * Write the entry.  Note that write_entry() handles
    788  1.1  joerg 		 * pathname editing and newness testing.
    789  1.1  joerg 		 */
    790  1.1  joerg 		write_entry(bsdtar, a, lst, name,
    791  1.1  joerg 		    tree_current_access_path(tree));
    792  1.1  joerg 	}
    793  1.1  joerg 	tree_close(tree);
    794  1.1  joerg }
    795  1.1  joerg 
    796  1.1  joerg /*
    797  1.1  joerg  * Backend for write_entry.
    798  1.1  joerg  */
    799  1.1  joerg static void
    800  1.1  joerg write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
    801  1.1  joerg     struct archive_entry *entry, int fd)
    802  1.1  joerg {
    803  1.1  joerg 	int e;
    804  1.1  joerg 
    805  1.1  joerg 	if (fd == -1 && archive_entry_size(entry) > 0) {
    806  1.1  joerg 		const char *pathname = archive_entry_sourcepath(entry);
    807  1.1  joerg 		fd = open(pathname, O_RDONLY);
    808  1.1  joerg 		if (fd == -1) {
    809  1.1  joerg 			if (!bsdtar->verbose)
    810  1.1  joerg 				bsdtar_warnc(bsdtar, errno,
    811  1.1  joerg 				    "%s: could not open file", pathname);
    812  1.1  joerg 			else
    813  1.1  joerg 				fprintf(stderr, ": %s", strerror(errno));
    814  1.1  joerg 			return;
    815  1.1  joerg 		}
    816  1.1  joerg 	}
    817  1.1  joerg 
    818  1.1  joerg 	e = archive_write_header(a, entry);
    819  1.1  joerg 	if (e != ARCHIVE_OK) {
    820  1.1  joerg 		if (!bsdtar->verbose)
    821  1.1  joerg 			bsdtar_warnc(bsdtar, 0, "%s: %s",
    822  1.1  joerg 			    archive_entry_pathname(entry),
    823  1.1  joerg 			    archive_error_string(a));
    824  1.1  joerg 		else
    825  1.1  joerg 			fprintf(stderr, ": %s", archive_error_string(a));
    826  1.1  joerg 	}
    827  1.1  joerg 
    828  1.1  joerg 	if (e == ARCHIVE_FATAL)
    829  1.1  joerg 		exit(1);
    830  1.1  joerg 
    831  1.1  joerg 	/*
    832  1.1  joerg 	 * If we opened a file earlier, write it out now.  Note that
    833  1.1  joerg 	 * the format handler might have reset the size field to zero
    834  1.1  joerg 	 * to inform us that the archive body won't get stored.  In
    835  1.1  joerg 	 * that case, just skip the write.
    836  1.1  joerg 	 */
    837  1.1  joerg 	if (e >= ARCHIVE_WARN && fd >= 0 && archive_entry_size(entry) > 0) {
    838  1.1  joerg 		if (write_file_data(bsdtar, a, fd))
    839  1.1  joerg 			exit(1);
    840  1.1  joerg 		close(fd);
    841  1.1  joerg 	}
    842  1.1  joerg }
    843  1.1  joerg 
    844  1.1  joerg /*
    845  1.1  joerg  * Add a single filesystem object to the archive.
    846  1.1  joerg  */
    847  1.1  joerg static void
    848  1.1  joerg write_entry(struct bsdtar *bsdtar, struct archive *a, const struct stat *st,
    849  1.1  joerg     const char *pathname, const char *accpath)
    850  1.1  joerg {
    851  1.1  joerg 	struct archive_entry	*entry, *sparse_entry;
    852  1.1  joerg 	int			fd;
    853  1.1  joerg #ifdef __linux
    854  1.1  joerg 	int			 r;
    855  1.1  joerg 	unsigned long		 stflags;
    856  1.1  joerg #endif
    857  1.1  joerg 	static char		 linkbuffer[PATH_MAX+1];
    858  1.1  joerg 
    859  1.1  joerg 	fd = -1;
    860  1.1  joerg 	entry = archive_entry_new();
    861  1.1  joerg 
    862  1.1  joerg 	archive_entry_set_pathname(entry, pathname);
    863  1.1  joerg 	archive_entry_copy_sourcepath(entry, accpath);
    864  1.1  joerg 
    865  1.1  joerg 	/*
    866  1.1  joerg 	 * Rewrite the pathname to be archived.  If rewrite
    867  1.1  joerg 	 * fails, skip the entry.
    868  1.1  joerg 	 */
    869  1.1  joerg 	if (edit_pathname(bsdtar, entry))
    870  1.1  joerg 		goto abort;
    871  1.1  joerg 
    872  1.1  joerg 	/*
    873  1.1  joerg 	 * In -u mode, check that the file is newer than what's
    874  1.1  joerg 	 * already in the archive; in all modes, obey --newerXXX flags.
    875  1.1  joerg 	 */
    876  1.1  joerg 	if (!new_enough(bsdtar, archive_entry_pathname(entry), st))
    877  1.1  joerg 		goto abort;
    878  1.1  joerg 
    879  1.1  joerg 	/* Display entry as we process it. This format is required by SUSv2. */
    880  1.1  joerg 	if (bsdtar->verbose)
    881  1.1  joerg 		safe_fprintf(stderr, "a %s", archive_entry_pathname(entry));
    882  1.1  joerg 
    883  1.1  joerg 	/* Read symbolic link information. */
    884  1.1  joerg 	if ((st->st_mode & S_IFMT) == S_IFLNK) {
    885  1.1  joerg 		int lnklen;
    886  1.1  joerg 
    887  1.1  joerg 		lnklen = readlink(accpath, linkbuffer, PATH_MAX);
    888  1.1  joerg 		if (lnklen < 0) {
    889  1.1  joerg 			if (!bsdtar->verbose)
    890  1.1  joerg 				bsdtar_warnc(bsdtar, errno,
    891  1.1  joerg 				    "%s: Couldn't read symbolic link",
    892  1.1  joerg 				    pathname);
    893  1.1  joerg 			else
    894  1.1  joerg 				safe_fprintf(stderr,
    895  1.1  joerg 				    ": Couldn't read symbolic link: %s",
    896  1.1  joerg 				    strerror(errno));
    897  1.1  joerg 			goto cleanup;
    898  1.1  joerg 		}
    899  1.1  joerg 		linkbuffer[lnklen] = 0;
    900  1.1  joerg 		archive_entry_set_symlink(entry, linkbuffer);
    901  1.1  joerg 	}
    902  1.1  joerg 
    903  1.1  joerg 	/* Look up username and group name. */
    904  1.1  joerg 	archive_entry_set_uname(entry, lookup_uname(bsdtar, st->st_uid));
    905  1.1  joerg 	archive_entry_set_gname(entry, lookup_gname(bsdtar, st->st_gid));
    906  1.1  joerg 
    907  1.1  joerg #ifdef HAVE_CHFLAGS
    908  1.1  joerg 	if (st->st_flags != 0)
    909  1.1  joerg 		archive_entry_set_fflags(entry, st->st_flags, 0);
    910  1.1  joerg #endif
    911  1.1  joerg 
    912  1.1  joerg #ifdef __linux
    913  1.1  joerg 	if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) &&
    914  1.1  joerg 	    ((fd = open(accpath, O_RDONLY|O_NONBLOCK)) >= 0) &&
    915  1.1  joerg 	    ((r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags)), close(fd), (fd = -1), r) >= 0 &&
    916  1.1  joerg 	    stflags) {
    917  1.1  joerg 		archive_entry_set_fflags(entry, stflags, 0);
    918  1.1  joerg 	}
    919  1.1  joerg #endif
    920  1.1  joerg 
    921  1.1  joerg 	archive_entry_copy_stat(entry, st);
    922  1.1  joerg 	setup_acls(bsdtar, entry, accpath);
    923  1.1  joerg 	setup_xattrs(bsdtar, entry, accpath);
    924  1.1  joerg 
    925  1.1  joerg 	/* Non-regular files get archived with zero size. */
    926  1.1  joerg 	if (!S_ISREG(st->st_mode))
    927  1.1  joerg 		archive_entry_set_size(entry, 0);
    928  1.1  joerg 
    929  1.1  joerg 	/* Record what we're doing, for the benefit of SIGINFO / SIGUSR1. */
    930  1.1  joerg 	siginfo_setinfo(bsdtar, "adding", archive_entry_pathname(entry),
    931  1.1  joerg 	    archive_entry_size(entry));
    932  1.1  joerg 	archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
    933  1.1  joerg 
    934  1.1  joerg 	/* Handle SIGINFO / SIGUSR1 request if one was made. */
    935  1.1  joerg 	siginfo_printinfo(bsdtar, 0);
    936  1.1  joerg 
    937  1.1  joerg 	while (entry != NULL) {
    938  1.1  joerg 		write_entry_backend(bsdtar, a, entry, fd);
    939  1.1  joerg 		fd = -1;
    940  1.1  joerg 		archive_entry_free(entry);
    941  1.1  joerg 		entry = sparse_entry;
    942  1.1  joerg 		sparse_entry = NULL;
    943  1.1  joerg 	}
    944  1.1  joerg 
    945  1.1  joerg cleanup:
    946  1.1  joerg 	if (bsdtar->verbose)
    947  1.1  joerg 		fprintf(stderr, "\n");
    948  1.1  joerg 
    949  1.1  joerg abort:
    950  1.1  joerg 	if (fd >= 0)
    951  1.1  joerg 		close(fd);
    952  1.1  joerg 
    953  1.1  joerg 	archive_entry_free(entry);
    954  1.1  joerg }
    955  1.1  joerg 
    956  1.1  joerg 
    957  1.1  joerg /* Helper function to copy file to archive, with stack-allocated buffer. */
    958  1.1  joerg static int
    959  1.1  joerg write_file_data(struct bsdtar *bsdtar, struct archive *a, int fd)
    960  1.1  joerg {
    961  1.1  joerg 	char	buff[64*1024];
    962  1.1  joerg 	ssize_t	bytes_read;
    963  1.1  joerg 	ssize_t	bytes_written;
    964  1.1  joerg 	off_t	progress = 0;
    965  1.1  joerg 
    966  1.1  joerg 	/* XXX TODO: Allocate buffer on heap and store pointer to
    967  1.1  joerg 	 * it in bsdtar structure; arrange cleanup as well. XXX */
    968  1.1  joerg 
    969  1.1  joerg 	bytes_read = read(fd, buff, sizeof(buff));
    970  1.1  joerg 	while (bytes_read > 0) {
    971  1.1  joerg 		siginfo_printinfo(bsdtar, progress);
    972  1.1  joerg 
    973  1.1  joerg 		bytes_written = archive_write_data(a, buff, bytes_read);
    974  1.1  joerg 		if (bytes_written < 0) {
    975  1.1  joerg 			/* Write failed; this is bad */
    976  1.1  joerg 			bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
    977  1.1  joerg 			return (-1);
    978  1.1  joerg 		}
    979  1.1  joerg 		if (bytes_written < bytes_read) {
    980  1.1  joerg 			/* Write was truncated; warn but continue. */
    981  1.1  joerg 			bsdtar_warnc(bsdtar, 0,
    982  1.1  joerg 			    "Truncated write; file may have grown while being archived.");
    983  1.1  joerg 			return (0);
    984  1.1  joerg 		}
    985  1.1  joerg 		progress += bytes_written;
    986  1.1  joerg 		bytes_read = read(fd, buff, sizeof(buff));
    987  1.1  joerg 	}
    988  1.1  joerg 	return 0;
    989  1.1  joerg }
    990  1.1  joerg 
    991  1.1  joerg 
    992  1.1  joerg static void
    993  1.1  joerg create_cleanup(struct bsdtar *bsdtar)
    994  1.1  joerg {
    995  1.1  joerg 	free_cache(bsdtar->uname_cache);
    996  1.1  joerg 	bsdtar->uname_cache = NULL;
    997  1.1  joerg 	free_cache(bsdtar->gname_cache);
    998  1.1  joerg 	bsdtar->gname_cache = NULL;
    999  1.1  joerg }
   1000  1.1  joerg 
   1001  1.1  joerg #ifdef HAVE_POSIX_ACL
   1002  1.1  joerg static void		setup_acl(struct bsdtar *bsdtar,
   1003  1.1  joerg 			     struct archive_entry *entry, const char *accpath,
   1004  1.1  joerg 			     int acl_type, int archive_entry_acl_type);
   1005  1.1  joerg 
   1006  1.1  joerg static void
   1007  1.1  joerg setup_acls(struct bsdtar *bsdtar, struct archive_entry *entry,
   1008  1.1  joerg     const char *accpath)
   1009  1.1  joerg {
   1010  1.1  joerg 	archive_entry_acl_clear(entry);
   1011  1.1  joerg 
   1012  1.1  joerg 	setup_acl(bsdtar, entry, accpath,
   1013  1.1  joerg 	    ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
   1014  1.1  joerg 	/* Only directories can have default ACLs. */
   1015  1.1  joerg 	if (S_ISDIR(archive_entry_mode(entry)))
   1016  1.1  joerg 		setup_acl(bsdtar, entry, accpath,
   1017  1.1  joerg 		    ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
   1018  1.1  joerg }
   1019  1.1  joerg 
   1020  1.1  joerg static void
   1021  1.1  joerg setup_acl(struct bsdtar *bsdtar, struct archive_entry *entry,
   1022  1.1  joerg     const char *accpath, int acl_type, int archive_entry_acl_type)
   1023  1.1  joerg {
   1024  1.1  joerg 	acl_t		 acl;
   1025  1.1  joerg 	acl_tag_t	 acl_tag;
   1026  1.1  joerg 	acl_entry_t	 acl_entry;
   1027  1.1  joerg 	acl_permset_t	 acl_permset;
   1028  1.1  joerg 	int		 s, ae_id, ae_tag, ae_perm;
   1029  1.1  joerg 	const char	*ae_name;
   1030  1.1  joerg 
   1031  1.1  joerg 	/* Retrieve access ACL from file. */
   1032  1.1  joerg 	acl = acl_get_file(accpath, acl_type);
   1033  1.1  joerg 	if (acl != NULL) {
   1034  1.1  joerg 		s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
   1035  1.1  joerg 		while (s == 1) {
   1036  1.1  joerg 			ae_id = -1;
   1037  1.1  joerg 			ae_name = NULL;
   1038  1.1  joerg 
   1039  1.1  joerg 			acl_get_tag_type(acl_entry, &acl_tag);
   1040  1.1  joerg 			if (acl_tag == ACL_USER) {
   1041  1.1  joerg 				ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
   1042  1.1  joerg 				ae_name = lookup_uname(bsdtar, ae_id);
   1043  1.1  joerg 				ae_tag = ARCHIVE_ENTRY_ACL_USER;
   1044  1.1  joerg 			} else if (acl_tag == ACL_GROUP) {
   1045  1.1  joerg 				ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
   1046  1.1  joerg 				ae_name = lookup_gname(bsdtar, ae_id);
   1047  1.1  joerg 				ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
   1048  1.1  joerg 			} else if (acl_tag == ACL_MASK) {
   1049  1.1  joerg 				ae_tag = ARCHIVE_ENTRY_ACL_MASK;
   1050  1.1  joerg 			} else if (acl_tag == ACL_USER_OBJ) {
   1051  1.1  joerg 				ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
   1052  1.1  joerg 			} else if (acl_tag == ACL_GROUP_OBJ) {
   1053  1.1  joerg 				ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
   1054  1.1  joerg 			} else if (acl_tag == ACL_OTHER) {
   1055  1.1  joerg 				ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
   1056  1.1  joerg 			} else {
   1057  1.1  joerg 				/* Skip types that libarchive can't support. */
   1058  1.1  joerg 				continue;
   1059  1.1  joerg 			}
   1060  1.1  joerg 
   1061  1.1  joerg 			acl_get_permset(acl_entry, &acl_permset);
   1062  1.1  joerg 			ae_perm = 0;
   1063  1.1  joerg 			/*
   1064  1.1  joerg 			 * acl_get_perm() is spelled differently on different
   1065  1.1  joerg 			 * platforms; see bsdtar_platform.h for details.
   1066  1.1  joerg 			 */
   1067  1.1  joerg 			if (ACL_GET_PERM(acl_permset, ACL_EXECUTE))
   1068  1.1  joerg 				ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
   1069  1.1  joerg 			if (ACL_GET_PERM(acl_permset, ACL_READ))
   1070  1.1  joerg 				ae_perm |= ARCHIVE_ENTRY_ACL_READ;
   1071  1.1  joerg 			if (ACL_GET_PERM(acl_permset, ACL_WRITE))
   1072  1.1  joerg 				ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
   1073  1.1  joerg 
   1074  1.1  joerg 			archive_entry_acl_add_entry(entry,
   1075  1.1  joerg 			    archive_entry_acl_type, ae_perm, ae_tag,
   1076  1.1  joerg 			    ae_id, ae_name);
   1077  1.1  joerg 
   1078  1.1  joerg 			s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
   1079  1.1  joerg 		}
   1080  1.1  joerg 		acl_free(acl);
   1081  1.1  joerg 	}
   1082  1.1  joerg }
   1083  1.1  joerg #else
   1084  1.1  joerg static void
   1085  1.1  joerg setup_acls(struct bsdtar *bsdtar, struct archive_entry *entry,
   1086  1.1  joerg     const char *accpath)
   1087  1.1  joerg {
   1088  1.1  joerg 	(void)bsdtar;
   1089  1.1  joerg 	(void)entry;
   1090  1.1  joerg 	(void)accpath;
   1091  1.1  joerg }
   1092  1.1  joerg #endif
   1093  1.1  joerg 
   1094  1.1  joerg #if HAVE_LISTXATTR && HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR
   1095  1.1  joerg 
   1096  1.1  joerg static void
   1097  1.1  joerg setup_xattr(struct bsdtar *bsdtar, struct archive_entry *entry,
   1098  1.1  joerg     const char *accpath, const char *name)
   1099  1.1  joerg {
   1100  1.1  joerg 	size_t size;
   1101  1.1  joerg 	void *value = NULL;
   1102  1.1  joerg 	char symlink_mode = bsdtar->symlink_mode;
   1103  1.1  joerg 
   1104  1.1  joerg 	if (symlink_mode == 'H')
   1105  1.1  joerg 		size = getxattr(accpath, name, NULL, 0);
   1106  1.1  joerg 	else
   1107  1.1  joerg 		size = lgetxattr(accpath, name, NULL, 0);
   1108  1.1  joerg 
   1109  1.1  joerg 	if (size == -1) {
   1110  1.1  joerg 		bsdtar_warnc(bsdtar, errno, "Couldn't get extended attribute");
   1111  1.1  joerg 		return;
   1112  1.1  joerg 	}
   1113  1.1  joerg 
   1114  1.1  joerg 	if (size > 0 && (value = malloc(size)) == NULL) {
   1115  1.1  joerg 		bsdtar_errc(bsdtar, 1, errno, "Out of memory");
   1116  1.1  joerg 		return;
   1117  1.1  joerg 	}
   1118  1.1  joerg 
   1119  1.1  joerg 	if (symlink_mode == 'H')
   1120  1.1  joerg 		size = getxattr(accpath, name, value, size);
   1121  1.1  joerg 	else
   1122  1.1  joerg 		size = lgetxattr(accpath, name, value, size);
   1123  1.1  joerg 
   1124  1.1  joerg 	if (size == -1) {
   1125  1.1  joerg 		bsdtar_warnc(bsdtar, errno, "Couldn't get extended attribute");
   1126  1.1  joerg 		return;
   1127  1.1  joerg 	}
   1128  1.1  joerg 
   1129  1.1  joerg 	archive_entry_xattr_add_entry(entry, name, value, size);
   1130  1.1  joerg 
   1131  1.1  joerg 	free(value);
   1132  1.1  joerg }
   1133  1.1  joerg 
   1134  1.1  joerg /*
   1135  1.1  joerg  * Linux extended attribute support
   1136  1.1  joerg  */
   1137  1.1  joerg static void
   1138  1.1  joerg setup_xattrs(struct bsdtar *bsdtar, struct archive_entry *entry,
   1139  1.1  joerg     const char *accpath)
   1140  1.1  joerg {
   1141  1.1  joerg 	char *list, *p;
   1142  1.1  joerg 	size_t list_size;
   1143  1.1  joerg 	char symlink_mode = bsdtar->symlink_mode;
   1144  1.1  joerg 
   1145  1.1  joerg 	if (symlink_mode == 'H')
   1146  1.1  joerg 		list_size = listxattr(accpath, NULL, 0);
   1147  1.1  joerg 	else
   1148  1.1  joerg 		list_size = llistxattr(accpath, NULL, 0);
   1149  1.1  joerg 
   1150  1.1  joerg 	if (list_size == -1) {
   1151  1.1  joerg 		bsdtar_warnc(bsdtar, errno,
   1152  1.1  joerg 			"Couldn't list extended attributes");
   1153  1.1  joerg 		return;
   1154  1.1  joerg 	} else if (list_size == 0)
   1155  1.1  joerg 		return;
   1156  1.1  joerg 
   1157  1.1  joerg 	if ((list = malloc(list_size)) == NULL) {
   1158  1.1  joerg 		bsdtar_errc(bsdtar, 1, errno, "Out of memory");
   1159  1.1  joerg 		return;
   1160  1.1  joerg 	}
   1161  1.1  joerg 
   1162  1.1  joerg 	if (symlink_mode == 'H')
   1163  1.1  joerg 		list_size = listxattr(accpath, list, list_size);
   1164  1.1  joerg 	else
   1165  1.1  joerg 		list_size = llistxattr(accpath, list, list_size);
   1166  1.1  joerg 
   1167  1.1  joerg 	if (list_size == -1) {
   1168  1.1  joerg 		bsdtar_warnc(bsdtar, errno,
   1169  1.1  joerg 			"Couldn't list extended attributes");
   1170  1.1  joerg 		free(list);
   1171  1.1  joerg 		return;
   1172  1.1  joerg 	}
   1173  1.1  joerg 
   1174  1.1  joerg 	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
   1175  1.1  joerg 		if (strncmp(p, "system.", 7) == 0 ||
   1176  1.1  joerg 				strncmp(p, "xfsroot.", 8) == 0)
   1177  1.1  joerg 			continue;
   1178  1.1  joerg 
   1179  1.1  joerg 		setup_xattr(bsdtar, entry, accpath, p);
   1180  1.1  joerg 	}
   1181  1.1  joerg 
   1182  1.1  joerg 	free(list);
   1183  1.1  joerg }
   1184  1.1  joerg 
   1185  1.1  joerg #else
   1186  1.1  joerg 
   1187  1.1  joerg /*
   1188  1.1  joerg  * Generic (stub) extended attribute support.
   1189  1.1  joerg  */
   1190  1.1  joerg static void
   1191  1.1  joerg setup_xattrs(struct bsdtar *bsdtar, struct archive_entry *entry,
   1192  1.1  joerg     const char *accpath)
   1193  1.1  joerg {
   1194  1.1  joerg 	(void)bsdtar; /* UNUSED */
   1195  1.1  joerg 	(void)entry; /* UNUSED */
   1196  1.1  joerg 	(void)accpath; /* UNUSED */
   1197  1.1  joerg }
   1198  1.1  joerg 
   1199  1.1  joerg #endif
   1200  1.1  joerg 
   1201  1.1  joerg static void
   1202  1.1  joerg free_cache(struct name_cache *cache)
   1203  1.1  joerg {
   1204  1.1  joerg 	size_t i;
   1205  1.1  joerg 
   1206  1.1  joerg 	if (cache != NULL) {
   1207  1.1  joerg 		for (i = 0; i < cache->size; i++) {
   1208  1.1  joerg 			if (cache->cache[i].name != NULL &&
   1209  1.1  joerg 			    cache->cache[i].name != NO_NAME)
   1210  1.1  joerg 				free((void *)(uintptr_t)cache->cache[i].name);
   1211  1.1  joerg 		}
   1212  1.1  joerg 		free(cache);
   1213  1.1  joerg 	}
   1214  1.1  joerg }
   1215  1.1  joerg 
   1216  1.1  joerg /*
   1217  1.1  joerg  * Lookup uid/gid from uname/gname, return NULL if no match.
   1218  1.1  joerg  */
   1219  1.1  joerg static const char *
   1220  1.1  joerg lookup_name(struct bsdtar *bsdtar, struct name_cache **name_cache_variable,
   1221  1.1  joerg     int (*lookup_fn)(struct bsdtar *, const char **, id_t), id_t id)
   1222  1.1  joerg {
   1223  1.1  joerg 	struct name_cache	*cache;
   1224  1.1  joerg 	const char *name;
   1225  1.1  joerg 	int slot;
   1226  1.1  joerg 
   1227  1.1  joerg 
   1228  1.1  joerg 	if (*name_cache_variable == NULL) {
   1229  1.1  joerg 		*name_cache_variable = malloc(sizeof(struct name_cache));
   1230  1.1  joerg 		if (*name_cache_variable == NULL)
   1231  1.1  joerg 			bsdtar_errc(bsdtar, 1, ENOMEM, "No more memory");
   1232  1.1  joerg 		memset(*name_cache_variable, 0, sizeof(struct name_cache));
   1233  1.1  joerg 		(*name_cache_variable)->size = name_cache_size;
   1234  1.1  joerg 	}
   1235  1.1  joerg 
   1236  1.1  joerg 	cache = *name_cache_variable;
   1237  1.1  joerg 	cache->probes++;
   1238  1.1  joerg 
   1239  1.1  joerg 	slot = id % cache->size;
   1240  1.1  joerg 	if (cache->cache[slot].name != NULL) {
   1241  1.1  joerg 		if (cache->cache[slot].id == id) {
   1242  1.1  joerg 			cache->hits++;
   1243  1.1  joerg 			if (cache->cache[slot].name == NO_NAME)
   1244  1.1  joerg 				return (NULL);
   1245  1.1  joerg 			return (cache->cache[slot].name);
   1246  1.1  joerg 		}
   1247  1.1  joerg 		if (cache->cache[slot].name != NO_NAME)
   1248  1.1  joerg 			free((void *)(uintptr_t)cache->cache[slot].name);
   1249  1.1  joerg 		cache->cache[slot].name = NULL;
   1250  1.1  joerg 	}
   1251  1.1  joerg 
   1252  1.1  joerg 	if (lookup_fn(bsdtar, &name, id) == 0) {
   1253  1.1  joerg 		if (name == NULL || name[0] == '\0') {
   1254  1.1  joerg 			/* Cache the negative response. */
   1255  1.1  joerg 			cache->cache[slot].name = NO_NAME;
   1256  1.1  joerg 			cache->cache[slot].id = id;
   1257  1.1  joerg 		} else {
   1258  1.1  joerg 			cache->cache[slot].name = strdup(name);
   1259  1.1  joerg 			if (cache->cache[slot].name != NULL) {
   1260  1.1  joerg 				cache->cache[slot].id = id;
   1261  1.1  joerg 				return (cache->cache[slot].name);
   1262  1.1  joerg 			}
   1263  1.1  joerg 			/*
   1264  1.1  joerg 			 * Conveniently, NULL marks an empty slot, so
   1265  1.1  joerg 			 * if the strdup() fails, we've just failed to
   1266  1.1  joerg 			 * cache it.  No recovery necessary.
   1267  1.1  joerg 			 */
   1268  1.1  joerg 		}
   1269  1.1  joerg 	}
   1270  1.1  joerg 	return (NULL);
   1271  1.1  joerg }
   1272  1.1  joerg 
   1273  1.1  joerg static const char *
   1274  1.1  joerg lookup_uname(struct bsdtar *bsdtar, uid_t uid)
   1275  1.1  joerg {
   1276  1.1  joerg 	return (lookup_name(bsdtar, &bsdtar->uname_cache,
   1277  1.1  joerg 		    &lookup_uname_helper, (id_t)uid));
   1278  1.1  joerg }
   1279  1.1  joerg 
   1280  1.1  joerg static int
   1281  1.1  joerg lookup_uname_helper(struct bsdtar *bsdtar, const char **name, id_t id)
   1282  1.1  joerg {
   1283  1.1  joerg 	struct passwd	*pwent;
   1284  1.1  joerg 
   1285  1.1  joerg 	(void)bsdtar; /* UNUSED */
   1286  1.1  joerg 
   1287  1.1  joerg 	errno = 0;
   1288  1.1  joerg 	pwent = getpwuid((uid_t)id);
   1289  1.1  joerg 	if (pwent == NULL) {
   1290  1.1  joerg 		*name = NULL;
   1291  1.1  joerg 		if (errno != 0)
   1292  1.1  joerg 			bsdtar_warnc(bsdtar, errno, "getpwuid(%d) failed", id);
   1293  1.1  joerg 		return (errno);
   1294  1.1  joerg 	}
   1295  1.1  joerg 
   1296  1.1  joerg 	*name = pwent->pw_name;
   1297  1.1  joerg 	return (0);
   1298  1.1  joerg }
   1299  1.1  joerg 
   1300  1.1  joerg static const char *
   1301  1.1  joerg lookup_gname(struct bsdtar *bsdtar, gid_t gid)
   1302  1.1  joerg {
   1303  1.1  joerg 	return (lookup_name(bsdtar, &bsdtar->gname_cache,
   1304  1.1  joerg 		    &lookup_gname_helper, (id_t)gid));
   1305  1.1  joerg }
   1306  1.1  joerg 
   1307  1.1  joerg static int
   1308  1.1  joerg lookup_gname_helper(struct bsdtar *bsdtar, const char **name, id_t id)
   1309  1.1  joerg {
   1310  1.1  joerg 	struct group	*grent;
   1311  1.1  joerg 
   1312  1.1  joerg 	(void)bsdtar; /* UNUSED */
   1313  1.1  joerg 
   1314  1.1  joerg 	errno = 0;
   1315  1.1  joerg 	grent = getgrgid((gid_t)id);
   1316  1.1  joerg 	if (grent == NULL) {
   1317  1.1  joerg 		*name = NULL;
   1318  1.1  joerg 		if (errno != 0)
   1319  1.1  joerg 			bsdtar_warnc(bsdtar, errno, "getgrgid(%d) failed", id);
   1320  1.1  joerg 		return (errno);
   1321  1.1  joerg 	}
   1322  1.1  joerg 
   1323  1.1  joerg 	*name = grent->gr_name;
   1324  1.1  joerg 	return (0);
   1325  1.1  joerg }
   1326  1.1  joerg 
   1327  1.1  joerg /*
   1328  1.1  joerg  * Test if the specified file is new enough to include in the archive.
   1329  1.1  joerg  */
   1330  1.1  joerg int
   1331  1.1  joerg new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st)
   1332  1.1  joerg {
   1333  1.1  joerg 	struct archive_dir_entry *p;
   1334  1.1  joerg 
   1335  1.1  joerg 	/*
   1336  1.1  joerg 	 * If this file/dir is excluded by a time comparison, skip it.
   1337  1.1  joerg 	 */
   1338  1.1  joerg 	if (bsdtar->newer_ctime_sec > 0) {
   1339  1.1  joerg 		if (st->st_ctime < bsdtar->newer_ctime_sec)
   1340  1.1  joerg 			return (0); /* Too old, skip it. */
   1341  1.1  joerg 		if (st->st_ctime == bsdtar->newer_ctime_sec
   1342  1.1  joerg 		    && ARCHIVE_STAT_CTIME_NANOS(st)
   1343  1.1  joerg 		    <= bsdtar->newer_ctime_nsec)
   1344  1.1  joerg 			return (0); /* Too old, skip it. */
   1345  1.1  joerg 	}
   1346  1.1  joerg 	if (bsdtar->newer_mtime_sec > 0) {
   1347  1.1  joerg 		if (st->st_mtime < bsdtar->newer_mtime_sec)
   1348  1.1  joerg 			return (0); /* Too old, skip it. */
   1349  1.1  joerg 		if (st->st_mtime == bsdtar->newer_mtime_sec
   1350  1.1  joerg 		    && ARCHIVE_STAT_MTIME_NANOS(st)
   1351  1.1  joerg 		    <= bsdtar->newer_mtime_nsec)
   1352  1.1  joerg 			return (0); /* Too old, skip it. */
   1353  1.1  joerg 	}
   1354  1.1  joerg 
   1355  1.1  joerg 	/*
   1356  1.1  joerg 	 * In -u mode, we only write an entry if it's newer than
   1357  1.1  joerg 	 * what was already in the archive.
   1358  1.1  joerg 	 */
   1359  1.1  joerg 	if (bsdtar->archive_dir != NULL &&
   1360  1.1  joerg 	    bsdtar->archive_dir->head != NULL) {
   1361  1.1  joerg 		for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) {
   1362  1.1  joerg 			if (pathcmp(path, p->name)==0)
   1363  1.1  joerg 				return (p->mtime_sec < st->st_mtime ||
   1364  1.1  joerg 				    (p->mtime_sec == st->st_mtime &&
   1365  1.1  joerg 					p->mtime_nsec
   1366  1.1  joerg 					< ARCHIVE_STAT_MTIME_NANOS(st)));
   1367  1.1  joerg 		}
   1368  1.1  joerg 	}
   1369  1.1  joerg 
   1370  1.1  joerg 	/* If the file wasn't rejected, include it. */
   1371  1.1  joerg 	return (1);
   1372  1.1  joerg }
   1373  1.1  joerg 
   1374  1.1  joerg /*
   1375  1.1  joerg  * Add an entry to the dir list for 'u' mode.
   1376  1.1  joerg  *
   1377  1.1  joerg  * XXX TODO: Make this fast.
   1378  1.1  joerg  */
   1379  1.1  joerg static void
   1380  1.1  joerg add_dir_list(struct bsdtar *bsdtar, const char *path,
   1381  1.1  joerg     time_t mtime_sec, int mtime_nsec)
   1382  1.1  joerg {
   1383  1.1  joerg 	struct archive_dir_entry	*p;
   1384  1.1  joerg 
   1385  1.1  joerg 	/*
   1386  1.1  joerg 	 * Search entire list to see if this file has appeared before.
   1387  1.1  joerg 	 * If it has, override the timestamp data.
   1388  1.1  joerg 	 */
   1389  1.1  joerg 	p = bsdtar->archive_dir->head;
   1390  1.1  joerg 	while (p != NULL) {
   1391  1.1  joerg 		if (strcmp(path, p->name)==0) {
   1392  1.1  joerg 			p->mtime_sec = mtime_sec;
   1393  1.1  joerg 			p->mtime_nsec = mtime_nsec;
   1394  1.1  joerg 			return;
   1395  1.1  joerg 		}
   1396  1.1  joerg 		p = p->next;
   1397  1.1  joerg 	}
   1398  1.1  joerg 
   1399  1.1  joerg 	p = malloc(sizeof(*p));
   1400  1.1  joerg 	if (p == NULL)
   1401  1.1  joerg 		bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read archive directory");
   1402  1.1  joerg 
   1403  1.1  joerg 	p->name = strdup(path);
   1404  1.1  joerg 	if (p->name == NULL)
   1405  1.1  joerg 		bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read archive directory");
   1406  1.1  joerg 	p->mtime_sec = mtime_sec;
   1407  1.1  joerg 	p->mtime_nsec = mtime_nsec;
   1408  1.1  joerg 	p->next = NULL;
   1409  1.1  joerg 	if (bsdtar->archive_dir->tail == NULL) {
   1410  1.1  joerg 		bsdtar->archive_dir->head = bsdtar->archive_dir->tail = p;
   1411  1.1  joerg 	} else {
   1412  1.1  joerg 		bsdtar->archive_dir->tail->next = p;
   1413  1.1  joerg 		bsdtar->archive_dir->tail = p;
   1414  1.1  joerg 	}
   1415  1.1  joerg }
   1416  1.1  joerg 
   1417  1.1  joerg void
   1418  1.1  joerg test_for_append(struct bsdtar *bsdtar)
   1419  1.1  joerg {
   1420  1.1  joerg 	struct stat s;
   1421  1.1  joerg 
   1422  1.1  joerg 	if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
   1423  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0, "no files or directories specified");
   1424  1.1  joerg 	if (bsdtar->filename == NULL)
   1425  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0, "Cannot append to stdout.");
   1426  1.1  joerg 
   1427  1.1  joerg 	if (bsdtar->create_compression != 0)
   1428  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0,
   1429  1.1  joerg 		    "Cannot append to %s with compression", bsdtar->filename);
   1430  1.1  joerg 
   1431  1.1  joerg 	if (stat(bsdtar->filename, &s) != 0)
   1432  1.1  joerg 		return;
   1433  1.1  joerg 
   1434  1.1  joerg 	if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode))
   1435  1.1  joerg 		bsdtar_errc(bsdtar, 1, 0,
   1436  1.1  joerg 		    "Cannot append to %s: not a regular file.",
   1437  1.1  joerg 		    bsdtar->filename);
   1438  1.1  joerg }
   1439