[pacman-dev] [PATCH 1/2] alpm: check for invalid sync db before replacing original
ivy.foster at gmail.com
ivy.foster at gmail.com
Thu Sep 8 00:22:48 UTC 2016
From: Ivy Foster <ivy.foster at gmail.com>
Closes #46107
Signed-off-by: Ivy Foster <ivy.foster at gmail.com>
---
lib/libalpm/alpm.h | 1 +
lib/libalpm/be_sync.c | 26 +++++++++++++++++++++++++-
lib/libalpm/error.c | 2 ++
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 168d71b..0dd68a7 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -75,6 +75,7 @@ typedef enum _alpm_errno_t {
ALPM_ERR_DB_VERSION,
ALPM_ERR_DB_WRITE,
ALPM_ERR_DB_REMOVE,
+ ALPM_ERR_DB_BACKUP,
/* Servers */
ALPM_ERR_SERVER_BAD_URL,
ALPM_ERR_SERVER_NONE,
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 32a669d..ee438f8 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -182,6 +182,9 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
mode_t oldmask;
alpm_handle_t *handle;
alpm_siglevel_t level;
+ char *newdb;
+ char *olddb;
+ size_t len;
/* Sanity checks */
ASSERT(db != NULL, return -1);
@@ -218,10 +221,23 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
dbext = db->handle->dbext;
+ len = strlen(syncpath) + strlen(db->treename) + strlen(dbext) + 2;
+ /* TODO fix leak syncpath and umask unset */
+ MALLOC(newdb, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
+ snprintf(newdb, len, "%s/%s%s", syncpath, db->treename, dbext);
+ len += 4;
+ /* TODO fix leak syncpath and umask unset */
+ MALLOC(olddb, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
+ snprintf(olddb, len, "%s.bak", newdb);
+ if (rename(newdb, olddb) == -1) {
+ ret = -1;
+ handle->pm_errno = ALPM_ERR_DB_BACKUP;
+ goto cleanup;
+ }
+
for(i = db->servers; i; i = i->next) {
const char *server = i->data, *final_db_url = NULL;
struct dload_payload payload;
- size_t len;
int sig_ret = 0;
memset(&payload, 0, sizeof(struct dload_payload));
@@ -315,15 +331,23 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
}
}
+cleanup:
if(ret == -1) {
/* pm_errno was set by the download code */
_alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n",
alpm_strerror(handle->pm_errno));
+ if (handle->pm_errno != ALPM_ERR_DB_BACKUP && rename(olddb, newdb) == -1) {
+ _alpm_log(handle, ALPM_LOG_DEBUG, "failed to replace original db: %s\n",
+ alpm_strerror(ALPM_ERR_DB_BACKUP));
+ }
} else {
+ unlink(olddb);
handle->pm_errno = 0;
}
_alpm_handle_unlock(handle);
+ free(newdb);
+ free(olddb);
free(syncpath);
umask(oldmask);
return ret;
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 2d6d071..e707d43 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -78,6 +78,8 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
return _("could not update database");
case ALPM_ERR_DB_REMOVE:
return _("could not remove database entry");
+ case ALPM_ERR_DB_BACKUP:
+ return _("could not back up old database");
/* Servers */
case ALPM_ERR_SERVER_BAD_URL:
return _("invalid url for server");
--
2.9.3
More information about the pacman-dev
mailing list