2020-02-14 11:49:41 +00:00
|
|
|
/* app_info.c - Alpine Package Keeper (APK)
|
2009-01-09 11:02:16 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2005-2009 Natanael Copa <n@tanael.org>
|
2011-09-13 08:53:01 +00:00
|
|
|
* Copyright (C) 2008-2011 Timo Teräs <timo.teras@iki.fi>
|
2009-01-09 11:02:16 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2020-04-22 13:33:41 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
2009-01-09 11:02:16 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2009-04-16 14:05:27 +00:00
|
|
|
#include <unistd.h>
|
2014-10-06 11:45:10 +00:00
|
|
|
#include <limits.h>
|
2009-01-09 11:02:16 +00:00
|
|
|
#include "apk_defines.h"
|
|
|
|
#include "apk_applet.h"
|
2009-01-13 12:09:45 +00:00
|
|
|
#include "apk_package.h"
|
2009-01-09 11:02:16 +00:00
|
|
|
#include "apk_database.h"
|
2010-03-05 08:13:25 +00:00
|
|
|
#include "apk_print.h"
|
2009-01-09 11:02:16 +00:00
|
|
|
|
2009-01-13 12:09:45 +00:00
|
|
|
struct info_ctx {
|
2011-10-29 02:18:21 +00:00
|
|
|
struct apk_database *db;
|
2014-12-08 06:30:58 +00:00
|
|
|
void (*action)(struct info_ctx *ctx, struct apk_database *db, struct apk_string_array *args);
|
2009-06-19 16:20:27 +00:00
|
|
|
int subaction_mask;
|
2014-12-08 06:30:58 +00:00
|
|
|
int errors;
|
2009-06-19 16:20:27 +00:00
|
|
|
};
|
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
static int verbosity = 0;
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
/* These need to stay in sync with the function pointer array in
|
|
|
|
* info_subaction() */
|
|
|
|
#define APK_INFO_DESC 0x01
|
|
|
|
#define APK_INFO_URL 0x02
|
|
|
|
#define APK_INFO_SIZE 0x04
|
|
|
|
#define APK_INFO_DEPENDS 0x08
|
2012-02-29 06:59:26 +00:00
|
|
|
#define APK_INFO_PROVIDES 0x10
|
|
|
|
#define APK_INFO_RDEPENDS 0x20
|
|
|
|
#define APK_INFO_CONTENTS 0x40
|
|
|
|
#define APK_INFO_TRIGGERS 0x80
|
|
|
|
#define APK_INFO_INSTALL_IF 0x100
|
|
|
|
#define APK_INFO_RINSTALL_IF 0x200
|
|
|
|
#define APK_INFO_REPLACES 0x400
|
2016-06-13 10:02:08 +00:00
|
|
|
#define APK_INFO_LICENSE 0x800
|
2009-06-19 16:20:27 +00:00
|
|
|
|
2009-04-21 12:23:34 +00:00
|
|
|
static void verbose_print_pkg(struct apk_package *pkg, int minimal_verbosity)
|
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
int v = min(verbosity, minimal_verbosity);
|
|
|
|
if (pkg == NULL || v < 1) return;
|
2009-04-21 12:23:34 +00:00
|
|
|
printf("%s", pkg->name->name);
|
2020-10-05 15:52:51 +00:00
|
|
|
if (v > 1) printf("-" BLOB_FMT, BLOB_PRINTF(*pkg->version));
|
|
|
|
if (v > 2) printf(" - %s", pkg->description);
|
2009-04-21 12:23:34 +00:00
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2014-12-08 06:30:58 +00:00
|
|
|
static void info_exists(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
struct apk_string_array *args)
|
2009-01-13 12:09:45 +00:00
|
|
|
{
|
|
|
|
struct apk_name *name;
|
2009-08-05 12:36:04 +00:00
|
|
|
struct apk_dependency dep;
|
2013-06-18 05:03:40 +00:00
|
|
|
struct apk_provider *p;
|
2013-06-18 10:01:51 +00:00
|
|
|
char **parg;
|
2014-12-08 06:30:58 +00:00
|
|
|
int ok;
|
2009-01-13 12:09:45 +00:00
|
|
|
|
2013-06-18 10:01:51 +00:00
|
|
|
foreach_array_item(parg, args) {
|
|
|
|
apk_blob_t b = APK_BLOB_STR(*parg);
|
2012-01-12 12:33:29 +00:00
|
|
|
|
2011-10-18 22:11:26 +00:00
|
|
|
apk_blob_pull_dep(&b, db, &dep);
|
2012-01-12 12:33:29 +00:00
|
|
|
if (APK_BLOB_IS_NULL(b) || b.len > 0)
|
|
|
|
continue;
|
|
|
|
|
2011-10-18 22:11:26 +00:00
|
|
|
name = dep.name;
|
|
|
|
if (name == NULL)
|
2009-04-21 12:23:34 +00:00
|
|
|
continue;
|
2009-01-13 12:09:45 +00:00
|
|
|
|
2015-11-12 11:11:55 +00:00
|
|
|
ok = apk_dep_is_provided(&dep, NULL);
|
2013-06-18 05:03:40 +00:00
|
|
|
foreach_array_item(p, name->providers) {
|
2015-11-12 11:11:55 +00:00
|
|
|
if (!p->pkg->ipkg) continue;
|
|
|
|
ok = apk_dep_is_provided(&dep, p);
|
|
|
|
if (ok) verbose_print_pkg(p->pkg, 0);
|
|
|
|
break;
|
2009-01-13 12:09:45 +00:00
|
|
|
}
|
2014-12-08 06:30:58 +00:00
|
|
|
if (!ok) ctx->errors++;
|
2009-01-13 12:09:45 +00:00
|
|
|
}
|
2009-01-09 11:02:16 +00:00
|
|
|
}
|
|
|
|
|
2014-12-08 06:30:58 +00:00
|
|
|
static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
struct apk_string_array *args)
|
2009-01-13 13:22:14 +00:00
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
struct apk_out *out = &db->ctx->out;
|
2009-01-13 13:22:14 +00:00
|
|
|
struct apk_package *pkg;
|
2010-06-08 11:26:35 +00:00
|
|
|
struct apk_dependency_array *deps;
|
2009-01-13 13:22:14 +00:00
|
|
|
struct apk_dependency dep;
|
2013-06-18 10:01:51 +00:00
|
|
|
struct apk_ostream *os;
|
2014-10-06 11:45:10 +00:00
|
|
|
const char *via;
|
2016-05-31 13:58:05 +00:00
|
|
|
char **parg, fnbuf[PATH_MAX], buf[PATH_MAX];
|
|
|
|
apk_blob_t fn;
|
2014-10-06 11:45:10 +00:00
|
|
|
ssize_t r;
|
2009-01-13 13:22:14 +00:00
|
|
|
|
2010-06-08 11:26:35 +00:00
|
|
|
apk_dependency_array_init(&deps);
|
2013-06-18 10:01:51 +00:00
|
|
|
foreach_array_item(parg, args) {
|
2016-05-31 13:58:05 +00:00
|
|
|
if (*parg[0] != '/' && realpath(*parg, fnbuf))
|
|
|
|
fn = APK_BLOB_STR(fnbuf);
|
|
|
|
else
|
|
|
|
fn = APK_BLOB_STR(*parg);
|
|
|
|
|
2014-10-06 11:45:10 +00:00
|
|
|
via = "";
|
2016-05-31 13:58:05 +00:00
|
|
|
pkg = apk_db_get_file_owner(db, fn);
|
2014-10-06 11:45:10 +00:00
|
|
|
if (pkg == NULL) {
|
|
|
|
r = readlinkat(db->root_fd, *parg, buf, sizeof(buf));
|
|
|
|
if (r > 0 && r < PATH_MAX && buf[0] == '/') {
|
|
|
|
pkg = apk_db_get_file_owner(db, APK_BLOB_STR(buf));
|
|
|
|
via = "symlink target ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-15 10:20:30 +00:00
|
|
|
if (pkg == NULL) {
|
2020-10-05 15:52:51 +00:00
|
|
|
apk_err(out, BLOB_FMT ": Could not find owner package",
|
|
|
|
BLOB_PRINTF(fn));
|
2014-12-08 06:30:58 +00:00
|
|
|
ctx->errors++;
|
2009-01-13 13:22:14 +00:00
|
|
|
continue;
|
2010-12-15 10:20:30 +00:00
|
|
|
}
|
2009-01-13 13:22:14 +00:00
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity < 1) {
|
2009-01-13 13:22:14 +00:00
|
|
|
dep = (struct apk_dependency) {
|
|
|
|
.name = pkg->name,
|
2020-05-19 08:39:21 +00:00
|
|
|
.version = &apk_atom_null,
|
2012-02-29 06:53:43 +00:00
|
|
|
.result_mask = APK_DEPMASK_ANY,
|
2009-01-13 13:22:14 +00:00
|
|
|
};
|
|
|
|
apk_deps_add(&deps, &dep);
|
|
|
|
} else {
|
2016-05-31 13:58:05 +00:00
|
|
|
printf(BLOB_FMT " %sis owned by " PKG_VER_FMT "\n",
|
|
|
|
BLOB_PRINTF(fn), via, PKG_VER_PRINTF(pkg));
|
2009-01-13 13:22:14 +00:00
|
|
|
}
|
|
|
|
}
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity < 1 && deps->num != 0) {
|
2009-04-16 14:05:27 +00:00
|
|
|
os = apk_ostream_to_fd(STDOUT_FILENO);
|
2015-03-10 11:15:58 +00:00
|
|
|
if (!IS_ERR_OR_NULL(os)) {
|
|
|
|
apk_deps_write(db, deps, os, APK_BLOB_PTR_LEN(" ", 1));
|
2017-06-21 13:07:58 +00:00
|
|
|
apk_ostream_write(os, "\n", 1);
|
|
|
|
apk_ostream_close(os);
|
2015-03-10 11:15:58 +00:00
|
|
|
}
|
2009-01-13 13:22:14 +00:00
|
|
|
}
|
2010-06-08 11:26:35 +00:00
|
|
|
apk_dependency_array_free(&deps);
|
2009-01-13 13:22:14 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_description(struct apk_database *db, struct apk_package *pkg)
|
2009-06-19 16:20:27 +00:00
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2009-08-13 07:45:48 +00:00
|
|
|
printf("%s: %s", pkg->name->name, pkg->description);
|
|
|
|
else
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " description:\n%s\n",
|
|
|
|
PKG_VER_PRINTF(pkg),
|
|
|
|
pkg->description);
|
2009-06-19 16:20:27 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_url(struct apk_database *db, struct apk_package *pkg)
|
2009-04-14 06:35:02 +00:00
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2009-08-13 07:45:48 +00:00
|
|
|
printf("%s: %s", pkg->name->name, pkg->url);
|
|
|
|
else
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " webpage:\n%s\n",
|
|
|
|
PKG_VER_PRINTF(pkg),
|
2009-08-13 07:45:48 +00:00
|
|
|
pkg->url);
|
2009-04-14 06:35:02 +00:00
|
|
|
}
|
|
|
|
|
2016-06-13 10:02:08 +00:00
|
|
|
static void info_print_license(struct apk_database *db, struct apk_package *pkg)
|
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2016-06-13 10:02:08 +00:00
|
|
|
printf("%s: " BLOB_FMT , pkg->name->name, BLOB_PRINTF(*pkg->license));
|
|
|
|
else
|
|
|
|
printf(PKG_VER_FMT " license:\n" BLOB_FMT "\n",
|
|
|
|
PKG_VER_PRINTF(pkg),
|
|
|
|
BLOB_PRINTF(*pkg->license));
|
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_size(struct apk_database *db, struct apk_package *pkg)
|
2009-01-20 13:02:36 +00:00
|
|
|
{
|
2018-10-11 11:39:25 +00:00
|
|
|
off_t size;
|
|
|
|
const char *size_unit;
|
|
|
|
|
|
|
|
size_unit = apk_get_human_size(pkg->installed_size, &size);
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2018-10-11 11:39:25 +00:00
|
|
|
printf("%s: %lld %s", pkg->name->name,
|
|
|
|
(long long)size, size_unit);
|
2009-08-13 07:45:48 +00:00
|
|
|
else
|
2018-10-11 11:39:25 +00:00
|
|
|
printf(PKG_VER_FMT " installed size:\n%lld %s\n",
|
|
|
|
PKG_VER_PRINTF(pkg), (long long)size, size_unit);
|
2009-01-20 13:02:36 +00:00
|
|
|
}
|
|
|
|
|
2013-06-18 05:03:40 +00:00
|
|
|
static void info_print_dep_array(struct apk_database *db, struct apk_package *pkg,
|
|
|
|
struct apk_dependency_array *deps, const char *dep_text)
|
2009-02-08 19:08:48 +00:00
|
|
|
{
|
2013-06-18 05:03:40 +00:00
|
|
|
struct apk_dependency *d;
|
2020-10-05 15:52:51 +00:00
|
|
|
apk_blob_t separator = APK_BLOB_STR(verbosity > 1 ? " " : "\n");
|
2013-06-18 05:03:40 +00:00
|
|
|
char buf[256];
|
2011-03-29 13:36:10 +00:00
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity == 1)
|
2013-06-18 05:03:40 +00:00
|
|
|
printf(PKG_VER_FMT " %s:\n", PKG_VER_PRINTF(pkg), dep_text);
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2009-02-08 19:08:48 +00:00
|
|
|
printf("%s: ", pkg->name->name);
|
2013-06-18 05:03:40 +00:00
|
|
|
foreach_array_item(d, deps) {
|
|
|
|
apk_blob_t b = APK_BLOB_BUF(buf);
|
|
|
|
apk_blob_push_dep(&b, db, d);
|
2011-03-29 13:36:10 +00:00
|
|
|
apk_blob_push_blob(&b, separator);
|
2013-06-18 05:03:40 +00:00
|
|
|
b = apk_blob_pushed(APK_BLOB_BUF(buf), b);
|
2011-03-29 13:36:10 +00:00
|
|
|
fwrite(b.ptr, b.len, 1, stdout);
|
|
|
|
}
|
2009-02-08 19:08:48 +00:00
|
|
|
}
|
|
|
|
|
2013-06-18 05:03:40 +00:00
|
|
|
static void info_print_depends(struct apk_database *db, struct apk_package *pkg)
|
|
|
|
{
|
|
|
|
info_print_dep_array(db, pkg, pkg->depends, "depends on");
|
|
|
|
}
|
|
|
|
|
2012-02-29 06:59:26 +00:00
|
|
|
static void info_print_provides(struct apk_database *db, struct apk_package *pkg)
|
|
|
|
{
|
2013-06-18 05:03:40 +00:00
|
|
|
info_print_dep_array(db, pkg, pkg->provides, "provides");
|
|
|
|
}
|
2012-02-29 06:59:26 +00:00
|
|
|
|
2013-06-18 05:03:40 +00:00
|
|
|
static void print_rdep_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *pctx)
|
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
printf(PKG_VER_FMT "%s", PKG_VER_PRINTF(pkg0), verbosity > 1 ? " " : "\n");
|
2012-02-29 06:59:26 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_required_by(struct apk_database *db, struct apk_package *pkg)
|
2009-02-08 19:08:48 +00:00
|
|
|
{
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity == 1)
|
2013-06-18 05:03:40 +00:00
|
|
|
printf(PKG_VER_FMT " is required by:\n", PKG_VER_PRINTF(pkg));
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2009-04-14 06:35:02 +00:00
|
|
|
printf("%s: ", pkg->name->name);
|
2013-06-18 05:03:40 +00:00
|
|
|
apk_pkg_foreach_reverse_dependency(
|
|
|
|
pkg,
|
|
|
|
APK_FOREACH_INSTALLED | APK_DEP_SATISFIES | apk_foreach_genid(),
|
|
|
|
print_rdep_pkg, NULL);
|
2009-02-08 19:08:48 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_install_if(struct apk_database *db, struct apk_package *pkg)
|
2011-03-29 13:36:10 +00:00
|
|
|
{
|
2013-06-18 05:03:40 +00:00
|
|
|
info_print_dep_array(db, pkg, pkg->install_if, "has auto-install rule");
|
2011-03-29 13:36:10 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_rinstall_if(struct apk_database *db, struct apk_package *pkg)
|
2011-03-29 13:36:10 +00:00
|
|
|
{
|
2012-02-24 13:50:39 +00:00
|
|
|
int i, j;
|
2020-10-05 15:52:51 +00:00
|
|
|
char *separator = verbosity > 1 ? " " : "\n";
|
2011-03-29 13:36:10 +00:00
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity == 1)
|
2011-03-29 13:36:10 +00:00
|
|
|
printf(PKG_VER_FMT " affects auto-installation of:\n",
|
|
|
|
PKG_VER_PRINTF(pkg));
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2011-03-29 13:36:10 +00:00
|
|
|
printf("%s: ", pkg->name->name);
|
|
|
|
for (i = 0; i < pkg->name->rinstall_if->num; i++) {
|
2012-02-24 13:50:39 +00:00
|
|
|
struct apk_name *name0;
|
|
|
|
struct apk_package *pkg0;
|
2011-03-29 13:36:10 +00:00
|
|
|
|
|
|
|
/* Check only the package that is installed, and that
|
|
|
|
* it actually has this package in install_if. */
|
2012-02-24 13:50:39 +00:00
|
|
|
name0 = pkg->name->rinstall_if->item[i];
|
|
|
|
pkg0 = apk_pkg_get_installed(name0);
|
|
|
|
if (pkg0 == NULL)
|
|
|
|
continue;
|
2011-03-29 13:36:10 +00:00
|
|
|
|
2012-02-24 13:50:39 +00:00
|
|
|
for (j = 0; j < pkg0->install_if->num; j++) {
|
|
|
|
if (pkg0->install_if->item[j].name != pkg->name)
|
2011-03-29 13:36:10 +00:00
|
|
|
continue;
|
2012-02-24 13:50:39 +00:00
|
|
|
printf(PKG_VER_FMT "%s",
|
|
|
|
PKG_VER_PRINTF(pkg0),
|
|
|
|
separator);
|
|
|
|
break;
|
2011-03-29 13:36:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_contents(struct apk_database *db, struct apk_package *pkg)
|
2009-06-19 15:19:49 +00:00
|
|
|
{
|
2009-08-13 07:45:48 +00:00
|
|
|
struct apk_installed_package *ipkg = pkg->ipkg;
|
|
|
|
struct apk_db_dir_instance *diri;
|
|
|
|
struct apk_db_file *file;
|
|
|
|
struct hlist_node *dc, *dn, *fc, *fn;
|
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity == 1)
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " contains:\n",
|
|
|
|
PKG_VER_PRINTF(pkg));
|
2009-08-13 07:45:48 +00:00
|
|
|
|
|
|
|
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs,
|
|
|
|
pkg_dirs_list) {
|
|
|
|
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files,
|
|
|
|
diri_files_list) {
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2009-08-13 07:45:48 +00:00
|
|
|
printf("%s: ", pkg->name->name);
|
2013-06-17 11:24:34 +00:00
|
|
|
printf(DIR_FILE_FMT "\n", DIR_FILE_PRINTF(diri->dir, file));
|
2009-08-13 07:45:48 +00:00
|
|
|
}
|
|
|
|
}
|
2009-06-19 15:19:49 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_triggers(struct apk_database *db, struct apk_package *pkg)
|
2009-06-19 15:19:49 +00:00
|
|
|
{
|
2009-08-13 07:45:48 +00:00
|
|
|
struct apk_installed_package *ipkg = pkg->ipkg;
|
2013-06-18 05:03:40 +00:00
|
|
|
char **trigger;
|
2009-08-13 07:45:48 +00:00
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity == 1)
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " triggers:\n",
|
|
|
|
PKG_VER_PRINTF(pkg));
|
2009-08-13 07:45:48 +00:00
|
|
|
|
2013-06-18 05:03:40 +00:00
|
|
|
foreach_array_item(trigger, ipkg->triggers) {
|
2020-10-05 15:52:51 +00:00
|
|
|
if (verbosity > 1)
|
2009-08-13 07:45:48 +00:00
|
|
|
printf("%s: trigger ", pkg->name->name);
|
2013-06-18 05:03:40 +00:00
|
|
|
printf("%s\n", *trigger);
|
2009-08-13 07:45:48 +00:00
|
|
|
}
|
2009-06-19 15:19:49 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
static void info_print_replaces(struct apk_database *db, struct apk_package *pkg)
|
2011-10-18 22:11:26 +00:00
|
|
|
{
|
2014-03-07 08:22:03 +00:00
|
|
|
info_print_dep_array(db, pkg, pkg->ipkg->replaces, "replaces");
|
2011-10-18 22:11:26 +00:00
|
|
|
}
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
static void info_subaction(struct info_ctx *ctx, struct apk_package *pkg)
|
2009-06-19 16:35:17 +00:00
|
|
|
{
|
2011-10-29 02:18:21 +00:00
|
|
|
typedef void (*subaction_t)(struct apk_database *, struct apk_package *);
|
2009-08-13 07:45:48 +00:00
|
|
|
static subaction_t subactions[] = {
|
|
|
|
info_print_description,
|
|
|
|
info_print_url,
|
|
|
|
info_print_size,
|
|
|
|
info_print_depends,
|
2012-02-29 06:59:26 +00:00
|
|
|
info_print_provides,
|
2009-08-13 07:45:48 +00:00
|
|
|
info_print_required_by,
|
|
|
|
info_print_contents,
|
|
|
|
info_print_triggers,
|
2011-03-29 13:36:10 +00:00
|
|
|
info_print_install_if,
|
|
|
|
info_print_rinstall_if,
|
2011-10-18 22:11:26 +00:00
|
|
|
info_print_replaces,
|
2016-06-13 10:02:08 +00:00
|
|
|
info_print_license,
|
2009-08-13 07:45:48 +00:00
|
|
|
};
|
|
|
|
const int requireipkg =
|
2011-03-29 13:36:10 +00:00
|
|
|
APK_INFO_CONTENTS | APK_INFO_TRIGGERS | APK_INFO_RDEPENDS |
|
2011-10-18 22:11:26 +00:00
|
|
|
APK_INFO_RINSTALL_IF | APK_INFO_REPLACES;
|
2009-08-13 07:45:48 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(subactions); i++) {
|
|
|
|
if (!(BIT(i) & ctx->subaction_mask))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pkg->ipkg == NULL && (BIT(i) & requireipkg))
|
|
|
|
continue;
|
|
|
|
|
2011-10-29 02:18:21 +00:00
|
|
|
subactions[i](ctx->db, pkg);
|
2009-08-13 07:45:48 +00:00
|
|
|
puts("");
|
|
|
|
}
|
2009-06-19 16:35:17 +00:00
|
|
|
}
|
2009-08-13 07:45:48 +00:00
|
|
|
|
2013-06-18 10:34:01 +00:00
|
|
|
static void print_name_info(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
|
2009-08-13 07:45:48 +00:00
|
|
|
{
|
2013-06-18 10:34:01 +00:00
|
|
|
struct info_ctx *ctx = (struct info_ctx *) pctx;
|
2013-06-18 05:03:40 +00:00
|
|
|
struct apk_provider *p;
|
2009-08-13 07:45:48 +00:00
|
|
|
|
2014-12-08 06:30:58 +00:00
|
|
|
if (name == NULL) {
|
|
|
|
ctx->errors++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-18 10:34:01 +00:00
|
|
|
foreach_array_item(p, name->providers)
|
|
|
|
info_subaction(ctx, p->pkg);
|
2009-08-13 07:45:48 +00:00
|
|
|
}
|
|
|
|
|
2020-08-24 10:35:36 +00:00
|
|
|
#define INFO_OPTIONS(OPT) \
|
|
|
|
OPT(OPT_INFO_all, APK_OPT_SH("a") "all") \
|
|
|
|
OPT(OPT_INFO_contents, APK_OPT_SH("L") "contents") \
|
|
|
|
OPT(OPT_INFO_depends, APK_OPT_SH("R") "depends") \
|
|
|
|
OPT(OPT_INFO_description, APK_OPT_SH("d") "description") \
|
|
|
|
OPT(OPT_INFO_install_if, "install-if") \
|
|
|
|
OPT(OPT_INFO_installed, APK_OPT_SH("e") "installed") \
|
|
|
|
OPT(OPT_INFO_license, "license") \
|
|
|
|
OPT(OPT_INFO_provides, APK_OPT_SH("P") "provides") \
|
|
|
|
OPT(OPT_INFO_rdepends, APK_OPT_SH("r") "rdepends") \
|
|
|
|
OPT(OPT_INFO_replaces, "replaces") \
|
|
|
|
OPT(OPT_INFO_rinstall_if, "rinstall-if") \
|
|
|
|
OPT(OPT_INFO_size, APK_OPT_SH("s") "size") \
|
|
|
|
OPT(OPT_INFO_triggers, APK_OPT_SH("t") "triggers") \
|
|
|
|
OPT(OPT_INFO_webpage, APK_OPT_SH("w") "webpage") \
|
|
|
|
OPT(OPT_INFO_who_owns, APK_OPT_SH("W") "who-owns")
|
|
|
|
|
|
|
|
APK_OPT_APPLET(option_desc, INFO_OPTIONS);
|
2020-05-04 18:45:11 +00:00
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const char *optarg)
|
2009-01-13 12:09:45 +00:00
|
|
|
{
|
2013-06-18 10:34:01 +00:00
|
|
|
struct info_ctx *ctx = (struct info_ctx *) pctx;
|
2009-01-13 12:09:45 +00:00
|
|
|
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->action = NULL;
|
2020-05-04 18:45:11 +00:00
|
|
|
switch (opt) {
|
|
|
|
case OPT_INFO_installed:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->action = info_exists;
|
2020-10-05 15:52:51 +00:00
|
|
|
ac->open_flags |= APK_OPENF_NO_REPOS;
|
2009-01-13 12:09:45 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_who_owns:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->action = info_who_owns;
|
2020-10-05 15:52:51 +00:00
|
|
|
ac->open_flags |= APK_OPENF_NO_REPOS;
|
2009-01-13 13:22:14 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_webpage:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_URL;
|
2009-06-19 15:19:49 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_depends:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_DEPENDS;
|
2009-04-14 06:35:02 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_provides:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_PROVIDES;
|
2012-02-29 06:59:26 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_rdepends:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_RDEPENDS;
|
2009-02-08 19:08:48 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_install_if:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_INSTALL_IF;
|
2011-03-29 13:36:10 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_rinstall_if:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_RINSTALL_IF;
|
2011-03-29 13:36:10 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_size:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_SIZE;
|
2009-06-19 15:19:49 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_description:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_DESC;
|
2009-06-19 16:35:17 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_contents:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_CONTENTS;
|
2009-08-13 07:45:48 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_triggers:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_TRIGGERS;
|
2009-08-13 07:45:48 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_replaces:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_REPLACES;
|
2011-10-18 22:11:26 +00:00
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_license:
|
2016-06-13 10:02:08 +00:00
|
|
|
ctx->subaction_mask |= APK_INFO_LICENSE;
|
|
|
|
break;
|
2020-05-04 18:45:11 +00:00
|
|
|
case OPT_INFO_all:
|
2013-06-18 10:34:01 +00:00
|
|
|
ctx->subaction_mask = 0xffffffff;
|
2009-08-13 07:45:48 +00:00
|
|
|
break;
|
2009-01-13 12:09:45 +00:00
|
|
|
default:
|
2019-06-05 06:32:29 +00:00
|
|
|
return -ENOTSUP;
|
2009-01-13 12:09:45 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-18 10:01:51 +00:00
|
|
|
static int info_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
|
2009-01-13 12:09:45 +00:00
|
|
|
{
|
|
|
|
struct info_ctx *ictx = (struct info_ctx *) ctx;
|
2013-06-18 10:01:51 +00:00
|
|
|
struct apk_installed_package *ipkg;
|
2009-01-13 12:09:45 +00:00
|
|
|
|
2020-10-05 15:52:51 +00:00
|
|
|
verbosity = apk_out_verbosity(&db->ctx->out);
|
2011-10-29 02:18:21 +00:00
|
|
|
ictx->db = db;
|
2013-06-18 10:34:01 +00:00
|
|
|
if (ictx->subaction_mask == 0)
|
|
|
|
ictx->subaction_mask = APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE;
|
2014-12-08 06:30:58 +00:00
|
|
|
if (ictx->action != NULL) {
|
|
|
|
ictx->action(ictx, db, args);
|
|
|
|
} else if (args->num > 0) {
|
2013-06-18 10:01:51 +00:00
|
|
|
/* Print info on given names */
|
2013-06-19 17:55:01 +00:00
|
|
|
apk_name_foreach_matching(
|
|
|
|
db, args, APK_FOREACH_NULL_MATCHES_ALL | apk_foreach_genid(),
|
|
|
|
print_name_info, ctx);
|
2013-06-18 10:01:51 +00:00
|
|
|
} else {
|
|
|
|
/* Print all installed packages */
|
|
|
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list)
|
|
|
|
verbose_print_pkg(ipkg->pkg, 1);
|
|
|
|
}
|
2012-01-06 09:38:23 +00:00
|
|
|
|
2014-12-08 06:30:58 +00:00
|
|
|
return ictx->errors;
|
2009-01-13 12:09:45 +00:00
|
|
|
}
|
|
|
|
|
2014-10-08 12:29:27 +00:00
|
|
|
static const struct apk_option_group optgroup_applet = {
|
2020-05-04 18:45:11 +00:00
|
|
|
.desc = option_desc,
|
2014-10-08 12:29:27 +00:00
|
|
|
.parse = option_parse_applet,
|
|
|
|
};
|
|
|
|
|
2009-01-09 11:02:16 +00:00
|
|
|
static struct apk_applet apk_info = {
|
|
|
|
.name = "info",
|
2009-08-13 07:45:48 +00:00
|
|
|
.open_flags = APK_OPENF_READ,
|
2009-01-13 12:09:45 +00:00
|
|
|
.context_size = sizeof(struct info_ctx),
|
2014-10-08 12:29:27 +00:00
|
|
|
.optgroups = { &optgroup_global, &optgroup_applet },
|
2009-01-09 11:02:16 +00:00
|
|
|
.main = info_main,
|
|
|
|
};
|
|
|
|
|
|
|
|
APK_DEFINE_APPLET(apk_info);
|
|
|
|
|