Skip to content
Snippets Groups Projects
database.c 54.4 KiB
Newer Older

		if (bs == NULL) {
			apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
			bs = apk_repo_file_open(repo, pkg->arch ?: db->arch, item, file, sizeof(file));
			if (apk_repo_is_remote(repo))
				need_copy = TRUE;
		}
	} else {
		bs = apk_bstream_from_file(AT_FDCWD, pkg->filename);
		strncpy(file, pkg->filename, sizeof(file));
		need_copy = TRUE;
	}
Timo Teräs's avatar
Timo Teräs committed
	if (!apk_db_cache_active(db))
		need_copy = FALSE;
	if (bs == NULL) {
		apk_error("%s: %s", file, strerror(errno));
	if (need_copy) {
		apk_pkg_format_cache(pkg, APK_BLOB_BUF(item));
		bs = apk_bstream_tee(bs, db->cachetmp_fd, item);
		if (bs == NULL) {
			apk_error("Unable to cache %s: %s",
				  file, strerror(errno));
			return errno;
		}
	}
		.script = upgrade ?
			APK_SCRIPT_PRE_UPGRADE : APK_SCRIPT_PRE_INSTALL,
		.script_args = script_args,
		.cb = cb,
		.cb_ctx = cb_ctx,
	apk_name_array_init(&ctx.replaces);
	apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &pkg->csum, db->keys_fd);
	tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
	r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE, &db->id_cache);
	apk_sign_ctx_free(&ctx.sctx);
	apk_name_array_free(&ctx.replaces);
	tar->close(tar);
	if (need_copy) {
		if (r == 0)
			renameat(db->cachetmp_fd, file, db->cache_fd, file);
		else
			unlinkat(db->cachetmp_fd, file, 0);
	}

		apk_error("%s: %s", file, apk_error_str(r));
Timo Teräs's avatar
Timo Teräs committed
		goto err;
	r = apk_db_run_pending_script(&ctx);
	if (r != 0)
Timo Teräs's avatar
Timo Teräs committed
		goto err;

	apk_db_migrate_files(db, ipkg);
Timo Teräs's avatar
Timo Teräs committed
err:
	if (!reinstall)
		apk_db_purge_pkg(db, ipkg, ".apk-new");
Timo Teräs's avatar
Timo Teräs committed
	return r;
}

int apk_db_install_pkg(struct apk_database *db,
		       struct apk_package *oldpkg,
		       struct apk_package *newpkg,
		       apk_progress_cb cb, void *cb_ctx)
{
Timo Teräs's avatar
Timo Teräs committed
	char *script_args[] = { NULL, NULL, NULL, NULL };
	struct apk_installed_package *ipkg;
	/* Upgrade script gets two args: <new-pkg> <old-pkg> */
	if (oldpkg != NULL && newpkg != NULL) {
Timo Teräs's avatar
Timo Teräs committed
		script_args[1] = newpkg->version;
		script_args[2] = oldpkg->version;
Timo Teräs's avatar
Timo Teräs committed
		script_args[1] = oldpkg ? oldpkg->version : newpkg->version;
	/* Just purging? */
	if (oldpkg != NULL && newpkg == NULL) {
		ipkg = oldpkg->ipkg;

		if (ipkg == NULL)
			return 0;

		r = apk_ipkg_run_script(ipkg, db, 
					APK_SCRIPT_PRE_DEINSTALL, script_args);
		apk_db_purge_pkg(db, ipkg, NULL);
		r = apk_ipkg_run_script(ipkg, db,
					APK_SCRIPT_POST_DEINSTALL, script_args);
		apk_pkg_uninstall(db, oldpkg);

		return r;
	}

	/* Install the new stuff */
	ipkg = apk_pkg_install(db, newpkg);
	ipkg->flags |= APK_IPKGF_RUN_ALL_TRIGGERS;
	if (ipkg->triggers->num != 0) {
		list_del(&ipkg->trigger_pkgs_list);
		list_init(&ipkg->trigger_pkgs_list);
		apk_string_array_free(&ipkg->triggers);
	}

	if (newpkg->installed_size != 0) {
		r = apk_db_unpack_pkg(db, ipkg, (oldpkg != NULL),
				      (oldpkg == newpkg), cb, cb_ctx,
				      script_args);
		if (r != 0) {
			apk_pkg_uninstall(db, newpkg);
	if (oldpkg != NULL && oldpkg != newpkg && oldpkg->ipkg != NULL) {
		apk_db_purge_pkg(db, oldpkg->ipkg, NULL);
		apk_pkg_uninstall(db, oldpkg);
	}
	r = apk_ipkg_run_script(ipkg, db,
				(oldpkg == NULL) ?
				APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE,
				script_args);
		apk_error("%s-%s: Failed to execute post-install/upgrade script",
			  newpkg->name->name, newpkg->version);