On pátek 31. května 2019 20:00:07 CEST Pavel Raiskup wrote: > On Thursday, August 23, 2018 3:33:02 PM CEST Pavel Raiskup wrote: > > Gently ping, interlinking with another (upstream) report: > > http://lists.gnu.org/archive/html/bug-cpio/2017-12/msg00005.html > > Ping again, I'm continuously asked about this. Can I do something > with the patch to make it acceptable?
The previous patch was wrong, as we realized now in https://src.fedoraproject.org/rpms/cpio/pull-request/19 I'm attaching a new version of this patch that doesn't break the copypass mode, including a testcase. I'm going to keep this patch updated in https://github.com/praiskup/cpio/pull/1 Pavel
>From aad11bcf2059d2eca434715bcbc752bc78851243 Mon Sep 17 00:00:00 2001 From: Pavel Raiskup <prais...@redhat.com> Date: Wed, 17 May 2023 10:03:07 +0200 Subject: [PATCH] copyin, copypass: retain times for symlinks Original report by Pat Riehecky at https://bugzilla.redhat.com/1486364 * src/util.c (set_file_times): When the passed fd == -1, call lutimens() instead of fdutimens() to actually affect the symlink. * src/copyin.c (copyin_link): Call set_file_times to restore the symlink times. * src/copypass.c (process_copy_pass): Call set_file_times for symlinks, as well as for other file types. * tests/retain-times.at: New test file. * tests/testsuite.at: Link the new test file. --- src/copyin.c | 3 +++ src/copypass.c | 4 ++++ src/util.c | 6 +++-- tests/retain-times.at | 53 +++++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/retain-times.at diff --git a/src/copyin.c b/src/copyin.c index 2e72356..e2f5e03 100644 --- a/src/copyin.c +++ b/src/copyin.c @@ -798,6 +798,9 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) chown_error_details (file_hdr->c_name, uid, gid); } } + + if (retain_time_flag) + set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime, file_hdr->c_mtime); free (link_name); } diff --git a/src/copypass.c b/src/copypass.c index a8280ae..b918896 100644 --- a/src/copypass.c +++ b/src/copypass.c @@ -300,6 +300,10 @@ process_copy_pass (void) && errno != EPERM) chown_error_details (output_name.ds_string, uid, gid); } + + if (retain_time_flag) + set_file_times (-1, output_name.ds_string, + in_file_stat.st_atime, in_file_stat.st_mtime); free (link_name); } #endif diff --git a/src/util.c b/src/util.c index 7415e10..5c5f7e1 100644 --- a/src/util.c +++ b/src/util.c @@ -1250,8 +1250,10 @@ set_file_times (int fd, ts[1].tv_sec = mtime; /* Silently ignore EROFS because reading the file won't have upset its - timestamp if it's on a read-only filesystem. */ - if (fdutimens (fd, name, ts) < 0 && errno != EROFS) + timestamp if it's on a read-only filesystem. When FD == -1, name + is a symlink */ + if ((fd >= 0 ? fdutimens (fd, NULL, ts) : lutimens (name, ts)) < 0 + && errno != EROFS) utime_error (name); } diff --git a/tests/retain-times.at b/tests/retain-times.at new file mode 100644 index 0000000..d40c4a6 --- /dev/null +++ b/tests/retain-times.at @@ -0,0 +1,53 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# Copyright (C) 2023 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 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. + +# 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. + +AT_SETUP([retain-times]) +AT_KEYWORDS([symlink copyin copypass]) + +AT_DATA([filelist],[file +symlink +]) + +AT_CHECK([ +genfile --file file +ln -s file symlink || AT_SKIP_TEST +old_time=`stat --format=%Y file symlink` || AT_SKIP_TEST +echo Creating the archive +cpio --quiet -o < filelist > archive +sleep 1 +echo Extracting the archive +mkdir dir +cd dir +cpio -m --quiet -i < ../archive +find . | sort +new_time=`stat --format=%Y file symlink` +test "$old_time" = "$new_time" || echo "copyin: symlink mtime differs" +cd .. +cpio -pmvd copypass < filelist 2>/dev/null +new_time=`stat --format=%Y copypass/file copypass/symlink` +test "$old_time" = "$new_time" || echo "copypass: symlink mtime differs" +], +[0], +[Creating the archive +Extracting the archive +. +./file +./symlink +],[]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index c58cbb7..2e434e1 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -45,3 +45,4 @@ m4_include([big-block-size.at]) m4_include([CVE-2015-1197.at]) m4_include([CVE-2019-14866.at]) +m4_include([retain-times.at]) -- 2.40.1