fix, info, ver: perform wildcard matching

ref #511
cute-signatures
Timo Teräs 2013-06-18 13:34:01 +03:00
parent fe41ae07b9
commit af2b008bab
4 changed files with 62 additions and 120 deletions

View File

@ -87,17 +87,13 @@ struct apk_name {
struct apk_provider_array *providers;
struct apk_name_array *rdepends;
struct apk_name_array *rinstall_if;
unsigned int foreach_genid;
union {
struct apk_solver_name_state ss;
struct {
unsigned int foreach_genid;
union {
void *state_ptr;
int state_int;
};
};
};
};
struct apk_repository {

View File

@ -52,13 +52,16 @@ static int mark_recalculate(apk_hash_item item, void *ctx)
return 0;
}
static void set_solver_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
apk_solver_set_name_flags(name, ctx->solver_flags, ctx->fix_depends ? ctx->solver_flags : 0);
}
static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
struct apk_name *name;
struct apk_package *pkg;
char **parg;
int r = 0;
if (!ctx->solver_flags)
ctx->solver_flags = APK_SOLVERF_REINSTALL;
@ -66,37 +69,9 @@ static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array
if (ctx->fix_directory_permissions)
apk_hash_foreach(&db->installed.dirs, mark_recalculate, db);
foreach_array_item(parg, args) {
pkg = NULL;
if (strstr(*parg, ".apk") != NULL) {
struct apk_sign_ctx sctx;
apk_name_foreach_matching(db, args, apk_foreach_genid(), set_solver_flags, ctx);
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
NULL, db->keys_fd);
r = apk_pkg_read(db, *parg, &sctx, &pkg);
apk_sign_ctx_free(&sctx);
if (r != 0) {
apk_error("%s: %s", *parg, apk_error_str(r));
goto err;
}
name = pkg->name;
} else {
name = apk_db_get_name(db, APK_BLOB_STR(*parg));
pkg = apk_pkg_get_installed(name);
}
if (pkg == NULL || pkg->ipkg == NULL) {
apk_error("%s is not installed", name->name);
goto err;
}
apk_solver_set_name_flags(
name,
ctx->solver_flags,
ctx->fix_depends ? ctx->solver_flags : 0);
}
r = apk_solver_commit(db, 0, db->world);
err:
return r;
return apk_solver_commit(db, 0, db->world);
}
static struct apk_option fix_options[] = {

View File

@ -320,75 +320,65 @@ static void info_subaction(struct info_ctx *ctx, struct apk_package *pkg)
}
}
static int info_package(struct info_ctx *ctx, struct apk_database *db,
struct apk_string_array *args)
static void print_name_info(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
struct apk_name *name;
struct info_ctx *ctx = (struct info_ctx *) pctx;
struct apk_provider *p;
char **parg;
foreach_array_item(parg, args) {
name = apk_db_query_name(db, APK_BLOB_STR(*parg));
if (name == NULL || name->providers->num == 0) {
apk_error("Not found: %s", *parg);
return 1;
}
foreach_array_item(p, name->providers)
info_subaction(ctx, p->pkg);
}
return 0;
}
static int info_parse(void *ctx, struct apk_db_options *dbopts,
static int info_parse(void *pctx, struct apk_db_options *dbopts,
int optch, int optindex, const char *optarg)
{
struct info_ctx *ictx = (struct info_ctx *) ctx;
struct info_ctx *ctx = (struct info_ctx *) pctx;
ictx->action = info_package;
ctx->action = NULL;
switch (optch) {
case 'e':
ictx->action = info_exists;
ctx->action = info_exists;
dbopts->open_flags |= APK_OPENF_NO_REPOS;
break;
case 'W':
ictx->action = info_who_owns;
ctx->action = info_who_owns;
dbopts->open_flags |= APK_OPENF_NO_REPOS;
break;
case 'w':
ictx->subaction_mask |= APK_INFO_URL;
ctx->subaction_mask |= APK_INFO_URL;
break;
case 'R':
ictx->subaction_mask |= APK_INFO_DEPENDS;
ctx->subaction_mask |= APK_INFO_DEPENDS;
break;
case 'P':
ictx->subaction_mask |= APK_INFO_PROVIDES;
ctx->subaction_mask |= APK_INFO_PROVIDES;
break;
case 'r':
ictx->subaction_mask |= APK_INFO_RDEPENDS;
ctx->subaction_mask |= APK_INFO_RDEPENDS;
break;
case 'I':
ictx->subaction_mask |= APK_INFO_INSTALL_IF;
ctx->subaction_mask |= APK_INFO_INSTALL_IF;
break;
case 'i':
ictx->subaction_mask |= APK_INFO_RINSTALL_IF;
ctx->subaction_mask |= APK_INFO_RINSTALL_IF;
break;
case 's':
ictx->subaction_mask |= APK_INFO_SIZE;
ctx->subaction_mask |= APK_INFO_SIZE;
break;
case 'd':
ictx->subaction_mask |= APK_INFO_DESC;
ctx->subaction_mask |= APK_INFO_DESC;
break;
case 'L':
ictx->subaction_mask |= APK_INFO_CONTENTS;
ctx->subaction_mask |= APK_INFO_CONTENTS;
break;
case 't':
ictx->subaction_mask |= APK_INFO_TRIGGERS;
ctx->subaction_mask |= APK_INFO_TRIGGERS;
break;
case 0x10000:
ictx->subaction_mask |= APK_INFO_REPLACES;
ctx->subaction_mask |= APK_INFO_REPLACES;
break;
case 'a':
ictx->subaction_mask = 0xffffffff;
ctx->subaction_mask = 0xffffffff;
break;
default:
return -1;
@ -402,13 +392,14 @@ static int info_main(void *ctx, struct apk_database *db, struct apk_string_array
struct apk_installed_package *ipkg;
ictx->db = db;
if (ictx->subaction_mask == 0)
ictx->subaction_mask = APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE;
if (ictx->action != NULL)
return ictx->action(ictx, db, args);
if (args->num > 0) {
/* Print info on given names */
ictx->subaction_mask |= APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE;
return info_package(ictx, db, args);
apk_name_foreach_matching(db, args, apk_foreach_genid(), print_name_info, ctx);
} else {
/* Print all installed packages */
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list)

View File

@ -96,9 +96,11 @@ static int ver_parse(void *ctx, struct apk_db_options *dbopts,
return 0;
}
static void ver_print_package_status(struct ver_ctx *ictx, struct apk_database *db, struct apk_package *pkg)
static void ver_print_package_status(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
struct apk_name *name;
struct ver_ctx *ctx = (struct ver_ctx *) pctx;
struct apk_package *pkg;
struct apk_provider *p0;
char pkgname[256];
const char *opstr;
apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR(""));
@ -106,15 +108,18 @@ static void ver_print_package_status(struct ver_ctx *ictx, struct apk_database *
int i, r = -1;
unsigned short tag, allowed_repos;
tag = pkg->ipkg ? pkg->ipkg->repository_tag : 0;
pkg = apk_pkg_get_installed(name);
if (pkg == NULL)
return;
tag = pkg->ipkg->repository_tag;
allowed_repos = db->repo_tags[tag].allowed_repos;
name = pkg->name;
for (i = 0; i < name->providers->num; i++) {
struct apk_package *pkg0 = name->providers->item[i].pkg;
foreach_array_item(p0, name->providers) {
struct apk_package *pkg0 = p0->pkg;
if (pkg0->name != name || pkg0->repos == 0)
continue;
if (!(ictx->all_tags || (pkg0->repos & allowed_repos)))
if (!(ctx->all_tags || (pkg0->repos & allowed_repos)))
continue;
r = apk_version_compare_blob(*pkg0->version, *latest);
switch (r) {
@ -130,20 +135,19 @@ static void ver_print_package_status(struct ver_ctx *ictx, struct apk_database *
r = latest->len ? apk_version_compare_blob(*pkg->version, *latest)
: APK_VERSION_UNKNOWN;
opstr = apk_version_op_string(r);
if ((ictx->limchars != NULL) && (strchr(ictx->limchars, *opstr) == NULL))
if ((ctx->limchars != NULL) && (strchr(ctx->limchars, *opstr) == NULL))
return;
if (apk_verbosity <= 0) {
printf("%s\n", pkg->name->name);
return;
}
snprintf(pkgname, sizeof(pkgname), PKG_VER_FMT,
PKG_VER_PRINTF(pkg));
snprintf(pkgname, sizeof(pkgname), PKG_VER_FMT, PKG_VER_PRINTF(pkg));
printf("%-40s%s " BLOB_FMT, pkgname, opstr, BLOB_PRINTF(*latest));
if (!(latest_repos & db->repo_tags[APK_DEFAULT_REPOSITORY_TAG].allowed_repos)) {
for (i = 1; i < db->num_repo_tags; i++) {
if (!(latest_repos & db->repo_tags[i].allowed_repos))
continue;
if (!(ictx->all_tags || i == tag))
if (!(ctx->all_tags || i == tag))
continue;
printf(" @" BLOB_FMT,
BLOB_PRINTF(*db->repo_tags[i].name));
@ -152,50 +156,27 @@ static void ver_print_package_status(struct ver_ctx *ictx, struct apk_database *
printf("\n");
}
static int ver_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
static int ver_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
struct ver_ctx *ictx = (struct ver_ctx *) ctx;
struct apk_installed_package *ipkg;
struct apk_name *name;
struct apk_package *pkg;
char **parg;
int ret = 0;
struct ver_ctx *ctx = (struct ver_ctx *) pctx;
if (ictx->limchars) {
if (strlen(ictx->limchars) == 0)
ictx->limchars = NULL;
if (ctx->limchars) {
if (strlen(ctx->limchars) == 0)
ctx->limchars = NULL;
} else if (args->num == 0 && apk_verbosity == 1) {
ictx->limchars = "<";
ctx->limchars = "<";
}
if (ictx->action != NULL)
return ictx->action(db, args);
if (ctx->action != NULL)
return ctx->action(db, args);
if (apk_verbosity > 0)
printf("%-42sAvailable:\n", "Installed:");
if (args->num == 0) {
list_for_each_entry(ipkg, &db->installed.packages,
installed_pkgs_list) {
ver_print_package_status(ictx, db, ipkg->pkg);
}
goto ver_exit;
}
apk_name_foreach_matching(db, args, apk_foreach_genid(),
ver_print_package_status, ctx);
foreach_array_item(parg, args) {
name = apk_db_query_name(db, APK_BLOB_STR(*parg));
if (name == NULL) {
apk_error("Not found: %s", *parg);
ret = 1;
goto ver_exit;
}
pkg = apk_pkg_get_installed(name);
if (pkg != NULL)
ver_print_package_status(ictx, db, pkg);
}
ver_exit:
return ret;
return 0;
}
static struct apk_option ver_options[] = {
@ -220,4 +201,3 @@ static struct apk_applet apk_ver = {
};
APK_DEFINE_APPLET(apk_ver);