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,16 +87,12 @@ struct apk_name {
struct apk_provider_array *providers; struct apk_provider_array *providers;
struct apk_name_array *rdepends; struct apk_name_array *rdepends;
struct apk_name_array *rinstall_if; struct apk_name_array *rinstall_if;
unsigned int foreach_genid;
union { union {
struct apk_solver_name_state ss; struct apk_solver_name_state ss;
struct { void *state_ptr;
unsigned int foreach_genid; int state_int;
union {
void *state_ptr;
int state_int;
};
};
}; };
}; };

View File

@ -52,13 +52,16 @@ static int mark_recalculate(apk_hash_item item, void *ctx)
return 0; 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) static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{ {
struct fix_ctx *ctx = (struct fix_ctx *) pctx; 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) if (!ctx->solver_flags)
ctx->solver_flags = APK_SOLVERF_REINSTALL; 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) if (ctx->fix_directory_permissions)
apk_hash_foreach(&db->installed.dirs, mark_recalculate, db); apk_hash_foreach(&db->installed.dirs, mark_recalculate, db);
foreach_array_item(parg, args) { apk_name_foreach_matching(db, args, apk_foreach_genid(), set_solver_flags, ctx);
pkg = NULL;
if (strstr(*parg, ".apk") != NULL) {
struct apk_sign_ctx sctx;
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE, return apk_solver_commit(db, 0, db->world);
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;
} }
static struct apk_option fix_options[] = { 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, static void print_name_info(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
struct apk_string_array *args)
{ {
struct apk_name *name; struct info_ctx *ctx = (struct info_ctx *) pctx;
struct apk_provider *p; struct apk_provider *p;
char **parg;
foreach_array_item(parg, args) { foreach_array_item(p, name->providers)
name = apk_db_query_name(db, APK_BLOB_STR(*parg)); info_subaction(ctx, p->pkg);
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) 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) { switch (optch) {
case 'e': case 'e':
ictx->action = info_exists; ctx->action = info_exists;
dbopts->open_flags |= APK_OPENF_NO_REPOS; dbopts->open_flags |= APK_OPENF_NO_REPOS;
break; break;
case 'W': case 'W':
ictx->action = info_who_owns; ctx->action = info_who_owns;
dbopts->open_flags |= APK_OPENF_NO_REPOS; dbopts->open_flags |= APK_OPENF_NO_REPOS;
break; break;
case 'w': case 'w':
ictx->subaction_mask |= APK_INFO_URL; ctx->subaction_mask |= APK_INFO_URL;
break; break;
case 'R': case 'R':
ictx->subaction_mask |= APK_INFO_DEPENDS; ctx->subaction_mask |= APK_INFO_DEPENDS;
break; break;
case 'P': case 'P':
ictx->subaction_mask |= APK_INFO_PROVIDES; ctx->subaction_mask |= APK_INFO_PROVIDES;
break; break;
case 'r': case 'r':
ictx->subaction_mask |= APK_INFO_RDEPENDS; ctx->subaction_mask |= APK_INFO_RDEPENDS;
break; break;
case 'I': case 'I':
ictx->subaction_mask |= APK_INFO_INSTALL_IF; ctx->subaction_mask |= APK_INFO_INSTALL_IF;
break; break;
case 'i': case 'i':
ictx->subaction_mask |= APK_INFO_RINSTALL_IF; ctx->subaction_mask |= APK_INFO_RINSTALL_IF;
break; break;
case 's': case 's':
ictx->subaction_mask |= APK_INFO_SIZE; ctx->subaction_mask |= APK_INFO_SIZE;
break; break;
case 'd': case 'd':
ictx->subaction_mask |= APK_INFO_DESC; ctx->subaction_mask |= APK_INFO_DESC;
break; break;
case 'L': case 'L':
ictx->subaction_mask |= APK_INFO_CONTENTS; ctx->subaction_mask |= APK_INFO_CONTENTS;
break; break;
case 't': case 't':
ictx->subaction_mask |= APK_INFO_TRIGGERS; ctx->subaction_mask |= APK_INFO_TRIGGERS;
break; break;
case 0x10000: case 0x10000:
ictx->subaction_mask |= APK_INFO_REPLACES; ctx->subaction_mask |= APK_INFO_REPLACES;
break; break;
case 'a': case 'a':
ictx->subaction_mask = 0xffffffff; ctx->subaction_mask = 0xffffffff;
break; break;
default: default:
return -1; 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; struct apk_installed_package *ipkg;
ictx->db = db; ictx->db = db;
if (ictx->subaction_mask == 0)
ictx->subaction_mask = APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE;
if (ictx->action != NULL) if (ictx->action != NULL)
return ictx->action(ictx, db, args); return ictx->action(ictx, db, args);
if (args->num > 0) { if (args->num > 0) {
/* Print info on given names */ /* Print info on given names */
ictx->subaction_mask |= APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE; apk_name_foreach_matching(db, args, apk_foreach_genid(), print_name_info, ctx);
return info_package(ictx, db, args);
} else { } else {
/* Print all installed packages */ /* Print all installed packages */
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) 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; 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]; char pkgname[256];
const char *opstr; const char *opstr;
apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR("")); 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; int i, r = -1;
unsigned short tag, allowed_repos; 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; allowed_repos = db->repo_tags[tag].allowed_repos;
name = pkg->name; foreach_array_item(p0, name->providers) {
for (i = 0; i < name->providers->num; i++) { struct apk_package *pkg0 = p0->pkg;
struct apk_package *pkg0 = name->providers->item[i].pkg;
if (pkg0->name != name || pkg0->repos == 0) if (pkg0->name != name || pkg0->repos == 0)
continue; continue;
if (!(ictx->all_tags || (pkg0->repos & allowed_repos))) if (!(ctx->all_tags || (pkg0->repos & allowed_repos)))
continue; continue;
r = apk_version_compare_blob(*pkg0->version, *latest); r = apk_version_compare_blob(*pkg0->version, *latest);
switch (r) { 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) r = latest->len ? apk_version_compare_blob(*pkg->version, *latest)
: APK_VERSION_UNKNOWN; : APK_VERSION_UNKNOWN;
opstr = apk_version_op_string(r); 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; return;
if (apk_verbosity <= 0) { if (apk_verbosity <= 0) {
printf("%s\n", pkg->name->name); printf("%s\n", pkg->name->name);
return; return;
} }
snprintf(pkgname, sizeof(pkgname), PKG_VER_FMT, snprintf(pkgname, sizeof(pkgname), PKG_VER_FMT, PKG_VER_PRINTF(pkg));
PKG_VER_PRINTF(pkg));
printf("%-40s%s " BLOB_FMT, pkgname, opstr, BLOB_PRINTF(*latest)); printf("%-40s%s " BLOB_FMT, pkgname, opstr, BLOB_PRINTF(*latest));
if (!(latest_repos & db->repo_tags[APK_DEFAULT_REPOSITORY_TAG].allowed_repos)) { if (!(latest_repos & db->repo_tags[APK_DEFAULT_REPOSITORY_TAG].allowed_repos)) {
for (i = 1; i < db->num_repo_tags; i++) { for (i = 1; i < db->num_repo_tags; i++) {
if (!(latest_repos & db->repo_tags[i].allowed_repos)) if (!(latest_repos & db->repo_tags[i].allowed_repos))
continue; continue;
if (!(ictx->all_tags || i == tag)) if (!(ctx->all_tags || i == tag))
continue; continue;
printf(" @" BLOB_FMT, printf(" @" BLOB_FMT,
BLOB_PRINTF(*db->repo_tags[i].name)); 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"); 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 ver_ctx *ctx = (struct ver_ctx *) pctx;
struct apk_installed_package *ipkg;
struct apk_name *name;
struct apk_package *pkg;
char **parg;
int ret = 0;
if (ictx->limchars) { if (ctx->limchars) {
if (strlen(ictx->limchars) == 0) if (strlen(ctx->limchars) == 0)
ictx->limchars = NULL; ctx->limchars = NULL;
} else if (args->num == 0 && apk_verbosity == 1) { } else if (args->num == 0 && apk_verbosity == 1) {
ictx->limchars = "<"; ctx->limchars = "<";
} }
if (ictx->action != NULL) if (ctx->action != NULL)
return ictx->action(db, args); return ctx->action(db, args);
if (apk_verbosity > 0) if (apk_verbosity > 0)
printf("%-42sAvailable:\n", "Installed:"); printf("%-42sAvailable:\n", "Installed:");
if (args->num == 0) { apk_name_foreach_matching(db, args, apk_foreach_genid(),
list_for_each_entry(ipkg, &db->installed.packages, ver_print_package_status, ctx);
installed_pkgs_list) {
ver_print_package_status(ictx, db, ipkg->pkg);
}
goto ver_exit;
}
foreach_array_item(parg, args) { return 0;
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;
} }
static struct apk_option ver_options[] = { static struct apk_option ver_options[] = {
@ -220,4 +201,3 @@ static struct apk_applet apk_ver = {
}; };
APK_DEFINE_APPLET(apk_ver); APK_DEFINE_APPLET(apk_ver);