summaryrefslogtreecommitdiff
path: root/lib/libalpm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/alpm.h12
-rw-r--r--lib/libalpm/be_local.c31
-rw-r--r--lib/libalpm/be_package.c9
-rw-r--r--lib/libalpm/be_sync.c19
-rw-r--r--lib/libalpm/conflict.c21
-rw-r--r--lib/libalpm/db.c3
-rw-r--r--lib/libalpm/deps.c30
-rw-r--r--lib/libalpm/package.c22
-rw-r--r--lib/libalpm/sync.c7
9 files changed, 83 insertions, 71 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 3febd0ec..fc8f0bcd 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -155,7 +155,7 @@ typedef struct _alpm_conflict_t {
unsigned long package2_hash;
char *package1;
char *package2;
- char *reason;
+ alpm_depend_t *reason;
} alpm_conflict_t;
/** File conflict */
@@ -670,15 +670,15 @@ alpm_list_t *alpm_pkg_get_depends(alpm_pkg_t *pkg);
*/
alpm_list_t *alpm_pkg_get_optdepends(alpm_pkg_t *pkg);
-/** Returns the list of package names conflicting with pkg.
+/** Returns the list of packages conflicting with pkg.
* @param pkg a pointer to package
- * @return a reference to an internal list of strings.
+ * @return a reference to an internal list of alpm_depend_t structures.
*/
alpm_list_t *alpm_pkg_get_conflicts(alpm_pkg_t *pkg);
-/** Returns the list of package names provided by pkg.
+/** Returns the list of packages provided by pkg.
* @param pkg a pointer to package
- * @return a reference to an internal list of strings.
+ * @return a reference to an internal list of alpm_depend_t structures.
*/
alpm_list_t *alpm_pkg_get_provides(alpm_pkg_t *pkg);
@@ -690,7 +690,7 @@ alpm_list_t *alpm_pkg_get_deltas(alpm_pkg_t *pkg);
/** Returns the list of packages to be replaced by pkg.
* @param pkg a pointer to package
- * @return a reference to an internal list of strings.
+ * @return a reference to an internal list of alpm_depend_t structures.
*/
alpm_list_t *alpm_pkg_get_replaces(alpm_pkg_t *pkg);
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index fdb4ceaf..a874504e 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -509,6 +509,12 @@ static char *get_pkgpath(alpm_db_t *db, alpm_pkg_t *info)
f = alpm_list_add(f, linedup); \
} while(1) /* note the while(1) and not (0) */
+#define READ_AND_SPLITDEP(f) do { \
+ if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
+ if(_alpm_strip_newline(line) == 0) break; \
+ f = alpm_list_add(f, _alpm_splitdep(line)); \
+} while(1) /* note the while(1) and not (0) */
+
static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
{
FILE *fp = NULL;
@@ -601,20 +607,15 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
/* also store this value to isize */
info->isize = info->size;
} else if(strcmp(line, "%REPLACES%") == 0) {
- READ_AND_STORE_ALL(info->replaces);
+ READ_AND_SPLITDEP(info->replaces);
} else if(strcmp(line, "%DEPENDS%") == 0) {
- /* Different than the rest because of the _alpm_splitdep call. */
- while(1) {
- READ_NEXT();
- if(strlen(line) == 0) break;
- info->depends = alpm_list_add(info->depends, _alpm_splitdep(line));
- }
+ READ_AND_SPLITDEP(info->depends);
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
READ_AND_STORE_ALL(info->optdepends);
} else if(strcmp(line, "%CONFLICTS%") == 0) {
- READ_AND_STORE_ALL(info->conflicts);
+ READ_AND_SPLITDEP(info->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
- READ_AND_STORE_ALL(info->provides);
+ READ_AND_SPLITDEP(info->provides);
}
}
fclose(fp);
@@ -771,7 +772,9 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq
if(info->replaces) {
fputs("%REPLACES%\n", fp);
for(lp = info->replaces; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
+ char *depstring = alpm_dep_compute_string(lp->data);
+ fprintf(fp, "%s\n", depstring);
+ free(depstring);
}
fprintf(fp, "\n");
}
@@ -830,14 +833,18 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq
if(info->conflicts) {
fputs("%CONFLICTS%\n", fp);
for(lp = info->conflicts; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
+ char *depstring = alpm_dep_compute_string(lp->data);
+ fprintf(fp, "%s\n", depstring);
+ free(depstring);
}
fprintf(fp, "\n");
}
if(info->provides) {
fputs("%PROVIDES%\n", fp);
for(lp = info->provides; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
+ char *depstring = alpm_dep_compute_string(lp->data);
+ fprintf(fp, "%s\n", depstring);
+ free(depstring);
}
fprintf(fp, "\n");
}
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 9762cbca..3b5b0d0c 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -194,11 +194,14 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
} else if(strcmp(key, "optdepend") == 0) {
newpkg->optdepends = alpm_list_add(newpkg->optdepends, strdup(ptr));
} else if(strcmp(key, "conflict") == 0) {
- newpkg->conflicts = alpm_list_add(newpkg->conflicts, strdup(ptr));
+ alpm_depend_t *conflict = _alpm_splitdep(ptr);
+ newpkg->conflicts = alpm_list_add(newpkg->conflicts, conflict);
} else if(strcmp(key, "replaces") == 0) {
- newpkg->replaces = alpm_list_add(newpkg->replaces, strdup(ptr));
+ alpm_depend_t *replace = _alpm_splitdep(ptr);
+ newpkg->replaces = alpm_list_add(newpkg->replaces, replace);
} else if(strcmp(key, "provides") == 0) {
- newpkg->provides = alpm_list_add(newpkg->provides, strdup(ptr));
+ alpm_depend_t *provide = _alpm_splitdep(ptr);
+ newpkg->provides = alpm_list_add(newpkg->provides, provide);
} else if(strcmp(key, "backup") == 0) {
alpm_backup_t *backup;
CALLOC(backup, 1, sizeof(alpm_backup_t), return -1);
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 069e39dd..66808a7f 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -460,6 +460,12 @@ static int sync_db_populate(alpm_db_t *db)
f = alpm_list_add(f, linedup); \
} while(1) /* note the while(1) and not (0) */
+#define READ_AND_SPLITDEP(f) do { \
+ if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
+ if(_alpm_strip_newline(buf.line) == 0) break; \
+ f = alpm_list_add(f, _alpm_splitdep(line)); \
+} while(1) /* note the while(1) and not (0) */
+
static int sync_db_read(alpm_db_t *db, struct archive *archive,
struct archive_entry *entry, alpm_pkg_t **likely_pkg)
{
@@ -547,20 +553,15 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
} else if(strcmp(line, "%PGPSIG%") == 0) {
READ_AND_STORE(pkg->base64_sig);
} else if(strcmp(line, "%REPLACES%") == 0) {
- READ_AND_STORE_ALL(pkg->replaces);
+ READ_AND_SPLITDEP(pkg->replaces);
} else if(strcmp(line, "%DEPENDS%") == 0) {
- /* Different than the rest because of the _alpm_splitdep call. */
- while(1) {
- READ_NEXT();
- if(strlen(line) == 0) break;
- pkg->depends = alpm_list_add(pkg->depends, _alpm_splitdep(line));
- }
+ READ_AND_SPLITDEP(pkg->depends);
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
READ_AND_STORE_ALL(pkg->optdepends);
} else if(strcmp(line, "%CONFLICTS%") == 0) {
- READ_AND_STORE_ALL(pkg->conflicts);
+ READ_AND_SPLITDEP(pkg->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
- READ_AND_STORE_ALL(pkg->provides);
+ READ_AND_SPLITDEP(pkg->provides);
} else if(strcmp(line, "%DELTAS%") == 0) {
/* Different than the rest because of the _alpm_delta_parse call. */
while(1) {
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 91e6b677..fe182094 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -42,7 +42,7 @@
#include "deps.h"
static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2,
- const char *reason)
+ alpm_depend_t *reason)
{
alpm_conflict_t *conflict;
@@ -52,7 +52,7 @@ static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2,
conflict->package2_hash = pkg2->name_hash;
STRDUP(conflict->package1, pkg1->name, return NULL);
STRDUP(conflict->package2, pkg2->name, return NULL);
- STRDUP(conflict->reason, reason, return NULL);
+ conflict->reason = reason;
return conflict;
}
@@ -61,7 +61,6 @@ void _alpm_conflict_free(alpm_conflict_t *conflict)
{
FREE(conflict->package2);
FREE(conflict->package1);
- FREE(conflict->reason);
FREE(conflict);
}
@@ -74,7 +73,7 @@ alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict)
newconflict->package2_hash = conflict->package2_hash;
STRDUP(newconflict->package1, conflict->package1, return NULL);
STRDUP(newconflict->package2, conflict->package2, return NULL);
- STRDUP(newconflict->reason, conflict->reason, return NULL);
+ newconflict->reason = conflict->reason;
return newconflict;
}
@@ -103,16 +102,18 @@ static int conflict_isin(alpm_conflict_t *needle, alpm_list_t *haystack)
* @param reason reason for this conflict
*/
static int add_conflict(alpm_handle_t *handle, alpm_list_t **baddeps,
- alpm_pkg_t *pkg1, alpm_pkg_t *pkg2, const char *reason)
+ alpm_pkg_t *pkg1, alpm_pkg_t *pkg2, alpm_depend_t *reason)
{
alpm_conflict_t *conflict = conflict_new(pkg1, pkg2, reason);
if(!conflict) {
return -1;
}
- _alpm_log(handle, ALPM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",
- pkg1->name, pkg2->name, reason);
if(!conflict_isin(conflict, *baddeps)) {
+ char *conflict_str = alpm_dep_compute_string(reason);
*baddeps = alpm_list_add(*baddeps, conflict);
+ _alpm_log(handle, ALPM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",
+ pkg1->name, pkg2->name, conflict_str);
+ free(conflict_str);
} else {
_alpm_conflict_free(conflict);
}
@@ -144,9 +145,8 @@ static void check_conflict(alpm_handle_t *handle,
alpm_list_t *j;
for(j = alpm_pkg_get_conflicts(pkg1); j; j = j->next) {
- const char *conflict = j->data;
+ alpm_depend_t *conflict = j->data;
alpm_list_t *k;
- alpm_depend_t *parsed_conflict = _alpm_splitdep(conflict);
for(k = list2; k; k = k->next) {
alpm_pkg_t *pkg2 = k->data;
@@ -157,7 +157,7 @@ static void check_conflict(alpm_handle_t *handle,
continue;
}
- if(_alpm_depcmp(pkg2, parsed_conflict)) {
+ if(_alpm_depcmp(pkg2, conflict)) {
if(order >= 0) {
add_conflict(handle, baddeps, pkg1, pkg2, conflict);
} else {
@@ -165,7 +165,6 @@ static void check_conflict(alpm_handle_t *handle,
}
}
}
- _alpm_dep_free(parsed_conflict);
}
}
}
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 9e8e75bf..5765ab2c 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -437,7 +437,8 @@ alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles)
if(!matched) {
/* check provides */
for(k = alpm_pkg_get_provides(pkg); k; k = k->next) {
- if(regexec(&reg, k->data, 0, 0, 0) == 0) {
+ alpm_depend_t *provide = k->data;
+ if(regexec(&reg, provide->name, 0, 0, 0) == 0) {
matched = k->data;
break;
}
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 992ebe23..6869087c 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -384,25 +384,19 @@ int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep)
}
}
- /* check provisions, format : "name=version" */
+ /* check provisions, name and version if available */
for(i = alpm_pkg_get_provides(pkg); i && !satisfy; i = i->next) {
- const char *provision = i->data;
- const char *provver = strchr(provision, '=');
-
- if(provver == NULL) { /* no provision version */
- satisfy = (dep->mod == ALPM_DEP_MOD_ANY
- && strcmp(provision, dep->name) == 0);
- } else {
- /* This is a bit tricker than the old code for performance reasons. To
- * prevent the need to copy and duplicate strings, strncmp only the name
- * portion if they are the same length, since there is a version and
- * operator in play here. Cast is to silence sign conversion warning;
- * we know provver >= provision if we are here. */
- size_t namelen = (size_t)(provver - provision);
- provver += 1;
- satisfy = (strlen(dep->name) == namelen
- && strncmp(provision, dep->name, namelen) == 0
- && dep_vercmp(provver, dep->mod, dep->version));
+ alpm_depend_t *provision = i->data;
+
+ if(dep->mod == ALPM_DEP_MOD_ANY) {
+ /* any version will satisfy the requirement */
+ satisfy = (provision->name_hash == dep->name_hash
+ && strcmp(provision->name, dep->name) == 0);
+ } else if (provision->mod == ALPM_DEP_MOD_EQ) {
+ /* provision specifies a version, so try it out */
+ satisfy = (provision->name_hash == dep->name_hash
+ && strcmp(provision->name, dep->name) == 0
+ && dep_vercmp(provision->version, dep->mod, dep->version));
}
}
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index a8dc1440..19d2c844 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -496,7 +496,9 @@ alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg)
newpkg->reason = pkg->reason;
newpkg->licenses = alpm_list_strdup(pkg->licenses);
- newpkg->replaces = alpm_list_strdup(pkg->replaces);
+ for(i = pkg->replaces; i; i = alpm_list_next(i)) {
+ newpkg->replaces = alpm_list_add(newpkg->replaces, _alpm_dep_dup(i->data));
+ }
newpkg->groups = alpm_list_strdup(pkg->groups);
if(pkg->files.count) {
size_t filenum;
@@ -517,8 +519,12 @@ alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg)
newpkg->depends = alpm_list_add(newpkg->depends, _alpm_dep_dup(i->data));
}
newpkg->optdepends = alpm_list_strdup(pkg->optdepends);
- newpkg->conflicts = alpm_list_strdup(pkg->conflicts);
- newpkg->provides = alpm_list_strdup(pkg->provides);
+ for(i = pkg->conflicts; i; i = alpm_list_next(i)) {
+ newpkg->conflicts = alpm_list_add(newpkg->conflicts, _alpm_dep_dup(i->data));
+ }
+ for(i = pkg->provides; i; i = alpm_list_next(i)) {
+ newpkg->provides = alpm_list_add(newpkg->provides, _alpm_dep_dup(i->data));
+ }
for(i = pkg->deltas; i; i = alpm_list_next(i)) {
newpkg->deltas = alpm_list_add(newpkg->deltas, _alpm_delta_dup(i->data));
}
@@ -557,8 +563,10 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
FREE(pkg->sha256sum);
FREE(pkg->base64_sig);
FREE(pkg->arch);
+
FREELIST(pkg->licenses);
- FREELIST(pkg->replaces);
+ alpm_list_free_inner(pkg->replaces, (alpm_list_fn_free)_alpm_dep_free);
+ alpm_list_free(pkg->replaces);
FREELIST(pkg->groups);
if(pkg->files.count) {
size_t i;
@@ -572,8 +580,10 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
alpm_list_free(pkg->depends);
FREELIST(pkg->optdepends);
- FREELIST(pkg->conflicts);
- FREELIST(pkg->provides);
+ alpm_list_free_inner(pkg->conflicts, (alpm_list_fn_free)_alpm_dep_free);
+ alpm_list_free(pkg->conflicts);
+ alpm_list_free_inner(pkg->provides, (alpm_list_fn_free)_alpm_dep_free);
+ alpm_list_free(pkg->provides);
alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free);
alpm_list_free(pkg->deltas);
alpm_list_free(pkg->delta_path);
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index f16489d9..3e38707e 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -150,14 +150,11 @@ int SYMEXPORT alpm_sync_sysupgrade(alpm_handle_t *handle, int enable_downgrade)
for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) {
spkg = k->data;
for(l = alpm_pkg_get_replaces(spkg); l; l = l->next) {
- const char *replace = l->data;
- alpm_depend_t *parsed_replace = _alpm_splitdep(replace);
- if(_alpm_depcmp(lpkg, parsed_replace)) {
+ alpm_depend_t *replace = l->data;
+ if(_alpm_depcmp(lpkg, replace)) {
found = 1;
- _alpm_dep_free(parsed_replace);
break;
}
- _alpm_dep_free(parsed_replace);
}
if(found) {
/* check IgnorePkg/IgnoreGroup */