summaryrefslogtreecommitdiff
path: root/src/package.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2011-10-18 18:11:26 -0400
committerTimo Teräs <timo.teras@iki.fi>2011-10-18 18:11:26 -0400
commita787038dbe643a7169a4b3610e104ac94b175ed0 (patch)
tree93e0e6629d805cdef6fa5833100ed0366225b019 /src/package.c
parentafd854a3e2cf20b3f35c5503c9df9589f482dc74 (diff)
downloadapk-tools-a787038dbe643a7169a4b3610e104ac94b175ed0.tar.gz
apk-tools-a787038dbe643a7169a4b3610e104ac94b175ed0.tar.bz2
apk-tools-a787038dbe643a7169a4b3610e104ac94b175ed0.tar.xz
apk-tools-a787038dbe643a7169a4b3610e104ac94b175ed0.zip
pkg, info: remember installed packages "replaces"
"replaces" is now turned to a full dependency type list, so you can make package overwrite files only certain versions of the package (though, we should probably take this into account already at solution calculation phase). Also make 'info --replaces' print the "replaces" of the package. This is in preparation for the policy package support, which still requires "replacement priority" field to decide which packages' files get the preference.
Diffstat (limited to 'src/package.c')
-rw-r--r--src/package.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/src/package.c b/src/package.c
index 0f882e2..76b6550 100644
--- a/src/package.c
+++ b/src/package.c
@@ -77,6 +77,7 @@ struct apk_installed_package *apk_pkg_install(struct apk_database *db,
ipkg->pkg = pkg;
apk_string_array_init(&ipkg->triggers);
apk_string_array_init(&ipkg->pending_triggers);
+ apk_dependency_array_init(&ipkg->replaces);
/* Overlay override information resides in a nameless package */
if (pkg->name != NULL) {
@@ -109,6 +110,7 @@ void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg)
}
apk_string_array_free(&ipkg->triggers);
apk_string_array_free(&ipkg->pending_triggers);
+ apk_dependency_array_free(&ipkg->replaces);
for (i = 0; i < APK_SCRIPT_MAX; i++)
if (ipkg->script[i].ptr != NULL)
@@ -189,26 +191,28 @@ struct parse_depend_ctx {
struct apk_dependency_array **depends;
};
-int apk_dep_from_blob(struct apk_dependency *dep, struct apk_database *db,
- apk_blob_t blob)
+void apk_blob_pull_dep(apk_blob_t *b, struct apk_database *db, struct apk_dependency *dep)
{
struct apk_name *name;
apk_blob_t bname, bop, bver = APK_BLOB_NULL;
int mask = APK_DEPMASK_REQUIRE;
+ size_t len;
/* [!]name[<,<=,=,>=,>]ver */
- if (blob.ptr[0] == '!') {
+ if (APK_BLOB_IS_NULL(*b))
+ goto fail;
+ if (b->ptr[0] == '!') {
mask = 0;
- blob.ptr++;
- blob.len--;
+ b->ptr++;
+ b->len--;
}
- if (apk_blob_cspn(blob, "<>=", &bname, &bop)) {
+ if (apk_blob_cspn(*b, "<>= ", &bname, &bop)) {
int i;
if (mask == 0)
- return -EINVAL;
+ goto fail;
if (!apk_blob_spn(bop, "<>=", &bop, &bver))
- return -EINVAL;
+ goto fail;
mask = 0;
for (i = 0; i < bop.len; i++) {
switch (bop.ptr[i]) {
@@ -225,21 +229,29 @@ int apk_dep_from_blob(struct apk_dependency *dep, struct apk_database *db,
}
if ((mask & APK_DEPMASK_CHECKSUM) != APK_DEPMASK_CHECKSUM &&
!apk_version_validate(bver))
- return -EINVAL;
-
- blob = bname;
+ goto fail;
+ } else {
+ bname = *b;
+ bop = APK_BLOB_NULL;
+ bver = APK_BLOB_NULL;
}
+ len = bname.len + bop.len + bver.len;
+ b->ptr += len;
+ b->len -= len;
- name = apk_db_get_name(db, blob);
+ name = apk_db_get_name(db, bname);
if (name == NULL)
- return -ENOENT;
+ goto fail;
*dep = (struct apk_dependency){
.name = name,
.version = apk_blob_atomize_dup(bver),
.result_mask = mask,
};
- return 0;
+ return;
+fail:
+ *dep = (struct apk_dependency){ .name = NULL };
+ *b = APK_BLOB_NULL;
}
void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
@@ -266,7 +278,8 @@ static int parse_depend(void *ctx, apk_blob_t blob)
if (blob.len == 0)
return 0;
- if (apk_dep_from_blob(&p, pctx->db, blob) < 0)
+ apk_blob_pull_dep(&blob, pctx->db, &p);
+ if (p.name == NULL || blob.len != 0)
return -1;
dep = apk_dependency_array_add(pctx->depends);
@@ -301,16 +314,14 @@ int apk_dep_is_satisfied(struct apk_dependency *dep, struct apk_package *pkg)
return 0;
}
-void apk_deps_parse(struct apk_database *db,
- struct apk_dependency_array **depends,
- apk_blob_t blob)
+void apk_blob_pull_deps(apk_blob_t *b, struct apk_database *db, struct apk_dependency_array **deps)
{
- struct parse_depend_ctx ctx = { db, depends };
+ struct parse_depend_ctx ctx = { db, deps };
- if (blob.len > 0 && blob.ptr[blob.len-1] == '\n')
- blob.len--;
+ if (b->len > 0 && b->ptr[b->len-1] == '\n')
+ b->len--;
- apk_blob_for_each_segment(blob, " ", parse_depend, &ctx);
+ apk_blob_for_each_segment(*b, " ", parse_depend, &ctx);
}
void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep)
@@ -327,6 +338,20 @@ void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep)
}
}
+void apk_blob_push_deps(apk_blob_t *to, struct apk_dependency_array *deps)
+{
+ int i;
+
+ if (deps == NULL)
+ return;
+
+ for (i = 0; i < deps->num; i++) {
+ if (i)
+ apk_blob_push_blob(to, APK_BLOB_PTR_LEN(" ", 1));
+ apk_blob_push_dep(to, &deps->item[i]);
+ }
+}
+
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os)
{
apk_blob_t blob;
@@ -657,7 +682,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
pkg->arch = apk_blob_atomize_dup(value);
break;
case 'D':
- apk_deps_parse(db, &pkg->depends, value);
+ apk_blob_pull_deps(&value, db, &pkg->depends);
break;
case 'C':
apk_blob_pull_csum(&value, &pkg->csum);
@@ -669,7 +694,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
pkg->installed_size = apk_blob_pull_uint(&value, 10);
break;
case 'i':
- apk_deps_parse(db, &pkg->install_if, value);
+ apk_blob_pull_deps(&value, db, &pkg->install_if);
break;
case 'o':
pkg->origin = apk_blob_atomize_dup(value);
@@ -683,7 +708,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'c':
pkg->commit = apk_blob_cstr(value);
break;
- case 'F': case 'M': case 'R': case 'Z':
+ case 'F': case 'M': case 'R': case 'Z': case 'r':
/* installed db entries which are handled in database.c */
return 1;
default: