2009-01-09 11:02:16 +00:00
|
|
|
/* info.c - Alpine Package Keeper (APK)
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005-2009 Natanael Copa <n@tanael.org>
|
|
|
|
* Copyright (C) 2009 Timo Teräs <timo.teras@iki.fi>
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
2009-06-25 12:14:07 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
2009-01-09 11:02:16 +00:00
|
|
|
* under the terms of the GNU General Public License version 2 as published
|
|
|
|
* by the Free Software Foundation. See http://www.gnu.org/ for details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2009-04-16 14:05:27 +00:00
|
|
|
#include <unistd.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"
|
2009-01-13 12:09:45 +00:00
|
|
|
#include "apk_state.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 {
|
2009-04-14 06:35:02 +00:00
|
|
|
int (*action)(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
int argc, char **argv);
|
2009-06-19 16:20:27 +00:00
|
|
|
int subaction_mask;
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
#define APK_INFO_RDEPENDS 0x10
|
|
|
|
#define APK_INFO_CONTENTS 0x20
|
|
|
|
#define APK_INFO_TRIGGERS 0x40
|
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)
|
|
|
|
{
|
|
|
|
int verbosity = apk_verbosity;
|
|
|
|
if (verbosity < minimal_verbosity)
|
|
|
|
verbosity = minimal_verbosity;
|
|
|
|
|
|
|
|
if (pkg == NULL || verbosity < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
printf("%s", pkg->name->name);
|
|
|
|
if (apk_verbosity > 1)
|
2010-12-14 17:51:16 +00:00
|
|
|
printf("-" BLOB_FMT, BLOB_PRINTF(*pkg->version));
|
2009-04-21 12:23:34 +00:00
|
|
|
if (apk_verbosity > 2)
|
|
|
|
printf(" - %s", pkg->description);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-14 06:35:02 +00:00
|
|
|
static int info_list(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
int argc, char **argv)
|
2009-01-09 11:02:16 +00:00
|
|
|
{
|
2009-08-12 16:17:46 +00:00
|
|
|
struct apk_installed_package *ipkg;
|
2009-01-09 11:02:16 +00:00
|
|
|
|
2009-08-12 16:17:46 +00:00
|
|
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list)
|
|
|
|
verbose_print_pkg(ipkg->pkg, 1);
|
2009-01-13 12:09:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-04-14 06:35:02 +00:00
|
|
|
static int info_exists(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
int argc, char **argv)
|
2009-01-13 12:09:45 +00:00
|
|
|
{
|
|
|
|
struct apk_name *name;
|
2009-08-05 12:36:04 +00:00
|
|
|
struct apk_package *pkg = NULL;
|
|
|
|
struct apk_dependency dep;
|
|
|
|
int r, i, j, ok = 0;
|
2009-01-13 12:09:45 +00:00
|
|
|
|
|
|
|
for (i = 0; i < argc; i++) {
|
2009-08-05 12:36:04 +00:00
|
|
|
r = apk_dep_from_blob(&dep, db, APK_BLOB_STR(argv[i]));
|
|
|
|
if (r != 0)
|
2009-04-21 12:23:34 +00:00
|
|
|
continue;
|
2009-01-13 12:09:45 +00:00
|
|
|
|
2009-08-05 12:36:04 +00:00
|
|
|
name = dep.name;
|
2009-01-13 12:09:45 +00:00
|
|
|
for (j = 0; j < name->pkgs->num; j++) {
|
2009-08-05 12:36:04 +00:00
|
|
|
pkg = name->pkgs->item[j];
|
2009-08-12 16:17:46 +00:00
|
|
|
if (pkg->ipkg != NULL)
|
2009-01-13 12:09:45 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-08-05 12:36:04 +00:00
|
|
|
if (j >= name->pkgs->num)
|
|
|
|
continue;
|
|
|
|
|
2010-12-14 17:51:16 +00:00
|
|
|
if (!(apk_version_compare_blob(*pkg->version, *dep.version)
|
2009-08-05 12:36:04 +00:00
|
|
|
& dep.result_mask))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
verbose_print_pkg(pkg, 0);
|
|
|
|
ok++;
|
2009-01-13 12:09:45 +00:00
|
|
|
}
|
2009-01-09 11:02:16 +00:00
|
|
|
|
2009-08-05 12:36:04 +00:00
|
|
|
return argc - ok;
|
2009-01-09 11:02:16 +00:00
|
|
|
}
|
|
|
|
|
2009-04-14 06:35:02 +00:00
|
|
|
static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
int argc, char **argv)
|
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;
|
2010-12-15 10:20:30 +00:00
|
|
|
int i, r=0;
|
2009-01-13 13:22:14 +00:00
|
|
|
|
2010-06-08 11:26:35 +00:00
|
|
|
apk_dependency_array_init(&deps);
|
2009-01-13 13:22:14 +00:00
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
pkg = apk_db_get_file_owner(db, APK_BLOB_STR(argv[i]));
|
2010-12-15 10:20:30 +00:00
|
|
|
if (pkg == NULL) {
|
|
|
|
apk_error("%s: Could not find owner package", argv[i]);
|
|
|
|
r++;
|
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
|
|
|
|
2009-01-16 09:33:55 +00:00
|
|
|
if (apk_verbosity < 1) {
|
2009-01-13 13:22:14 +00:00
|
|
|
dep = (struct apk_dependency) {
|
|
|
|
.name = pkg->name,
|
2011-01-01 10:11:49 +00:00
|
|
|
.version = apk_blob_atomize(APK_BLOB_NULL),
|
2009-04-14 15:48:02 +00:00
|
|
|
.result_mask = APK_DEPMASK_REQUIRE,
|
2009-01-13 13:22:14 +00:00
|
|
|
};
|
|
|
|
apk_deps_add(&deps, &dep);
|
|
|
|
} else {
|
2010-12-14 17:51:16 +00:00
|
|
|
printf("%s is owned by " PKG_VER_FMT "\n",
|
|
|
|
argv[i], PKG_VER_PRINTF(pkg));
|
2009-01-13 13:22:14 +00:00
|
|
|
}
|
|
|
|
}
|
2010-06-08 11:26:35 +00:00
|
|
|
if (apk_verbosity < 1 && deps->num != 0) {
|
2009-04-16 14:05:27 +00:00
|
|
|
struct apk_ostream *os;
|
|
|
|
|
|
|
|
os = apk_ostream_to_fd(STDOUT_FILENO);
|
|
|
|
apk_deps_write(deps, os);
|
|
|
|
os->write(os, "\n", 1);
|
|
|
|
os->close(os);
|
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
|
|
|
|
2010-12-15 10:20:30 +00:00
|
|
|
return r;
|
2009-01-13 13:22:14 +00:00
|
|
|
}
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
static void info_print_description(struct apk_package *pkg)
|
2009-06-19 16:20:27 +00:00
|
|
|
{
|
2009-08-13 07:45:48 +00:00
|
|
|
if (apk_verbosity > 1)
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
static void info_print_url(struct apk_package *pkg)
|
2009-04-14 06:35:02 +00:00
|
|
|
{
|
2009-08-13 07:45:48 +00:00
|
|
|
if (apk_verbosity > 1)
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
static void info_print_size(struct apk_package *pkg)
|
2009-01-20 13:02:36 +00:00
|
|
|
{
|
2009-08-13 07:45:48 +00:00
|
|
|
if (apk_verbosity > 1)
|
|
|
|
printf("%s: %zu", pkg->name->name, pkg->installed_size);
|
|
|
|
else
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " installed size:\n%zu\n",
|
|
|
|
PKG_VER_PRINTF(pkg),
|
2009-08-13 07:45:48 +00:00
|
|
|
pkg->installed_size);
|
2009-01-20 13:02:36 +00:00
|
|
|
}
|
|
|
|
|
2009-02-08 19:08:48 +00:00
|
|
|
static void info_print_depends(struct apk_package *pkg)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char *separator = apk_verbosity > 1 ? " " : "\n";
|
2009-06-25 12:14:07 +00:00
|
|
|
if (apk_verbosity == 1)
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " depends on:\n",
|
|
|
|
PKG_VER_PRINTF(pkg));
|
2009-02-08 19:08:48 +00:00
|
|
|
if (apk_verbosity > 1)
|
|
|
|
printf("%s: ", pkg->name->name);
|
2010-06-05 09:06:41 +00:00
|
|
|
for (i = 0; i < pkg->depends->num; i++)
|
2009-02-08 19:08:48 +00:00
|
|
|
printf("%s%s", pkg->depends->item[i].name->name, separator);
|
|
|
|
}
|
|
|
|
|
2009-04-14 06:35:02 +00:00
|
|
|
static void info_print_required_by(struct apk_package *pkg)
|
2009-02-08 19:08:48 +00:00
|
|
|
{
|
2009-04-14 06:35:02 +00:00
|
|
|
int i, j, k;
|
|
|
|
char *separator = apk_verbosity > 1 ? " " : "\n";
|
2009-02-08 19:08:48 +00:00
|
|
|
|
2009-04-14 06:35:02 +00:00
|
|
|
if (apk_verbosity == 1)
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT " is required by:\n",
|
|
|
|
PKG_VER_PRINTF(pkg));
|
2009-04-14 06:35:02 +00:00
|
|
|
if (apk_verbosity > 1)
|
|
|
|
printf("%s: ", pkg->name->name);
|
|
|
|
for (i = 0; i < pkg->name->rdepends->num; i++) {
|
|
|
|
struct apk_name *name0 = pkg->name->rdepends->item[i];
|
|
|
|
|
|
|
|
/* Check only the package that is installed, and that
|
|
|
|
* it actually has this package as dependency. */
|
|
|
|
for (j = 0; j < name0->pkgs->num; j++) {
|
|
|
|
struct apk_package *pkg0 = name0->pkgs->item[j];
|
|
|
|
|
2010-06-05 09:06:41 +00:00
|
|
|
if (pkg0->ipkg == NULL)
|
2009-04-14 06:35:02 +00:00
|
|
|
continue;
|
|
|
|
for (k = 0; k < pkg0->depends->num; k++) {
|
|
|
|
if (pkg0->depends->item[k].name != pkg->name)
|
|
|
|
continue;
|
2010-12-14 17:51:16 +00:00
|
|
|
printf(PKG_VER_FMT "%s",
|
|
|
|
PKG_VER_PRINTF(pkg0),
|
|
|
|
separator);
|
2009-04-14 06:35:02 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-08 19:08:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
static void info_print_contents(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;
|
|
|
|
|
|
|
|
if (apk_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) {
|
|
|
|
if (apk_verbosity > 1)
|
|
|
|
printf("%s: ", pkg->name->name);
|
|
|
|
printf("%s/%s\n", diri->dir->name, file->name);
|
|
|
|
}
|
|
|
|
}
|
2009-06-19 15:19:49 +00:00
|
|
|
}
|
|
|
|
|
2009-08-13 07:45:48 +00:00
|
|
|
static void info_print_triggers(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;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (apk_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
|
|
|
|
2010-06-05 09:06:41 +00:00
|
|
|
for (i = 0; i < ipkg->triggers->num; i++) {
|
2009-08-13 07:45:48 +00:00
|
|
|
if (apk_verbosity > 1)
|
|
|
|
printf("%s: trigger ", pkg->name->name);
|
|
|
|
printf("%s\n", ipkg->triggers->item[i]);
|
|
|
|
}
|
2009-06-19 15:19:49 +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
|
|
|
{
|
2009-08-13 07:45:48 +00:00
|
|
|
typedef void (*subaction_t)(struct apk_package *);
|
|
|
|
static subaction_t subactions[] = {
|
|
|
|
info_print_description,
|
|
|
|
info_print_url,
|
|
|
|
info_print_size,
|
|
|
|
info_print_depends,
|
|
|
|
info_print_required_by,
|
|
|
|
info_print_contents,
|
|
|
|
info_print_triggers,
|
|
|
|
};
|
|
|
|
const int requireipkg =
|
|
|
|
APK_INFO_CONTENTS | APK_INFO_TRIGGERS | APK_INFO_RDEPENDS;
|
|
|
|
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;
|
|
|
|
|
|
|
|
subactions[i](pkg);
|
|
|
|
puts("");
|
|
|
|
}
|
2009-06-19 16:35:17 +00:00
|
|
|
}
|
2009-08-13 07:45:48 +00:00
|
|
|
|
|
|
|
static int info_package(struct info_ctx *ctx, struct apk_database *db,
|
|
|
|
int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct apk_name *name;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
name = apk_db_query_name(db, APK_BLOB_STR(argv[i]));
|
2010-06-05 09:06:41 +00:00
|
|
|
if (name == NULL || name->pkgs->num == 0) {
|
2009-08-13 07:45:48 +00:00
|
|
|
apk_error("Not found: %s", argv[i]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
for (j = 0; j < name->pkgs->num; j++)
|
|
|
|
info_subaction(ctx, name->pkgs->item[j]);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-06 11:25:03 +00:00
|
|
|
static int info_parse(void *ctx, struct apk_db_options *dbopts,
|
|
|
|
int optch, int optindex, const char *optarg)
|
2009-01-13 12:09:45 +00:00
|
|
|
{
|
|
|
|
struct info_ctx *ictx = (struct info_ctx *) ctx;
|
|
|
|
|
2009-06-19 16:20:27 +00:00
|
|
|
ictx->action = info_package;
|
2009-01-13 12:09:45 +00:00
|
|
|
switch (optch) {
|
|
|
|
case 'e':
|
|
|
|
ictx->action = info_exists;
|
|
|
|
break;
|
2009-01-13 13:22:14 +00:00
|
|
|
case 'W':
|
|
|
|
ictx->action = info_who_owns;
|
|
|
|
break;
|
2009-06-19 15:19:49 +00:00
|
|
|
case 'w':
|
2009-06-19 16:20:27 +00:00
|
|
|
ictx->subaction_mask |= APK_INFO_URL;
|
2009-06-19 15:19:49 +00:00
|
|
|
break;
|
2009-02-08 19:08:48 +00:00
|
|
|
case 'R':
|
2009-06-19 16:20:27 +00:00
|
|
|
ictx->subaction_mask |= APK_INFO_DEPENDS;
|
2009-04-14 06:35:02 +00:00
|
|
|
break;
|
|
|
|
case 'r':
|
2009-06-19 16:20:27 +00:00
|
|
|
ictx->subaction_mask |= APK_INFO_RDEPENDS;
|
2009-02-08 19:08:48 +00:00
|
|
|
break;
|
2009-06-19 15:19:49 +00:00
|
|
|
case 's':
|
2009-06-19 16:20:27 +00:00
|
|
|
ictx->subaction_mask |= APK_INFO_SIZE;
|
2009-06-19 15:19:49 +00:00
|
|
|
break;
|
2009-06-19 16:35:17 +00:00
|
|
|
case 'd':
|
|
|
|
ictx->subaction_mask |= APK_INFO_DESC;
|
|
|
|
break;
|
2009-08-13 07:45:48 +00:00
|
|
|
case 'L':
|
|
|
|
ictx->subaction_mask |= APK_INFO_CONTENTS;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
ictx->subaction_mask |= APK_INFO_TRIGGERS;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
ictx->subaction_mask = 0xffffffff;
|
|
|
|
break;
|
2009-01-13 12:09:45 +00:00
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-06 11:25:03 +00:00
|
|
|
static int info_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
2009-01-13 12:09:45 +00:00
|
|
|
{
|
|
|
|
struct info_ctx *ictx = (struct info_ctx *) ctx;
|
|
|
|
|
|
|
|
if (ictx->action != NULL)
|
2009-08-06 11:25:03 +00:00
|
|
|
return ictx->action(ictx, db, argc, argv);
|
2009-01-13 12:09:45 +00:00
|
|
|
|
2009-08-06 11:25:03 +00:00
|
|
|
return info_list(ictx, db, argc, argv);
|
2009-01-13 12:09:45 +00:00
|
|
|
}
|
|
|
|
|
2009-06-25 12:14:07 +00:00
|
|
|
static struct apk_option info_options[] = {
|
|
|
|
{ 'L', "contents", "List contents of the PACKAGE" },
|
|
|
|
{ 'e', "installed", "Check if PACKAGE is installed" },
|
|
|
|
{ 'W', "who-owns", "Print the package owning the specified file" },
|
|
|
|
{ 'R', "depends", "List packages that the PACKAGE depends on" },
|
|
|
|
{ 'r', "rdepends", "List all packages depending on PACKAGE" },
|
|
|
|
{ 'w', "webpage", "Show URL for more information about PACKAGE" },
|
|
|
|
{ 's', "size", "Show installed size of PACKAGE" },
|
|
|
|
{ 'd', "description", "Print description for PACKAGE" },
|
2009-08-13 07:45:48 +00:00
|
|
|
{ 't', "triggers", "Print active triggers of PACKAGE" },
|
|
|
|
{ 'a', "all", "Print all information about PACKAGE" },
|
2009-01-13 12:09:45 +00:00
|
|
|
};
|
|
|
|
|
2009-01-09 11:02:16 +00:00
|
|
|
static struct apk_applet apk_info = {
|
|
|
|
.name = "info",
|
2009-09-03 10:56:24 +00:00
|
|
|
.help = "Give detailed information about PACKAGEs or repositores.",
|
2009-06-25 12:14:07 +00:00
|
|
|
.arguments = "PACKAGE...",
|
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),
|
|
|
|
.num_options = ARRAY_SIZE(info_options),
|
|
|
|
.options = info_options,
|
|
|
|
.parse = info_parse,
|
2009-01-09 11:02:16 +00:00
|
|
|
.main = info_main,
|
|
|
|
};
|
|
|
|
|
|
|
|
APK_DEFINE_APPLET(apk_info);
|
|
|
|
|