diff options
-rw-r--r-- | src/add.c | 38 | ||||
-rw-r--r-- | src/apk_database.h | 2 | ||||
-rw-r--r-- | src/database.c | 81 |
3 files changed, 85 insertions, 36 deletions
@@ -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; } |