db, pkg: separate structure for fields of installed packages
this makes the database package entry smaller, and we propbably get more fields to installed_package later too. this cleans up the way scripts are stored and is a preparation for supporting triggers. some parsing for trigger meta-data. ref #45.cute-signatures
parent
dee6ffa492
commit
36b5cee98b
|
@ -38,6 +38,7 @@ struct apk_db_file {
|
||||||
|
|
||||||
#define APK_DBDIRF_PROTECTED 0x0001
|
#define APK_DBDIRF_PROTECTED 0x0001
|
||||||
#define APK_DBDIRF_SYMLINKS_ONLY 0x0002
|
#define APK_DBDIRF_SYMLINKS_ONLY 0x0002
|
||||||
|
#define APK_DBDIRF_MODIFIED 0x0100
|
||||||
|
|
||||||
struct apk_db_dir {
|
struct apk_db_dir {
|
||||||
apk_hash_node hash_node;
|
apk_hash_node hash_node;
|
||||||
|
@ -111,6 +112,7 @@ struct apk_database {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct list_head packages;
|
struct list_head packages;
|
||||||
|
struct list_head triggers;
|
||||||
struct apk_hash dirs;
|
struct apk_hash dirs;
|
||||||
struct apk_hash files;
|
struct apk_hash files;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -20,12 +20,14 @@ struct apk_database;
|
||||||
struct apk_name;
|
struct apk_name;
|
||||||
|
|
||||||
#define APK_SCRIPT_INVALID -1
|
#define APK_SCRIPT_INVALID -1
|
||||||
#define APK_SCRIPT_PRE_INSTALL 1
|
#define APK_SCRIPT_PRE_INSTALL 0
|
||||||
#define APK_SCRIPT_POST_INSTALL 2
|
#define APK_SCRIPT_POST_INSTALL 1
|
||||||
#define APK_SCRIPT_PRE_DEINSTALL 3
|
#define APK_SCRIPT_PRE_DEINSTALL 2
|
||||||
#define APK_SCRIPT_POST_DEINSTALL 4
|
#define APK_SCRIPT_POST_DEINSTALL 3
|
||||||
#define APK_SCRIPT_PRE_UPGRADE 5
|
#define APK_SCRIPT_PRE_UPGRADE 4
|
||||||
#define APK_SCRIPT_POST_UPGRADE 6
|
#define APK_SCRIPT_POST_UPGRADE 5
|
||||||
|
#define APK_SCRIPT_TRIGGER 6
|
||||||
|
#define APK_SCRIPT_MAX 7
|
||||||
|
|
||||||
#define APK_PKG_NOT_INSTALLED 0
|
#define APK_PKG_NOT_INSTALLED 0
|
||||||
#define APK_PKG_INSTALLED 1
|
#define APK_PKG_INSTALLED 1
|
||||||
|
@ -58,13 +60,6 @@ struct apk_sign_ctx {
|
||||||
} signature;
|
} signature;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct apk_script {
|
|
||||||
struct hlist_node script_list;
|
|
||||||
unsigned int type;
|
|
||||||
unsigned int size;
|
|
||||||
char script[];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define APK_DEPMASK_REQUIRE (APK_VERSION_EQUAL|APK_VERSION_LESS|\
|
#define APK_DEPMASK_REQUIRE (APK_VERSION_EQUAL|APK_VERSION_LESS|\
|
||||||
APK_VERSION_GREATER)
|
APK_VERSION_GREATER)
|
||||||
#define APK_DEPMASK_CONFLICT (0)
|
#define APK_DEPMASK_CONFLICT (0)
|
||||||
|
@ -76,9 +71,17 @@ struct apk_dependency {
|
||||||
};
|
};
|
||||||
APK_ARRAY(apk_dependency_array, struct apk_dependency);
|
APK_ARRAY(apk_dependency_array, struct apk_dependency);
|
||||||
|
|
||||||
|
struct apk_installed_package {
|
||||||
|
struct apk_package *pkg;
|
||||||
|
struct list_head installed_pkgs_list;
|
||||||
|
struct list_head trigger_pkgs_list;
|
||||||
|
struct hlist_head owned_dirs;
|
||||||
|
apk_blob_t script[APK_SCRIPT_MAX];
|
||||||
|
struct apk_string_array *triggers;
|
||||||
|
};
|
||||||
|
|
||||||
struct apk_package {
|
struct apk_package {
|
||||||
apk_hash_node hash_node;
|
apk_hash_node hash_node;
|
||||||
|
|
||||||
unsigned repos;
|
unsigned repos;
|
||||||
struct apk_name *name;
|
struct apk_name *name;
|
||||||
char *version;
|
char *version;
|
||||||
|
@ -87,11 +90,7 @@ struct apk_package {
|
||||||
size_t installed_size, size;
|
size_t installed_size, size;
|
||||||
char *filename;
|
char *filename;
|
||||||
struct apk_checksum csum;
|
struct apk_checksum csum;
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
/* for installed packages only */
|
|
||||||
struct list_head installed_pkgs_list;
|
|
||||||
struct hlist_head owned_dirs;
|
|
||||||
struct hlist_head scripts;
|
|
||||||
};
|
};
|
||||||
APK_ARRAY(apk_package_array, struct apk_package *);
|
APK_ARRAY(apk_package_array, struct apk_package *);
|
||||||
|
|
||||||
|
@ -134,12 +133,15 @@ int apk_pkg_parse_name(apk_blob_t apkname, apk_blob_t *name, apk_blob_t *version
|
||||||
|
|
||||||
int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
||||||
char field, apk_blob_t value);
|
char field, apk_blob_t value);
|
||||||
int apk_pkg_get_state(struct apk_package *pkg);
|
|
||||||
void apk_pkg_set_state(struct apk_database *db, struct apk_package *pkg, int state);
|
struct apk_installed_package *apk_pkg_install(struct apk_database *db, struct apk_package *pkg);
|
||||||
int apk_pkg_add_script(struct apk_package *pkg, struct apk_istream *is,
|
void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg);
|
||||||
unsigned int type, unsigned int size);
|
|
||||||
int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
int apk_ipkg_add_script(struct apk_installed_package *ipkg,
|
||||||
unsigned int type);
|
struct apk_istream *is,
|
||||||
|
unsigned int type, unsigned int size);
|
||||||
|
int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd,
|
||||||
|
unsigned int type, char **argv);
|
||||||
|
|
||||||
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry);
|
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry);
|
||||||
int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os);
|
int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os);
|
||||||
|
|
|
@ -106,6 +106,7 @@ static int audit_backup(struct apk_database *db)
|
||||||
|
|
||||||
static int audit_system(struct apk_database *db)
|
static int audit_system(struct apk_database *db)
|
||||||
{
|
{
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct apk_db_file *file;
|
struct apk_db_file *file;
|
||||||
|
@ -113,8 +114,9 @@ static int audit_system(struct apk_database *db)
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
int done;
|
int done;
|
||||||
|
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
hlist_for_each_entry(diri, dn, &pkg->owned_dirs, pkg_dirs_list) {
|
pkg = ipkg->pkg;
|
||||||
|
hlist_for_each_entry(diri, dn, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||||
if (diri->dir->flags & APK_DBDIRF_PROTECTED)
|
if (diri->dir->flags & APK_DBDIRF_PROTECTED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
207
src/database.c
207
src/database.c
|
@ -35,9 +35,12 @@ static const char * const apk_linked_cache_dir = "etc/apk/cache";
|
||||||
struct install_ctx {
|
struct install_ctx {
|
||||||
struct apk_database *db;
|
struct apk_database *db;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
|
|
||||||
int script;
|
int script;
|
||||||
|
char **script_args;
|
||||||
int script_pending : 1;
|
int script_pending : 1;
|
||||||
|
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct apk_checksum data_csum;
|
struct apk_checksum data_csum;
|
||||||
struct apk_sign_ctx sctx;
|
struct apk_sign_ctx sctx;
|
||||||
|
@ -471,6 +474,7 @@ int apk_cache_download(struct apk_database *db, const char *url,
|
||||||
int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg = NULL;
|
struct apk_package *pkg = NULL;
|
||||||
|
struct apk_installed_package *ipkg = NULL;
|
||||||
struct apk_db_dir_instance *diri = NULL;
|
struct apk_db_dir_instance *diri = NULL;
|
||||||
struct apk_db_file *file = NULL;
|
struct apk_db_file *file = NULL;
|
||||||
struct hlist_node **diri_node = NULL;
|
struct hlist_node **diri_node = NULL;
|
||||||
|
@ -485,14 +489,13 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
|
|
||||||
if (repo >= 0)
|
if (repo >= 0)
|
||||||
pkg->repos |= BIT(repo);
|
pkg->repos |= BIT(repo);
|
||||||
else if (repo == -1)
|
|
||||||
apk_pkg_set_state(db, pkg, APK_PKG_INSTALLED);
|
|
||||||
|
|
||||||
if (apk_db_pkg_add(db, pkg) != pkg && repo == -1) {
|
if (apk_db_pkg_add(db, pkg) == NULL) {
|
||||||
apk_error("Installed database load failed");
|
apk_error("Installed database load failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pkg = NULL;
|
pkg = NULL;
|
||||||
|
ipkg = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,7 +508,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
if (pkg == NULL) {
|
if (pkg == NULL) {
|
||||||
pkg = apk_pkg_new();
|
pkg = apk_pkg_new();
|
||||||
diri = NULL;
|
diri = NULL;
|
||||||
diri_node = hlist_tail_ptr(&pkg->owned_dirs);
|
diri_node = NULL;
|
||||||
file_diri_node = NULL;
|
file_diri_node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,6 +521,12 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create the installation entry */
|
||||||
|
if (ipkg == NULL) {
|
||||||
|
ipkg = apk_pkg_install(db, pkg);
|
||||||
|
diri_node = hlist_tail_ptr(&ipkg->owned_dirs);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check FDB special entries */
|
/* Check FDB special entries */
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case 'F':
|
case 'F':
|
||||||
|
@ -568,6 +577,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
|
|
||||||
static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||||
{
|
{
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct apk_db_file *file;
|
struct apk_db_file *file;
|
||||||
|
@ -576,12 +586,13 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||||
apk_blob_t bbuf = APK_BLOB_BUF(buf);
|
apk_blob_t bbuf = APK_BLOB_BUF(buf);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
|
pkg = ipkg->pkg;
|
||||||
r = apk_pkg_write_index_entry(pkg, os);
|
r = apk_pkg_write_index_entry(pkg, os);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
hlist_for_each_entry(diri, c1, &pkg->owned_dirs, pkg_dirs_list) {
|
hlist_for_each_entry(diri, c1, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("F:"));
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("F:"));
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN(diri->dir->name, diri->dir->namelen));
|
apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN(diri->dir->name, diri->dir->namelen));
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nM:"));
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nM:"));
|
||||||
|
@ -617,19 +628,23 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||||
|
|
||||||
static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os)
|
static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os)
|
||||||
{
|
{
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
struct apk_script *script;
|
|
||||||
struct hlist_node *c2;
|
|
||||||
struct apk_file_info fi;
|
struct apk_file_info fi;
|
||||||
char filename[256];
|
char filename[256];
|
||||||
apk_blob_t bfn;
|
apk_blob_t bfn;
|
||||||
int r;
|
int r, i;
|
||||||
|
|
||||||
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
|
pkg = ipkg->pkg;
|
||||||
|
|
||||||
|
for (i = 0; i < APK_SCRIPT_MAX; i++) {
|
||||||
|
if (ipkg->script[i].ptr == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
|
||||||
hlist_for_each_entry(script, c2, &pkg->scripts, script_list) {
|
|
||||||
fi = (struct apk_file_info) {
|
fi = (struct apk_file_info) {
|
||||||
.name = filename,
|
.name = filename,
|
||||||
.size = script->size,
|
.size = ipkg->script[i].len,
|
||||||
.mode = 0755 | S_IFREG,
|
.mode = 0755 | S_IFREG,
|
||||||
};
|
};
|
||||||
/* The scripts db expects file names in format:
|
/* The scripts db expects file names in format:
|
||||||
|
@ -641,10 +656,10 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
|
||||||
apk_blob_push_blob(&bfn, APK_BLOB_STR("."));
|
apk_blob_push_blob(&bfn, APK_BLOB_STR("."));
|
||||||
apk_blob_push_csum(&bfn, &pkg->csum);
|
apk_blob_push_csum(&bfn, &pkg->csum);
|
||||||
apk_blob_push_blob(&bfn, APK_BLOB_STR("."));
|
apk_blob_push_blob(&bfn, APK_BLOB_STR("."));
|
||||||
apk_blob_push_blob(&bfn, APK_BLOB_STR(apk_script_types[script->type]));
|
apk_blob_push_blob(&bfn, APK_BLOB_STR(apk_script_types[i]));
|
||||||
apk_blob_push_blob(&bfn, APK_BLOB_PTR_LEN("", 1));
|
apk_blob_push_blob(&bfn, APK_BLOB_PTR_LEN("", 1));
|
||||||
|
|
||||||
r = apk_tar_write_entry(os, &fi, script->script);
|
r = apk_tar_write_entry(os, &fi, ipkg->script[i].ptr);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -668,8 +683,8 @@ static int apk_db_scriptdb_read_v1(struct apk_database *db, struct apk_istream *
|
||||||
csum.type = APK_CHECKSUM_MD5;
|
csum.type = APK_CHECKSUM_MD5;
|
||||||
|
|
||||||
pkg = apk_db_get_pkg(db, &csum);
|
pkg = apk_db_get_pkg(db, &csum);
|
||||||
if (pkg != NULL)
|
if (pkg != NULL && pkg->ipkg != NULL)
|
||||||
apk_pkg_add_script(pkg, is, hdr.type, hdr.size);
|
apk_ipkg_add_script(pkg->ipkg, is, hdr.type, hdr.size);
|
||||||
else
|
else
|
||||||
apk_istream_skip(is, hdr.size);
|
apk_istream_skip(is, hdr.size);
|
||||||
}
|
}
|
||||||
|
@ -711,8 +726,8 @@ static int apk_read_script_archive_entry(void *ctx,
|
||||||
|
|
||||||
/* Attach script */
|
/* Attach script */
|
||||||
pkg = apk_db_get_pkg(db, &csum);
|
pkg = apk_db_get_pkg(db, &csum);
|
||||||
if (pkg != NULL)
|
if (pkg != NULL && pkg->ipkg != NULL)
|
||||||
apk_pkg_add_script(pkg, is, type, ae->size);
|
apk_ipkg_add_script(pkg->ipkg, is, type, ae->size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -805,7 +820,7 @@ static int write_index_entry(apk_hash_item item, void *ctx)
|
||||||
static int apk_db_index_write_nr_cache(struct apk_database *db)
|
static int apk_db_index_write_nr_cache(struct apk_database *db)
|
||||||
{
|
{
|
||||||
struct index_write_ctx ctx = { NULL, 0, TRUE };
|
struct index_write_ctx ctx = { NULL, 0, TRUE };
|
||||||
struct apk_package *pkg;
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_ostream *os;
|
struct apk_ostream *os;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -822,10 +837,10 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ctx.os = os;
|
ctx.os = os;
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
if (pkg->repos != 0)
|
if (ipkg->pkg->repos != 0)
|
||||||
continue;
|
continue;
|
||||||
r = write_index_entry(pkg, &ctx);
|
r = write_index_entry(ipkg->pkg, &ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1074,13 +1089,13 @@ int apk_db_write_config(struct apk_database *db)
|
||||||
|
|
||||||
void apk_db_close(struct apk_database *db)
|
void apk_db_close(struct apk_database *db)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg;
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct hlist_node *dc, *dn;
|
struct hlist_node *dc, *dn;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
hlist_for_each_entry_safe(diri, dc, dn, &pkg->owned_dirs, pkg_dirs_list) {
|
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||||
apk_db_diri_free(db, diri);
|
apk_db_diri_free(db, diri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1384,7 +1399,8 @@ static int apk_db_run_pending_script(struct install_ctx *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ctx->script_pending = FALSE;
|
ctx->script_pending = FALSE;
|
||||||
r = apk_pkg_run_script(ctx->pkg, ctx->db->root_fd, ctx->script);
|
r = apk_ipkg_run_script(ctx->ipkg, ctx->db->root_fd, ctx->script,
|
||||||
|
ctx->script_args);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
apk_error("%s-%s: Failed to execute "
|
apk_error("%s-%s: Failed to execute "
|
||||||
"pre-install/upgrade script",
|
"pre-install/upgrade script",
|
||||||
|
@ -1392,7 +1408,7 @@ static int apk_db_run_pending_script(struct install_ctx *ctx)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct apk_db_dir_instance *find_diri(struct apk_package *pkg,
|
static struct apk_db_dir_instance *find_diri(struct apk_installed_package *ipkg,
|
||||||
apk_blob_t dirname,
|
apk_blob_t dirname,
|
||||||
struct apk_db_dir_instance *curdiri,
|
struct apk_db_dir_instance *curdiri,
|
||||||
struct hlist_node ***tail)
|
struct hlist_node ***tail)
|
||||||
|
@ -1406,7 +1422,7 @@ static struct apk_db_dir_instance *find_diri(struct apk_package *pkg,
|
||||||
dirname) == 0)
|
dirname) == 0)
|
||||||
return curdiri;
|
return curdiri;
|
||||||
|
|
||||||
hlist_for_each_entry(diri, n, &pkg->owned_dirs, pkg_dirs_list) {
|
hlist_for_each_entry(diri, n, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||||
if (apk_blob_compare(APK_BLOB_PTR_LEN(diri->dir->name,
|
if (apk_blob_compare(APK_BLOB_PTR_LEN(diri->dir->name,
|
||||||
diri->dir->namelen), dirname) == 0) {
|
diri->dir->namelen), dirname) == 0) {
|
||||||
if (tail != NULL)
|
if (tail != NULL)
|
||||||
|
@ -1428,9 +1444,23 @@ static int parse_replaces(void *_ctx, apk_blob_t blob)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_triggers(void *_ctx, apk_blob_t blob)
|
||||||
|
{
|
||||||
|
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
||||||
|
struct apk_installed_package *ipkg = ctx->ipkg;
|
||||||
|
|
||||||
|
if (blob.len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*apk_string_array_add(&ipkg->triggers) = apk_blob_cstr(blob);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_info_line(void *_ctx, apk_blob_t line)
|
static int read_info_line(void *_ctx, apk_blob_t line)
|
||||||
{
|
{
|
||||||
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
||||||
|
struct apk_installed_package *ipkg = ctx->ipkg;
|
||||||
|
struct apk_database *db = ctx->db;
|
||||||
apk_blob_t l, r;
|
apk_blob_t l, r;
|
||||||
|
|
||||||
if (line.ptr == NULL || line.len < 1 || line.ptr[0] == '#')
|
if (line.ptr == NULL || line.len < 1 || line.ptr[0] == '#')
|
||||||
|
@ -1441,10 +1471,18 @@ static int read_info_line(void *_ctx, apk_blob_t line)
|
||||||
|
|
||||||
if (apk_blob_compare(APK_BLOB_STR("replaces"), l) == 0) {
|
if (apk_blob_compare(APK_BLOB_STR("replaces"), l) == 0) {
|
||||||
apk_blob_for_each_segment(r, " ", parse_replaces, ctx);
|
apk_blob_for_each_segment(r, " ", parse_replaces, ctx);
|
||||||
return 0;
|
} else if (apk_blob_compare(APK_BLOB_STR("triggers"), l) == 0) {
|
||||||
|
if (ipkg->triggers) {
|
||||||
|
free(ipkg->triggers);
|
||||||
|
ipkg->triggers = NULL;
|
||||||
|
}
|
||||||
|
if (!list_hashed(&ipkg->trigger_pkgs_list))
|
||||||
|
list_add(&ipkg->trigger_pkgs_list,
|
||||||
|
&db->installed.triggers);
|
||||||
|
apk_blob_for_each_segment(r, " ", parse_triggers, ctx);
|
||||||
|
} else {
|
||||||
|
apk_sign_ctx_parse_pkginfo_line(&ctx->sctx, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
apk_sign_ctx_parse_pkginfo_line(&ctx->sctx, line);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1455,6 +1493,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
||||||
struct apk_database *db = ctx->db;
|
struct apk_database *db = ctx->db;
|
||||||
struct apk_package *pkg = ctx->pkg, *opkg;
|
struct apk_package *pkg = ctx->pkg, *opkg;
|
||||||
|
struct apk_installed_package *ipkg = pkg->ipkg;
|
||||||
apk_blob_t name = APK_BLOB_STR(ae->name), bdir, bfile;
|
apk_blob_t name = APK_BLOB_STR(ae->name), bdir, bfile;
|
||||||
struct apk_db_dir_instance *diri = ctx->diri;
|
struct apk_db_dir_instance *diri = ctx->diri;
|
||||||
struct apk_db_file *file;
|
struct apk_db_file *file;
|
||||||
|
@ -1493,7 +1532,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
|
|
||||||
/* Handle script */
|
/* Handle script */
|
||||||
if (type != APK_SCRIPT_INVALID) {
|
if (type != APK_SCRIPT_INVALID) {
|
||||||
apk_pkg_add_script(pkg, is, type, ae->size);
|
apk_ipkg_add_script(ipkg, is, type, ae->size);
|
||||||
if (type == ctx->script)
|
if (type == ctx->script)
|
||||||
ctx->script_pending = TRUE;
|
ctx->script_pending = TRUE;
|
||||||
return apk_db_run_pending_script(ctx);
|
return apk_db_run_pending_script(ctx);
|
||||||
|
@ -1520,7 +1559,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Make sure the file is part of the cached directory tree */
|
/* Make sure the file is part of the cached directory tree */
|
||||||
diri = find_diri(pkg, bdir, diri, &ctx->file_diri_node);
|
diri = find_diri(ipkg, bdir, diri, &ctx->file_diri_node);
|
||||||
if (diri == NULL) {
|
if (diri == NULL) {
|
||||||
apk_error("%s: File '%*s' entry without directory entry.\n",
|
apk_error("%s: File '%*s' entry without directory entry.\n",
|
||||||
pkg->name->name, name.len, name.ptr);
|
pkg->name->name, name.len, name.ptr);
|
||||||
|
@ -1579,7 +1618,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
'/', &bdir, &bfile))
|
'/', &bdir, &bfile))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ldiri = find_diri(pkg, bdir, diri, NULL);
|
ldiri = find_diri(ipkg, bdir, diri, NULL);
|
||||||
if (ldiri == NULL)
|
if (ldiri == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1604,7 +1643,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
name.len--;
|
name.len--;
|
||||||
|
|
||||||
if (ctx->diri_node == NULL)
|
if (ctx->diri_node == NULL)
|
||||||
ctx->diri_node = hlist_tail_ptr(&pkg->owned_dirs);
|
ctx->diri_node = hlist_tail_ptr(&ipkg->owned_dirs);
|
||||||
ctx->diri = diri = apk_db_diri_new(db, pkg, name,
|
ctx->diri = diri = apk_db_diri_new(db, pkg, name,
|
||||||
&ctx->diri_node);
|
&ctx->diri_node);
|
||||||
ctx->file_diri_node = hlist_tail_ptr(&diri->owned_files);
|
ctx->file_diri_node = hlist_tail_ptr(&diri->owned_files);
|
||||||
|
@ -1617,7 +1656,8 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apk_db_purge_pkg(struct apk_database *db, struct apk_package *pkg,
|
static void apk_db_purge_pkg(struct apk_database *db,
|
||||||
|
struct apk_installed_package *ipkg,
|
||||||
const char *exten)
|
const char *exten)
|
||||||
{
|
{
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
|
@ -1628,7 +1668,10 @@ static void apk_db_purge_pkg(struct apk_database *db, struct apk_package *pkg,
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
char name[1024];
|
char name[1024];
|
||||||
|
|
||||||
hlist_for_each_entry_safe(diri, dc, dn, &pkg->owned_dirs, pkg_dirs_list) {
|
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||||
|
if (exten == NULL)
|
||||||
|
diri->dir->flags |= APK_DBDIRF_MODIFIED;
|
||||||
|
|
||||||
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
|
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
|
||||||
snprintf(name, sizeof(name), "%s/%s%s",
|
snprintf(name, sizeof(name), "%s/%s%s",
|
||||||
diri->dir->name, file->name, exten ?: "");
|
diri->dir->name, file->name, exten ?: "");
|
||||||
|
@ -1653,15 +1696,14 @@ static void apk_db_purge_pkg(struct apk_database *db, struct apk_package *pkg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apk_db_diri_rmdir(db, diri);
|
apk_db_diri_rmdir(db, diri);
|
||||||
__hlist_del(dc, &pkg->owned_dirs.first);
|
__hlist_del(dc, &ipkg->owned_dirs.first);
|
||||||
apk_db_diri_free(db, diri);
|
apk_db_diri_free(db, diri);
|
||||||
}
|
}
|
||||||
apk_pkg_set_state(db, pkg, APK_PKG_NOT_INSTALLED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void apk_db_migrate_files(struct apk_database *db,
|
static void apk_db_migrate_files(struct apk_database *db,
|
||||||
struct apk_package *pkg)
|
struct apk_installed_package *ipkg)
|
||||||
{
|
{
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct apk_db_dir *dir;
|
struct apk_db_dir *dir;
|
||||||
|
@ -1673,8 +1715,9 @@ static void apk_db_migrate_files(struct apk_database *db,
|
||||||
char name[PATH_MAX], tmpname[PATH_MAX];
|
char name[PATH_MAX], tmpname[PATH_MAX];
|
||||||
int cstype, r;
|
int cstype, r;
|
||||||
|
|
||||||
hlist_for_each_entry_safe(diri, dc, dn, &pkg->owned_dirs, pkg_dirs_list) {
|
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||||
dir = diri->dir;
|
dir = diri->dir;
|
||||||
|
dir->flags |= APK_DBDIRF_MODIFIED;
|
||||||
|
|
||||||
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
|
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
|
||||||
snprintf(name, sizeof(name), "%s/%s",
|
snprintf(name, sizeof(name), "%s/%s",
|
||||||
|
@ -1741,45 +1784,47 @@ static void apk_db_migrate_files(struct apk_database *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apk_db_unpack_pkg(struct apk_database *db,
|
static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
struct apk_package *newpkg,
|
struct apk_installed_package *ipkg,
|
||||||
int upgrade, int reinstall,
|
int upgrade, int reinstall,
|
||||||
apk_progress_cb cb, void *cb_ctx)
|
apk_progress_cb cb, void *cb_ctx,
|
||||||
|
char **script_args)
|
||||||
{
|
{
|
||||||
struct install_ctx ctx;
|
struct install_ctx ctx;
|
||||||
struct apk_bstream *bs = NULL;
|
struct apk_bstream *bs = NULL;
|
||||||
struct apk_istream *tar;
|
struct apk_istream *tar;
|
||||||
|
struct apk_package *pkg = ipkg->pkg;
|
||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
int r, need_copy = FALSE;
|
int r, need_copy = FALSE;
|
||||||
|
|
||||||
if (newpkg->filename == NULL) {
|
if (pkg->filename == NULL) {
|
||||||
struct apk_repository *repo;
|
struct apk_repository *repo;
|
||||||
|
|
||||||
repo = apk_db_select_repo(db, newpkg);
|
repo = apk_db_select_repo(db, pkg);
|
||||||
if (repo == NULL) {
|
if (repo == NULL) {
|
||||||
apk_error("%s-%s: package is not currently available",
|
apk_error("%s-%s: package is not currently available",
|
||||||
newpkg->name->name, newpkg->version);
|
pkg->name->name, pkg->version);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apk_db_cache_active(db) && apk_repo_is_remote(repo)) {
|
if (apk_db_cache_active(db) && apk_repo_is_remote(repo)) {
|
||||||
apk_pkg_format_cache(newpkg, APK_BLOB_BUF(file));
|
apk_pkg_format_cache(pkg, APK_BLOB_BUF(file));
|
||||||
bs = apk_bstream_from_file(db->cache_fd, file);
|
bs = apk_bstream_from_file(db->cache_fd, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
apk_pkg_format_plain(newpkg, APK_BLOB_BUF(file));
|
apk_pkg_format_plain(pkg, APK_BLOB_BUF(file));
|
||||||
bs = apk_repo_file_open(repo, file);
|
bs = apk_repo_file_open(repo, file);
|
||||||
if (apk_repo_is_remote(repo))
|
if (apk_repo_is_remote(repo))
|
||||||
need_copy = TRUE;
|
need_copy = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bs = apk_bstream_from_file(AT_FDCWD, newpkg->filename);
|
bs = apk_bstream_from_file(AT_FDCWD, pkg->filename);
|
||||||
need_copy = TRUE;
|
need_copy = TRUE;
|
||||||
}
|
}
|
||||||
if (!apk_db_cache_active(db))
|
if (!apk_db_cache_active(db))
|
||||||
need_copy = FALSE;
|
need_copy = FALSE;
|
||||||
if (need_copy) {
|
if (need_copy) {
|
||||||
apk_pkg_format_cache(newpkg, APK_BLOB_BUF(file));
|
apk_pkg_format_cache(pkg, APK_BLOB_BUF(file));
|
||||||
bs = apk_bstream_tee(bs, db->cachetmp_fd, file);
|
bs = apk_bstream_tee(bs, db->cachetmp_fd, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1790,13 +1835,15 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
|
|
||||||
ctx = (struct install_ctx) {
|
ctx = (struct install_ctx) {
|
||||||
.db = db,
|
.db = db,
|
||||||
.pkg = newpkg,
|
.pkg = pkg,
|
||||||
|
.ipkg = ipkg,
|
||||||
.script = upgrade ?
|
.script = upgrade ?
|
||||||
APK_SCRIPT_PRE_UPGRADE : APK_SCRIPT_PRE_INSTALL,
|
APK_SCRIPT_PRE_UPGRADE : APK_SCRIPT_PRE_INSTALL,
|
||||||
|
.script_args = script_args,
|
||||||
.cb = cb,
|
.cb = cb,
|
||||||
.cb_ctx = cb_ctx,
|
.cb_ctx = cb_ctx,
|
||||||
};
|
};
|
||||||
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &newpkg->csum, db->keys_fd);
|
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);
|
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);
|
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE);
|
||||||
apk_sign_ctx_free(&ctx.sctx);
|
apk_sign_ctx_free(&ctx.sctx);
|
||||||
|
@ -1813,7 +1860,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
apk_error("%s-%s: %s",
|
apk_error("%s-%s: %s",
|
||||||
newpkg->name->name, newpkg->version,
|
pkg->name->name, pkg->version,
|
||||||
apk_error_str(r));
|
apk_error_str(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -1821,12 +1868,12 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
apk_db_migrate_files(db, newpkg);
|
apk_db_migrate_files(db, ipkg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
if (!reinstall)
|
if (!reinstall)
|
||||||
apk_db_purge_pkg(db, newpkg, ".apk-new");
|
apk_db_purge_pkg(db, ipkg, ".apk-new");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1835,37 +1882,59 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
struct apk_package *newpkg,
|
struct apk_package *newpkg,
|
||||||
apk_progress_cb cb, void *cb_ctx)
|
apk_progress_cb cb, void *cb_ctx)
|
||||||
{
|
{
|
||||||
|
char *script_args[] = { NULL, NULL, NULL };
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
/* Upgrade script gets two args: <new-pkg> <old-pkg> */
|
||||||
|
if (oldpkg != NULL && newpkg != NULL) {
|
||||||
|
script_args[0] = newpkg->version;
|
||||||
|
script_args[1] = oldpkg->version;
|
||||||
|
} else {
|
||||||
|
script_args[0] = oldpkg ? oldpkg->version : newpkg->version;
|
||||||
|
}
|
||||||
|
|
||||||
/* Just purging? */
|
/* Just purging? */
|
||||||
if (oldpkg != NULL && newpkg == NULL) {
|
if (oldpkg != NULL && newpkg == NULL) {
|
||||||
r = apk_pkg_run_script(oldpkg, db->root_fd,
|
ipkg = oldpkg->ipkg;
|
||||||
APK_SCRIPT_PRE_DEINSTALL);
|
|
||||||
|
if (ipkg == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = apk_ipkg_run_script(ipkg, db->root_fd,
|
||||||
|
APK_SCRIPT_PRE_DEINSTALL, script_args);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
apk_db_purge_pkg(db, oldpkg, NULL);
|
apk_db_purge_pkg(db, ipkg, NULL);
|
||||||
|
r = apk_ipkg_run_script(ipkg, db->root_fd,
|
||||||
|
APK_SCRIPT_POST_DEINSTALL, script_args);
|
||||||
|
apk_pkg_uninstall(db, oldpkg);
|
||||||
|
|
||||||
r = apk_pkg_run_script(oldpkg, db->root_fd,
|
|
||||||
APK_SCRIPT_POST_DEINSTALL);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install the new stuff */
|
/* Install the new stuff */
|
||||||
|
ipkg = apk_pkg_install(db, newpkg);
|
||||||
if (newpkg->installed_size != 0) {
|
if (newpkg->installed_size != 0) {
|
||||||
r = apk_db_unpack_pkg(db, newpkg, (oldpkg != NULL),
|
r = apk_db_unpack_pkg(db, ipkg, (oldpkg != NULL),
|
||||||
(oldpkg == newpkg), cb, cb_ctx);
|
(oldpkg == newpkg), cb, cb_ctx,
|
||||||
if (r != 0)
|
script_args);
|
||||||
|
if (r != 0) {
|
||||||
|
apk_pkg_uninstall(db, newpkg);
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apk_pkg_set_state(db, newpkg, APK_PKG_INSTALLED);
|
if (oldpkg != NULL && oldpkg != newpkg && oldpkg->ipkg != NULL) {
|
||||||
if (oldpkg != NULL && oldpkg != newpkg)
|
apk_db_purge_pkg(db, oldpkg->ipkg, NULL);
|
||||||
apk_db_purge_pkg(db, oldpkg, NULL);
|
apk_pkg_uninstall(db, oldpkg);
|
||||||
|
}
|
||||||
|
|
||||||
r = apk_pkg_run_script(newpkg, db->root_fd,
|
r = apk_ipkg_run_script(ipkg, db->root_fd,
|
||||||
(oldpkg == NULL) ?
|
(oldpkg == NULL) ?
|
||||||
APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE);
|
APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE,
|
||||||
|
script_args);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
apk_error("%s-%s: Failed to execute post-install/upgrade script",
|
apk_error("%s-%s: Failed to execute post-install/upgrade script",
|
||||||
newpkg->name->name, newpkg->version);
|
newpkg->name->name, newpkg->version);
|
||||||
|
|
|
@ -53,7 +53,7 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
for (j = 0; j < name->pkgs->num; j++) {
|
for (j = 0; j < name->pkgs->num; j++) {
|
||||||
if (apk_pkg_get_state(name->pkgs->item[j]) == APK_PKG_INSTALLED)
|
if (name->pkgs->item[j]->ipkg != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j >= name->pkgs->num) {
|
if (j >= name->pkgs->num) {
|
||||||
|
|
19
src/info.c
19
src/info.c
|
@ -73,10 +73,10 @@ static void verbose_print_pkg(struct apk_package *pkg, int minimal_verbosity)
|
||||||
static int info_list(struct info_ctx *ctx, struct apk_database *db,
|
static int info_list(struct info_ctx *ctx, struct apk_database *db,
|
||||||
int argc, char **argv)
|
int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg;
|
struct apk_installed_package *ipkg;
|
||||||
|
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list)
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list)
|
||||||
verbose_print_pkg(pkg, 1);
|
verbose_print_pkg(ipkg->pkg, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db,
|
||||||
|
|
||||||
for (j = 0; j < name->pkgs->num; j++) {
|
for (j = 0; j < name->pkgs->num; j++) {
|
||||||
pkg = name->pkgs->item[j];
|
pkg = name->pkgs->item[j];
|
||||||
if (apk_pkg_get_state(pkg) == APK_PKG_INSTALLED)
|
if (pkg->ipkg != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j >= name->pkgs->num)
|
if (j >= name->pkgs->num)
|
||||||
|
@ -178,7 +178,7 @@ static int info_package(struct info_ctx *ctx, struct apk_database *db,
|
||||||
}
|
}
|
||||||
for (j = 0; j < name->pkgs->num; j++) {
|
for (j = 0; j < name->pkgs->num; j++) {
|
||||||
struct apk_package *pkg = name->pkgs->item[j];
|
struct apk_package *pkg = name->pkgs->item[j];
|
||||||
if (apk_pkg_get_state(pkg) == APK_PKG_INSTALLED)
|
if (pkg->ipkg != NULL)
|
||||||
info_subaction(ctx, pkg);
|
info_subaction(ctx, pkg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,14 +187,18 @@ static int info_package(struct info_ctx *ctx, struct apk_database *db,
|
||||||
|
|
||||||
static void info_print_contents(struct apk_package *pkg)
|
static void info_print_contents(struct apk_package *pkg)
|
||||||
{
|
{
|
||||||
|
struct apk_installed_package *ipkg = pkg->ipkg;
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct apk_db_file *file;
|
struct apk_db_file *file;
|
||||||
struct hlist_node *dc, *dn, *fc, *fn;
|
struct hlist_node *dc, *dn, *fc, *fn;
|
||||||
|
|
||||||
|
if (ipkg == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (apk_verbosity == 1)
|
if (apk_verbosity == 1)
|
||||||
printf("%s-%s contains:\n", pkg->name->name, pkg->version);
|
printf("%s-%s contains:\n", pkg->name->name, pkg->version);
|
||||||
|
|
||||||
hlist_for_each_entry_safe(diri, dc, dn, &pkg->owned_dirs,
|
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs,
|
||||||
pkg_dirs_list) {
|
pkg_dirs_list) {
|
||||||
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files,
|
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files,
|
||||||
diri_files_list) {
|
diri_files_list) {
|
||||||
|
@ -241,8 +245,7 @@ static void info_print_required_by(struct apk_package *pkg)
|
||||||
for (j = 0; j < name0->pkgs->num; j++) {
|
for (j = 0; j < name0->pkgs->num; j++) {
|
||||||
struct apk_package *pkg0 = name0->pkgs->item[j];
|
struct apk_package *pkg0 = name0->pkgs->item[j];
|
||||||
|
|
||||||
if (apk_pkg_get_state(pkg0) != APK_PKG_INSTALLED ||
|
if (pkg0->ipkg == NULL || pkg0->depends == NULL)
|
||||||
pkg0->depends == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
for (k = 0; k < pkg0->depends->num; k++) {
|
for (k = 0; k < pkg0->depends->num; k++) {
|
||||||
if (pkg0->depends->item[k].name != pkg->name)
|
if (pkg0->depends->item[k].name != pkg->name)
|
||||||
|
|
199
src/package.c
199
src/package.c
|
@ -53,13 +53,52 @@ void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to)
|
||||||
|
|
||||||
struct apk_package *apk_pkg_new(void)
|
struct apk_package *apk_pkg_new(void)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg;
|
return calloc(1, sizeof(struct apk_package));
|
||||||
|
}
|
||||||
|
|
||||||
pkg = calloc(1, sizeof(struct apk_package));
|
struct apk_installed_package *apk_pkg_install(struct apk_database *db,
|
||||||
if (pkg != NULL)
|
struct apk_package *pkg)
|
||||||
list_init(&pkg->installed_pkgs_list);
|
{
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
|
|
||||||
return pkg;
|
if (pkg->ipkg != NULL)
|
||||||
|
return pkg->ipkg;
|
||||||
|
|
||||||
|
pkg->ipkg = ipkg = calloc(1, sizeof(struct apk_installed_package));
|
||||||
|
ipkg->pkg = pkg;
|
||||||
|
list_init(&ipkg->installed_pkgs_list);
|
||||||
|
|
||||||
|
db->installed.stats.packages++;
|
||||||
|
list_add_tail(&ipkg->installed_pkgs_list, &db->installed.packages);
|
||||||
|
|
||||||
|
return ipkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg)
|
||||||
|
{
|
||||||
|
struct apk_installed_package *ipkg = pkg->ipkg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ipkg == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (db != NULL)
|
||||||
|
db->installed.stats.packages--;
|
||||||
|
|
||||||
|
list_del(&ipkg->installed_pkgs_list);
|
||||||
|
|
||||||
|
if (ipkg->triggers) {
|
||||||
|
list_del(&ipkg->trigger_pkgs_list);
|
||||||
|
for (i = 0; i < ipkg->triggers->num; i++)
|
||||||
|
free(ipkg->triggers->item[i]);
|
||||||
|
free(ipkg->triggers);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < APK_SCRIPT_MAX; i++)
|
||||||
|
if (ipkg->script[i].ptr != NULL)
|
||||||
|
free(ipkg->script[i].ptr);
|
||||||
|
free(ipkg);
|
||||||
|
pkg->ipkg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_pkg_parse_name(apk_blob_t apkname,
|
int apk_pkg_parse_name(apk_blob_t apkname,
|
||||||
|
@ -293,6 +332,7 @@ const char *apk_script_types[] = {
|
||||||
[APK_SCRIPT_POST_DEINSTALL] = "post-deinstall",
|
[APK_SCRIPT_POST_DEINSTALL] = "post-deinstall",
|
||||||
[APK_SCRIPT_PRE_UPGRADE] = "pre-upgrade",
|
[APK_SCRIPT_PRE_UPGRADE] = "pre-upgrade",
|
||||||
[APK_SCRIPT_POST_UPGRADE] = "post-upgrade",
|
[APK_SCRIPT_POST_UPGRADE] = "post-upgrade",
|
||||||
|
[APK_SCRIPT_TRIGGER] = "trigger",
|
||||||
};
|
};
|
||||||
|
|
||||||
int apk_script_type(const char *name)
|
int apk_script_type(const char *name)
|
||||||
|
@ -763,15 +803,10 @@ err:
|
||||||
|
|
||||||
void apk_pkg_free(struct apk_package *pkg)
|
void apk_pkg_free(struct apk_package *pkg)
|
||||||
{
|
{
|
||||||
struct apk_script *script;
|
|
||||||
struct hlist_node *c, *n;
|
|
||||||
|
|
||||||
if (pkg == NULL)
|
if (pkg == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hlist_for_each_entry_safe(script, c, n, &pkg->scripts, script_list)
|
apk_pkg_uninstall(NULL, pkg);
|
||||||
free(script);
|
|
||||||
|
|
||||||
if (pkg->depends)
|
if (pkg->depends)
|
||||||
free(pkg->depends);
|
free(pkg->depends);
|
||||||
if (pkg->version)
|
if (pkg->version)
|
||||||
|
@ -785,106 +820,84 @@ void apk_pkg_free(struct apk_package *pkg)
|
||||||
free(pkg);
|
free(pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_pkg_get_state(struct apk_package *pkg)
|
int apk_ipkg_add_script(struct apk_installed_package *ipkg,
|
||||||
|
struct apk_istream *is,
|
||||||
|
unsigned int type, unsigned int size)
|
||||||
{
|
{
|
||||||
if (list_hashed(&pkg->installed_pkgs_list))
|
void *ptr;
|
||||||
return APK_PKG_INSTALLED;
|
|
||||||
return APK_PKG_NOT_INSTALLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void apk_pkg_set_state(struct apk_database *db, struct apk_package *pkg, int state)
|
|
||||||
{
|
|
||||||
switch (state) {
|
|
||||||
case APK_PKG_INSTALLED:
|
|
||||||
if (!list_hashed(&pkg->installed_pkgs_list)) {
|
|
||||||
db->installed.stats.packages++;
|
|
||||||
list_add_tail(&pkg->installed_pkgs_list,
|
|
||||||
&db->installed.packages);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case APK_PKG_NOT_INSTALLED:
|
|
||||||
if (list_hashed(&pkg->installed_pkgs_list)) {
|
|
||||||
db->installed.stats.packages--;
|
|
||||||
list_del(&pkg->installed_pkgs_list);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int apk_pkg_add_script(struct apk_package *pkg, struct apk_istream *is,
|
|
||||||
unsigned int type, unsigned int size)
|
|
||||||
{
|
|
||||||
struct apk_script *script;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
script = malloc(sizeof(struct apk_script) + size);
|
if (type >= APK_SCRIPT_MAX)
|
||||||
script->type = type;
|
return -1;
|
||||||
script->size = size;
|
|
||||||
r = is->read(is, script->script, size);
|
ptr = malloc(size);
|
||||||
|
r = is->read(is, ptr, size);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
free(script);
|
free(ptr);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlist_add_head(&script->script_list, &pkg->scripts);
|
if (ipkg->script[type].ptr)
|
||||||
return r;
|
free(ipkg->script[type].ptr);
|
||||||
|
ipkg->script[type].ptr = ptr;
|
||||||
|
ipkg->script[type].len = size;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd,
|
||||||
unsigned int type)
|
unsigned int type, char **argv)
|
||||||
{
|
{
|
||||||
static const char * const environment[] = {
|
static char * const environment[] = {
|
||||||
"PATH=/usr/sbin:/usr/bin:/sbin:/bin",
|
"PATH=/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
struct apk_script *script;
|
struct apk_package *pkg = ipkg->pkg;
|
||||||
struct hlist_node *c;
|
char fn[PATH_MAX];
|
||||||
int fd, status;
|
int fd, status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char fn[PATH_MAX];
|
|
||||||
|
|
||||||
hlist_for_each_entry(script, c, &pkg->scripts, script_list) {
|
if (type >= APK_SCRIPT_MAX)
|
||||||
if (script->type != type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Avoid /tmp as it can be mounted noexec */
|
|
||||||
snprintf(fn, sizeof(fn), "var/cache/misc/%s-%s.%s",
|
|
||||||
pkg->name->name, pkg->version,
|
|
||||||
apk_script_types[type]);
|
|
||||||
|
|
||||||
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755);
|
|
||||||
if (fd < 0) {
|
|
||||||
mkdirat(root_fd, "var/cache/misc", 0755);
|
|
||||||
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755);
|
|
||||||
if (fd < 0)
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
write(fd, script->script, script->size);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
apk_message("Executing %s", &fn[15]);
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid == -1)
|
|
||||||
return -1;
|
|
||||||
if (pid == 0) {
|
|
||||||
fchdir(root_fd);
|
|
||||||
if (chroot(".") < 0) {
|
|
||||||
apk_error("chroot: %s", strerror(errno));
|
|
||||||
} else {
|
|
||||||
execle(fn, apk_script_types[type],
|
|
||||||
pkg->version, "", NULL, environment);
|
|
||||||
}
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
waitpid(pid, &status, 0);
|
|
||||||
unlinkat(root_fd, fn, 0);
|
|
||||||
if (WIFEXITED(status))
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
if (ipkg->script[type].ptr == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
argv[0] = (char *) apk_script_types[type];
|
||||||
|
|
||||||
|
/* Avoid /tmp as it can be mounted noexec */
|
||||||
|
snprintf(fn, sizeof(fn), "var/cache/misc/%s-%s.%s",
|
||||||
|
pkg->name->name, pkg->version,
|
||||||
|
apk_script_types[type]);
|
||||||
|
|
||||||
|
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755);
|
||||||
|
if (fd < 0) {
|
||||||
|
mkdirat(root_fd, "var/cache/misc", 0755);
|
||||||
|
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
write(fd, ipkg->script[type].ptr, ipkg->script[type].len);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
apk_message("Executing %s", &fn[15]);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1)
|
||||||
|
return -1;
|
||||||
|
if (pid == 0) {
|
||||||
|
fchdir(root_fd);
|
||||||
|
if (chroot(".") < 0) {
|
||||||
|
apk_error("chroot: %s", strerror(errno));
|
||||||
|
} else {
|
||||||
|
execve(fn, argv, environment);
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
unlinkat(root_fd, fn, 0);
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_index_line(void *ctx, apk_blob_t line)
|
static int parse_index_line(void *ctx, apk_blob_t line)
|
||||||
|
|
10
src/state.c
10
src/state.c
|
@ -296,7 +296,7 @@ int apk_state_lock_dependency(struct apk_state *state,
|
||||||
for (i = 0; i < c->num; i++) {
|
for (i = 0; i < c->num; i++) {
|
||||||
struct apk_package *pkg = c->pkgs[i];
|
struct apk_package *pkg = c->pkgs[i];
|
||||||
|
|
||||||
if (apk_pkg_get_state(c->pkgs[i]) == APK_PKG_INSTALLED)
|
if (c->pkgs[i]->ipkg != NULL)
|
||||||
installed = pkg;
|
installed = pkg;
|
||||||
else if (pkg->filename == NULL &&
|
else if (pkg->filename == NULL &&
|
||||||
apk_db_select_repo(state->db, pkg) == NULL)
|
apk_db_select_repo(state->db, pkg) == NULL)
|
||||||
|
@ -422,8 +422,7 @@ static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
ns_to_choices(state->name[name0->id]);
|
ns_to_choices(state->name[name0->id]);
|
||||||
|
|
||||||
for (j = 0; j < ns->num; j++) {
|
for (j = 0; j < ns->num; j++) {
|
||||||
if (apk_pkg_get_state(ns->pkgs[j])
|
if (ns->pkgs[j]->ipkg == NULL)
|
||||||
!= APK_PKG_INSTALLED)
|
|
||||||
continue;
|
continue;
|
||||||
r = call_if_dependency_broke(state,
|
r = call_if_dependency_broke(state,
|
||||||
ns->pkgs[j],
|
ns->pkgs[j],
|
||||||
|
@ -436,7 +435,7 @@ static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
for (j = 0; j < name0->pkgs->num; j++) {
|
for (j = 0; j < name0->pkgs->num; j++) {
|
||||||
pkg0 = name0->pkgs->item[j];
|
pkg0 = name0->pkgs->item[j];
|
||||||
|
|
||||||
if (apk_pkg_get_state(pkg0) != APK_PKG_INSTALLED)
|
if (pkg0->ipkg == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = call_if_dependency_broke(state,
|
r = call_if_dependency_broke(state,
|
||||||
|
@ -487,8 +486,7 @@ int apk_state_lock_name(struct apk_state *state,
|
||||||
struct apk_package *pkg = name->pkgs->item[i];
|
struct apk_package *pkg = name->pkgs->item[i];
|
||||||
|
|
||||||
if (name->pkgs->item[i]->name == name &&
|
if (name->pkgs->item[i]->name == name &&
|
||||||
apk_pkg_get_state(name->pkgs->item[i])
|
name->pkgs->item[i]->ipkg != NULL)
|
||||||
== APK_PKG_INSTALLED)
|
|
||||||
oldpkg = pkg;
|
oldpkg = pkg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ static void ver_print_package_status(struct apk_package *pkg, const char *limit)
|
||||||
static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct ver_ctx *ictx = (struct ver_ctx *) ctx;
|
struct ver_ctx *ictx = (struct ver_ctx *) ctx;
|
||||||
struct apk_package *pkg;
|
struct apk_installed_package *ipkg;
|
||||||
struct apk_name *name;
|
struct apk_name *name;
|
||||||
int i, j, ret = 0;
|
int i, j, ret = 0;
|
||||||
|
|
||||||
|
@ -105,9 +105,9 @@ static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
printf("%-42sAvailable:\n", "Installed:");
|
printf("%-42sAvailable:\n", "Installed:");
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
list_for_each_entry(pkg, &db->installed.packages,
|
list_for_each_entry(ipkg, &db->installed.packages,
|
||||||
installed_pkgs_list) {
|
installed_pkgs_list) {
|
||||||
ver_print_package_status(pkg, ictx->limchars);
|
ver_print_package_status(ipkg->pkg, ictx->limchars);
|
||||||
}
|
}
|
||||||
goto ver_exit;
|
goto ver_exit;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
}
|
}
|
||||||
for (j = 0; j < name->pkgs->num; j++) {
|
for (j = 0; j < name->pkgs->num; j++) {
|
||||||
struct apk_package *pkg = name->pkgs->item[j];
|
struct apk_package *pkg = name->pkgs->item[j];
|
||||||
if (apk_pkg_get_state(pkg) == APK_PKG_INSTALLED)
|
if (pkg->ipkg != NULL)
|
||||||
ver_print_package_status(pkg, ictx->limchars);
|
ver_print_package_status(pkg, ictx->limchars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue