summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/add.c38
-rw-r--r--src/apk_database.h2
-rw-r--r--src/database.c81
3 files changed, 85 insertions, 36 deletions
diff --git a/src/add.c b/src/add.c
index cf518af..da83fe0 100644
--- a/src/add.c
+++ b/src/add.c
@@ -17,6 +17,7 @@
struct add_ctx {
unsigned int open_flags;
+ const char *virtpkg;
};
static int add_parse(void *ctx, int optch, int optindex, const char *optarg)
@@ -30,6 +31,9 @@ static int add_parse(void *ctx, int optch, int optindex, const char *optarg)
case 'u':
apk_flags |= APK_UPGRADE;
break;
+ case 't':
+ actx->virtpkg = optarg;
+ break;
default:
return -1;
}
@@ -41,12 +45,33 @@ static int add_main(void *ctx, int argc, char **argv)
struct add_ctx *actx = (struct add_ctx *) ctx;
struct apk_database db;
struct apk_state *state = NULL;
- struct apk_dependency_array *pkgs = NULL; /* list of pkgs to install */
+ struct apk_dependency_array *pkgs = NULL;
+ struct apk_package *virtpkg = NULL;
int i, r;
r = apk_db_open(&db, apk_root, actx->open_flags | APK_OPENF_WRITE);
if (r != 0)
return r;
+
+ if (actx->virtpkg) {
+ struct apk_dependency dep;
+ virtpkg = apk_pkg_new();
+ if (virtpkg == NULL) {
+ apk_error("Failed to allocate virtual meta package");
+ goto err;
+ }
+ virtpkg->name = apk_db_get_name(&db, APK_BLOB_STR(actx->virtpkg));
+ virtpkg->version = strdup("0");
+ virtpkg->description = strdup("virtual meta package");
+ dep = (struct apk_dependency) {
+ .name = virtpkg->name,
+ .version = virtpkg->version,
+ .result_mask = APK_VERSION_EQUAL,
+ };
+ dep.name->flags |= APK_NAME_TOPLEVEL | APK_NAME_VIRTUAL;
+ virtpkg = apk_db_pkg_add(&db, virtpkg);
+ apk_deps_add(&pkgs, &dep);
+ }
for (i = 0; i < argc; i++) {
struct apk_dependency dep;
@@ -71,8 +96,12 @@ static int add_main(void *ctx, int argc, char **argv)
.result_mask = APK_DEPMASK_REQUIRE,
};
}
- dep.name->flags |= APK_NAME_TOPLEVEL;
- apk_deps_add(&pkgs, &dep);
+ if (virtpkg) {
+ apk_deps_add(&virtpkg->depends, &dep);
+ } else {
+ dep.name->flags |= APK_NAME_TOPLEVEL;
+ apk_deps_add(&pkgs, &dep);
+ }
}
state = apk_state_new(&db);
@@ -95,11 +124,12 @@ err:
static struct option add_options[] = {
{ "initdb", no_argument, NULL, 0x10000 },
{ "upgrade", no_argument, NULL, 'u' },
+ { "virtual", required_argument, NULL, 't' },
};
static struct apk_applet apk_add = {
.name = "add",
- .usage = "[--initdb] [--upgrade|-u] apkname...",
+ .usage = "[--initdb] [--upgrade|-u] [--virtual metaname] apkname...",
.context_size = sizeof(struct add_ctx),
.num_options = ARRAY_SIZE(add_options),
.options = add_options,
diff --git a/src/apk_database.h b/src/apk_database.h
index 0a0e52d..523dab5 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -55,6 +55,7 @@ struct apk_db_dir_instance {
};
#define APK_NAME_TOPLEVEL 0x0001
+#define APK_NAME_VIRTUAL 0x0002
struct apk_name {
apk_hash_node hash_node;
@@ -120,6 +121,7 @@ int apk_db_write_config(struct apk_database *db);
void apk_db_close(struct apk_database *db);
struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file);
+struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum);
struct apk_package *apk_db_get_file_owner(struct apk_database *db, apk_blob_t filename);
diff --git a/src/database.c b/src/database.c
index e91c64a..32ee3bd 100644
--- a/src/database.c
+++ b/src/database.c
@@ -349,7 +349,7 @@ static void apk_db_pkg_rdepends(struct apk_database *db, struct apk_package *pkg
}
}
-static struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg)
+struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg)
{
struct apk_package *idb;
@@ -1229,35 +1229,16 @@ static void apk_db_purge_pkg(struct apk_database *db,
apk_pkg_set_state(db, pkg, APK_PKG_NOT_INSTALLED);
}
-int apk_db_install_pkg(struct apk_database *db,
- struct apk_package *oldpkg,
- struct apk_package *newpkg,
- apk_progress_cb cb, void *cb_ctx)
+static int apk_db_unpack_pkg(struct apk_database *db,
+ struct apk_package *newpkg,
+ int upgrade, csum_t csum,
+ apk_progress_cb cb, void *cb_ctx)
{
- struct apk_bstream *bs;
struct install_ctx ctx;
- csum_t csum;
+ struct apk_bstream *bs;
char file[256];
- int r, i;
-
- if (fchdir(db->root_fd) < 0)
- return errno;
-
- /* Just purging? */
- if (oldpkg != NULL && newpkg == NULL) {
- r = apk_pkg_run_script(oldpkg, db->root_fd,
- APK_SCRIPT_PRE_DEINSTALL);
- if (r != 0)
- return r;
-
- apk_db_purge_pkg(db, oldpkg);
-
- r = apk_pkg_run_script(oldpkg, db->root_fd,
- APK_SCRIPT_POST_DEINSTALL);
- return r;
- }
+ int i;
- /* Install the new stuff */
if (newpkg->filename == NULL) {
for (i = 0; i < APK_MAX_REPOS; i++)
if (newpkg->repos & BIT(i))
@@ -1285,8 +1266,8 @@ int apk_db_install_pkg(struct apk_database *db,
ctx = (struct install_ctx) {
.db = db,
.pkg = newpkg,
- .script = (oldpkg == NULL) ?
- APK_SCRIPT_PRE_INSTALL : APK_SCRIPT_PRE_UPGRADE,
+ .script = upgrade ?
+ APK_SCRIPT_PRE_UPGRADE : APK_SCRIPT_PRE_INSTALL,
.cb = cb,
.cb_ctx = cb_ctx,
};
@@ -1294,10 +1275,49 @@ int apk_db_install_pkg(struct apk_database *db,
goto err_close;
bs->close(bs, csum, NULL);
+ return 0;
+err_close:
+ bs->close(bs, NULL, NULL);
+ return -1;
+}
+
+int apk_db_install_pkg(struct apk_database *db,
+ struct apk_package *oldpkg,
+ struct apk_package *newpkg,
+ apk_progress_cb cb, void *cb_ctx)
+{
+ csum_t csum;
+ int r;
+
+ if (fchdir(db->root_fd) < 0)
+ return errno;
+
+ /* Just purging? */
+ if (oldpkg != NULL && newpkg == NULL) {
+ r = apk_pkg_run_script(oldpkg, db->root_fd,
+ APK_SCRIPT_PRE_DEINSTALL);
+ if (r != 0)
+ return r;
+
+ apk_db_purge_pkg(db, oldpkg);
+
+ r = apk_pkg_run_script(oldpkg, db->root_fd,
+ APK_SCRIPT_POST_DEINSTALL);
+ return r;
+ }
+
+ /* Install the new stuff */
+ if (!(newpkg->name->flags & APK_NAME_VIRTUAL)) {
+ r = apk_db_unpack_pkg(db, newpkg, (oldpkg == NULL), csum,
+ cb, cb_ctx);
+ if (r != 0)
+ return r;
+ }
apk_pkg_set_state(db, newpkg, APK_PKG_INSTALLED);
- if (memcmp(csum, newpkg->csum, sizeof(csum)) != 0)
+ if (!(newpkg->name->flags & APK_NAME_VIRTUAL) &&
+ memcmp(csum, newpkg->csum, sizeof(csum)) != 0)
apk_warning("%s-%s: checksum does not match",
newpkg->name->name, newpkg->version);
@@ -1312,7 +1332,4 @@ int apk_db_install_pkg(struct apk_database *db,
newpkg->name->name, newpkg->version);
}
return r;
-err_close:
- bs->close(bs, NULL, NULL);
- return -1;
}