[pacman-dev] [PATCH] Append timestamp to .pacsave files; PacsaveDate config option

Florian Pritz bluewind at xinu.at
Sun Apr 22 09:46:01 EDT 2012


This implements FS#7308

Signed-off-by: Florian Pritz <bluewind at 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


More information about the pacman-dev mailing list