summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--src/pacman/package.c34
-rw-r--r--src/pacman/sync.c7
11 files changed, 108 insertions, 87 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 */
diff --git a/src/pacman/package.c b/src/pacman/package.c
index 8c101851..7fe33a9f 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -37,6 +37,22 @@
#define CLBUF_SIZE 4096
+/** Turn a depends list into a text list.
+ * @param deps a list with items of type alpm_depend_t
+ * @return a string list, must be freed
+ */
+static void deplist_display(const char *title,
+ alpm_list_t *deps)
+{
+ alpm_list_t *i, *text = NULL;
+ for(i = deps; i; i = alpm_list_next(i)) {
+ alpm_depend_t *dep = alpm_list_getdata(i);
+ text = alpm_list_add(text, alpm_dep_compute_string(dep));
+ }
+ list_display(title, text);
+ FREELIST(text);
+}
+
/**
* Display the details of a package.
* Extra information entails 'required by' info for sync packages and backup
@@ -52,8 +68,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
char bdatestr[50] = "", idatestr[50] = "";
const char *label;
double size;
- const alpm_list_t *i;
- alpm_list_t *requiredby = NULL, *depstrings = NULL;
+ alpm_list_t *requiredby = NULL;
if(pkg == NULL) {
return;
@@ -81,12 +96,6 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
break;
}
- /* turn depends list into a text list */
- for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) {
- alpm_depend_t *dep = (alpm_depend_t *)alpm_list_getdata(i);
- depstrings = alpm_list_add(depstrings, alpm_dep_compute_string(dep));
- }
-
if(extra || from == PKG_FROM_LOCALDB) {
/* compute this here so we don't get a pause in the middle of output */
requiredby = alpm_pkg_compute_requiredby(pkg);
@@ -102,14 +111,14 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
string_display(_("URL :"), alpm_pkg_get_url(pkg));
list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg));
list_display(_("Groups :"), alpm_pkg_get_groups(pkg));
- list_display(_("Provides :"), alpm_pkg_get_provides(pkg));
- list_display(_("Depends On :"), depstrings);
+ deplist_display(_("Provides :"), alpm_pkg_get_provides(pkg));
+ deplist_display(_("Depends On :"), alpm_pkg_get_depends(pkg));
list_display_linebreak(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg));
if(extra || from == PKG_FROM_LOCALDB) {
list_display(_("Required By :"), requiredby);
}
- list_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
- list_display(_("Replaces :"), alpm_pkg_get_replaces(pkg));
+ deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
+ deplist_display(_("Replaces :"), alpm_pkg_get_replaces(pkg));
size = humanize_size(alpm_pkg_get_size(pkg), 'K', 1, &label);
if(from == PKG_FROM_SYNCDB) {
@@ -162,7 +171,6 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
/* final newline to separate packages */
printf("\n");
- FREELIST(depstrings);
FREELIST(requiredby);
}
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index 7b50d805..ea32a264 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -779,13 +779,14 @@ int sync_prepare_execute(void)
for(i = data; i; i = alpm_list_next(i)) {
alpm_conflict_t *conflict = alpm_list_getdata(i);
/* only print reason if it contains new information */
- if(strcmp(conflict->package1, conflict->reason) == 0 ||
- strcmp(conflict->package2, conflict->reason) == 0) {
+ if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
printf(_(":: %s and %s are in conflict\n"),
conflict->package1, conflict->package2);
} else {
+ char *reason = alpm_dep_compute_string(conflict->reason);
printf(_(":: %s and %s are in conflict (%s)\n"),
- conflict->package1, conflict->package2, conflict->reason);
+ conflict->package1, conflict->package2, reason);
+ free(reason);
}
}
break;