summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/add.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/add.c')
-rw-r--r--lib/libalpm/add.c105
1 files changed, 63 insertions, 42 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index f39a0ecf..ed57a079 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -40,7 +40,6 @@
#include "alpm_list.h"
#include "trans.h"
#include "util.h"
-#include "cache.h"
#include "log.h"
#include "backup.h"
#include "package.h"
@@ -54,7 +53,7 @@
* @param target the name of the file target to add
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
-int SYMEXPORT alpm_add_target(char *target)
+int SYMEXPORT alpm_add_target(const char *target)
{
pmpkg_t *pkg = NULL;
const char *pkgname, *pkgver;
@@ -110,6 +109,31 @@ error:
return(-1);
}
+static int perform_extraction(struct archive *archive,
+ struct archive_entry *entry, const char *filename, const char *origname)
+{
+ int ret;
+ const int archive_flags = ARCHIVE_EXTRACT_OWNER |
+ ARCHIVE_EXTRACT_PERM |
+ ARCHIVE_EXTRACT_TIME;
+
+ archive_entry_set_pathname(entry, filename);
+
+ ret = archive_read_extract(archive, entry, archive_flags);
+ if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) {
+ /* operation succeeded but a "non-critical" error was encountered */
+ _alpm_log(PM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
+ origname, archive_error_string(archive));
+ } else if(ret != ARCHIVE_OK) {
+ _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"),
+ origname, archive_error_string(archive));
+ alpm_logaction("error: could not extract %s (%s)\n",
+ origname, archive_error_string(archive));
+ return(1);
+ }
+ return(0);
+}
+
static int extract_single_file(struct archive *archive,
struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg,
pmtrans_t *trans, pmdb_t *db)
@@ -120,9 +144,6 @@ static int extract_single_file(struct archive *archive,
int needbackup = 0, notouch = 0;
char *hash_orig = NULL;
char *entryname_orig = NULL;
- const int archive_flags = ARCHIVE_EXTRACT_OWNER |
- ARCHIVE_EXTRACT_PERM |
- ARCHIVE_EXTRACT_TIME;
int errors = 0;
entryname = archive_entry_pathname(entry);
@@ -277,18 +298,10 @@ static int extract_single_file(struct archive *archive,
int ret;
snprintf(checkfile, PATH_MAX, "%s.paccheck", filename);
- archive_entry_set_pathname(entry, checkfile);
-
- ret = archive_read_extract(archive, entry, archive_flags);
- if(ret == ARCHIVE_WARN) {
- /* operation succeeded but a non-critical error was encountered */
- _alpm_log(PM_LOG_DEBUG, "warning extracting %s (%s)\n",
- entryname_orig, archive_error_string(archive));
- } else if(ret != ARCHIVE_OK) {
- _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"),
- entryname_orig, archive_error_string(archive));
- alpm_logaction("error: could not extract %s (%s)\n",
- entryname_orig, archive_error_string(archive));
+
+ ret = perform_extraction(archive, entry, checkfile, entryname_orig);
+ if(ret == 1) {
+ /* error */
FREE(hash_orig);
FREE(entryname_orig);
return(1);
@@ -430,18 +443,9 @@ static int extract_single_file(struct archive *archive,
unlink(filename);
}
- archive_entry_set_pathname(entry, filename);
-
- ret = archive_read_extract(archive, entry, archive_flags);
- if(ret == ARCHIVE_WARN) {
- /* operation succeeded but a non-critical error was encountered */
- _alpm_log(PM_LOG_DEBUG, "warning extracting %s (%s)\n",
- entryname_orig, archive_error_string(archive));
- } else if(ret != ARCHIVE_OK) {
- _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"),
- entryname_orig, archive_error_string(archive));
- alpm_logaction("error: could not extract %s (%s)\n",
- entryname_orig, archive_error_string(archive));
+ ret = perform_extraction(archive, entry, filename, entryname_orig);
+ if(ret == 1) {
+ /* error */
FREE(entryname_orig);
return(1);
}
@@ -498,7 +502,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
oldpkg = _alpm_pkg_dup(local);
/* make sure all infos are loaded because the database entry
* will be removed soon */
- _alpm_db_read(oldpkg->origin_data.db, oldpkg, INFRQ_ALL);
+ _alpm_local_db_read(oldpkg->origin_data.db, oldpkg, INFRQ_ALL);
EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg);
_alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
@@ -544,7 +548,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
/* prepare directory for database entries so permission are correct after
changelog/install script installation (FS#12263) */
- if(_alpm_db_prepare(db, newpkg)) {
+ if(_alpm_local_db_prepare(db, newpkg)) {
alpm_logaction("error: could not create database entry %s-%s\n",
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
pm_errno = PM_ERR_DB_WRITE;
@@ -556,6 +560,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
struct archive *archive;
struct archive_entry *entry;
char cwd[PATH_MAX] = "";
+ int restore_cwd = 0;
_alpm_log(PM_LOG_DEBUG, "extracting files\n");
@@ -579,11 +584,16 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
/* save the cwd so we can restore it later */
if(getcwd(cwd, PATH_MAX) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not get current working directory\n"));
- cwd[0] = 0;
+ } else {
+ restore_cwd = 1;
}
/* libarchive requires this for extracting hard links */
- chdir(handle->root);
+ if(chdir(handle->root) != 0) {
+ _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), handle->root, strerror(errno));
+ ret = -1;
+ goto cleanup;
+ }
/* call PROGRESS once with 0 percent, as we sort-of skip that here */
if(is_upgrade) {
@@ -629,9 +639,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
}
archive_read_finish(archive);
- /* restore the old cwd is we have it */
- if(strlen(cwd)) {
- chdir(cwd);
+ /* restore the old cwd if we have it */
+ if(restore_cwd && chdir(cwd) != 0) {
+ _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));
}
if(errors) {
@@ -656,7 +666,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
_alpm_log(PM_LOG_DEBUG, "updating database\n");
_alpm_log(PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);
- if(_alpm_db_write(db, newpkg, INFRQ_ALL)) {
+ if(_alpm_local_db_write(db, newpkg, INFRQ_ALL)) {
_alpm_log(PM_LOG_ERROR, _("could not update database entry %s-%s\n"),
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
alpm_logaction("error: could not update database entry %s-%s\n",
@@ -706,6 +716,7 @@ cleanup:
int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)
{
int pkg_count, pkg_current;
+ int skip_ldconfig = 0, ret = 0;
alpm_list_t *targ;
ALPM_LOG_FUNC;
@@ -723,18 +734,28 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)
/* loop through our package list adding/upgrading one at a time */
for(targ = trans->add; targ; targ = targ->next) {
if(handle->trans->state == STATE_INTERRUPTED) {
- return(0);
+ return(ret);
}
pmpkg_t *newpkg = (pmpkg_t *)targ->data;
- commit_single_pkg(newpkg, pkg_current, pkg_count, trans, db);
+ if(commit_single_pkg(newpkg, pkg_current, pkg_count, trans, db)) {
+ /* something screwed up on the commit, abort the trans */
+ trans->state = STATE_INTERRUPTED;
+ pm_errno = PM_ERR_TRANS_ABORT;
+ /* running ldconfig at this point could possibly screw system */
+ skip_ldconfig = 1;
+ ret = -1;
+ }
+
pkg_current++;
}
- /* run ldconfig if it exists */
- _alpm_ldconfig(handle->root);
+ if(!skip_ldconfig) {
+ /* run ldconfig if it exists */
+ _alpm_ldconfig(handle->root);
+ }
- return(0);
+ return(ret);
}
/* vim: set ts=2 sw=2 noet: */