apk: per applet options
parent
0a7910c144
commit
3755e1cde3
|
@ -13,7 +13,7 @@
|
||||||
#include "apk_applet.h"
|
#include "apk_applet.h"
|
||||||
#include "apk_database.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;
|
struct apk_database db;
|
||||||
int i;
|
int i;
|
||||||
|
|
100
src/apk.c
100
src/apk.c
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -67,21 +68,11 @@ static struct apk_applet *find_applet(const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
static struct apk_applet *deduce_applet(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static struct option generic_options[] = {
|
struct apk_applet *a;
|
||||||
{"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;
|
|
||||||
const char *prog;
|
const char *prog;
|
||||||
int r;
|
int i;
|
||||||
|
|
||||||
umask(0);
|
|
||||||
apk_cwd_fd = open(".", O_RDONLY);
|
|
||||||
|
|
||||||
prog = strrchr(argv[0], '/');
|
prog = strrchr(argv[0], '/');
|
||||||
if (prog == NULL)
|
if (prog == NULL)
|
||||||
|
@ -90,10 +81,64 @@ int main(int argc, char **argv)
|
||||||
prog++;
|
prog++;
|
||||||
|
|
||||||
if (strncmp(prog, "apk_", 4) == 0)
|
if (strncmp(prog, "apk_", 4) == 0)
|
||||||
applet = find_applet(prog + 4);
|
return find_applet(prog + 4);
|
||||||
|
|
||||||
while ((r = getopt_long(argc, argv, "",
|
for (i = 1; i < argc; i++) {
|
||||||
generic_options, NULL)) != -1) {
|
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;
|
||||||
|
|
||||||
|
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) {
|
switch (r) {
|
||||||
case 'Q':
|
case 'Q':
|
||||||
apk_root = optarg;
|
apk_root = optarg;
|
||||||
|
@ -108,27 +153,24 @@ int main(int argc, char **argv)
|
||||||
apk_progress = 1;
|
apk_progress = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
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)
|
if (apk_root == NULL)
|
||||||
apk_root = "/";
|
apk_root = "/";
|
||||||
|
|
||||||
if (applet == NULL) {
|
argc -= optind;
|
||||||
if (argc > 0)
|
argv += optind;
|
||||||
applet = find_applet(argv[0]);
|
if (argc >= 1 && strcmp(argv[0], applet->name) == 0) {
|
||||||
if (applet == NULL)
|
|
||||||
return usage();
|
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return applet->main(argc, argv);
|
return applet->main(ctx, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,21 @@
|
||||||
#ifndef APK_APPLET_H
|
#ifndef APK_APPLET_H
|
||||||
#define APK_APPLET_H
|
#define APK_APPLET_H
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
extern const char *apk_root;
|
extern const char *apk_root;
|
||||||
extern const char *apk_repository;
|
extern const char *apk_repository;
|
||||||
|
|
||||||
struct apk_applet {
|
struct apk_applet {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *usage;
|
const char *usage;
|
||||||
int (*main)(int argc, char **argv);
|
|
||||||
|
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;
|
extern struct apk_applet *__start_apkapplets, *__stop_apkapplets;
|
||||||
|
|
|
@ -93,6 +93,7 @@ typedef union apk_database_or_void {
|
||||||
} apk_database_t __attribute__ ((__transparent_union__));
|
} 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_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);
|
void apk_name_free(struct apk_name *pkgname);
|
||||||
|
|
||||||
int apk_db_create(const char *root);
|
int apk_db_create(const char *root);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "apk_applet.h"
|
#include "apk_applet.h"
|
||||||
#include "apk_database.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) {
|
if (strcmp(apk_root, "/") == 0) {
|
||||||
apk_error("Will not recreate system root.");
|
apk_error("Will not recreate system root.");
|
||||||
|
|
|
@ -87,11 +87,16 @@ static const struct apk_hash_ops dir_hash_ops = {
|
||||||
.delete_item = (apk_hash_delete_f) free,
|
.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 *apk_db_get_name(struct apk_database *db, apk_blob_t name)
|
||||||
{
|
{
|
||||||
struct apk_name *pn;
|
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)
|
if (pn != NULL)
|
||||||
return pn;
|
return pn;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "apk_applet.h"
|
#include "apk_applet.h"
|
||||||
#include "apk_database.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;
|
struct apk_database db;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
|
@ -39,7 +39,7 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
|
||||||
return 0;
|
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 apk_database db;
|
||||||
struct counts counts = {0,0};
|
struct counts counts = {0,0};
|
||||||
|
|
79
src/info.c
79
src/info.c
|
@ -12,30 +12,91 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "apk_defines.h"
|
#include "apk_defines.h"
|
||||||
#include "apk_applet.h"
|
#include "apk_applet.h"
|
||||||
|
#include "apk_package.h"
|
||||||
#include "apk_database.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;
|
struct apk_package *pkg;
|
||||||
|
|
||||||
|
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
|
printf("%s", pkg->name->name);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
if (apk_db_open(&db, apk_root) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
list_for_each_entry(pkg, &db.installed.packages, installed_pkgs_list) {
|
if (ictx->action != NULL)
|
||||||
printf("%s", pkg->name->name);
|
r = ictx->action(&db, argc, argv);
|
||||||
if (!apk_quiet)
|
else
|
||||||
printf(" %s", pkg->version);
|
r = info_list(&db, argc, argv);
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
apk_db_close(&db);
|
apk_db_close(&db);
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct option info_options[] = {
|
||||||
|
{ "installed", no_argument, NULL, 'e' },
|
||||||
|
};
|
||||||
|
|
||||||
static struct apk_applet apk_info = {
|
static struct apk_applet apk_info = {
|
||||||
.name = "info",
|
.name = "info",
|
||||||
.usage = "",
|
.usage = "",
|
||||||
|
.context_size = sizeof(struct info_ctx),
|
||||||
|
.num_options = ARRAY_SIZE(info_options),
|
||||||
|
.options = info_options,
|
||||||
|
.parse = info_parse,
|
||||||
.main = info_main,
|
.main = info_main,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue