This implements FS#7308

Signed-off-by: Florian Pritz <[email protected]>
---

This is bascially the same as the first patch, apart from small changes to
the error checking code (gettext support, only printing errno when it was
set, checking error of time() independently).

 doc/pacman.conf.5.txt |    3 +++
 lib/libalpm/alpm.h    |    2 ++
 lib/libalpm/handle.c  |    7 +++++++
 lib/libalpm/handle.h  |    1 +
 lib/libalpm/remove.c  |   33 +++++++++++++++++++++++++++++++--
 src/pacman/conf.c     |    3 +++
 src/pacman/conf.h     |    1 +
 7 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
index a9c5db3..36ac223 100644
--- a/doc/pacman.conf.5.txt
+++ b/doc/pacman.conf.5.txt
@@ -177,6 +177,9 @@ Options
        Performs an approximate check for adequate available disk space before
        installing packages.
 
+*PacsaveDate*::
+       Append the date to the filename when generating .pacsave files.
+
 *VerbosePkgLists*::
        Displays name, version and size of target packages formatted
        as a table for upgrade, sync and remove operations.
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index bb792cf..2a9d0ba 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -547,6 +547,8 @@ int alpm_option_set_deltaratio(alpm_handle_t *handle, 
double ratio);
 int alpm_option_get_checkspace(alpm_handle_t *handle);
 int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
 
+int alpm_option_set_pacsavedate(alpm_handle_t *handle, int pacsavedate);
+
 alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle);
 int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t 
level);
 
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 2db27fb..86ca5eb 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -603,6 +603,13 @@ int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t 
*handle, int checkspace)
        return 0;
 }
 
+int SYMEXPORT alpm_option_set_pacsavedate(alpm_handle_t *handle, int 
pacsavedate)
+{
+       CHECK_HANDLE(handle, return -1);
+       handle->pacsavedate = pacsavedate;
+       return 0;
+}
+
 int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
                alpm_siglevel_t level)
 {
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index c0ad668..f551b8c 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -91,6 +91,7 @@ struct __alpm_handle_t {
        double deltaratio;       /* Download deltas if possible; a ratio value 
*/
        int usesyslog;           /* Use syslog instead of logfile? */ /* TODO 
move to frontend */
        int checkspace;          /* Check disk space before installing */
+       int pacsavedate;          /* Append date to .pacsave files */
        alpm_siglevel_t siglevel;   /* Default signature verification level */
 
        /* error code */
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 469ce9b..df2dda8 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -28,6 +28,7 @@
 #include <limits.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <time.h>
 
 /* libalpm */
 #include "remove.h"
@@ -322,9 +323,37 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t 
*oldpkg,
                                FREE(filehash);
                                if(cmp != 0) {
                                        char *newpath;
-                                       size_t len = strlen(file) + 8 + 1;
+
+                                       // not configurable, makes size 
calculation of the final string easier
+                                       char *date_fmt = "_%Y-%m-%d_%H%M%S";
+                                       char date_string[18 + 1];
+
+                                       size_t len = strlen(file) + 8 + 1 + 
sizeof(date_string);
+
+                                       if (handle->pacsavedate) {
+                                               time_t t;
+                                               struct tm *tm;
+
+                                               t = time(NULL);
+                                               if (t == ((time_t)-1)) {
+                                                       _alpm_log(handle, 
ALPM_LOG_ERROR, _("failed to determine time for pacsave name: time returned -1: 
%s\n"), strerror(errno));
+                                                       date_string[0] = '\0';
+                                               }
+
+                                               tm = localtime(&t);
+                                               if (tm == NULL) {
+                                                       _alpm_log(handle, 
ALPM_LOG_ERROR, _("failed to determine time for pacsave name: localtime 
returned NULL\n"));
+                                                       date_string[0] = '\0';
+                                               } else {
+                                                       if 
(strftime(date_string, sizeof(date_string), date_fmt, tm) == 0) {
+                                                               
_alpm_log(handle, ALPM_LOG_ERROR, _("failed to determine time for pacsave name: 
strftime returned 0\n"));
+                                                               date_string[0] 
= '\0';
+                                                       }
+                                               }
+                                       }
+
                                        MALLOC(newpath, len, RET_ERR(handle, 
ALPM_ERR_MEMORY, -1));
-                                       snprintf(newpath, len, "%s.pacsave", 
file);
+                                       snprintf(newpath, len, "%s.pacsave%s", 
file, date_string);
                                        if(rename(file, newpath)) {
                                                _alpm_log(handle, 
ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
                                                                file, newpath, 
strerror(errno));
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 4aaacb5..4357dc1 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -404,6 +404,8 @@ static int _parse_options(const char *key, char *value,
                        pm_printf(ALPM_LOG_DEBUG, "config: totaldownload\n");
                } else if(strcmp(key, "CheckSpace") == 0) {
                        config->checkspace = 1;
+               } else if(strcmp(key, "PacsaveDate") == 0) {
+                       config->pacsavedate = 1;
                } else {
                        pm_printf(ALPM_LOG_WARNING,
                                        _("config file %s, line %d: directive 
'%s' in section '%s' not recognized.\n"),
@@ -614,6 +616,7 @@ static int setup_libalpm(void)
 
        alpm_option_set_arch(handle, config->arch);
        alpm_option_set_checkspace(handle, config->checkspace);
+       alpm_option_set_pacsavedate(handle, config->pacsavedate);
        alpm_option_set_usesyslog(handle, config->usesyslog);
        alpm_option_set_deltaratio(handle, config->deltaratio);
 
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 69c955e..0e170ad 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -33,6 +33,7 @@ typedef struct __config_t {
        unsigned short logmask;
        unsigned short print;
        unsigned short checkspace;
+       unsigned short pacsavedate;
        unsigned short usesyslog;
        double deltaratio;
        char *arch;
-- 
1.7.10

Reply via email to