Commit 36b5cee9 authored by Timo Teräs's avatar Timo Teräs

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.
parent dee6ffa4
...@@ -38,6 +38,7 @@ struct apk_db_file { ...@@ -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 { ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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;
......
This diff is collapsed.
...@@ -53,7 +53,7 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) ...@@ -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) {
......
...@@ -73,10 +73,10 @@ static void verbose_print_pkg(struct apk_package *pkg, int minimal_verbosity) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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)
......
...@@ -53,13 +53,52 @@ void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to) ...@@ -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;
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--;
return pkg; 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[] = { ...@@ -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: ...@@ -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) ...@@ -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,
if (list_hashed(&pkg->installed_pkgs_list)) unsigned int type, unsigned int size)
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; void *ptr;
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) return -1;
continue;
/* Avoid /tmp as it can be mounted noexec */ if (ipkg->script[type].ptr == NULL)
snprintf(fn, sizeof(fn), "var/cache/misc/%s-%s.%s", return 0;
pkg->name->name, pkg->version,
apk_script_types[type]); 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); fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755);
if (fd < 0) { if (fd < 0)
mkdirat(root_fd, "var/cache/misc", 0755); return -errno;
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755); }
if (fd < 0) write(fd, ipkg->script[type].ptr, ipkg->script[type].len);
return -errno; close(fd);
}
write(fd, script->script, script->size);
close(fd);
apk_message("Executing %s", &fn[15]); apk_message("Executing %s", &fn[15]);
pid = fork(); pid = fork();
if (pid == -1) 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;
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);
return 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)
......
...@@ -296,7 +296,7 @@ int apk_state_lock_dependency(struct apk_state *state, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment