From owner-freebsd-questions@FreeBSD.ORG Thu Sep 22 05:36:44 2005 Return-Path: X-Original-To: freebsd-questions@freebsd.org Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CC8C616A41F for ; Thu, 22 Sep 2005 05:36:44 +0000 (GMT) (envelope-from kientzle@freebsd.org) Received: from kientzle.com (h-66-166-149-50.snvacaid.covad.net [66.166.149.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id 650D143D45 for ; Thu, 22 Sep 2005 05:36:44 +0000 (GMT) (envelope-from kientzle@freebsd.org) Received: from freebsd.org (p54.kientzle.com [66.166.149.54]) by kientzle.com (8.12.9/8.12.9) with ESMTP id j8M5afOZ054526; Wed, 21 Sep 2005 22:36:41 -0700 (PDT) (envelope-from kientzle@freebsd.org) Message-ID: <433242E9.2060100@freebsd.org> Date: Wed, 21 Sep 2005 22:36:41 -0700 From: Tim Kientzle User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.4) Gecko/20031006 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Lowell Gilbert References: <48a5f32a05090901591a16c062@mail.gmail.com> <44u0guw0ou.fsf@be-well.ilk.org> In-Reply-To: <44u0guw0ou.fsf@be-well.ilk.org> Content-Type: multipart/mixed; boundary="------------050000000803000805090904" Cc: gjbailey@gmail.com, freebsd-questions Subject: Re: tar -u adds all files regardless of mod date X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Sep 2005 05:36:45 -0000 This is a multi-part message in MIME format. --------------050000000803000805090904 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Lowell Gilbert wrote: > Gareth Bailey writes: > >>... If i then try to update modified files by doing this: >> >># tar -uf dir_b.tar /usr/dir_a/dir_b >> >>and I end up with dir_b.tar being 130MB (double size) which >>should not be the case since no files have been modified in >> /usr/dir_a/dir_b. The attached patch should fix this problem for 6-STABLE and 7-CURRENT systems. If someone could try it for me and let me know if it works for them, I'd greatly appreciate it. 5-STABLE is sufficiently different that the patch doesn't apply, unfortunately. It will take me a few days to figure out whether it's best to work up a different patch for 5-STABLE or whether I should MFC a lot of work from 6-STABLE to 5-STABLE. The crux of the problem is that bsdtar compares files on disk to files in the archive by pathname before it strips leading '/' characters. As a result, it tries to compare "/usr/dir_a" on disk to "usr/dir_a" in the archive, which fails. A temporary workaround is to not use absolute pathnames: cd / ; tar -uf dir_b.tar usr/dir_a/dir_b Another workaround is to use -P both when creating and when updating the archive. The attached patch causes bsdtar to do all pathname editing before it does the time comparison for -u. I think that correctly fixes this problem. Tim P.S. If you're testing this, do not use "touch" to update timestamps. If you do, you will get some very confusing results because "touch" updates high-precision timestamps, but the default tar format only stores whole seconds. This seems hard to fix. --------------050000000803000805090904 Content-Type: text/plain; name="fix-u-uption" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fix-u-uption" Index: write.c =================================================================== RCS file: /home/ncvs/src/usr.bin/tar/write.c,v retrieving revision 1.41 diff -u -r1.41 write.c --- write.c 8 May 2005 06:25:15 -0000 1.41 +++ write.c 22 Sep 2005 04:46:00 -0000 @@ -643,15 +643,12 @@ tree_descend(tree); /* - * In -u mode, we need to check whether this - * is newer than what's already in the archive. - * In all modes, we need to obey --newerXXX flags. + * Write the entry. Note that write_entry() handles + * pathname editing and newness testing. */ - if (new_enough(bsdtar, name, lst)) { - write_entry(bsdtar, a, lst, name, - tree_current_pathlen(tree), - tree_current_access_path(tree)); - } + write_entry(bsdtar, a, lst, name, + tree_current_pathlen(tree), + tree_current_access_path(tree)); } tree_close(tree); } @@ -686,6 +683,13 @@ if (edit_pathname(bsdtar, entry)) goto abort; + /* + * In -u mode, check that the file is newer than what's + * already in the archive; in all modes, obey --newerXXX flags. + */ + if (!new_enough(bsdtar, archive_entry_pathname(entry), st)) + goto abort; + if (!S_ISDIR(st->st_mode) && (st->st_nlink > 1)) lookup_hardlink(bsdtar, entry, st); @@ -1235,10 +1239,6 @@ */ if (bsdtar->archive_dir != NULL && bsdtar->archive_dir->head != NULL) { - /* Ignore leading './' when comparing names. */ - if (path[0] == '.' && path[1] == '/' && path[2] != '\0') - path += 2; - for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) { if (strcmp(path, p->name)==0) return (p->mtime_sec < st->st_mtime || --------------050000000803000805090904--