2 * Copyright (c) 2003-2004 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "bsdtar_platform.h"
28 __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.47 2006/07/31 04:57:46 kientzle Exp $");
31 #include <sys/types.h>
35 #ifdef HAVE_ATTR_XATTR_H
36 #include <attr/xattr.h>
49 #include <ext2fs/ext2_fs.h>
50 #include <sys/ioctl.h>
56 /* Fixed size of uname/gname caches. */
57 #define name_cache_size 101
59 static const char * const NO_NAME
= "(noname)";
61 /* Initial size of link cache. */
62 #define links_cache_initial_size 1024
64 struct archive_dir_entry
{
65 struct archive_dir_entry
*next
;
72 struct archive_dir_entry
*head
, *tail
;
76 unsigned long number_entries
;
77 size_t number_buckets
;
78 struct links_entry
**buckets
;
82 struct links_entry
*next
;
83 struct links_entry
*previous
;
97 } cache
[name_cache_size
];
100 static void add_dir_list(struct bsdtar
*bsdtar
, const char *path
,
101 time_t mtime_sec
, int mtime_nsec
);
102 static int append_archive(struct bsdtar
*, struct archive
*,
104 static void archive_names_from_file(struct bsdtar
*bsdtar
,
106 static int archive_names_from_file_helper(struct bsdtar
*bsdtar
,
108 static void create_cleanup(struct bsdtar
*);
109 static void free_buckets(struct bsdtar
*, struct links_cache
*);
110 static void free_cache(struct name_cache
*cache
);
111 static const char * lookup_gname(struct bsdtar
*bsdtar
, gid_t gid
);
112 static int lookup_gname_helper(struct bsdtar
*bsdtar
,
113 const char **name
, id_t gid
);
114 static void lookup_hardlink(struct bsdtar
*,
115 struct archive_entry
*entry
, const struct stat
*);
116 static const char * lookup_uname(struct bsdtar
*bsdtar
, uid_t uid
);
117 static int lookup_uname_helper(struct bsdtar
*bsdtar
,
118 const char **name
, id_t uid
);
119 static int new_enough(struct bsdtar
*, const char *path
,
120 const struct stat
*);
121 static void setup_acls(struct bsdtar
*, struct archive_entry
*,
123 static void setup_xattrs(struct bsdtar
*, struct archive_entry
*,
125 static void test_for_append(struct bsdtar
*);
126 static void write_archive(struct archive
*, struct bsdtar
*);
127 static void write_entry(struct bsdtar
*, struct archive
*,
128 const struct stat
*, const char *pathname
,
129 unsigned pathlen
, const char *accpath
);
130 static int write_file_data(struct bsdtar
*, struct archive
*,
132 static void write_hierarchy(struct bsdtar
*, struct archive
*,
136 tar_mode_c(struct bsdtar
*bsdtar
)
141 if (*bsdtar
->argv
== NULL
&& bsdtar
->names_from_file
== NULL
)
142 bsdtar_errc(bsdtar
, 1, 0, "no files or directories specified");
144 a
= archive_write_new();
146 /* Support any format that the library supports. */
147 if (bsdtar
->create_format
== NULL
) {
148 r
= archive_write_set_format_pax_restricted(a
);
149 bsdtar
->create_format
= "pax restricted";
151 r
= archive_write_set_format_by_name(a
, bsdtar
->create_format
);
153 if (r
!= ARCHIVE_OK
) {
154 fprintf(stderr
, "Can't use format %s: %s\n",
155 bsdtar
->create_format
,
156 archive_error_string(a
));
161 * If user explicitly set the block size, then assume they
162 * want the last block padded as well. Otherwise, use the
163 * default block size and accept archive_write_open_file()'s
164 * default padding decisions.
166 if (bsdtar
->bytes_per_block
!= 0) {
167 archive_write_set_bytes_per_block(a
, bsdtar
->bytes_per_block
);
168 archive_write_set_bytes_in_last_block(a
,
169 bsdtar
->bytes_per_block
);
171 archive_write_set_bytes_per_block(a
, DEFAULT_BYTES_PER_BLOCK
);
173 switch (bsdtar
->create_compression
) {
178 archive_write_set_compression_bzip2(a
);
183 archive_write_set_compression_gzip(a
);
187 bsdtar_errc(bsdtar
, 1, 0,
188 "Unrecognized compression option -%c",
189 bsdtar
->create_compression
);
192 r
= archive_write_open_file(a
, bsdtar
->filename
);
194 bsdtar_errc(bsdtar
, 1, 0, archive_error_string(a
));
196 write_archive(a
, bsdtar
);
198 if (bsdtar
->option_totals
) {
199 fprintf(stderr
, "Total bytes written: " BSDTAR_FILESIZE_PRINTF
"\n",
200 (BSDTAR_FILESIZE_TYPE
)archive_position_compressed(a
));
203 archive_write_finish(a
);
207 * Same as 'c', except we only support tar formats in uncompressed
211 tar_mode_r(struct bsdtar
*bsdtar
)
216 struct archive_entry
*entry
;
218 /* Sanity-test some arguments and the file. */
219 test_for_append(bsdtar
);
221 format
= ARCHIVE_FORMAT_TAR_PAX_RESTRICTED
;
223 bsdtar
->fd
= open(bsdtar
->filename
, O_RDWR
);
225 bsdtar_errc(bsdtar
, 1, errno
,
226 "Cannot open %s", bsdtar
->filename
);
228 a
= archive_read_new();
229 archive_read_support_compression_all(a
);
230 archive_read_support_format_tar(a
);
231 archive_read_support_format_gnutar(a
);
232 archive_read_open_fd(a
, bsdtar
->fd
, 10240);
233 while (0 == archive_read_next_header(a
, &entry
)) {
234 if (archive_compression(a
) != ARCHIVE_COMPRESSION_NONE
) {
235 archive_read_finish(a
);
237 bsdtar_errc(bsdtar
, 1, 0,
238 "Cannot append to compressed archive.");
240 /* Keep going until we hit end-of-archive */
241 format
= archive_format(a
);
244 end_offset
= archive_read_header_position(a
);
245 archive_read_finish(a
);
247 /* Re-open archive for writing */
248 a
= archive_write_new();
249 archive_write_set_compression_none(a
);
251 * Set format to same one auto-detected above, except use
252 * ustar for appending to GNU tar, since the library doesn't
253 * write GNU tar format.
255 if (format
== ARCHIVE_FORMAT_TAR_GNUTAR
)
256 format
= ARCHIVE_FORMAT_TAR_USTAR
;
257 archive_write_set_format(a
, format
);
258 lseek(bsdtar
->fd
, end_offset
, SEEK_SET
); /* XXX check return val XXX */
259 archive_write_open_fd(a
, bsdtar
->fd
); /* XXX check return val XXX */
261 write_archive(a
, bsdtar
); /* XXX check return val XXX */
263 if (bsdtar
->option_totals
) {
264 fprintf(stderr
, "Total bytes written: " BSDTAR_FILESIZE_PRINTF
"\n",
265 (BSDTAR_FILESIZE_TYPE
)archive_position_compressed(a
));
268 archive_write_finish(a
);
274 tar_mode_u(struct bsdtar
*bsdtar
)
278 struct archive_entry
*entry
;
280 struct archive_dir_entry
*p
;
281 struct archive_dir archive_dir
;
283 bsdtar
->archive_dir
= &archive_dir
;
284 memset(&archive_dir
, 0, sizeof(archive_dir
));
286 format
= ARCHIVE_FORMAT_TAR_PAX_RESTRICTED
;
288 /* Sanity-test some arguments and the file. */
289 test_for_append(bsdtar
);
291 bsdtar
->fd
= open(bsdtar
->filename
, O_RDWR
);
293 bsdtar_errc(bsdtar
, 1, errno
,
294 "Cannot open %s", bsdtar
->filename
);
296 a
= archive_read_new();
297 archive_read_support_compression_all(a
);
298 archive_read_support_format_tar(a
);
299 archive_read_support_format_gnutar(a
);
300 if (archive_read_open_fd(a
, bsdtar
->fd
,
301 bsdtar
->bytes_per_block
!= 0 ? bsdtar
->bytes_per_block
:
302 DEFAULT_BYTES_PER_BLOCK
) != ARCHIVE_OK
) {
303 bsdtar_errc(bsdtar
, 1, 0,
304 "Can't open %s: %s", bsdtar
->filename
,
305 archive_error_string(a
));
308 /* Build a list of all entries and their recorded mod times. */
309 while (0 == archive_read_next_header(a
, &entry
)) {
310 if (archive_compression(a
) != ARCHIVE_COMPRESSION_NONE
) {
311 archive_read_finish(a
);
313 bsdtar_errc(bsdtar
, 1, 0,
314 "Cannot append to compressed archive.");
316 add_dir_list(bsdtar
, archive_entry_pathname(entry
),
317 archive_entry_mtime(entry
),
318 archive_entry_mtime_nsec(entry
));
319 /* Record the last format determination we see */
320 format
= archive_format(a
);
321 /* Keep going until we hit end-of-archive */
324 end_offset
= archive_read_header_position(a
);
325 archive_read_finish(a
);
327 /* Re-open archive for writing. */
328 a
= archive_write_new();
329 archive_write_set_compression_none(a
);
331 * Set format to same one auto-detected above, except that
332 * we don't write GNU tar format, so use ustar instead.
334 if (format
== ARCHIVE_FORMAT_TAR_GNUTAR
)
335 format
= ARCHIVE_FORMAT_TAR_USTAR
;
336 archive_write_set_format(a
, format
);
337 if (bsdtar
->bytes_per_block
!= 0) {
338 archive_write_set_bytes_per_block(a
, bsdtar
->bytes_per_block
);
339 archive_write_set_bytes_in_last_block(a
,
340 bsdtar
->bytes_per_block
);
342 archive_write_set_bytes_per_block(a
, DEFAULT_BYTES_PER_BLOCK
);
343 lseek(bsdtar
->fd
, end_offset
, SEEK_SET
);
344 ftruncate(bsdtar
->fd
, end_offset
);
345 archive_write_open_fd(a
, bsdtar
->fd
);
347 write_archive(a
, bsdtar
);
349 if (bsdtar
->option_totals
) {
350 fprintf(stderr
, "Total bytes written: " BSDTAR_FILESIZE_PRINTF
"\n",
351 (BSDTAR_FILESIZE_TYPE
)archive_position_compressed(a
));
354 archive_write_finish(a
);
358 while (bsdtar
->archive_dir
->head
!= NULL
) {
359 p
= bsdtar
->archive_dir
->head
->next
;
360 free(bsdtar
->archive_dir
->head
->name
);
361 free(bsdtar
->archive_dir
->head
);
362 bsdtar
->archive_dir
->head
= p
;
364 bsdtar
->archive_dir
->tail
= NULL
;
369 * Write user-specified files/dirs to opened archive.
372 write_archive(struct archive
*a
, struct bsdtar
*bsdtar
)
376 if (bsdtar
->names_from_file
!= NULL
)
377 archive_names_from_file(bsdtar
, a
);
379 while (*bsdtar
->argv
) {
381 if (arg
[0] == '-' && arg
[1] == 'C') {
387 bsdtar_warnc(bsdtar
, 1, 0,
388 "Missing argument for -C");
389 bsdtar
->return_value
= 1;
393 set_chdir(bsdtar
, arg
);
395 if (*arg
!= '/' || (arg
[0] == '@' && arg
[1] != '/'))
396 do_chdir(bsdtar
); /* Handle a deferred -C */
398 if (append_archive(bsdtar
, a
, arg
+ 1) != 0)
401 write_hierarchy(bsdtar
, a
, arg
);
406 create_cleanup(bsdtar
);
407 archive_write_close(a
);
411 * Archive names specified in file.
413 * Unless --null was specified, a line containing exactly "-C" will
414 * cause the next line to be a directory to pass to chdir(). If
415 * --null is specified, then a line "-C" is just another filename.
418 archive_names_from_file(struct bsdtar
*bsdtar
, struct archive
*a
)
422 bsdtar
->next_line_is_dir
= 0;
423 process_lines(bsdtar
, bsdtar
->names_from_file
,
424 archive_names_from_file_helper
);
425 if (bsdtar
->next_line_is_dir
)
426 bsdtar_errc(bsdtar
, 1, errno
,
427 "Unexpected end of filename list; "
428 "directory expected after -C");
432 archive_names_from_file_helper(struct bsdtar
*bsdtar
, const char *line
)
434 if (bsdtar
->next_line_is_dir
) {
435 set_chdir(bsdtar
, line
);
436 bsdtar
->next_line_is_dir
= 0;
437 } else if (!bsdtar
->option_null
&& strcmp(line
, "-C") == 0)
438 bsdtar
->next_line_is_dir
= 1;
441 do_chdir(bsdtar
); /* Handle a deferred -C */
442 write_hierarchy(bsdtar
, bsdtar
->archive
, line
);
448 * Copy from specified archive to current archive. Returns non-zero
449 * for write errors (which force us to terminate the entire archiving
450 * operation). If there are errors reading the input archive, we set
451 * bsdtar->return_value but return zero, so the overall archiving
452 * operation will complete and return non-zero.
455 append_archive(struct bsdtar
*bsdtar
, struct archive
*a
, const char *filename
)
458 struct archive_entry
*in_entry
;
459 int bytes_read
, bytes_written
;
462 if (strcmp(filename
, "-") == 0)
463 filename
= NULL
; /* Library uses NULL for stdio. */
465 ina
= archive_read_new();
466 archive_read_support_format_all(ina
);
467 archive_read_support_compression_all(ina
);
468 if (archive_read_open_file(ina
, filename
, 10240)) {
469 bsdtar_warnc(bsdtar
, 0, "%s", archive_error_string(ina
));
470 bsdtar
->return_value
= 1;
473 while (0 == archive_read_next_header(ina
, &in_entry
)) {
474 if (!new_enough(bsdtar
, archive_entry_pathname(in_entry
),
475 archive_entry_stat(in_entry
)))
477 if (excluded(bsdtar
, archive_entry_pathname(in_entry
)))
479 if (bsdtar
->option_interactive
&&
480 !yes("copy '%s'", archive_entry_pathname(in_entry
)))
483 safe_fprintf(stderr
, "a %s",
484 archive_entry_pathname(in_entry
));
485 /* XXX handle/report errors XXX */
486 if (archive_write_header(a
, in_entry
)) {
487 bsdtar_warnc(bsdtar
, 0, "%s",
488 archive_error_string(ina
));
489 bsdtar
->return_value
= 1;
492 bytes_read
= archive_read_data(ina
, buff
, sizeof(buff
));
493 while (bytes_read
> 0) {
495 archive_write_data(a
, buff
, bytes_read
);
496 if (bytes_written
< bytes_read
) {
497 bsdtar_warnc(bsdtar
, archive_errno(a
), "%s",
498 archive_error_string(a
));
502 archive_read_data(ina
, buff
, sizeof(buff
));
505 fprintf(stderr
, "\n");
508 if (archive_errno(ina
)) {
509 bsdtar_warnc(bsdtar
, 0, "Error reading archive %s: %s",
510 filename
, archive_error_string(ina
));
511 bsdtar
->return_value
= 1;
514 /* Note: If we got here, we saw no write errors, so return success. */
519 * Add the file or dir hierarchy named by 'path' to the archive
522 write_hierarchy(struct bsdtar
*bsdtar
, struct archive
*a
, const char *path
)
525 char symlink_mode
= bsdtar
->symlink_mode
;
527 int dev_recorded
= 0;
531 unsigned long fflags
;
534 tree
= tree_open(path
);
537 bsdtar_warnc(bsdtar
, errno
, "%s: Cannot open", path
);
538 bsdtar
->return_value
= 1;
542 while ((tree_ret
= tree_next(tree
))) {
543 const char *name
= tree_current_path(tree
);
544 const struct stat
*st
= NULL
, *lst
= NULL
;
547 if (tree_ret
== TREE_ERROR_DIR
)
548 bsdtar_warnc(bsdtar
, errno
, "%s: Couldn't visit directory", name
);
549 if (tree_ret
!= TREE_REGULAR
)
551 lst
= tree_current_lstat(tree
);
553 /* Couldn't lstat(); must not exist. */
554 bsdtar_warnc(bsdtar
, errno
, "%s: Cannot stat", path
);
555 bsdtar
->return_value
= 1;
558 if (S_ISLNK(lst
->st_mode
))
559 st
= tree_current_stat(tree
);
560 /* Default: descend into any dir or symlink to dir. */
561 /* We'll adjust this later on. */
563 if ((st
!= NULL
) && S_ISDIR(st
->st_mode
))
565 if ((lst
!= NULL
) && S_ISDIR(lst
->st_mode
))
569 * If user has asked us not to cross mount points,
570 * then don't descend into into a dir on a different
574 first_dev
= lst
->st_dev
;
577 if (bsdtar
->option_dont_traverse_mounts
) {
578 if (lst
!= NULL
&& lst
->st_dev
!= first_dev
)
583 * If this file/dir is flagged "nodump" and we're
584 * honoring such flags, skip this file/dir.
587 if (bsdtar
->option_honor_nodump
&&
588 (lst
->st_flags
& UF_NODUMP
))
594 * Linux has a nodump flag too but to read it
595 * we have to open() the file/dir and do an ioctl on it...
597 if (bsdtar
->option_honor_nodump
&&
598 ((fd
= open(name
, O_RDONLY
|O_NONBLOCK
)) >= 0) &&
599 ((r
= ioctl(fd
, EXT2_IOC_GETFLAGS
, &fflags
)),
600 close(fd
), r
) >= 0 &&
601 (fflags
& EXT2_NODUMP_FL
))
606 * If this file/dir is excluded by a filename
609 if (excluded(bsdtar
, name
))
613 * If the user vetoes this file/directory, skip it.
615 if (bsdtar
->option_interactive
&&
616 !yes("add '%s'", name
))
620 * If this is a dir, decide whether or not to recurse.
622 if (bsdtar
->option_no_subdirs
)
626 * Distinguish 'L'/'P'/'H' symlink following.
628 switch(symlink_mode
) {
630 /* 'H': After the first item, rest like 'P'. */
632 /* 'H': First item (from command line) like 'L'. */
635 /* 'L': Do descend through a symlink to dir. */
636 /* 'L': Archive symlink to file as file. */
637 lst
= tree_current_stat(tree
);
638 /* If stat fails, we have a broken symlink;
639 * in that case, archive the link as such. */
641 lst
= tree_current_lstat(tree
);
644 /* 'P': Don't descend through a symlink to dir. */
645 if (!S_ISDIR(lst
->st_mode
))
647 /* 'P': Archive symlink to file as symlink. */
648 /* lst = tree_current_lstat(tree); */
656 * Write the entry. Note that write_entry() handles
657 * pathname editing and newness testing.
659 write_entry(bsdtar
, a
, lst
, name
,
660 tree_current_pathlen(tree
),
661 tree_current_access_path(tree
));
667 * Add a single filesystem object to the archive.
670 write_entry(struct bsdtar
*bsdtar
, struct archive
*a
, const struct stat
*st
,
671 const char *pathname
, unsigned pathlen
, const char *accpath
)
673 struct archive_entry
*entry
;
678 unsigned long stflags
;
680 static char linkbuffer
[PATH_MAX
+1];
682 (void)pathlen
; /* UNUSED */
685 entry
= archive_entry_new();
687 archive_entry_set_pathname(entry
, pathname
);
690 * Rewrite the pathname to be archived. If rewrite
691 * fails, skip the entry.
693 if (edit_pathname(bsdtar
, entry
))
697 * In -u mode, check that the file is newer than what's
698 * already in the archive; in all modes, obey --newerXXX flags.
700 if (!new_enough(bsdtar
, archive_entry_pathname(entry
), st
))
703 if (!S_ISDIR(st
->st_mode
) && (st
->st_nlink
> 1))
704 lookup_hardlink(bsdtar
, entry
, st
);
706 /* Display entry as we process it. This format is required by SUSv2. */
708 safe_fprintf(stderr
, "a %s", archive_entry_pathname(entry
));
710 /* Read symbolic link information. */
711 if ((st
->st_mode
& S_IFMT
) == S_IFLNK
) {
714 lnklen
= readlink(accpath
, linkbuffer
, PATH_MAX
);
716 if (!bsdtar
->verbose
)
717 bsdtar_warnc(bsdtar
, errno
,
718 "%s: Couldn't read symbolic link",
722 ": Couldn't read symbolic link: %s",
726 linkbuffer
[lnklen
] = 0;
727 archive_entry_set_symlink(entry
, linkbuffer
);
730 /* Look up username and group name. */
731 archive_entry_set_uname(entry
, lookup_uname(bsdtar
, st
->st_uid
));
732 archive_entry_set_gname(entry
, lookup_gname(bsdtar
, st
->st_gid
));
735 if (st
->st_flags
!= 0)
736 archive_entry_set_fflags(entry
, st
->st_flags
, 0);
740 if ((S_ISREG(st
->st_mode
) || S_ISDIR(st
->st_mode
)) &&
741 ((fd
= open(accpath
, O_RDONLY
|O_NONBLOCK
)) >= 0) &&
742 ((r
= ioctl(fd
, EXT2_IOC_GETFLAGS
, &stflags
)), close(fd
), (fd
= -1), r
) >= 0 &&
744 archive_entry_set_fflags(entry
, stflags
, 0);
748 archive_entry_copy_stat(entry
, st
);
749 setup_acls(bsdtar
, entry
, accpath
);
750 setup_xattrs(bsdtar
, entry
, accpath
);
753 * If it's a regular file (and non-zero in size) make sure we
754 * can open it before we start to write. In particular, note
755 * that we can always archive a zero-length file, even if we
758 if (S_ISREG(st
->st_mode
) && st
->st_size
> 0) {
759 fd
= open(accpath
, O_RDONLY
);
761 if (!bsdtar
->verbose
)
762 bsdtar_warnc(bsdtar
, errno
, "%s: could not open file", pathname
);
764 fprintf(stderr
, ": %s", strerror(errno
));
769 /* Non-regular files get archived with zero size. */
770 if (!S_ISREG(st
->st_mode
))
771 archive_entry_set_size(entry
, 0);
773 e
= archive_write_header(a
, entry
);
774 if (e
!= ARCHIVE_OK
) {
775 if (!bsdtar
->verbose
)
776 bsdtar_warnc(bsdtar
, 0, "%s: %s", pathname
,
777 archive_error_string(a
));
779 fprintf(stderr
, ": %s", archive_error_string(a
));
782 if (e
== ARCHIVE_FATAL
)
786 * If we opened a file earlier, write it out now. Note that
787 * the format handler might have reset the size field to zero
788 * to inform us that the archive body won't get stored. In
789 * that case, just skip the write.
791 if (fd
>= 0 && archive_entry_size(entry
) > 0)
792 write_file_data(bsdtar
, a
, fd
);
796 fprintf(stderr
, "\n");
803 archive_entry_free(entry
);
807 /* Helper function to copy file to archive, with stack-allocated buffer. */
809 write_file_data(struct bsdtar
*bsdtar
, struct archive
*a
, int fd
)
813 ssize_t bytes_written
;
815 /* XXX TODO: Allocate buffer on heap and store pointer to
816 * it in bsdtar structure; arrange cleanup as well. XXX */
819 bytes_read
= read(fd
, buff
, sizeof(buff
));
820 while (bytes_read
> 0) {
821 bytes_written
= archive_write_data(a
, buff
, bytes_read
);
822 if (bytes_written
<= 0)
823 return (-1); /* Write failed; this is bad */
824 bytes_read
= read(fd
, buff
, sizeof(buff
));
831 create_cleanup(struct bsdtar
*bsdtar
)
833 /* Free inode->pathname map used for hardlink detection. */
834 if (bsdtar
->links_cache
!= NULL
) {
835 free_buckets(bsdtar
, bsdtar
->links_cache
);
836 free(bsdtar
->links_cache
);
837 bsdtar
->links_cache
= NULL
;
840 free_cache(bsdtar
->uname_cache
);
841 bsdtar
->uname_cache
= NULL
;
842 free_cache(bsdtar
->gname_cache
);
843 bsdtar
->gname_cache
= NULL
;
848 free_buckets(struct bsdtar
*bsdtar
, struct links_cache
*links_cache
)
852 if (links_cache
->buckets
== NULL
)
855 for (i
= 0; i
< links_cache
->number_buckets
; i
++) {
856 while (links_cache
->buckets
[i
] != NULL
) {
857 struct links_entry
*lp
= links_cache
->buckets
[i
]->next
;
858 if (bsdtar
->option_warn_links
)
859 bsdtar_warnc(bsdtar
, 0, "Missing links to %s",
860 links_cache
->buckets
[i
]->name
);
861 if (links_cache
->buckets
[i
]->name
!= NULL
)
862 free(links_cache
->buckets
[i
]->name
);
863 free(links_cache
->buckets
[i
]);
864 links_cache
->buckets
[i
] = lp
;
867 free(links_cache
->buckets
);
868 links_cache
->buckets
= NULL
;
872 lookup_hardlink(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
873 const struct stat
*st
)
875 struct links_cache
*links_cache
;
876 struct links_entry
*le
, **new_buckets
;
880 /* If necessary, initialize the links cache. */
881 links_cache
= bsdtar
->links_cache
;
882 if (links_cache
== NULL
) {
883 bsdtar
->links_cache
= malloc(sizeof(struct links_cache
));
884 if (bsdtar
->links_cache
== NULL
)
885 bsdtar_errc(bsdtar
, 1, ENOMEM
,
886 "No memory for hardlink detection.");
887 links_cache
= bsdtar
->links_cache
;
888 memset(links_cache
, 0, sizeof(struct links_cache
));
889 links_cache
->number_buckets
= links_cache_initial_size
;
890 links_cache
->buckets
= malloc(links_cache
->number_buckets
*
891 sizeof(links_cache
->buckets
[0]));
892 if (links_cache
->buckets
== NULL
) {
893 bsdtar_errc(bsdtar
, 1, ENOMEM
,
894 "No memory for hardlink detection.");
896 for (i
= 0; i
< links_cache
->number_buckets
; i
++)
897 links_cache
->buckets
[i
] = NULL
;
900 /* If the links cache overflowed and got flushed, don't bother. */
901 if (links_cache
->buckets
== NULL
)
904 /* If the links cache is getting too full, enlarge the hash table. */
905 if (links_cache
->number_entries
> links_cache
->number_buckets
* 2)
907 new_size
= links_cache
->number_buckets
* 2;
908 new_buckets
= malloc(new_size
* sizeof(struct links_entry
*));
910 if (new_buckets
!= NULL
) {
911 memset(new_buckets
, 0,
912 new_size
* sizeof(struct links_entry
*));
913 for (i
= 0; i
< links_cache
->number_buckets
; i
++) {
914 while (links_cache
->buckets
[i
] != NULL
) {
915 /* Remove entry from old bucket. */
916 le
= links_cache
->buckets
[i
];
917 links_cache
->buckets
[i
] = le
->next
;
919 /* Add entry to new bucket. */
920 hash
= (le
->dev
^ le
->ino
) % new_size
;
922 if (new_buckets
[hash
] != NULL
)
923 new_buckets
[hash
]->previous
=
925 le
->next
= new_buckets
[hash
];
927 new_buckets
[hash
] = le
;
930 free(links_cache
->buckets
);
931 links_cache
->buckets
= new_buckets
;
932 links_cache
->number_buckets
= new_size
;
934 free_buckets(bsdtar
, links_cache
);
935 bsdtar_warnc(bsdtar
, ENOMEM
,
936 "No more memory for recording hard links");
937 bsdtar_warnc(bsdtar
, 0,
938 "Remaining links will be dumped as full files");
942 /* Try to locate this entry in the links cache. */
943 hash
= ( st
->st_dev
^ st
->st_ino
) % links_cache
->number_buckets
;
944 for (le
= links_cache
->buckets
[hash
]; le
!= NULL
; le
= le
->next
) {
945 if (le
->dev
== st
->st_dev
&& le
->ino
== st
->st_ino
) {
946 archive_entry_copy_hardlink(entry
, le
->name
);
949 * Decrement link count each time and release
950 * the entry if it hits zero. This saves
951 * memory and is necessary for proper -l
954 if (--le
->links
<= 0) {
955 if (le
->previous
!= NULL
)
956 le
->previous
->next
= le
->next
;
957 if (le
->next
!= NULL
)
958 le
->next
->previous
= le
->previous
;
959 if (le
->name
!= NULL
)
961 if (links_cache
->buckets
[hash
] == le
)
962 links_cache
->buckets
[hash
] = le
->next
;
963 links_cache
->number_entries
--;
971 /* Add this entry to the links cache. */
972 le
= malloc(sizeof(struct links_entry
));
974 le
->name
= strdup(archive_entry_pathname(entry
));
975 if ((le
== NULL
) || (le
->name
== NULL
)) {
976 free_buckets(bsdtar
, links_cache
);
977 bsdtar_warnc(bsdtar
, ENOMEM
,
978 "No more memory for recording hard links");
979 bsdtar_warnc(bsdtar
, 0,
980 "Remaining hard links will be dumped as full files");
985 if (links_cache
->buckets
[hash
] != NULL
)
986 links_cache
->buckets
[hash
]->previous
= le
;
987 links_cache
->number_entries
++;
988 le
->next
= links_cache
->buckets
[hash
];
990 links_cache
->buckets
[hash
] = le
;
991 le
->dev
= st
->st_dev
;
992 le
->ino
= st
->st_ino
;
993 le
->links
= st
->st_nlink
- 1;
996 #ifdef HAVE_POSIX_ACL
997 static void setup_acl(struct bsdtar
*bsdtar
,
998 struct archive_entry
*entry
, const char *accpath
,
999 int acl_type
, int archive_entry_acl_type
);
1002 setup_acls(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
1003 const char *accpath
)
1005 archive_entry_acl_clear(entry
);
1007 setup_acl(bsdtar
, entry
, accpath
,
1008 ACL_TYPE_ACCESS
, ARCHIVE_ENTRY_ACL_TYPE_ACCESS
);
1009 /* Only directories can have default ACLs. */
1010 if (S_ISDIR(archive_entry_mode(entry
)))
1011 setup_acl(bsdtar
, entry
, accpath
,
1012 ACL_TYPE_DEFAULT
, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
);
1016 setup_acl(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
1017 const char *accpath
, int acl_type
, int archive_entry_acl_type
)
1021 acl_entry_t acl_entry
;
1022 acl_permset_t acl_permset
;
1023 int s
, ae_id
, ae_tag
, ae_perm
;
1024 const char *ae_name
;
1026 /* Retrieve access ACL from file. */
1027 acl
= acl_get_file(accpath
, acl_type
);
1029 s
= acl_get_entry(acl
, ACL_FIRST_ENTRY
, &acl_entry
);
1034 acl_get_tag_type(acl_entry
, &acl_tag
);
1035 if (acl_tag
== ACL_USER
) {
1036 ae_id
= (int)*(uid_t
*)acl_get_qualifier(acl_entry
);
1037 ae_name
= lookup_uname(bsdtar
, ae_id
);
1038 ae_tag
= ARCHIVE_ENTRY_ACL_USER
;
1039 } else if (acl_tag
== ACL_GROUP
) {
1040 ae_id
= (int)*(gid_t
*)acl_get_qualifier(acl_entry
);
1041 ae_name
= lookup_gname(bsdtar
, ae_id
);
1042 ae_tag
= ARCHIVE_ENTRY_ACL_GROUP
;
1043 } else if (acl_tag
== ACL_MASK
) {
1044 ae_tag
= ARCHIVE_ENTRY_ACL_MASK
;
1045 } else if (acl_tag
== ACL_USER_OBJ
) {
1046 ae_tag
= ARCHIVE_ENTRY_ACL_USER_OBJ
;
1047 } else if (acl_tag
== ACL_GROUP_OBJ
) {
1048 ae_tag
= ARCHIVE_ENTRY_ACL_GROUP_OBJ
;
1049 } else if (acl_tag
== ACL_OTHER
) {
1050 ae_tag
= ARCHIVE_ENTRY_ACL_OTHER
;
1052 /* Skip types that libarchive can't support. */
1056 acl_get_permset(acl_entry
, &acl_permset
);
1059 * acl_get_perm() is spelled differently on different
1060 * platforms; see bsdtar_platform.h for details.
1062 if (ACL_GET_PERM(acl_permset
, ACL_EXECUTE
))
1063 ae_perm
|= ARCHIVE_ENTRY_ACL_EXECUTE
;
1064 if (ACL_GET_PERM(acl_permset
, ACL_READ
))
1065 ae_perm
|= ARCHIVE_ENTRY_ACL_READ
;
1066 if (ACL_GET_PERM(acl_permset
, ACL_WRITE
))
1067 ae_perm
|= ARCHIVE_ENTRY_ACL_WRITE
;
1069 archive_entry_acl_add_entry(entry
,
1070 archive_entry_acl_type
, ae_perm
, ae_tag
,
1073 s
= acl_get_entry(acl
, ACL_NEXT_ENTRY
, &acl_entry
);
1080 setup_acls(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
1081 const char *accpath
)
1089 #if HAVE_LISTXATTR && HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR
1092 setup_xattr(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
1093 const char *accpath
, const char *name
)
1097 char symlink_mode
= bsdtar
->symlink_mode
;
1099 if (symlink_mode
== 'H')
1100 size
= getxattr(accpath
, name
, NULL
, 0);
1102 size
= lgetxattr(accpath
, name
, NULL
, 0);
1105 bsdtar_warnc(bsdtar
, errno
, "Couldn't get extended attribute");
1109 if (size
> 0 && (value
= malloc(size
)) == NULL
) {
1110 bsdtar_errc(bsdtar
, 1, errno
, "Out of memory");
1114 if (symlink_mode
== 'H')
1115 size
= getxattr(accpath
, name
, value
, size
);
1117 size
= lgetxattr(accpath
, name
, value
, size
);
1120 bsdtar_warnc(bsdtar
, errno
, "Couldn't get extended attribute");
1124 archive_entry_xattr_add_entry(entry
, name
, value
, size
);
1130 * Linux extended attribute support
1133 setup_xattrs(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
1134 const char *accpath
)
1138 char symlink_mode
= bsdtar
->symlink_mode
;
1140 if (symlink_mode
== 'H')
1141 list_size
= listxattr(accpath
, NULL
, 0);
1143 list_size
= llistxattr(accpath
, NULL
, 0);
1145 if (list_size
== -1) {
1146 bsdtar_warnc(bsdtar
, errno
,
1147 "Couldn't list extended attributes");
1149 } else if (list_size
== 0)
1152 if ((list
= malloc(list_size
)) == NULL
) {
1153 bsdtar_errc(bsdtar
, 1, errno
, "Out of memory");
1157 if (symlink_mode
== 'H')
1158 list_size
= listxattr(accpath
, list
, list_size
);
1160 list_size
= llistxattr(accpath
, list
, list_size
);
1162 if (list_size
== -1) {
1163 bsdtar_warnc(bsdtar
, errno
,
1164 "Couldn't list extended attributes");
1169 for (p
= list
; (p
- list
) < list_size
; p
+= strlen(p
) + 1) {
1170 if (strncmp(p
, "system.", 7) == 0 ||
1171 strncmp(p
, "xfsroot.", 8) == 0)
1174 setup_xattr(bsdtar
, entry
, accpath
, p
);
1183 * Generic (stub) extended attribute support.
1186 setup_xattrs(struct bsdtar
*bsdtar
, struct archive_entry
*entry
,
1187 const char *accpath
)
1189 (void)bsdtar
; /* UNUSED */
1190 (void)entry
; /* UNUSED */
1191 (void)accpath
; /* UNUSED */
1197 free_cache(struct name_cache
*cache
)
1201 if (cache
!= NULL
) {
1202 for (i
= 0; i
< cache
->size
; i
++) {
1203 if (cache
->cache
[i
].name
!= NULL
&&
1204 cache
->cache
[i
].name
!= NO_NAME
)
1205 free((void *)(uintptr_t)cache
->cache
[i
].name
);
1212 * Lookup uid/gid from uname/gname, return NULL if no match.
1215 lookup_name(struct bsdtar
*bsdtar
, struct name_cache
**name_cache_variable
,
1216 int (*lookup_fn
)(struct bsdtar
*, const char **, id_t
), id_t id
)
1218 struct name_cache
*cache
;
1223 if (*name_cache_variable
== NULL
) {
1224 *name_cache_variable
= malloc(sizeof(struct name_cache
));
1225 if (*name_cache_variable
== NULL
)
1226 bsdtar_errc(bsdtar
, 1, ENOMEM
, "No more memory");
1227 memset(*name_cache_variable
, 0, sizeof(struct name_cache
));
1228 (*name_cache_variable
)->size
= name_cache_size
;
1231 cache
= *name_cache_variable
;
1234 slot
= id
% cache
->size
;
1235 if (cache
->cache
[slot
].name
!= NULL
) {
1236 if (cache
->cache
[slot
].id
== id
) {
1238 if (cache
->cache
[slot
].name
== NO_NAME
)
1240 return (cache
->cache
[slot
].name
);
1242 if (cache
->cache
[slot
].name
!= NO_NAME
)
1243 free((void *)(uintptr_t)cache
->cache
[slot
].name
);
1244 cache
->cache
[slot
].name
= NULL
;
1247 if (lookup_fn(bsdtar
, &name
, id
) == 0) {
1248 if (name
== NULL
|| name
[0] == '\0') {
1249 /* Cache the negative response. */
1250 cache
->cache
[slot
].name
= NO_NAME
;
1251 cache
->cache
[slot
].id
= id
;
1253 cache
->cache
[slot
].name
= strdup(name
);
1254 if (cache
->cache
[slot
].name
!= NULL
) {
1255 cache
->cache
[slot
].id
= id
;
1256 return (cache
->cache
[slot
].name
);
1259 * Conveniently, NULL marks an empty slot, so
1260 * if the strdup() fails, we've just failed to
1261 * cache it. No recovery necessary.
1269 lookup_uname(struct bsdtar
*bsdtar
, uid_t uid
)
1271 return (lookup_name(bsdtar
, &bsdtar
->uname_cache
,
1272 &lookup_uname_helper
, (id_t
)uid
));
1276 lookup_uname_helper(struct bsdtar
*bsdtar
, const char **name
, id_t id
)
1278 struct passwd
*pwent
;
1280 (void)bsdtar
; /* UNUSED */
1283 pwent
= getpwuid((uid_t
)id
);
1284 if (pwent
== NULL
) {
1287 bsdtar_warnc(bsdtar
, errno
, "getpwuid(%d) failed", id
);
1291 *name
= pwent
->pw_name
;
1296 lookup_gname(struct bsdtar
*bsdtar
, gid_t gid
)
1298 return (lookup_name(bsdtar
, &bsdtar
->gname_cache
,
1299 &lookup_gname_helper
, (id_t
)gid
));
1303 lookup_gname_helper(struct bsdtar
*bsdtar
, const char **name
, id_t id
)
1305 struct group
*grent
;
1307 (void)bsdtar
; /* UNUSED */
1310 grent
= getgrgid((gid_t
)id
);
1311 if (grent
== NULL
) {
1314 bsdtar_warnc(bsdtar
, errno
, "getgrgid(%d) failed", id
);
1318 *name
= grent
->gr_name
;
1323 * Test if the specified file is new enough to include in the archive.
1326 new_enough(struct bsdtar
*bsdtar
, const char *path
, const struct stat
*st
)
1328 struct archive_dir_entry
*p
;
1331 * If this file/dir is excluded by a time comparison, skip it.
1333 if (bsdtar
->newer_ctime_sec
> 0) {
1334 if (st
->st_ctime
< bsdtar
->newer_ctime_sec
)
1335 return (0); /* Too old, skip it. */
1336 if (st
->st_ctime
== bsdtar
->newer_ctime_sec
1337 && ARCHIVE_STAT_CTIME_NANOS(st
)
1338 <= bsdtar
->newer_ctime_nsec
)
1339 return (0); /* Too old, skip it. */
1341 if (bsdtar
->newer_mtime_sec
> 0) {
1342 if (st
->st_mtime
< bsdtar
->newer_mtime_sec
)
1343 return (0); /* Too old, skip it. */
1344 if (st
->st_mtime
== bsdtar
->newer_mtime_sec
1345 && ARCHIVE_STAT_MTIME_NANOS(st
)
1346 <= bsdtar
->newer_mtime_nsec
)
1347 return (0); /* Too old, skip it. */
1351 * In -u mode, we only write an entry if it's newer than
1352 * what was already in the archive.
1354 if (bsdtar
->archive_dir
!= NULL
&&
1355 bsdtar
->archive_dir
->head
!= NULL
) {
1356 for (p
= bsdtar
->archive_dir
->head
; p
!= NULL
; p
= p
->next
) {
1357 if (strcmp(path
, p
->name
)==0)
1358 return (p
->mtime_sec
< st
->st_mtime
||
1359 (p
->mtime_sec
== st
->st_mtime
&&
1361 < ARCHIVE_STAT_MTIME_NANOS(st
)));
1365 /* If the file wasn't rejected, include it. */
1370 * Add an entry to the dir list for 'u' mode.
1372 * XXX TODO: Make this fast.
1375 add_dir_list(struct bsdtar
*bsdtar
, const char *path
,
1376 time_t mtime_sec
, int mtime_nsec
)
1378 struct archive_dir_entry
*p
;
1380 if (path
[0] == '.' && path
[1] == '/' && path
[2] != '\0')
1384 * Search entire list to see if this file has appeared before.
1385 * If it has, override the timestamp data.
1387 p
= bsdtar
->archive_dir
->head
;
1389 if (strcmp(path
, p
->name
)==0) {
1390 p
->mtime_sec
= mtime_sec
;
1391 p
->mtime_nsec
= mtime_nsec
;
1397 p
= malloc(sizeof(*p
));
1399 bsdtar_errc(bsdtar
, 1, ENOMEM
, "Can't read archive directory");
1401 p
->name
= strdup(path
);
1402 if (p
->name
== NULL
)
1403 bsdtar_errc(bsdtar
, 1, ENOMEM
, "Can't read archive directory");
1404 p
->mtime_sec
= mtime_sec
;
1405 p
->mtime_nsec
= mtime_nsec
;
1407 if (bsdtar
->archive_dir
->tail
== NULL
) {
1408 bsdtar
->archive_dir
->head
= bsdtar
->archive_dir
->tail
= p
;
1410 bsdtar
->archive_dir
->tail
->next
= p
;
1411 bsdtar
->archive_dir
->tail
= p
;
1416 test_for_append(struct bsdtar
*bsdtar
)
1420 if (*bsdtar
->argv
== NULL
)
1421 bsdtar_errc(bsdtar
, 1, 0, "no files or directories specified");
1422 if (bsdtar
->filename
== NULL
)
1423 bsdtar_errc(bsdtar
, 1, 0, "Cannot append to stdout.");
1425 if (bsdtar
->create_compression
!= 0)
1426 bsdtar_errc(bsdtar
, 1, 0,
1427 "Cannot append to %s with compression", bsdtar
->filename
);
1429 if (stat(bsdtar
->filename
, &s
) != 0)
1430 bsdtar_errc(bsdtar
, 1, errno
,
1431 "Cannot stat %s", bsdtar
->filename
);
1433 if (!S_ISREG(s
.st_mode
))
1434 bsdtar_errc(bsdtar
, 1, 0,
1435 "Cannot append to %s: not a regular file.",