X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftar;a=blobdiff_plain;f=src%2Fupdate.c;h=e9fad3f2ae48ab6a196c9b6aa85d4a76da9192ad;hp=ade42830f1395798c2fb94fba992a221fe806a85;hb=45ccda119355a1087450039a250359c1d0de0d08;hpb=51aee274e892923a3f8fdb774e4f6b90bce47437 diff --git a/src/update.c b/src/update.c index ade4283..e9fad3f 100644 --- a/src/update.c +++ b/src/update.c @@ -1,21 +1,22 @@ /* Update a tar archive. - Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003, - 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright 1988, 1992, 1994, 1996-1997, 1999-2001, 2003-2005, 2007, + 2010, 2013-2014 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any later - version. + This file is part of GNU tar. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - Public License for more details. + GNU tar is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + GNU tar is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ /* Implement the 'r', 'u' and 'A' options for tar. 'A' means that the file names are tar files, and they should simply be appended to the end @@ -47,7 +48,7 @@ char *output_start; static void append_file (char *file_name) { - int handle = open (file_name, O_RDONLY | O_BINARY); + int handle = openat (chdir_fd, file_name, O_RDONLY | O_BINARY); struct stat stat_data; if (handle < 0) @@ -114,7 +115,9 @@ update_archive (void) while (!found_end) { - enum read_header status = read_header (false); + enum read_header status = read_header (¤t_header, + ¤t_stat_info, + read_header_auto); switch (status) { @@ -128,6 +131,8 @@ update_archive (void) decode_header (current_header, ¤t_stat_info, ¤t_format, 0); + transform_stat_info (current_header->header.typeflag, + ¤t_stat_info); archive_format = current_format; if (subcommand_option == UPDATE_SUBCOMMAND @@ -136,12 +141,30 @@ update_archive (void) struct stat s; chdir_do (name->change_dir); - if (deref_stat (dereference_option, - current_stat_info.file_name, &s) == 0 - && (tar_timespec_cmp (get_stat_mtime (&s), - current_stat_info.mtime) - <= 0)) - add_avoided_name (current_stat_info.file_name); + if (deref_stat (current_stat_info.file_name, &s) == 0) + { + if (S_ISDIR (s.st_mode)) + { + char *p, *dirp = tar_savedir (name->name, 1); + if (dirp) + { + namebuf_t nbuf = namebuf_create (name->name); + + for (p = dirp; *p; p += strlen (p) + 1) + addname (namebuf_name (nbuf, p), + 0, false, NULL); + + namebuf_free (nbuf); + free (dirp); + + remname (name); + } + } + else if (tar_timespec_cmp (get_stat_mtime (&s), + current_stat_info.mtime) + <= 0) + remname (name); + } } skip_member (); @@ -200,11 +223,12 @@ update_archive (void) if (subcommand_option == CAT_SUBCOMMAND) append_file (file_name); else - dump_file (file_name, 1, (dev_t) 0); + dump_file (0, file_name, file_name); } } write_eot (); close_archive (); + finish_deferred_unlinks (); names_notfound (); }