summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-01-13 14:09:45 +0200
committerTimo Teras <timo.teras@iki.fi>2009-01-13 14:09:45 +0200
commit3755e1cde35828aad4af0578d4271af6b7d57b61 (patch)
tree474c3fc5f5cd064b3b301cabe5e5d2bf09825461
parent0a7910c144568d8c22a99e359d9c3caf087bc368 (diff)
downloadapk-tools-3755e1cde35828aad4af0578d4271af6b7d57b61.tar.gz
apk-tools-3755e1cde35828aad4af0578d4271af6b7d57b61.tar.bz2
apk-tools-3755e1cde35828aad4af0578d4271af6b7d57b61.tar.xz
apk-tools-3755e1cde35828aad4af0578d4271af6b7d57b61.zip
apk: per applet options
-rw-r--r--src/add.c2
-rw-r--r--src/apk.c100
-rw-r--r--src/apk_applet.h12
-rw-r--r--src/apk_database.h1
-rw-r--r--src/create.c2
-rw-r--r--src/database.c7
-rw-r--r--src/del.c2
-rw-r--r--src/index.c2
-rw-r--r--src/info.c79
-rw-r--r--src/ver.c2
10 files changed, 163 insertions, 46 deletions
diff --git a/src/add.c b/src/add.c
index 562ce26..2716fe4 100644
--- a/src/add.c
+++ b/src/add.c
@@ -13,7 +13,7 @@
#include "apk_applet.h"
#include "apk_database.h"
-static int add_main(int argc, char **argv)
+static int add_main(void *ctx, int argc, char **argv)
{
struct apk_database db;
int i;
diff --git a/src/apk.c b/src/apk.c
index e874cbb..4062e56 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <fcntl.h>
+#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -67,21 +68,11 @@ static struct apk_applet *find_applet(const char *name)
return NULL;
}
-int main(int argc, char **argv)
+static struct apk_applet *deduce_applet(int argc, char **argv)
{
- static struct option generic_options[] = {
- {"root", required_argument, NULL, 'Q' },
- {"repository", required_argument, NULL, 'X' },
- {"quiet", no_argument, NULL, 'q' },
- {"progress", no_argument, NULL, 0x100 },
- {0, 0, 0, 0},
- };
- struct apk_applet *applet = NULL;
+ struct apk_applet *a;
const char *prog;
- int r;
-
- umask(0);
- apk_cwd_fd = open(".", O_RDONLY);
+ int i;
prog = strrchr(argv[0], '/');
if (prog == NULL)
@@ -90,10 +81,64 @@ int main(int argc, char **argv)
prog++;
if (strncmp(prog, "apk_", 4) == 0)
- applet = find_applet(prog + 4);
+ return find_applet(prog + 4);
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-')
+ continue;
+
+ a = find_applet(argv[i]);
+ if (a != NULL)
+ return a;
+ }
+
+ return NULL;
+}
+
+#define NUM_GENERIC_OPTS 4
+static struct option generic_options[32] = {
+ { "root", required_argument, NULL, 'Q' },
+ { "repository", required_argument, NULL, 'X' },
+ { "quiet", no_argument, NULL, 'q' },
+ { "progress", no_argument, NULL, 0x100 },
+};
+
+int main(int argc, char **argv)
+{
+ struct apk_applet *applet;
+ char short_options[256], *sopt;
+ struct option *opt;
+ int r, optindex;
+ void *ctx = NULL;
- while ((r = getopt_long(argc, argv, "",
- generic_options, NULL)) != -1) {
+ umask(0);
+ apk_cwd_fd = open(".", O_RDONLY);
+ apk_root = getenv("ROOT");
+
+ applet = deduce_applet(argc, argv);
+ if (applet == NULL)
+ return usage();
+
+ if (applet->num_options && applet->options) {
+ memcpy(&generic_options[NUM_GENERIC_OPTS],
+ applet->options,
+ applet->num_options * sizeof(struct option));
+ }
+ for (opt = &generic_options[0], sopt = short_options;
+ opt->name != NULL; opt++) {
+ if (opt->flag == NULL && isalnum(opt->val)) {
+ *(sopt++) = opt->val;
+ if (opt->has_arg != no_argument)
+ *(sopt++) = ':';
+ }
+ }
+
+ if (applet->context_size != 0)
+ ctx = calloc(1, applet->context_size);
+
+ optindex = 0;
+ while ((r = getopt_long(argc, argv, short_options,
+ generic_options, &optindex)) != -1) {
switch (r) {
case 'Q':
apk_root = optarg;
@@ -108,27 +153,24 @@ int main(int argc, char **argv)
apk_progress = 1;
break;
default:
- return usage();
+ if (applet->parse == NULL)
+ return usage();
+ if (applet->parse(ctx, r, optindex - NUM_GENERIC_OPTS,
+ optarg) != 0)
+ return usage();
+ break;
}
}
- argc -= optind;
- argv += optind;
-
- if (apk_root == NULL)
- apk_root = getenv("ROOT");
if (apk_root == NULL)
apk_root = "/";
- if (applet == NULL) {
- if (argc > 0)
- applet = find_applet(argv[0]);
- if (applet == NULL)
- return usage();
-
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1 && strcmp(argv[0], applet->name) == 0) {
argc--;
argv++;
}
- return applet->main(argc, argv);
+ return applet->main(ctx, argc, argv);
}
diff --git a/src/apk_applet.h b/src/apk_applet.h
index e4c2e1d..4fdce0d 100644
--- a/src/apk_applet.h
+++ b/src/apk_applet.h
@@ -12,13 +12,21 @@
#ifndef APK_APPLET_H
#define APK_APPLET_H
+#include <getopt.h>
+
extern const char *apk_root;
extern const char *apk_repository;
struct apk_applet {
const char *name;
- const char *usage;
- int (*main)(int argc, char **argv);
+ const char *usage;
+
+ int context_size;
+ int num_options;
+ struct option *options;
+
+ int (*parse)(void *ctx, int optch, int optindex, const char *optarg);
+ int (*main)(void *ctx, int argc, char **argv);
};
extern struct apk_applet *__start_apkapplets, *__stop_apkapplets;
diff --git a/src/apk_database.h b/src/apk_database.h
index 06d7b6d..c6134d7 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -93,6 +93,7 @@ typedef union apk_database_or_void {
} apk_database_t __attribute__ ((__transparent_union__));
struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name);
+struct apk_name *apk_db_query_name(struct apk_database *db, apk_blob_t name);
void apk_name_free(struct apk_name *pkgname);
int apk_db_create(const char *root);
diff --git a/src/create.c b/src/create.c
index c1dbea3..d12abfb 100644
--- a/src/create.c
+++ b/src/create.c
@@ -13,7 +13,7 @@
#include "apk_applet.h"
#include "apk_database.h"
-static int create_main(int argc, char **argv)
+static int create_main(void *ctx, int argc, char **argv)
{
if (strcmp(apk_root, "/") == 0) {
apk_error("Will not recreate system root.");
diff --git a/src/database.c b/src/database.c
index a45d8d1..373acb6 100644
--- a/src/database.c
+++ b/src/database.c
@@ -87,11 +87,16 @@ static const struct apk_hash_ops dir_hash_ops = {
.delete_item = (apk_hash_delete_f) free,
};
+struct apk_name *apk_db_query_name(struct apk_database *db, apk_blob_t name)
+{
+ return (struct apk_name *) apk_hash_get(&db->available.names, name);
+}
+
struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
{
struct apk_name *pn;
- pn = (struct apk_name *) apk_hash_get(&db->available.names, name);
+ pn = apk_db_query_name(db, name);
if (pn != NULL)
return pn;
diff --git a/src/del.c b/src/del.c
index 2fc6048..546a4db 100644
--- a/src/del.c
+++ b/src/del.c
@@ -13,7 +13,7 @@
#include "apk_applet.h"
#include "apk_database.h"
-static int del_main(int argc, char **argv)
+static int del_main(void *ctx, int argc, char **argv)
{
struct apk_database db;
int i, j;
diff --git a/src/index.c b/src/index.c
index 91d1ce6..81adc51 100644
--- a/src/index.c
+++ b/src/index.c
@@ -39,7 +39,7 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
return 0;
}
-static int index_main(int argc, char **argv)
+static int index_main(void *ctx, int argc, char **argv)
{
struct apk_database db;
struct counts counts = {0,0};
diff --git a/src/info.c b/src/info.c
index 780850d..2e41742 100644
--- a/src/info.c
+++ b/src/info.c
@@ -12,30 +12,91 @@
#include <stdio.h>
#include "apk_defines.h"
#include "apk_applet.h"
+#include "apk_package.h"
#include "apk_database.h"
+#include "apk_state.h"
-static int info_main(int argc, char **argv)
+struct info_ctx {
+ int (*action)(struct apk_database *db, int argc, char **argv);
+};
+
+static int info_list(struct apk_database *db, int argc, char **argv)
{
- struct apk_database db;
struct apk_package *pkg;
- if (apk_db_open(&db, apk_root) < 0)
- return -1;
-
- list_for_each_entry(pkg, &db.installed.packages, installed_pkgs_list) {
+ list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
printf("%s", pkg->name->name);
- if (!apk_quiet)
- printf(" %s", pkg->version);
+ if (!apk_quiet)
+ printf("-%s - %s", pkg->version, pkg->description);
printf("\n");
}
+ return 0;
+}
+
+static int info_exists(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]));
+ if (name == NULL)
+ return 1;
+
+ for (j = 0; j < name->pkgs->num; j++) {
+ if (apk_pkg_get_state(name->pkgs->item[j]) == APK_STATE_INSTALL)
+ break;
+ }
+ if (j >= name->pkgs->num)
+ return 2;
+ }
- apk_db_close(&db);
return 0;
}
+static int info_parse(void *ctx, int optch, int optindex, const char *optarg)
+{
+ struct info_ctx *ictx = (struct info_ctx *) ctx;
+
+ switch (optch) {
+ case 'e':
+ ictx->action = info_exists;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int info_main(void *ctx, int argc, char **argv)
+{
+ struct info_ctx *ictx = (struct info_ctx *) ctx;
+ struct apk_database db;
+ int r;
+
+ if (apk_db_open(&db, apk_root) < 0)
+ return -1;
+
+ if (ictx->action != NULL)
+ r = ictx->action(&db, argc, argv);
+ else
+ r = info_list(&db, argc, argv);
+
+ apk_db_close(&db);
+ return r;
+}
+
+static struct option info_options[] = {
+ { "installed", no_argument, NULL, 'e' },
+};
+
static struct apk_applet apk_info = {
.name = "info",
.usage = "",
+ .context_size = sizeof(struct info_ctx),
+ .num_options = ARRAY_SIZE(info_options),
+ .options = info_options,
+ .parse = info_parse,
.main = info_main,
};
diff --git a/src/ver.c b/src/ver.c
index 71e3d01..6665e8f 100644
--- a/src/ver.c
+++ b/src/ver.c
@@ -29,7 +29,7 @@ static int res2char(int res)
}
}
-static int ver_main(int argc, char **argv)
+static int ver_main(void *ctx, int argc, char **argv)
{
struct apk_database db;
struct apk_name *name;