[pacman-dev] [PATCH] Append timestamp to .pacsave files; PacsaveDate config option
This implements FS#7308 Signed-off-by: Florian Pritz <bluewind@xinu.at> --- The bugreport also suggests that this could be added for .pacnew, but I don't think this make much sense because those will change more often and when you diff them you only really need the most recent version. I'm not too happy about the name of the config option so if you have ideas, please shoot. I'm adding the date after ".pacsave" in order to keep scripts such as pacdiff working. I haven't checked, but they might not be able to deal properly with "foo_<date>.pacsave". 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 | 29 +++++++++++++++++++++++++++-- src/pacman/conf.c | 3 +++ src/pacman/conf.h | 1 + 7 files changed, 44 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..713018f 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,33 @@ 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); + tm = localtime(&t); + + if (tm == NULL) { + _alpm_log(handle, ALPM_LOG_ERROR, "failed to determine time for pacsave name: localtime: %s\n", strerror(errno)); + 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: %s\n", strerror(errno)); + 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
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
On 23/04/12 01:28, Florian Pritz wrote:
This implements FS#7308
Signed-off-by: Florian Pritz <bluewind@xinu.at> ---
For reference: Dan suggests using .1, .2 ... for extensions logrotate style instead of dates here: http://mailman.archlinux.org/pipermail/pacman-dev/2011-August/013972.html Note that with that scheme, we do not need a config option. And here is a patchset that does this: http://mailman.archlinux.org/pipermail/pacman-dev/2011-August/013981.html Allan
participants (2)
-
Allan McRae
-
Florian Pritz