[pacman-dev] [PATCH] Save backup files with extension .pacsave.timestamp

Dan McGee dpmcgee at gmail.com
Tue Aug 2 08:32:31 EDT 2011


On Fri, Jul 29, 2011 at 2:03 AM, Pang Yan Han <pangyanhan at gmail.com> wrote:
> Teach pacman to save backup files using extension of .pacsave.timestamp
> "timestamp" is the time of removal of the backup file. It is in
> <year>-<month>-<day>-<HHMMSS> format, where:
>
> - year is either the year with century or a 2 digit number from 00 to 99 (year
>  without century) if the timestamp string exceeds 20 characters
Already too odd to me. There is zero reason to not always do
YYYY-MM-DD_HH:MM:SS format IMO, which also makes this whole
explanation unnecessary as it will be recognized as a standard format.

Is the HH:MM:SS bit really necessary? Perhaps a format such as that
like logrotate would work. Given 99% of the time you wouldn't have
more than one file on a given day, stick with foo.pacsave.2011-08-02,
then the next would become something like foo.pacsave.2011-08-02.1,
.2, etc.

As I'm thinking as I'm typing and drinking my morning coffee here, why
even do the date at all? Why not just check for the presence of an
existing pacsave file and rotate them down to .1, .2, etc. just like
logrotate would? This is what the feature request asks for, and
double-timestamping a file just seems confusing.

> - month is a 2 digit number from 01 to 12
> - day is a 2 digit number from 01 to 31
> - HH is a 2 digit number from 00 to 23 representing the hour
> - MM and SS are 2 digit numbers from 00 to 59 representing minutes and seconds
>  respectively
>
> An example of such a pacsave file is /etc/pacman.conf.pacsave.2011-07-29-145035
>
> This addresses FS#24192 (pacman overwrites .pacsave files)
>
> FILE_PACSAVE rule for the test suite is updated to reflect the change in
> .pacsave file extension. FILE_PACSAVE rules can be used as per before this patch.
>
> Signed-off-by: Pang Yan Han <pangyanhan at gmail.com>
> ---
>  doc/pacman.8.txt      |   13 ++++++++++++-
>  lib/libalpm/remove.c  |   20 ++++++++++++++++++--
>  test/pacman/pmrule.py |   21 +++++++++++++++++++--
>  3 files changed, 49 insertions(+), 5 deletions(-)
>
> diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
> index 64b1ff3..d029294 100644
> --- a/doc/pacman.8.txt
> +++ b/doc/pacman.8.txt
> @@ -54,8 +54,19 @@ Operations
>        removed, in which case every package in that group will be removed.
>        Files belonging to the specified package will be deleted, and the
>        database will be updated. Most configuration files will be saved
> -       with a '.pacsave' extension unless the '\--nosave' option is used.
> +       with a '.pacsave-<timestamp>' extension unless the '\--nosave' option is used.
>        See <<RO,Remove Options>> below.
> ++
> +'<timestamp>' is the time of removal of the configuration file. It is in
> +<year>-<month>-<day>-<HHMMSS> format, where:
> ++
> +       - year is either the year with century or a 2 digit number from 00 to 99
> +         (year without century) if the string exceeds 20 characters
> +       - month is a 2 digit number from 01 to 12
> +       - day is a 2 digit number from 01 to 31
> +       - HH is a 2 digit number from 00 to 23 representing the hour
> +       - MM and SS are 2 digit numbers from 00 to 59 representing minutes and seconds
> +         respectively
>
>  *-S, \--sync*::
>        Synchronize packages. Packages are installed directly from the ftp
> diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
> index 83c437f..a39a154 100644
> --- a/lib/libalpm/remove.c
> +++ b/lib/libalpm/remove.c
> @@ -27,6 +27,7 @@
>  #include <stdlib.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <time.h>
>  #include <limits.h>
>  #include <unistd.h>
>  #include <sys/stat.h>
> @@ -287,7 +288,8 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info,
>                        }
>                }
>        } else {
> -               /* if the file needs backup and has been modified, back it up to .pacsave */
> +               /* if the file needs backup and has been modified, back it up to
> +                * .pacsave.YYYY-MM-DD-HHMMSS */
>                alpm_backup_t *backup = _alpm_needbackup(fileobj->name, info);
>                if(backup) {
>                        if(nosave) {
> @@ -298,7 +300,21 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info,
>                                FREE(filehash);
>                                if(cmp != 0) {
>                                        char newpath[PATH_MAX];
> -                                       snprintf(newpath, PATH_MAX, "%s.pacsave", file);
> +                                       char timestr[21];
> +                                       time_t curtime;
> +                                       struct tm tm;
> +                                       size_t ret;
> +
> +                                       curtime = time(NULL);
> +                                       localtime_r(&curtime, &tm);
> +                                       ret = strftime(timestr, 21, "%Y-%m-%d-%H%M%S", &tm);
> +                                       if (ret == 0) {
> +                                               /* Year with century can't fit.
> +                                                * So we print year without century (00 to 99) */
> +                                               strftime(timestr, 21, "%y-%m-%d-%H%M%S", &tm);
> +                                       }
> +
> +                                       snprintf(newpath, PATH_MAX, "%s.pacsave.%s", file, timestr);
>                                        rename(file, newpath);
>                                        _alpm_log(handle, ALPM_LOG_WARNING, _("%s saved as %s\n"), file, newpath);
>                                        alpm_logaction(handle, "warning: %s saved as %s\n", file, newpath);
> diff --git a/test/pacman/pmrule.py b/test/pacman/pmrule.py
> index cb7ae88..44cee8a 100644
> --- a/test/pacman/pmrule.py
> +++ b/test/pacman/pmrule.py
> @@ -17,6 +17,7 @@
>
>  import os
>  import stat
> +import re
>
>  import util
>
> @@ -141,8 +142,24 @@ def check(self, test):
>                 if not os.path.isfile("%s.pacorig" % filename):
>                     success = 0
>             elif case == "PACSAVE":
> -                if not os.path.isfile("%s.pacsave" % filename):
> -                    success = 0
> +                # pacsave.YYYY-MM-DD-HHMMSS
> +                saved_re = re.compile(filename + ".pacsave." + "\d{2,}-\d{2}-\d{2}-\d{6}")
> +
> +                # Extract directory component of pacsave file
> +                dir_ = ""
> +                dir_re = re.compile('(.*)/[^/]*')
> +                dir_match = dir_re.match(filename)
> +                if dir_match is not None:
> +                    dir_ = dir_match.group(1)
> +                dir_ = os.path.join(test.root, dir_)
> +
> +                success = 0
> +                files = os.listdir(dir_)
> +                for f in files:
> +                    fullname = os.path.join(dir_, f)
> +                    if saved_re.match(fullname):
> +                        success = 1
> +                        break
>             else:
>                 print "FILE rule '%s' not found" % case
>                 success = -1
> --
> 1.7.6.178.g55272
>
>
>


More information about the pacman-dev mailing list