This implements FS#7308 Signed-off-by: Florian Pritz <bluewind@xinu.at> --- 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