summaryrefslogtreecommitdiff
path: root/lib/libalpm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/add.c19
-rw-r--r--lib/libalpm/alpm.h32
-rw-r--r--lib/libalpm/be_files.c83
-rw-r--r--lib/libalpm/cache.c31
-rw-r--r--lib/libalpm/conflict.c6
-rw-r--r--lib/libalpm/db.c45
-rw-r--r--lib/libalpm/db.h5
-rw-r--r--lib/libalpm/delta.c4
-rw-r--r--lib/libalpm/deps.c104
-rw-r--r--lib/libalpm/deps.h6
-rw-r--r--lib/libalpm/dload.c68
-rw-r--r--lib/libalpm/error.c12
-rw-r--r--lib/libalpm/handle.c41
-rw-r--r--lib/libalpm/handle.h1
-rw-r--r--lib/libalpm/package.c9
-rw-r--r--lib/libalpm/remove.c16
-rw-r--r--lib/libalpm/sync.c172
-rw-r--r--lib/libalpm/sync.h3
-rw-r--r--lib/libalpm/trans.c22
-rw-r--r--lib/libalpm/trans.h1
-rw-r--r--lib/libalpm/util.c51
21 files changed, 340 insertions, 391 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 838f5a6d..6eb2085e 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -114,7 +114,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
/* look for unsatisfied dependencies */
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
- lp = alpm_checkdeps(db, 1, NULL, trans->packages);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, NULL, trans->packages);
if(lp != NULL) {
if(data) {
*data = lp;
@@ -456,8 +456,8 @@ static int extract_single_file(struct archive *archive,
return(1);
}
- hash_local = alpm_get_md5sum(filename);
- hash_pkg = alpm_get_md5sum(checkfile);
+ hash_local = alpm_compute_md5sum(filename);
+ hash_pkg = alpm_compute_md5sum(checkfile);
/* append the new md5 hash to it's respective entry
* in newpkg's backup (it will be the new orginal) */
@@ -618,7 +618,7 @@ static int extract_single_file(struct archive *archive,
}
_alpm_log(PM_LOG_DEBUG, "appending backup entry for %s\n", filename);
- hash = alpm_get_md5sum(filename);
+ hash = alpm_compute_md5sum(filename);
MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(backup, "%s\t%s", oldbackup, hash);
@@ -650,17 +650,18 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
if(local) {
is_upgrade = 1;
- EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, NULL);
- _alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
- newpkg->name, newpkg->version);
-
/* we'll need to save some record for backup checks later */
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);
+
+ EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg);
+ _alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
+ newpkg->name, newpkg->version);
+
/* copy over the install reason */
- newpkg->reason = alpm_pkg_get_reason(local);
+ newpkg->reason = alpm_pkg_get_reason(oldpkg);
/* pre_upgrade scriptlet */
if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 16b48a0a..3836d608 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -132,11 +132,6 @@ void alpm_option_add_ignorepkg(const char *pkg);
void alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs);
int alpm_option_remove_ignorepkg(const char *pkg);
-alpm_list_t *alpm_option_get_holdpkgs();
-void alpm_option_add_holdpkg(const char *pkg);
-void alpm_option_set_holdpkgs(alpm_list_t *holdpkgs);
-int alpm_option_remove_holdpkg(const char *pkg);
-
alpm_list_t *alpm_option_get_ignoregrps();
void alpm_option_add_ignoregrp(const char *grp);
void alpm_option_set_ignoregrps(alpm_list_t *ignoregrps);
@@ -170,10 +165,10 @@ int alpm_db_setserver(pmdb_t *db, const char *url);
int alpm_db_update(int level, pmdb_t *db);
pmpkg_t *alpm_db_get_pkg(pmdb_t *db, const char *name);
-alpm_list_t *alpm_db_getpkgcache(pmdb_t *db);
+alpm_list_t *alpm_db_get_pkgcache(pmdb_t *db);
pmgrp_t *alpm_db_readgrp(pmdb_t *db, const char *name);
-alpm_list_t *alpm_db_getgrpcache(pmdb_t *db);
+alpm_list_t *alpm_db_get_grpcache(pmdb_t *db);
alpm_list_t *alpm_db_search(pmdb_t *db, const alpm_list_t* needles);
/*
@@ -218,6 +213,7 @@ alpm_list_t *alpm_pkg_get_deltas(pmpkg_t *pkg);
alpm_list_t *alpm_pkg_get_replaces(pmpkg_t *pkg);
alpm_list_t *alpm_pkg_get_files(pmpkg_t *pkg);
alpm_list_t *alpm_pkg_get_backup(pmpkg_t *pkg);
+pmdb_t *alpm_pkg_get_db(pmpkg_t *pkg);
void *alpm_pkg_changelog_open(pmpkg_t *pkg);
size_t alpm_pkg_changelog_read(void *ptr, size_t size,
const pmpkg_t *pkg, const void *fp);
@@ -253,8 +249,6 @@ alpm_list_t *alpm_grp_get_pkgs(const pmgrp_t *grp);
pmpkg_t *alpm_sync_get_pkg(const pmsyncpkg_t *sync);
alpm_list_t *alpm_sync_get_removes(const pmsyncpkg_t *sync);
pmpkg_t *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync);
-int alpm_sync_sysupgrade(pmdb_t *db_local,
- alpm_list_t *dbs_sync, alpm_list_t **syncpkgs);
/*
* Transactions
@@ -282,7 +276,7 @@ typedef enum _pmtransflag_t {
PM_TRANS_FLAG_DOWNLOADONLY = 0x200,
PM_TRANS_FLAG_NOSCRIPTLET = 0x400,
PM_TRANS_FLAG_NOCONFLICTS = 0x800,
- PM_TRANS_FLAG_PRINTURIS = 0x1000,
+ /* 0x1000 flag can go here */
PM_TRANS_FLAG_NEEDED = 0x2000,
PM_TRANS_FLAG_ALLEXPLICIT = 0x4000,
PM_TRANS_FLAG_UNNEEDED = 0x8000,
@@ -364,10 +358,6 @@ typedef enum _pmtransevt_t {
* A line of text is passed to the callback.
*/
PM_TRANS_EVT_SCRIPTLET_INFO,
- /** Print URI.
- * The database's URI and the package's filename are passed to the callback.
- */
- PM_TRANS_EVT_PRINTURI,
/** Files will be downloaded from a repository.
* The repository's tree name is passed to the callback.
*/
@@ -382,8 +372,7 @@ typedef enum _pmtransconv_t {
PM_TRANS_CONV_CONFLICT_PKG = 0x04,
PM_TRANS_CONV_CORRUPTED_PKG = 0x08,
PM_TRANS_CONV_LOCAL_NEWER = 0x10,
- /* 0x20 flag can go here */
- PM_TRANS_CONV_REMOVE_HOLDPKG = 0x40
+ PM_TRANS_CONV_REMOVE_PKGS = 0x20,
} pmtransconv_t;
/* Transaction Progress */
@@ -431,7 +420,7 @@ typedef enum _pmdepmod_t {
} pmdepmod_t;
int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep);
-alpm_list_t *alpm_checkdeps(pmdb_t *db, int reversedeps,
+alpm_list_t *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
alpm_list_t *remove, alpm_list_t *upgrade);
alpm_list_t *alpm_deptest(pmdb_t *db, alpm_list_t *targets);
@@ -439,7 +428,7 @@ const char *alpm_miss_get_target(const pmdepmissing_t *miss);
pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss);
const char *alpm_miss_get_causingpkg(const pmdepmissing_t *miss);
-alpm_list_t *alpm_checkdbconflicts(pmdb_t *db_local);
+alpm_list_t *alpm_checkconflicts(alpm_list_t *pkglist);
const char *alpm_conflict_get_package1(pmconflict_t *conflict);
const char *alpm_conflict_get_package2(pmconflict_t *conflict);
@@ -447,7 +436,7 @@ const char *alpm_conflict_get_package2(pmconflict_t *conflict);
pmdepmod_t alpm_dep_get_mod(const pmdepend_t *dep);
const char *alpm_dep_get_name(const pmdepend_t *dep);
const char *alpm_dep_get_version(const pmdepend_t *dep);
-char *alpm_dep_get_string(const pmdepend_t *dep);
+char *alpm_dep_compute_string(const pmdepend_t *dep);
/*
* File conflicts
@@ -468,7 +457,7 @@ const char *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict);
*/
/* checksums */
-char *alpm_get_md5sum(const char *name);
+char *alpm_compute_md5sum(const char *name);
/*
* Errors
@@ -527,11 +516,10 @@ enum _pmerrno_t {
PM_ERR_INTERNAL_ERROR,
PM_ERR_DB_SYNC,
PM_ERR_RETRIEVE,
- PM_ERR_PKG_HOLD,
PM_ERR_INVALID_REGEX,
/* External library errors */
PM_ERR_LIBARCHIVE,
- PM_ERR_LIBDOWNLOAD,
+ PM_ERR_LIBFETCH,
PM_ERR_EXTERNAL_DOWNLOAD
};
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 31b23172..0765b8db 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -113,6 +113,26 @@ static int setlastupdate(const pmdb_t *db, time_t time)
return(ret);
}
+static int checkdbdir(pmdb_t *db)
+{
+ struct stat buf;
+ char *path = db->path;
+
+ if(stat(path, &buf) != 0) {
+ _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
+ path);
+ if(_alpm_makepath(path) != 0) {
+ RET_ERR(PM_ERR_SYSTEM, -1);
+ }
+ } else if(!S_ISDIR(buf.st_mode)) {
+ _alpm_log(PM_LOG_WARNING, "removing bogus database: %s\n", path);
+ if(unlink(path) != 0 || _alpm_makepath(path) != 0) {
+ RET_ERR(PM_ERR_SYSTEM, -1);
+ }
+ }
+ return(0);
+}
+
/** Update a package database
* @param force if true, then forces the update, otherwise update only in case
* the database isn't up to date
@@ -122,7 +142,6 @@ static int setlastupdate(const pmdb_t *db, time_t time)
*/
int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
{
- alpm_list_t *lp;
char *dbfile, *dbfilepath;
time_t newmtime = 0, lastupdate = 0;
const char *dbpath;
@@ -176,14 +195,9 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
return(-1);
} else {
/* remove the old dir */
- _alpm_log(PM_LOG_DEBUG, "flushing database %s\n", db->path);
- for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
- pmpkg_t *pkg = lp->data;
- if(pkg && _alpm_db_remove(db, pkg) == -1) {
- _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"),
- db->treename, pkg->name);
- RET_ERR(PM_ERR_DB_REMOVE, -1);
- }
+ if(_alpm_rmrf(db->path) != 0) {
+ _alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename);
+ RET_ERR(PM_ERR_DB_REMOVE, -1);
}
/* Cache needs to be rebuilt */
@@ -195,6 +209,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
sprintf(dbfilepath, "%s%s" DBEXT, dbpath, db->treename);
/* uncompress the sync database */
+ checkdbdir(db);
ret = _alpm_unpack(dbfilepath, db->path, NULL);
if(ret) {
free(dbfilepath);
@@ -214,36 +229,6 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
return(0);
}
-int _alpm_db_open(pmdb_t *db)
-{
- ALPM_LOG_FUNC;
-
- if(db == NULL) {
- RET_ERR(PM_ERR_DB_NULL, -1);
- }
-
- _alpm_log(PM_LOG_DEBUG, "opening database from path '%s'\n", db->path);
- db->handle = opendir(db->path);
- if(db->handle == NULL) {
- RET_ERR(PM_ERR_DB_OPEN, -1);
- }
-
- return(0);
-}
-
-void _alpm_db_close(pmdb_t *db)
-{
- ALPM_LOG_FUNC;
-
- if(db == NULL) {
- return;
- }
-
- if(db->handle) {
- closedir(db->handle);
- db->handle = NULL;
- }
-}
static int splitname(const char *target, pmpkg_t *pkg)
{
@@ -290,13 +275,17 @@ int _alpm_db_populate(pmdb_t *db)
struct dirent *ent = NULL;
struct stat sbuf;
char path[PATH_MAX];
+ DIR *dbdir;
ALPM_LOG_FUNC;
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
- rewinddir(db->handle);
- while((ent = readdir(db->handle)) != NULL) {
+ dbdir = opendir(db->path);
+ if(dbdir == NULL) {
+ return(0);
+ }
+ while((ent = readdir(dbdir)) != NULL) {
const char *name = ent->d_name;
pmpkg_t *pkg;
@@ -311,6 +300,7 @@ int _alpm_db_populate(pmdb_t *db)
pkg = _alpm_pkg_new();
if(pkg == NULL) {
+ closedir(dbdir);
return(-1);
}
/* split the db entry name */
@@ -336,6 +326,7 @@ int _alpm_db_populate(pmdb_t *db)
count++;
}
+ closedir(dbdir);
db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
return(count);
}
@@ -658,12 +649,16 @@ int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info)
int retval = 0;
char *pkgpath = NULL;
- oldmask = umask(0000);
+ if(checkdbdir(db) != 0) {
+ return(-1);
+ }
+ oldmask = umask(0000);
pkgpath = get_pkgpath(db, info);
if((retval = mkdir(pkgpath, 0755)) != 0) {
- _alpm_log(PM_LOG_ERROR, _("could not create directory %s: %s\n"), pkgpath, strerror(errno));
+ _alpm_log(PM_LOG_ERROR, _("could not create directory %s: %s\n"),
+ pkgpath, strerror(errno));
}
free(pkgpath);
@@ -826,7 +821,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
if(info->depends) {
fputs("%DEPENDS%\n", fp);
for(lp = info->depends; lp; lp = lp->next) {
- char *depstring = alpm_dep_get_string(lp->data);
+ char *depstring = alpm_dep_compute_string(lp->data);
fprintf(fp, "%s\n", depstring);
free(depstring);
}
diff --git a/lib/libalpm/cache.c b/lib/libalpm/cache.c
index 10857792..8d18f3ee 100644
--- a/lib/libalpm/cache.c
+++ b/lib/libalpm/cache.c
@@ -54,6 +54,7 @@ int _alpm_db_load_pkgcache(pmdb_t *db)
return(-1);
}
+ db->pkgcache_loaded = 1;
return(0);
}
@@ -61,7 +62,7 @@ void _alpm_db_free_pkgcache(pmdb_t *db)
{
ALPM_LOG_FUNC;
- if(db == NULL || db->pkgcache == NULL) {
+ if(db == NULL || !db->pkgcache_loaded) {
return;
}
@@ -71,10 +72,9 @@ void _alpm_db_free_pkgcache(pmdb_t *db)
alpm_list_free_inner(db->pkgcache, (alpm_list_fn_free)_alpm_pkg_free);
alpm_list_free(db->pkgcache);
db->pkgcache = NULL;
+ db->pkgcache_loaded = 0;
- if(db->grpcache) {
- _alpm_db_free_grpcache(db);
- }
+ _alpm_db_free_grpcache(db);
}
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
@@ -85,13 +85,13 @@ alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
return(NULL);
}
- if(!db->pkgcache) {
+ if(!db->pkgcache_loaded) {
_alpm_db_load_pkgcache(db);
}
/* hmmm, still NULL ?*/
if(!db->pkgcache) {
- _alpm_log(PM_LOG_DEBUG, "error: pkgcache is NULL for db '%s'\n", db->treename);
+ _alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename);
}
return(db->pkgcache);
@@ -104,7 +104,7 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
ALPM_LOG_FUNC;
- if(db == NULL || pkg == NULL) {
+ if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
return(-1);
}
@@ -139,7 +139,7 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)
ALPM_LOG_FUNC;
- if(db == NULL || pkg == NULL) {
+ if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
return(-1);
}
@@ -172,7 +172,7 @@ pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)
alpm_list_t *pkgcache = _alpm_db_get_pkgcache(db);
if(!pkgcache) {
- _alpm_log(PM_LOG_DEBUG, "error: failed to get '%s' from NULL pkgcache\n",
+ _alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n",
target);
return(NULL);
}
@@ -192,10 +192,6 @@ int _alpm_db_load_grpcache(pmdb_t *db)
return(-1);
}
- if(db->pkgcache == NULL) {
- _alpm_db_load_pkgcache(db);
- }
-
_alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n",
db->treename);
@@ -230,6 +226,7 @@ int _alpm_db_load_grpcache(pmdb_t *db)
}
}
+ db->grpcache_loaded = 1;
return(0);
}
@@ -239,15 +236,19 @@ void _alpm_db_free_grpcache(pmdb_t *db)
ALPM_LOG_FUNC;
- if(db == NULL || db->grpcache == NULL) {
+ if(db == NULL || !db->grpcache_loaded) {
return;
}
+ _alpm_log(PM_LOG_DEBUG, "freeing group cache for repository '%s'\n",
+ db->treename);
+
for(lg = db->grpcache; lg; lg = lg->next) {
_alpm_grp_free(lg->data);
lg->data = NULL;
}
FREELIST(db->grpcache);
+ db->grpcache_loaded = 0;
}
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
@@ -258,7 +259,7 @@ alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
return(NULL);
}
- if(db->grpcache == NULL) {
+ if(!db->grpcache_loaded) {
_alpm_db_load_grpcache(db);
}
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index a044fc60..499e55a4 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -218,11 +218,11 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages)
/** Check the package conflicts in a database
*
- * @param db_local the database to check
+ * @param pkglist the list of packages to check
* @return an alpm_list_t of pmconflict_t
*/
-alpm_list_t SYMEXPORT *alpm_checkdbconflicts(pmdb_t *db_local) {
- return(_alpm_innerconflicts(_alpm_db_get_pkgcache(db_local)));
+alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_list_t *pkglist) {
+ return(_alpm_innerconflicts(pkglist));
}
/* Returns a alpm_list_t* of file conflicts.
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 5632ffac..561967ce 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -85,9 +85,6 @@ static void _alpm_db_unregister(pmdb_t *db)
return;
}
- _alpm_log(PM_LOG_DEBUG, "closing database '%s'\n", db->treename);
- _alpm_db_close(db);
-
_alpm_log(PM_LOG_DEBUG, "unregistering database '%s'\n", db->treename);
_alpm_db_free(db);
}
@@ -263,7 +260,7 @@ pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name)
* @param db pointer to the package database to get the package from
* @return the list of packages on success, NULL on error
*/
-alpm_list_t SYMEXPORT *alpm_db_getpkgcache(pmdb_t *db)
+alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(pmdb_t *db)
{
ALPM_LOG_FUNC;
@@ -295,7 +292,7 @@ pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name)
* @param db pointer to the package database to get the group from
* @return the list of groups on success, NULL on error
*/
-alpm_list_t SYMEXPORT *alpm_db_getgrpcache(pmdb_t *db)
+alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db)
{
ALPM_LOG_FUNC;
@@ -431,10 +428,8 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
pmdb_t *_alpm_db_register_local(void)
{
- struct stat buf;
pmdb_t *db;
const char *dbpath;
- char path[PATH_MAX];
ALPM_LOG_FUNC;
@@ -445,40 +440,23 @@ pmdb_t *_alpm_db_register_local(void)
_alpm_log(PM_LOG_DEBUG, "registering local database\n");
- /* make sure the database directory exists */
dbpath = alpm_option_get_dbpath();
if(!dbpath) {
_alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
RET_ERR(PM_ERR_DB_OPEN, NULL);
}
- snprintf(path, PATH_MAX, "%slocal", dbpath);
- /* TODO this is rediculous, we try to do this even if we can't */
- if(stat(path, &buf) != 0 || !S_ISDIR(buf.st_mode)) {
- _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
- path);
- if(_alpm_makepath(path) != 0) {
- RET_ERR(PM_ERR_SYSTEM, NULL);
- }
- }
db = _alpm_db_new(dbpath, "local");
if(db == NULL) {
RET_ERR(PM_ERR_DB_CREATE, NULL);
}
- _alpm_log(PM_LOG_DEBUG, "opening database '%s'\n", db->treename);
- if(_alpm_db_open(db) == -1) {
- _alpm_db_free(db);
- RET_ERR(PM_ERR_DB_OPEN, NULL);
- }
-
handle->db_local = db;
return(db);
}
pmdb_t *_alpm_db_register_sync(const char *treename)
{
- struct stat buf;
pmdb_t *db;
const char *dbpath;
char path[PATH_MAX];
@@ -496,25 +474,12 @@ pmdb_t *_alpm_db_register_sync(const char *treename)
_alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename);
- /* make sure the database directory exists */
dbpath = alpm_option_get_dbpath();
if(!dbpath) {
_alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
RET_ERR(PM_ERR_DB_OPEN, NULL);
}
/* all sync DBs now reside in the sync/ subdir of the dbpath */
- snprintf(path, PATH_MAX, "%ssync/%s", dbpath, treename);
- /* TODO this is rediculous, we try to do this even if we can't */
- if(stat(path, &buf) != 0 || !S_ISDIR(buf.st_mode)) {
- _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
- path);
- if(_alpm_makepath(path) != 0) {
- RET_ERR(PM_ERR_SYSTEM, NULL);
- }
- }
-
- /* Ensure the db gets the real path. */
- path[0] = '\0';
snprintf(path, PATH_MAX, "%ssync/", dbpath);
db = _alpm_db_new(path, treename);
@@ -522,12 +487,6 @@ pmdb_t *_alpm_db_register_sync(const char *treename)
RET_ERR(PM_ERR_DB_CREATE, NULL);
}
- _alpm_log(PM_LOG_DEBUG, "opening database '%s'\n", db->treename);
- if(_alpm_db_open(db) == -1) {
- _alpm_db_free(db);
- RET_ERR(PM_ERR_DB_OPEN, NULL);
- }
-
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
return(db);
}
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index 25b90b5f..1af16355 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -41,8 +41,9 @@ typedef enum _pmdbinfrq_t {
struct __pmdb_t {
char *path;
char *treename;
- void *handle;
+ unsigned short pkgcache_loaded;
alpm_list_t *pkgcache;
+ unsigned short grpcache_loaded;
alpm_list_t *grpcache;
alpm_list_t *servers;
};
@@ -56,8 +57,6 @@ pmdb_t *_alpm_db_register_local(void);
pmdb_t *_alpm_db_register_sync(const char *treename);
/* be.c, backend specific calls */
-int _alpm_db_open(pmdb_t *db);
-void _alpm_db_close(pmdb_t *db);
int _alpm_db_populate(pmdb_t *db);
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info);
diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c
index 8dce7e3b..ff77501e 100644
--- a/lib/libalpm/delta.c
+++ b/lib/libalpm/delta.c
@@ -95,7 +95,7 @@ static alpm_list_t *delta_graph_init(alpm_list_t *deltas)
/* determine whether the delta file already exists */
fpath = _alpm_filecache_find(vdelta->delta);
- md5sum = alpm_get_md5sum(fpath);
+ md5sum = alpm_compute_md5sum(fpath);
if(fpath && md5sum && strcmp(md5sum, vdelta->delta_md5) == 0) {
vdelta->download_size = 0;
}
@@ -104,7 +104,7 @@ static alpm_list_t *delta_graph_init(alpm_list_t *deltas)
/* determine whether a base 'from' file exists */
fpath = _alpm_filecache_find(vdelta->from);
- md5sum = alpm_get_md5sum(fpath);
+ md5sum = alpm_compute_md5sum(fpath);
if(fpath && md5sum && strcmp(md5sum, vdelta->from_md5) == 0) {
v->weight = vdelta->download_size;
}
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index c667daa2..694e5be5 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -229,13 +229,13 @@ alpm_list_t SYMEXPORT *alpm_deptest(pmdb_t *db, alpm_list_t *targets)
/** Checks dependencies and returns missing ones in a list.
* Dependencies can include versions with depmod operators.
- * @param db pointer to the local package database
+ * @param pkglist the list of local packages
* @param reversedeps handles the backward dependencies
* @param remove an alpm_list_t* of packages to be removed
* @param upgrade an alpm_list_t* of packages to be upgraded (remove-then-upgrade)
* @return an alpm_list_t* of pmpkg_t* of missing_t pointers.
*/
-alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
+alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
alpm_list_t *remove, alpm_list_t *upgrade)
{
alpm_list_t *i, *j;
@@ -245,12 +245,8 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
ALPM_LOG_FUNC;
- if(db == NULL) {
- return(NULL);
- }
-
targets = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade));
- for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
+ for(i = pkglist; i; i = i->next) {
void *pkg = i->data;
if(alpm_list_find(targets, pkg, _alpm_pkg_cmp)) {
modified = alpm_list_add(modified, pkg);
@@ -273,7 +269,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
if(!_alpm_find_dep_satisfier(upgrade, depend) &&
!_alpm_find_dep_satisfier(dblist, depend)) {
/* Unsatisfied dependency in the upgrade list */
- char *missdepstring = alpm_dep_get_string(depend);
+ char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",
missdepstring, alpm_pkg_get_name(tp));
free(missdepstring);
@@ -297,7 +293,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
if(causingpkg &&
!_alpm_find_dep_satisfier(upgrade, depend) &&
!_alpm_find_dep_satisfier(dblist, depend)) {
- char *missdepstring = alpm_dep_get_string(depend);
+ char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
missdepstring, alpm_pkg_get_name(lp));
free(missdepstring);
@@ -508,8 +504,20 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)
}
}
-/* helper function for resolvedeps: search for dep satisfier in dbs */
-pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg)
+/**
+ * helper function for resolvedeps: search for dep satisfier in dbs
+ *
+ * @param dep is the dependency to search for
+ * @param dbs are the databases to search
+ * @param excluding are the packages to exclude from the search
+ * @param prompt if true, will cause an unresolvable dependency to issue an
+ * interactive prompt asking whether the package should be removed from
+ * the transaction or the transaction aborted; if false, simply returns
+ * an error code without prompting
+ * @return the resolved package
+ **/
+pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
+ alpm_list_t *excluding, int prompt)
{
alpm_list_t *i, *j;
/* 1. literals */
@@ -517,9 +525,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud
pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
if(pkg && alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) {
if(_alpm_pkg_should_ignore(pkg)) {
- int install;
- QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
- tpkg, NULL, &install);
+ int install = 0;
+ if (prompt) {
+ QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
+ NULL, NULL, &install);
+ }
if(!install) {
continue;
}
@@ -534,9 +544,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud
if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) &&
!_alpm_pkg_find(excluding, pkg->name)) {
if(_alpm_pkg_should_ignore(pkg)) {
- int install;
- QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
- tpkg, NULL, &install);
+ int install = 0;
+ if (prompt) {
+ QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG,
+ pkg, NULL, NULL, &install);
+ }
if(!install) {
continue;
}
@@ -550,17 +562,33 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud
return(NULL);
}
-/* populates list with packages that need to be installed to satisfy all
- * dependencies of packages in list
+/* Computes resolvable dependencies for a given package and adds that package
+ * and those resolvable dependencies to a list.
*
- * @param remove contains packages elected for removal
+ * @param local is the local database
+ * @param dbs_sync are the sync databases
+ * @param pkg is the package to resolve
+ * @param packages is a pointer to a list of packages which will be
+ * searched first for any dependency packages needed to complete the
+ * resolve, and to which will be added any [pkg] and all of its
+ * dependencies not already on the list
+ * @param remove is the set of packages which will be removed in this
+ * transaction
+ * @param data returns the dependency which could not be satisfied in the
+ * event of an error
+ * @return 0 on success, with [pkg] and all of its dependencies not already on
+ * the [*packages] list added to that list, or -1 on failure due to an
+ * unresolvable dependency, in which case the [*packages] list will be
+ * unmodified by this function
*/
-int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
- alpm_list_t *remove, alpm_list_t **data)
+int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg,
+ alpm_list_t **packages, alpm_list_t *remove,
+ alpm_list_t **data)
{
alpm_list_t *i, *j;
alpm_list_t *targ;
alpm_list_t *deps = NULL;
+ alpm_list_t *packages_copy;
ALPM_LOG_FUNC;
@@ -568,25 +596,36 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
return(-1);
}
+ if(_alpm_pkg_find(*packages, pkg->name) != NULL) {
+ return(0);
+ }
+
+ /* Create a copy of the packages list, so that it can be restored
+ on error */
+ packages_copy = alpm_list_copy(*packages);
+ /* [pkg] has not already been resolved into the packages list, so put it
+ on that list */
+ *packages = alpm_list_add(*packages, pkg);
+
_alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n");
- for(i = list; i; i = i->next) {
+ for(i = alpm_list_last(*packages); i; i = i->next) {
pmpkg_t *tpkg = i->data;
targ = alpm_list_add(NULL, tpkg);
- deps = alpm_checkdeps(local, 0, remove, targ);
+ deps = alpm_checkdeps(_alpm_db_get_pkgcache(local), 0, remove, targ);
alpm_list_free(targ);
for(j = deps; j; j = j->next) {
pmdepmissing_t *miss = j->data;
pmdepend_t *missdep = alpm_miss_get_dep(miss);
- /* check if one of the packages in list already satisfies this dependency */
- if(_alpm_find_dep_satisfier(list, missdep)) {
+ /* check if one of the packages in the [*packages] list already satisfies this dependency */
+ if(_alpm_find_dep_satisfier(*packages, missdep)) {
continue;
}
/* find a satisfier package in the given repositories */
- pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, list, tpkg);
+ pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, 0);
if(!spkg) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
- char *missdepstring = alpm_dep_get_string(missdep);
- _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"),
+ char *missdepstring = alpm_dep_compute_string(missdep);
+ _alpm_log(PM_LOG_WARNING, _("cannot resolve \"%s\", a dependency of \"%s\"\n"),
missdepstring, tpkg->name);
free(missdepstring);
if(data) {
@@ -596,18 +635,21 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
*data = alpm_list_add(*data, missd);
}
}
+ alpm_list_free(*packages);
+ *packages = packages_copy;
alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(deps);
return(-1);
} else {
_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg));
- list = alpm_list_add(list, spkg);
+ *packages = alpm_list_add(*packages, spkg);
}
}
alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(deps);
}
+ alpm_list_free(packages_copy);
_alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n");
return(0);
}
@@ -689,7 +731,7 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)
* @param dep the depend to turn into a string
* @return a string-formatted dependency with operator if necessary
*/
-char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep)
+char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)
{
char *name, *opr, *ver, *str = NULL;
size_t len;
diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
index 2f3c4502..eb1400bd 100644
--- a/lib/libalpm/deps.h
+++ b/lib/libalpm/deps.h
@@ -47,9 +47,9 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep,
void _alpm_depmiss_free(pmdepmissing_t *miss);
alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse);
void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit);
-pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg);
-int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
- alpm_list_t *remove, alpm_list_t **data);
+pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, int prompt);
+int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg,
+ alpm_list_t **packages, alpm_list_t *remove, alpm_list_t **data);
int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2);
pmdepend_t *_alpm_splitdep(const char *depstring);
pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep);
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index ca13652e..5b0a691f 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
+#include <signal.h>
#include <limits.h>
/* the following two are needed on BSD for libfetch */
#if defined(HAVE_SYS_SYSLIMITS_H)
@@ -33,16 +34,8 @@
#include <sys/param.h> /* MAXHOSTNAMELEN */
#endif
-#if defined(HAVE_LIBDOWNLOAD)
-#include <download.h>
-#elif defined(HAVE_LIBFETCH)
+#if defined(INTERNAL_DOWNLOAD)
#include <fetch.h>
-#define downloadFreeURL fetchFreeURL
-#define downloadLastErrCode fetchLastErrCode
-#define downloadLastErrString fetchLastErrString
-#define downloadParseURL fetchParseURL
-#define downloadTimeout fetchTimeout
-#define downloadXGet fetchXGet
#endif
/* libalpm */
@@ -86,7 +79,7 @@ static char *get_tempfile(const char *path, const char *filename) {
static struct url *url_for_string(const char *url)
{
struct url *ret = NULL;
- ret = downloadParseURL(url);
+ ret = fetchParseURL(url);
if(!ret) {
_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
RET_ERR(PM_ERR_SERVER_BAD_URL, NULL);
@@ -108,12 +101,14 @@ static struct url *url_for_string(const char *url)
static int download_internal(const char *url, const char *localpath,
time_t mtimeold, time_t *mtimenew) {
- FILE *dlf, *localf = NULL;
+ fetchIO *dlf = NULL;
+ FILE *localf = NULL;
struct url_stat ust;
struct stat st;
int chk_resume = 0, ret = 0;
size_t dl_thisfile = 0, nread = 0;
char *tempfile, *destfile, *filename;
+ struct sigaction new_action, old_action;
struct url *fileurl = url_for_string(url);
char buffer[PM_DLBUF_LEN];
@@ -148,23 +143,29 @@ static int download_internal(const char *url, const char *localpath,
_alpm_log(PM_LOG_DEBUG, "FTP_PROXY: %s\n", getenv("FTP_PROXY"));
_alpm_log(PM_LOG_DEBUG, "ftp_proxy: %s\n", getenv("ftp_proxy"));
- /* libdownload does not reset the error code, reset it in
- * the case of previous errors */
- downloadLastErrCode = 0;
+ /* libfetch does not reset the error code */
+ fetchLastErrCode = 0;
/* 10s timeout - TODO make a config option */
- downloadTimeout = 10000;
+ fetchTimeout = 10000;
+
+ /* ignore any SIGPIPE signals- these may occur if our FTP socket dies or
+ * something along those lines. Store the old signal handler first. */
+ new_action.sa_handler = SIG_IGN;
+ sigemptyset(&new_action.sa_mask);
+ sigaction(SIGPIPE, NULL, &old_action);
+ sigaction(SIGPIPE, &new_action, NULL);
- dlf = downloadXGet(fileurl, &ust, (handle->nopassiveftp ? "" : "p"));
+ dlf = fetchXGet(fileurl, &ust, (handle->nopassiveftp ? "" : "p"));
- if(downloadLastErrCode != 0 || dlf == NULL) {
+ if(fetchLastErrCode != 0 || dlf == NULL) {
const char *host = _("disk");
if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) {
host = fileurl->host;
}
- pm_errno = PM_ERR_LIBDOWNLOAD;
+ pm_errno = PM_ERR_LIBFETCH;
_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
- filename, host, downloadLastErrString);
+ filename, host, fetchLastErrString);
ret = -1;
goto cleanup;
} else {
@@ -206,16 +207,8 @@ static int download_internal(const char *url, const char *localpath,
handle->dlcb(filename, 0, ust.size);
}
- while((nread = fread(buffer, 1, PM_DLBUF_LEN, dlf)) > 0) {
+ while((nread = fetchIO_read(dlf, buffer, PM_DLBUF_LEN)) > 0) {
size_t nwritten = 0;
- if(ferror(dlf)) {
- pm_errno = PM_ERR_LIBDOWNLOAD;
- _alpm_log(PM_LOG_ERROR, _("error downloading '%s': %s\n"),
- filename, downloadLastErrString);
- ret = -1;
- goto cleanup;
- }
-
while(nwritten < nread) {
nwritten += fwrite(buffer, 1, (nread - nwritten), localf);
if(ferror(localf)) {
@@ -231,27 +224,40 @@ static int download_internal(const char *url, const char *localpath,
handle->dlcb(filename, dl_thisfile, ust.size);
}
}
+
+ /* did the transfer complete normally? */
+ if (ust.size != -1 && dl_thisfile < ust.size) {
+ pm_errno = PM_ERR_LIBFETCH;
+ _alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"),
+ filename, (intmax_t)dl_thisfile, (intmax_t)ust.size);
+ ret = -1;
+ goto cleanup;
+ }
+
/* probably safer to close the file descriptors now before renaming the file,
* for example to make sure the buffers are flushed.
*/
fclose(localf);
localf = NULL;
- fclose(dlf);
+ fetchIO_close(dlf);
dlf = NULL;
rename(tempfile, destfile);
ret = 0;
cleanup:
+ /* restore any existing SIGPIPE signal handler */
+ sigaction(SIGPIPE, &old_action, NULL);
+
FREE(tempfile);
FREE(destfile);
if(localf != NULL) {
fclose(localf);
}
if(dlf != NULL) {
- fclose(dlf);
+ fetchIO_close(dlf);
}
- downloadFreeURL(fileurl);
+ fetchFreeURL(fileurl);
return(ret);
}
#endif
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 05caf8ec..1f605806 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -30,11 +30,8 @@
#include <sys/param.h> /* MAXHOSTNAMELEN */
#endif
-#if defined(HAVE_LIBDOWNLOAD)
-#include <download.h> /* downloadLastErrString */
-#elif defined(HAVE_LIBFETCH)
+#if defined(INTERNAL_DOWNLOAD)
#include <fetch.h> /* fetchLastErrString */
-#define downloadLastErrString fetchLastErrString
#endif
/* libalpm */
@@ -143,9 +140,6 @@ const char SYMEXPORT *alpm_strerror(int err)
return _("user aborted the operation");
case PM_ERR_INTERNAL_ERROR:
return _("internal error");
- case PM_ERR_PKG_HOLD:
- /* TODO wow this is not descriptive at all... what does this mean? */
- return _("not confirmed");
case PM_ERR_INVALID_REGEX:
return _("invalid regular expression");
/* Errors from external libraries- our own wrapper error */
@@ -154,9 +148,9 @@ const char SYMEXPORT *alpm_strerror(int err)
* requires the archive struct, so we can't. Just use a generic
* error string instead. */
return _("libarchive error");
- case PM_ERR_LIBDOWNLOAD:
+ case PM_ERR_LIBFETCH:
#if defined(INTERNAL_DOWNLOAD)
- return downloadLastErrString;
+ return fetchLastErrString;
#else
/* obviously shouldn't get here... */
return _("download library error");
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index af1cc78b..813f4399 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -48,16 +48,7 @@ pmhandle_t *_alpm_handle_new()
ALPM_LOG_FUNC;
CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
-
handle->lckfd = -1;
- handle->logstream = NULL;
-
- handle->root = NULL;
- handle->dbpath = NULL;
- handle->cachedirs = NULL;
- handle->lockfile = NULL;
- handle->logfile = NULL;
- handle->usedelta = 0;
return(handle);
}
@@ -92,7 +83,6 @@ void _alpm_handle_free(pmhandle_t *handle)
FREELIST(handle->noupgrade);
FREELIST(handle->noextract);
FREELIST(handle->ignorepkg);
- FREELIST(handle->holdpkg);
FREELIST(handle->ignoregrp);
FREE(handle);
}
@@ -205,15 +195,6 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs()
return handle->ignorepkg;
}
-alpm_list_t SYMEXPORT *alpm_option_get_holdpkgs()
-{
- if (handle == NULL) {
- pm_errno = PM_ERR_HANDLE_NULL;
- return NULL;
- }
- return handle->holdpkg;
-}
-
alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps()
{
if (handle == NULL) {
@@ -516,28 +497,6 @@ int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg)
return(0);
}
-void SYMEXPORT alpm_option_add_holdpkg(const char *pkg)
-{
- handle->holdpkg = alpm_list_add(handle->holdpkg, strdup(pkg));
-}
-
-void SYMEXPORT alpm_option_set_holdpkgs(alpm_list_t *holdpkgs)
-{
- if(handle->holdpkg) FREELIST(handle->holdpkg);
- if(holdpkgs) handle->holdpkg = holdpkgs;
-}
-
-int SYMEXPORT alpm_option_remove_holdpkg(const char *pkg)
-{
- char *vdata = NULL;
- handle->holdpkg = alpm_list_remove_str(handle->holdpkg, pkg, &vdata);
- if(vdata != NULL) {
- FREE(vdata);
- return(1);
- }
- return(0);
-}
-
void SYMEXPORT alpm_option_add_ignoregrp(const char *grp)
{
handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp));
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index bec0a6f1..ad7666dc 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -52,7 +52,6 @@ typedef struct _pmhandle_t {
alpm_list_t *noupgrade; /* List of packages NOT to be upgraded */
alpm_list_t *noextract; /* List of files NOT to extract */
alpm_list_t *ignorepkg; /* List of packages to ignore */
- alpm_list_t *holdpkg; /* List of packages which 'hold' pacman */
alpm_list_t *ignoregrp; /* List of groups to ignore */
/* options */
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index a9f4b43d..ee0ff6f5 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -422,6 +422,15 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)
return pkg->backup;
}
+pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)
+{
+ /* Sanity checks */
+ ASSERT(pkg != NULL, return(NULL));
+ ASSERT(pkg->origin == PKG_FROM_CACHE, return(NULL));
+
+ return(pkg->origin_data.db);
+}
+
/**
* Open a package changelog for reading. Similar to fopen in functionality,
* except that the returned 'file stream' could really be from an archive
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 0bec5229..9dfff9c3 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -65,16 +65,6 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
- /* ignore holdpkgs on upgrade */
- if((trans == handle->trans)
- && alpm_list_find_str(handle->holdpkg, info->name)) {
- int resp = 0;
- QUESTION(trans, PM_TRANS_CONV_REMOVE_HOLDPKG, info, NULL, NULL, &resp);
- if(!resp) {
- RET_ERR(PM_ERR_PKG_HOLD, -1);
- }
- }
-
_alpm_log(PM_LOG_DEBUG, "adding %s in the targets list\n", info->name);
trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info));
@@ -104,7 +94,7 @@ static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db,
}
alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(lp);
- lp = alpm_checkdeps(db, 1, trans->packages, NULL);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->packages, NULL);
}
}
@@ -134,7 +124,7 @@ static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db,
}
alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(lp);
- lp = alpm_checkdeps(db, 1, trans->packages, NULL);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->packages, NULL);
}
}
@@ -161,7 +151,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
- lp = alpm_checkdeps(db, 1, trans->packages, NULL);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->packages, NULL);
if(lp != NULL) {
if(trans->flags & PM_TRANS_FLAG_CASCADE) {
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 4a705b57..709a36dc 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -77,17 +77,12 @@ void _alpm_sync_free(pmsyncpkg_t *sync)
/* Find recommended replacements for packages during a sync.
*/
-static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
- alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
+static int find_replacements(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync)
{
alpm_list_t *i, *j, *k; /* wow */
ALPM_LOG_FUNC;
- if(syncpkgs == NULL) {
- return(-1);
- }
-
/* check for "recommended" package replacements */
_alpm_log(PM_LOG_DEBUG, "checking for package replacements\n");
for(i = dbs_sync; i; i = i->next) {
@@ -113,13 +108,10 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg),
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
} else {
- /* get confirmation for the replacement */
- if(trans) {
- int doreplace = 0;
- QUESTION(trans, PM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, db->treename, &doreplace);
- if(!doreplace) {
- continue;
- }
+ int doreplace = 0;
+ QUESTION(trans, PM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, db->treename, &doreplace);
+ if(!doreplace) {
+ continue;
}
/* if confirmed, add this to the 'final' list, designating 'lpkg' as
@@ -129,7 +121,7 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
/* check if spkg->name is already in the packages list. */
/* TODO: same package name doesn't mean same package */
- sync = _alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg));
+ sync = _alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg));
if(sync) {
/* found it -- just append to the removes list */
sync->removes = alpm_list_add(sync->removes, lpkg);
@@ -143,15 +135,12 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
sync = _alpm_sync_new(alpm_pkg_get_reason(lpkg), spkg, NULL);
if(sync == NULL) {
pm_errno = PM_ERR_MEMORY;
- alpm_list_free_inner(*syncpkgs, (alpm_list_fn_free)_alpm_sync_free);
- alpm_list_free(*syncpkgs);
- *syncpkgs = NULL;
return(-1);
}
sync->removes = alpm_list_add(NULL, lpkg);
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
- *syncpkgs = alpm_list_add(*syncpkgs, sync);
+ trans->packages = alpm_list_add(trans->packages, sync);
}
_alpm_log(PM_LOG_DEBUG, "%s-%s elected for removal (to be replaced by %s-%s)\n",
alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg),
@@ -199,33 +188,19 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync)
return(NULL);
}
-/** Get a list of upgradable packages on the current system
- * Adds out of date packages to *list.
- * @arg list pointer to a list of pmsyncpkg_t.
- */
-int SYMEXPORT alpm_sync_sysupgrade(pmdb_t *db_local,
- alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
-{
- return(_alpm_sync_sysupgrade(NULL, db_local, dbs_sync, syncpkgs));
-}
-
-int _alpm_sync_sysupgrade(pmtrans_t *trans,
- pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
+int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync)
{
alpm_list_t *i, *j, *replaced = NULL;
ALPM_LOG_FUNC;
- if(syncpkgs == NULL) {
- return(-1);
- }
/* check for "recommended" package replacements */
- if(find_replacements(trans, db_local, dbs_sync, syncpkgs)) {
+ if(find_replacements(trans, db_local, dbs_sync)) {
return(-1);
}
/* compute the to-be-replaced packages for efficiency */
- for(i = *syncpkgs; i; i = i->next) {
+ for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
for(j = sync->removes; j; j = j->next) {
replaced = alpm_list_add(replaced, j->data);
@@ -255,22 +230,19 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans,
}
/* add the upgrade package to our pmsyncpkg_t list */
- if(_alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg))) {
+ if(_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
/* avoid duplicated targets */
continue;
}
/* we can set any reason here, it will be overridden by add_commit */
pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_EXPLICIT, spkg, NULL);
if(sync == NULL) {
- alpm_list_free_inner(*syncpkgs, (alpm_list_fn_free)_alpm_sync_free);
- alpm_list_free(*syncpkgs);
- *syncpkgs = NULL;
alpm_list_free(replaced);
return(-1);
}
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
- *syncpkgs = alpm_list_add(*syncpkgs, sync);
+ trans->packages = alpm_list_add(trans->packages, sync);
}
}
@@ -313,12 +285,12 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1);
}
dep = _alpm_splitdep(targ);
- spkg = _alpm_resolvedep(dep, dbs, NULL, NULL);
+ spkg = _alpm_resolvedep(dep, dbs, NULL, 1);
_alpm_dep_free(dep);
alpm_list_free(dbs);
} else {
dep = _alpm_splitdep(targline);
- spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL);
+ spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1);
_alpm_dep_free(dep);
}
FREE(targline);
@@ -427,6 +399,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
{
alpm_list_t *deps = NULL;
alpm_list_t *list = NULL, *remove = NULL; /* allow checkdeps usage with trans->packages */
+ alpm_list_t *unresolvable = NULL;
alpm_list_t *i, *j;
int ret = 0;
@@ -439,15 +412,13 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
*data = NULL;
}
- for(i = trans->packages; i; i = i->next) {
- pmsyncpkg_t *sync = i->data;
- list = alpm_list_add(list, sync->pkg);
- }
-
- if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
- /* store a pointer to the last original target so we can tell what was
- * pulled by resolvedeps */
- alpm_list_t *pulled = alpm_list_last(list);
+ if(trans->flags & PM_TRANS_FLAG_NODEPS) {
+ for(i = trans->packages; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ list = alpm_list_add(list, sync->pkg);
+ }
+ } else {
+ /* Build up list by repeatedly resolving each transaction package */
/* Resolve targets dependencies */
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
@@ -460,14 +431,53 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
}
- if(_alpm_resolvedeps(db_local, dbs_sync, list, remove, data) == -1) {
- /* pm_errno is set by resolvedeps */
- ret = -1;
- goto cleanup;
+ /* Resolve packages in the transaction one at a time, in addtion
+ building up a list of packages which could not be resolved. */
+ for(i = trans->packages; i; i = i->next) {
+ pmpkg_t *pkg = ((pmsyncpkg_t *) i->data)->pkg;
+ if(_alpm_resolvedeps(db_local, dbs_sync, pkg, &list, remove, data) == -1) {
+ unresolvable = alpm_list_add(unresolvable, pkg);
+ }
+ /* Else, [list] now additionally contains [pkg] and all of its
+ dependencies not already on the list */
}
- for(i = pulled->next; i; i = i->next) {
+ /* If there were unresolvable top-level packages, prompt the user to
+ see if they'd like to ignore them rather than failing the sync */
+ if(unresolvable != NULL) {
+ int remove_unresolvable = 0;
+ QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,
+ NULL, NULL, &remove_unresolvable);
+ if (remove_unresolvable) {
+ /* User wants to remove the unresolvable packages from the
+ transaction, so simply drop the unresolvable list. The
+ packages will be removed from the actual transaction when
+ the transaction packages are replaced with a
+ dependency-reordered list below */
+ alpm_list_free(unresolvable);
+ unresolvable = NULL;
+ }
+ else {
+ /* pm_errno is set by resolvedeps */
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ /* Add all packages which were "pulled" (i.e. weren't already in the
+ transaction) to the transaction in pmsyncpkg_t structures */
+ for(i = list; i; i = i->next) {
pmpkg_t *spkg = i->data;
+ for(j = trans->packages; j; j = j->next) {
+ if(_alpm_pkg_cmp(spkg, ((pmsyncpkg_t *) j->data)->pkg) == 0) {
+ spkg = NULL;
+ break;
+ }
+ }
+ if (spkg == NULL) {
+ continue;
+ }
+
pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_DEPEND, spkg, NULL);
if(sync == NULL) {
ret = -1;
@@ -497,8 +507,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
}
- /* We don't care about conflicts if we're just printing uris */
- if(!(trans->flags & (PM_TRANS_FLAG_NOCONFLICTS | PM_TRANS_FLAG_PRINTURIS))) {
+ if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) {
/* check for inter-conflicts and whatnot */
EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL);
@@ -631,7 +640,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
_alpm_log(PM_LOG_DEBUG, "checking dependencies\n");
- deps = alpm_checkdeps(db_local, 1, remove, list);
+ deps = alpm_checkdeps(_alpm_db_get_pkgcache(db_local), 1, remove, list);
if(deps) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
ret = -1;
@@ -656,6 +665,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
cleanup:
alpm_list_free(list);
alpm_list_free(remove);
+ alpm_list_free(unresolvable);
return(ret);
}
@@ -838,32 +848,27 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
fname = alpm_pkg_get_filename(spkg);
ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1));
- if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
- EVENT(trans, PM_TRANS_EVT_PRINTURI, (char *)alpm_db_get_url(current),
- (char *)fname);
- } else {
- if(spkg->download_size != 0) {
- alpm_list_t *delta_path = spkg->delta_path;
- if(delta_path) {
- alpm_list_t *dlts = NULL;
-
- for(dlts = delta_path; dlts; dlts = dlts->next) {
- pmdelta_t *d = dlts->data;
-
- if(d->download_size != 0) {
- /* add the delta filename to the download list if
- * it's not in the cache */
- files = alpm_list_add(files, strdup(d->delta));
- }
-
- /* keep a list of the delta files for md5sums */
- deltas = alpm_list_add(deltas, d);
+ if(spkg->download_size != 0) {
+ alpm_list_t *delta_path = spkg->delta_path;
+ if(delta_path) {
+ alpm_list_t *dlts = NULL;
+
+ for(dlts = delta_path; dlts; dlts = dlts->next) {
+ pmdelta_t *d = dlts->data;
+
+ if(d->download_size != 0) {
+ /* add the delta filename to the download list if
+ * it's not in the cache */
+ files = alpm_list_add(files, strdup(d->delta));
}
- } else {
- /* not using deltas, so add the file to the download list */
- files = alpm_list_add(files, strdup(fname));
+ /* keep a list of the delta files for md5sums */
+ deltas = alpm_list_add(deltas, d);
}
+
+ } else {
+ /* not using deltas, so add the file to the download list */
+ files = alpm_list_add(files, strdup(fname));
}
}
}
@@ -880,9 +885,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
FREELIST(files);
}
}
- if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
- return(0);
- }
/* clear out value to let callback know we are done */
if(handle->totaldlcb) {
diff --git a/lib/libalpm/sync.h b/lib/libalpm/sync.h
index b71f0ef2..b6a4bbff 100644
--- a/lib/libalpm/sync.h
+++ b/lib/libalpm/sync.h
@@ -33,8 +33,7 @@ struct __pmsyncpkg_t {
pmsyncpkg_t *_alpm_sync_new(pmpkgreason_t newreason, pmpkg_t *spkg, alpm_list_t *removes);
void _alpm_sync_free(pmsyncpkg_t *data);
-int _alpm_sync_sysupgrade(pmtrans_t *trans,
- pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **syncpkgs);
+int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync);
int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, char *name);
int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data);
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index acad84e8..4b831193 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -100,7 +100,7 @@ int SYMEXPORT alpm_trans_sysupgrade()
ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
ASSERT(trans->type == PM_TRANS_TYPE_SYNC, RET_ERR(PM_ERR_TRANS_TYPE, -1));
- return(_alpm_trans_sysupgrade(trans));
+ return(_alpm_sync_sysupgrade(trans, handle->db_local, handle->dbs_sync));
}
/** Add a target to the transaction.
@@ -226,15 +226,6 @@ pmtrans_t *_alpm_trans_new()
ALPM_LOG_FUNC;
CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(PM_ERR_MEMORY, NULL));
-
- trans->packages = NULL;
- trans->skip_add = NULL;
- trans->skip_remove = NULL;
- trans->type = 0;
- trans->flags = 0;
- trans->cb_event = NULL;
- trans->cb_conv = NULL;
- trans->cb_progress = NULL;
trans->state = STATE_IDLE;
return(trans);
@@ -280,17 +271,6 @@ int _alpm_trans_init(pmtrans_t *trans, pmtranstype_t type, pmtransflag_t flags,
return(0);
}
-int _alpm_trans_sysupgrade(pmtrans_t *trans)
-{
- ALPM_LOG_FUNC;
-
- /* Sanity checks */
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
-
- return(_alpm_sync_sysupgrade(trans, handle->db_local, handle->dbs_sync,
- &(trans->packages)));
-}
-
/** Add a target to the transaction.
* @param trans the current transaction
* @param target the name of the target to add
diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h
index d74c3e90..48996573 100644
--- a/lib/libalpm/trans.h
+++ b/lib/libalpm/trans.h
@@ -71,7 +71,6 @@ void _alpm_trans_free(pmtrans_t *trans);
int _alpm_trans_init(pmtrans_t *trans, pmtranstype_t type, pmtransflag_t flags,
alpm_trans_cb_event event, alpm_trans_cb_conv conv,
alpm_trans_cb_progress progress);
-int _alpm_trans_sysupgrade(pmtrans_t *trans);
int _alpm_trans_addtarget(pmtrans_t *trans, char *target);
int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data);
int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data);
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index be465afa..75f6042d 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -242,7 +242,8 @@ char *_alpm_strreplace(const char *str, const char *needle, const char *replace)
int _alpm_lckmk()
{
int fd;
- char *dir, *ptr;
+ pid_t pid;
+ char *dir, *ptr, *spid = NULL;
const char *file = alpm_option_get_lockfile();
/* create the dir of the lockfile first */
@@ -256,7 +257,17 @@ int _alpm_lckmk()
while((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0000)) == -1
&& errno == EINTR);
- return(fd > 0 ? fd : -1);
+ if(fd > 0) {
+ pid = getpid();
+ size_t len = snprintf(spid, 0, "%ld\n", (long)pid) + 1;
+ spid = malloc(len);
+ snprintf(spid, len, "%ld\n", (long)pid);
+ while(write(fd, (void *)spid, len) == -1 && errno == EINTR);
+ fsync(fd);
+ free(spid);
+ return(fd);
+ }
+ return(-1);
}
/* Remove a lock file */
@@ -277,19 +288,21 @@ int _alpm_lckrm()
* @param archive the archive to unpack
* @param prefix where to extract the files
* @param fn a file within the archive to unpack or NULL for all
+ * @return 0 on success, 1 on failure
*/
int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
{
- int ret = 1;
+ int ret = 0;
mode_t oldmask;
struct archive *_archive;
struct archive_entry *entry;
- char expath[PATH_MAX];
+ char cwd[PATH_MAX];
+ int restore_cwd = 0;
ALPM_LOG_FUNC;
if((_archive = archive_read_new()) == NULL)
- RET_ERR(PM_ERR_LIBARCHIVE, -1);
+ RET_ERR(PM_ERR_LIBARCHIVE, 1);
archive_read_support_compression_all(_archive);
archive_read_support_format_all(_archive);
@@ -298,10 +311,25 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), archive,
archive_error_string(_archive));
- RET_ERR(PM_ERR_PKG_OPEN, -1);
+ RET_ERR(PM_ERR_PKG_OPEN, 1);
}
oldmask = umask(0022);
+
+ /* 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"));
+ } else {
+ restore_cwd = 1;
+ }
+
+ /* just in case our cwd was removed in the upgrade operation */
+ if(chdir(prefix) != 0) {
+ _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), prefix, strerror(errno));
+ ret = 1;
+ goto cleanup;
+ }
+
while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) {
const struct stat *st;
const char *entryname; /* the name of the file in the archive */
@@ -326,10 +354,6 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
}
/* Extract the archive entry. */
- ret = 0;
- snprintf(expath, PATH_MAX, "%s/%s", prefix, entryname);
- archive_entry_set_pathname(entry, expath);
-
int readret = archive_read_extract(_archive, entry, 0);
if(readret == ARCHIVE_WARN) {
/* operation succeeded but a non-critical error was encountered */
@@ -350,6 +374,9 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
cleanup:
umask(oldmask);
archive_read_finish(_archive);
+ if(restore_cwd) {
+ chdir(cwd);
+ }
return(ret);
}
@@ -539,7 +566,7 @@ int _alpm_lstat(const char *path, struct stat *buf)
* @return the checksum on success, NULL on error
* @addtogroup alpm_misc
*/
-char SYMEXPORT *alpm_get_md5sum(const char *filename)
+char SYMEXPORT *alpm_compute_md5sum(const char *filename)
{
unsigned char output[16];
char *md5sum;
@@ -573,7 +600,7 @@ int _alpm_test_md5sum(const char *filepath, const char *md5sum)
char *md5sum2;
int ret;
- md5sum2 = alpm_get_md5sum(filepath);
+ md5sum2 = alpm_compute_md5sum(filepath);
if(md5sum == NULL || md5sum2 == NULL) {
ret = -1;