From fe41ae07b90bbd4609ee6871def851a41027aae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Tue, 18 Jun 2013 13:01:51 +0300 Subject: [PATCH] apk: use string array in applet mains, separate apk_name_foreach_matching --- src/add.c | 17 +++++----- src/apk.c | 7 +++- src/apk_applet.h | 2 +- src/apk_database.h | 13 ++++++-- src/audit.c | 41 ++++++++++++----------- src/cache.c | 13 ++++---- src/database.c | 77 +++++++++++++++++++++++++++++++++++++++++++ src/del.c | 24 +++++++------- src/dot.c | 10 +++--- src/fetch.c | 13 ++++---- src/fix.c | 15 +++++---- src/index.c | 21 ++++++------ src/info.c | 82 ++++++++++++++++++++-------------------------- src/package.c | 15 +++++---- src/search.c | 80 +++++++++++++++----------------------------- src/update.c | 2 +- src/upgrade.c | 2 +- src/ver.c | 43 +++++++++++++----------- src/verify.c | 17 +++++----- 19 files changed, 282 insertions(+), 212 deletions(-) diff --git a/src/add.c b/src/add.c index 9fe09b4..9f900e3 100644 --- a/src/add.c +++ b/src/add.c @@ -58,13 +58,14 @@ static int non_repository_check(struct apk_database *db) return 1; } -static int add_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int add_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct add_ctx *actx = (struct add_ctx *) ctx; struct apk_package *virtpkg = NULL; struct apk_dependency virtdep; struct apk_dependency_array *world = NULL; - int i, r = 0; + char **parg; + int r = 0; apk_dependency_array_copy(&world, db->world); @@ -96,10 +97,10 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv) virtpkg = apk_db_pkg_add(db, virtpkg); } - for (i = 0; i < argc; i++) { + foreach_array_item(parg, args) { struct apk_dependency dep; - if (strstr(argv[i], ".apk") != NULL) { + if (strstr(*parg, ".apk") != NULL) { struct apk_package *pkg = NULL; struct apk_sign_ctx sctx; @@ -108,20 +109,20 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv) apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE, NULL, db->keys_fd); - r = apk_pkg_read(db, argv[i], &sctx, &pkg); + r = apk_pkg_read(db, *parg, &sctx, &pkg); apk_sign_ctx_free(&sctx); if (r != 0) { - apk_error("%s: %s", argv[i], apk_error_str(r)); + apk_error("%s: %s", *parg, apk_error_str(r)); return -1; } apk_dep_from_pkg(&dep, db, pkg); } else { - apk_blob_t b = APK_BLOB_STR(argv[i]); + apk_blob_t b = APK_BLOB_STR(*parg); apk_blob_pull_dep(&b, db, &dep); if (APK_BLOB_IS_NULL(b) || b.len > 0) { apk_error("'%s' is not a valid dependency, format is name(@tag)([<>=]version)", - argv[i]); + *parg); return -1; } } diff --git a/src/apk.c b/src/apk.c index f5f6f13..cb039d1 100644 --- a/src/apk.c +++ b/src/apk.c @@ -291,6 +291,7 @@ int main(int argc, char **argv) struct apk_repository_list *repo = NULL; struct apk_database db; struct apk_db_options dbopts; + struct apk_string_array *args; #ifdef TEST_MODE const char *test_installed_db = NULL; const char *test_world = NULL; @@ -495,7 +496,11 @@ int main(int argc, char **argv) } #endif - r = applet->main(ctx, &db, argc, argv); + apk_string_array_init(&args); + apk_string_array_resize(&args, argc); + memcpy(args->item, argv, argc * sizeof(*argv)); + + r = applet->main(ctx, &db, args); apk_db_close(&db); if (r == -EINVAL) diff --git a/src/apk_applet.h b/src/apk_applet.h index 63f9da9..fa690fc 100644 --- a/src/apk_applet.h +++ b/src/apk_applet.h @@ -36,7 +36,7 @@ struct apk_applet { int (*parse)(void *ctx, struct apk_db_options *dbopts, int optch, int optindex, const char *optarg); - int (*main)(void *ctx, struct apk_database *db, int argc, char **argv); + int (*main)(void *ctx, struct apk_database *db, struct apk_string_array *args); }; extern struct apk_applet *__start_apkapplets, *__stop_apkapplets; diff --git a/src/apk_database.h b/src/apk_database.h index 03a0751..d270e18 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -90,8 +90,13 @@ struct apk_name { union { struct apk_solver_name_state ss; - void *state_ptr; - int state_int; + struct { + unsigned int foreach_genid; + union { + void *state_ptr; + int state_int; + }; + }; }; }; @@ -239,4 +244,8 @@ int apk_db_install_pkg(struct apk_database *db, struct apk_package *newpkg, apk_progress_cb cb, void *cb_ctx); +void apk_name_foreach_matching(struct apk_database *db, struct apk_string_array *filter, unsigned int match, + void (*cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx), + void *ctx); + #endif diff --git a/src/audit.c b/src/audit.c index 3e08930..27d3391 100644 --- a/src/audit.c +++ b/src/audit.c @@ -236,39 +236,40 @@ done: return reason < 0 ? reason : 0; } -static int audit_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int audit_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct audit_tree_ctx atctx; - int i, r = 0; + char **parg, *arg; + int r = 0; atctx.db = db; atctx.actx = (struct audit_ctx *) ctx; atctx.pathlen = 0; atctx.path[0] = 0; - if (argc == 0) { + if (args->num == 0) { atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen)); r = apk_dir_foreach_file(dup(db->root_fd), audit_directory_tree_item, &atctx); apk_db_dir_unref(db, atctx.dir, FALSE); - } else { - for (i = 0; i < argc; i++) { - if (argv[i][0] != '/') { - apk_warning("%s: relative path skipped.\n", - argv[i]); - continue; - } - argv[i]++; - atctx.pathlen = strlen(argv[i]); - memcpy(atctx.path, argv[i], atctx.pathlen); - if (atctx.path[atctx.pathlen-1] != '/') - atctx.path[atctx.pathlen++] = '/'; + return r; + } - atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen)); - r |= apk_dir_foreach_file( - openat(db->root_fd, argv[i], O_RDONLY|O_CLOEXEC), - audit_directory_tree_item, &atctx); - apk_db_dir_unref(db, atctx.dir, FALSE); + foreach_array_item(parg, args) { + arg = *parg; + if (arg[0] != '/') { + apk_warning("%s: relative path skipped.\n", arg); + continue; } + arg++; + atctx.pathlen = strlen(arg); + memcpy(atctx.path, arg, atctx.pathlen); + if (atctx.path[atctx.pathlen-1] != '/') + atctx.path[atctx.pathlen++] = '/'; + + atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen)); + r |= apk_dir_foreach_file(openat(db->root_fd, arg, O_RDONLY|O_CLOEXEC), + audit_directory_tree_item, &atctx); + apk_db_dir_unref(db, atctx.dir, FALSE); } return r; } diff --git a/src/cache.c b/src/cache.c index babfaa6..84b2786 100644 --- a/src/cache.c +++ b/src/cache.c @@ -111,18 +111,20 @@ static int cache_clean(struct apk_database *db) return apk_db_cache_foreach_item(db, cache_clean_item); } -static int cache_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int cache_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { + char *arg; int r = 0, actions = 0; - if (argc != 1) + if (args->num != 1) return -EINVAL; - if (strcmp(argv[0], "sync") == 0) + arg = args->item[0]; + if (strcmp(arg, "sync") == 0) actions = CACHE_CLEAN | CACHE_DOWNLOAD; - else if (strcmp(argv[0], "clean") == 0) + else if (strcmp(arg, "clean") == 0) actions = CACHE_CLEAN; - else if (strcmp(argv[0], "download") == 0) + else if (strcmp(arg, "download") == 0) actions = CACHE_DOWNLOAD; else return -EINVAL; @@ -137,7 +139,6 @@ static int cache_main(void *ctx, struct apk_database *db, int argc, char **argv) r = cache_clean(db); if (r == 0 && (actions & CACHE_DOWNLOAD)) r = cache_download(db); - err: return r; } diff --git a/src/database.c b/src/database.c index 964bc22..1d10d59 100644 --- a/src/database.c +++ b/src/database.c @@ -2673,3 +2673,80 @@ ret_r: free(script_args[2]); return r; } + +struct match_ctx { + struct apk_database *db; + struct apk_string_array *filter; + unsigned int match; + void (*cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx); + void *cb_ctx; +}; + +static int match_names(apk_hash_item item, void *pctx) +{ + struct match_ctx *ctx = (struct match_ctx *) pctx; + struct apk_name *name = (struct apk_name *) item; + unsigned int genid = ctx->match & APK_FOREACH_GENID_MASK; + char **pmatch; + + if (genid) { + if (name->foreach_genid >= genid) + return 0; + name->foreach_genid = genid; + } + + if (ctx->filter->num == 0) { + ctx->cb(ctx->db, NULL, name, ctx->cb_ctx); + return 0; + } + + foreach_array_item(pmatch, ctx->filter) { + if (fnmatch(*pmatch, name->name, FNM_CASEFOLD) == 0) { + ctx->cb(ctx->db, *pmatch, name, ctx->cb_ctx); + if (genid) + break; + } + } + + return 0; +} + +void apk_name_foreach_matching(struct apk_database *db, struct apk_string_array *filter, unsigned int match, + void (*cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx), + void *ctx) +{ + char **pmatch; + unsigned int genid = match & APK_FOREACH_GENID_MASK; + struct apk_name *name; + struct match_ctx mctx = { + .db = db, + .filter = filter, + .match = match, + .cb = cb, + .cb_ctx = ctx, + }; + + if (filter == NULL || filter->num == 0) { + apk_string_array_init(&mctx.filter); + goto all; + } + foreach_array_item(pmatch, filter) + if (strchr(*pmatch, '*') != NULL) + goto all; + + foreach_array_item(pmatch, filter) { + name = (struct apk_name *) apk_hash_get(&db->available.names, APK_BLOB_STR(*pmatch)); + if (name == NULL) + continue; + if (genid) { + if (name->foreach_genid >= genid) + continue; + name->foreach_genid = genid; + } + cb(db, *pmatch, name, ctx); + } + return; + +all: + apk_hash_foreach(&db->available.names, match_names, &mctx); +} diff --git a/src/del.c b/src/del.c index 2e7de8b..4e4da08 100644 --- a/src/del.c +++ b/src/del.c @@ -75,22 +75,24 @@ static void delete_from_world( delete_from_world, pctx); } -static int del_main(void *pctx, struct apk_database *db, int argc, char **argv) +static int del_main(void *pctx, struct apk_database *db, struct apk_string_array *args) { struct del_ctx *ctx = (struct del_ctx *) pctx; struct not_deleted_ctx ndctx = {}; - struct apk_name **name; + struct apk_name_array *names; + struct apk_name **pname; struct apk_changeset changeset = {}; struct apk_change *change; struct apk_provider *p; - int i, r = 0; + int r = 0, i; + apk_name_array_init(&names); + apk_name_array_resize(&names, args->num); apk_dependency_array_copy(&ctx->world, db->world); - name = alloca(argc * sizeof(struct apk_name*)); - for (i = 0; i < argc; i++) { - name[i] = apk_db_get_name(db, APK_BLOB_STR(argv[i])); - delete_from_world(apk_pkg_get_installed(name[i]), NULL, NULL, ctx); + for (i = 0; i < args->num; i++) { + names->item[i] = apk_db_get_name(db, APK_BLOB_STR(args->item[i])); + delete_from_world(apk_pkg_get_installed(names->item[i]), NULL, NULL, ctx); } r = apk_solver_solve(db, 0, ctx->world, &changeset); @@ -102,11 +104,11 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv) continue; pkg->marked = 1; } - for (i = 0; i < argc; i++) { + foreach_array_item(pname, names) { ndctx.indent.indent = 0; - ndctx.name = name[i]; + ndctx.name = *pname; ndctx.matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES; - foreach_array_item(p, name[i]->providers) { + foreach_array_item(p, (*pname)->providers) { if (!p->pkg->marked) continue; print_not_deleted_message(p->pkg, NULL, NULL, &ndctx); @@ -122,6 +124,7 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv) apk_solver_print_errors(db, &changeset, ctx->world); } apk_dependency_array_free(&ctx->world); + apk_name_array_free(&names); return r; } @@ -144,4 +147,3 @@ static struct apk_applet apk_del = { }; APK_DEFINE_APPLET(apk_del); - diff --git a/src/dot.c b/src/dot.c index 1939ca9..0909a73 100644 --- a/src/dot.c +++ b/src/dot.c @@ -120,15 +120,15 @@ static int foreach_pkg(apk_hash_item item, void *ctx) return 0; } -static int dot_main(void *pctx, struct apk_database *db, int argc, char **argv) +static int dot_main(void *pctx, struct apk_database *db, struct apk_string_array *args) { struct dot_ctx *ctx = (struct dot_ctx *) pctx; struct apk_provider *p; - int i; + char **parg; - if (argc) { - for (i = 0; i < argc; i++) { - struct apk_name *name = apk_db_get_name(db, APK_BLOB_STR(argv[i])); + if (args->num) { + foreach_array_item(parg, args) { + struct apk_name *name = apk_db_get_name(db, APK_BLOB_STR(*parg)); if (!name) continue; foreach_array_item(p, name->providers) diff --git a/src/fetch.c b/src/fetch.c index f2aa6e9..eaa6961 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -190,26 +190,27 @@ static void mark_package(struct fetch_ctx *ctx, struct apk_package *pkg) pkg->marked = 1; } -static int fetch_main(void *pctx, struct apk_database *db, int argc, char **argv) +static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_array *args) { struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; struct apk_dependency_array *world; struct apk_change *change; - int r = 0, i; + char **parg; + int r = 0; if (ctx->outdir_fd == 0) ctx->outdir_fd = AT_FDCWD; - if ((argc > 0) && (strcmp(argv[0], "coffee") == 0)) { + if ((args->num == 1) && (strcmp(args->item[0], "coffee") == 0)) { if (apk_flags & APK_FORCE) return cup(); apk_message("Go and fetch your own coffee."); return 0; } - for (i = 0; i < argc; i++) { + foreach_array_item(parg, args) { struct apk_dependency dep = (struct apk_dependency) { - .name = apk_db_get_name(db, APK_BLOB_STR(argv[i])), + .name = apk_db_get_name(db, APK_BLOB_STR(*parg)), .version = apk_blob_atomize(APK_BLOB_NULL), .result_mask = APK_DEPMASK_ANY, }; @@ -222,7 +223,7 @@ static int fetch_main(void *pctx, struct apk_database *db, int argc, char **argv r = apk_solver_solve(db, 0, world, &changeset); apk_dependency_array_free(&world); if (r != 0) { - apk_error("%s: unable to get dependencies", argv[i]); + apk_error("%s: unable to get dependencies", dep.name->name); ctx->errors++; } else { foreach_array_item(change, changeset.changes) diff --git a/src/fix.c b/src/fix.c index 7314ddc..c14f93f 100644 --- a/src/fix.c +++ b/src/fix.c @@ -52,12 +52,13 @@ static int mark_recalculate(apk_hash_item item, void *ctx) return 0; } -static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) +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; - int r = 0, i; + char **parg; + int r = 0; if (!ctx->solver_flags) ctx->solver_flags = APK_SOLVERF_REINSTALL; @@ -65,22 +66,22 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) if (ctx->fix_directory_permissions) apk_hash_foreach(&db->installed.dirs, mark_recalculate, db); - for (i = 0; i < argc; i++) { + foreach_array_item(parg, args) { pkg = NULL; - if (strstr(argv[i], ".apk") != NULL) { + if (strstr(*parg, ".apk") != NULL) { struct apk_sign_ctx sctx; apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE, NULL, db->keys_fd); - r = apk_pkg_read(db, argv[i], &sctx, &pkg); + r = apk_pkg_read(db, *parg, &sctx, &pkg); apk_sign_ctx_free(&sctx); if (r != 0) { - apk_error("%s: %s", argv[i], apk_error_str(r)); + apk_error("%s: %s", *parg, apk_error_str(r)); goto err; } name = pkg->name; } else { - name = apk_db_get_name(db, APK_BLOB_STR(argv[i])); + name = apk_db_get_name(db, APK_BLOB_STR(*parg)); pkg = apk_pkg_get_installed(name); } if (pkg == NULL || pkg->ipkg == NULL) { diff --git a/src/index.c b/src/index.c index 2e93209..ec6a859 100644 --- a/src/index.c +++ b/src/index.c @@ -87,14 +87,15 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx) return 0; } -static int index_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int index_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct counts counts = {0}; struct apk_ostream *os; struct apk_file_info fi; - int total, r, i, found, newpkgs = 0, errors = 0; + int total, r, found, newpkgs = 0, errors = 0; struct index_ctx *ictx = (struct index_ctx *) ctx; struct apk_package *pkg; + char **parg; if (isatty(STDOUT_FILENO) && ictx->output == NULL && !(apk_flags & APK_FORCE)) { @@ -111,9 +112,9 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv) return r; } - for (i = 0; i < argc; i++) { - if (apk_file_get_info(AT_FDCWD, argv[i], APK_CHECKSUM_NONE, &fi) < 0) { - apk_warning("File '%s' is unaccessible", argv[i]); + foreach_array_item(parg, args) { + if (apk_file_get_info(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi) < 0) { + apk_warning("File '%s' is unaccessible", *parg); continue; } @@ -129,9 +130,9 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv) break; /* Check that it looks like a package name */ - fname = strrchr(argv[i], '/'); + fname = strrchr(*parg, '/'); if (fname == NULL) - fname = argv[i]; + fname = *parg; else fname++; fend = strstr(fname, ".apk"); @@ -154,7 +155,7 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv) continue; if (pkg->size != fi.size) continue; - pkg->filename = strdup(argv[i]); + pkg->filename = strdup(*parg); if (ictx->rewrite_arch != NULL) pkg->arch = ictx->rewrite_arch; found = TRUE; @@ -165,9 +166,9 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv) if (!found) { struct apk_sign_ctx sctx; apk_sign_ctx_init(&sctx, ictx->method, NULL, db->keys_fd); - r = apk_pkg_read(db, argv[i], &sctx, &pkg); + r = apk_pkg_read(db, *parg, &sctx, &pkg); if (r < 0) { - apk_error("%s: %s", argv[i], apk_error_str(r)); + apk_error("%s: %s", *parg, apk_error_str(r)); errors++; } else { newpkgs++; diff --git a/src/info.c b/src/info.c index e44233e..0456999 100644 --- a/src/info.c +++ b/src/info.c @@ -19,8 +19,7 @@ struct info_ctx { struct apk_database *db; - int (*action)(struct info_ctx *ctx, struct apk_database *db, - int argc, char **argv); + int (*action)(struct info_ctx *ctx, struct apk_database *db, struct apk_string_array *args); int subaction_mask; }; @@ -55,27 +54,17 @@ static void verbose_print_pkg(struct apk_package *pkg, int minimal_verbosity) printf("\n"); } - -static int info_list(struct info_ctx *ctx, struct apk_database *db, - int argc, char **argv) -{ - struct apk_installed_package *ipkg; - - list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) - verbose_print_pkg(ipkg->pkg, 1); - return 0; -} - static int info_exists(struct info_ctx *ctx, struct apk_database *db, - int argc, char **argv) + struct apk_string_array *args) { struct apk_name *name; struct apk_dependency dep; struct apk_provider *p; - int i, ok, rc = 0; + char **parg; + int ok, errors = 0; - for (i = 0; i < argc; i++) { - apk_blob_t b = APK_BLOB_STR(argv[i]); + foreach_array_item(parg, args) { + apk_blob_t b = APK_BLOB_STR(*parg); apk_blob_pull_dep(&b, db, &dep); if (APK_BLOB_IS_NULL(b) || b.len > 0) @@ -93,26 +82,28 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db, ok = 1; } if (!ok) - rc++; + errors++; } - return rc; + return errors; } static int info_who_owns(struct info_ctx *ctx, struct apk_database *db, - int argc, char **argv) + struct apk_string_array *args) { struct apk_package *pkg; struct apk_dependency_array *deps; struct apk_dependency dep; - int i, r=0; + struct apk_ostream *os; + char **parg; + int errors = 0; apk_dependency_array_init(&deps); - for (i = 0; i < argc; i++) { - pkg = apk_db_get_file_owner(db, APK_BLOB_STR(argv[i])); + foreach_array_item(parg, args) { + pkg = apk_db_get_file_owner(db, APK_BLOB_STR(*parg)); if (pkg == NULL) { - apk_error("%s: Could not find owner package", argv[i]); - r++; + apk_error("%s: Could not find owner package", *parg); + errors++; continue; } @@ -125,12 +116,10 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db, apk_deps_add(&deps, &dep); } else { printf("%s is owned by " PKG_VER_FMT "\n", - argv[i], PKG_VER_PRINTF(pkg)); + *parg, PKG_VER_PRINTF(pkg)); } } if (apk_verbosity < 1 && deps->num != 0) { - struct apk_ostream *os; - os = apk_ostream_to_fd(STDOUT_FILENO); apk_deps_write(db, deps, os, APK_BLOB_PTR_LEN(" ", 1)); os->write(os, "\n", 1); @@ -138,7 +127,7 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db, } apk_dependency_array_free(&deps); - return r; + return errors; } static void info_print_description(struct apk_database *db, struct apk_package *pkg) @@ -332,16 +321,16 @@ static void info_subaction(struct info_ctx *ctx, struct apk_package *pkg) } static int info_package(struct info_ctx *ctx, struct apk_database *db, - int argc, char **argv) + struct apk_string_array *args) { struct apk_name *name; struct apk_provider *p; - int i; + char **parg; - for (i = 0; i < argc; i++) { - name = apk_db_query_name(db, APK_BLOB_STR(argv[i])); + 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", argv[i]); + apk_error("Not found: %s", *parg); return 1; } foreach_array_item(p, name->providers) @@ -407,25 +396,26 @@ static int info_parse(void *ctx, struct apk_db_options *dbopts, return 0; } -static int info_package_short(struct info_ctx *ictx, struct apk_database *db, - int argc, char **argv) -{ - ictx->subaction_mask |= APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE; - return info_package(ictx, db, argc, argv); -} - -static int info_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int info_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct info_ctx *ictx = (struct info_ctx *) ctx; + struct apk_installed_package *ipkg; ictx->db = db; if (ictx->action != NULL) - return ictx->action(ictx, db, argc, argv); + return ictx->action(ictx, db, args); - if (argc > 0) - return info_package_short(ictx, db, argc, argv); + 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); + } else { + /* Print all installed packages */ + list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) + verbose_print_pkg(ipkg->pkg, 1); + } - return info_list(ictx, db, argc, argv); + return 0; } static struct apk_option info_options[] = { diff --git a/src/package.c b/src/package.c index 702a643..fcfdd00 100644 --- a/src/package.c +++ b/src/package.c @@ -1174,10 +1174,11 @@ void apk_pkg_foreach_matching_dependency( unsigned int genid = match & APK_FOREACH_GENID_MASK; struct apk_dependency *d; - if (genid && pkg->foreach_genid >= genid) - return; - if (pkg) + if (pkg && genid) { + if (pkg->foreach_genid >= genid) + return; pkg->foreach_genid = genid; + } foreach_array_item(d, deps) { if (apk_dep_analyze(d, mpkg) & match) { @@ -1211,9 +1212,11 @@ static void foreach_reverse_dependency( continue; if (marked && !pkg0->marked) continue; - if (genid && pkg0->foreach_genid >= genid) - continue; - pkg0->foreach_genid = genid; + if (genid) { + if (pkg0->foreach_genid >= genid) + continue; + pkg0->foreach_genid = genid; + } foreach_array_item(d0, pkg0->depends) { if (apk_dep_analyze(d0, pkg) & match) cb(pkg0, d0, pkg, ctx); diff --git a/src/search.c b/src/search.c index 410becd..b168465 100644 --- a/src/search.c +++ b/src/search.c @@ -25,8 +25,7 @@ struct search_ctx { int search_description : 1; unsigned int matches; - int argc; - char **argv; + struct apk_string_array *filter; }; static void print_package_name(struct search_ctx *ctx, struct apk_package *pkg) @@ -96,95 +95,70 @@ static int search_parse(void *ctx, struct apk_db_options *dbopts, static void print_result_pkg(struct search_ctx *ctx, struct apk_package *pkg) { - int i; - - if (pkg == NULL) - return; + char **pmatch; if (ctx->search_description) { - for (i = 0; i < ctx->argc; i++) { - if (strstr(pkg->description, ctx->argv[i]) != NULL || - strstr(pkg->name->name, ctx->argv[i]) != NULL) - break; + foreach_array_item(pmatch, ctx->filter) { + if (strstr(*pmatch, pkg->description) != NULL || + strstr(*pmatch, pkg->name->name) != NULL) + goto match; } - if (i >= ctx->argc) - return; + return; } - +match: ctx->print_result(ctx, pkg); } -static void print_result(struct search_ctx *ctx, struct apk_name *name) +static void print_result(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { + struct search_ctx *ctx = pctx; struct apk_provider *p; struct apk_package *pkg = NULL; - apk_blob_t *version = NULL; if (ctx->show_all) { foreach_array_item(p, name->providers) print_result_pkg(ctx, p->pkg); } else { foreach_array_item(p, name->providers) { - if (version == NULL || - apk_version_compare_blob(*p->version, *version) == APK_VERSION_GREATER) + if (pkg == NULL || + apk_version_compare_blob(*p->version, *pkg->version) == APK_VERSION_GREATER) pkg = p->pkg; } - print_result_pkg(ctx, pkg); + if (pkg) + print_result_pkg(ctx, pkg); } } -static int match_names(apk_hash_item item, void *pctx) +static int print_pkg(apk_hash_item item, void *pctx) { - struct search_ctx *ctx = (struct search_ctx *) pctx; - struct apk_name *name = (struct apk_name *) item; - int i; - - if (!ctx->search_description) { - for (i = 0; i < ctx->argc; i++) - if (fnmatch(ctx->argv[i], name->name, FNM_CASEFOLD) == 0) - break; - if (ctx->argc > 0 && i >= ctx->argc) - return 0; - } - print_result(ctx, name); - + print_result_pkg((struct search_ctx *) pctx, (struct apk_package *) item); return 0; } -static int search_main(void *pctx, struct apk_database *db, int argc, char **argv) +static int search_main(void *pctx, struct apk_database *db, struct apk_string_array *args) { struct search_ctx *ctx = (struct search_ctx *) pctx; - char s[256]; - int i, l; + char *tmp, **pmatch; + ctx->filter = args; ctx->matches = apk_foreach_genid() | APK_DEP_SATISFIES; if (ctx->print_package == NULL) ctx->print_package = print_package_name; if (ctx->print_result == NULL) ctx->print_result = ctx->print_package; - if (argc == 0 && ctx->search_description) - return -1; + if (ctx->search_description) + return apk_hash_foreach(&db->available.packages, print_pkg, ctx); - ctx->argc = argc; if (!ctx->search_exact) { - ctx->argv = alloca(argc * sizeof(char*)); - for (i = 0; i < argc; i++) { - l = snprintf(s, sizeof(s), "*%s*", argv[i]); - ctx->argv[i] = alloca(l+1); - memcpy(ctx->argv[i], s, l); - ctx->argv[i][l] = 0; - } - } else { - ctx->argv = argv; - if (!ctx->search_description) { - for (i = 0; i < argc; i++) - print_result(ctx, apk_db_get_name(db, APK_BLOB_STR(argv[i]))); - return 0; + foreach_array_item(pmatch, ctx->filter) { + tmp = alloca(strlen(*pmatch) + 3); + sprintf(tmp, "*%s*", *pmatch); + *pmatch = tmp; } } - - return apk_hash_foreach(&db->available.names, match_names, ctx); + apk_name_foreach_matching(db, args, apk_foreach_genid(), print_result, ctx); + return 0; } static struct apk_option search_options[] = { diff --git a/src/update.c b/src/update.c index f0bfff5..c9dd710 100644 --- a/src/update.c +++ b/src/update.c @@ -16,7 +16,7 @@ #include "apk_version.h" #include "apk_print.h" -static int update_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int update_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct apk_repository *repo; int i; diff --git a/src/upgrade.c b/src/upgrade.c index 335afa6..41d3cf7 100644 --- a/src/upgrade.c +++ b/src/upgrade.c @@ -85,7 +85,7 @@ ret: return r; } -static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct upgrade_ctx *uctx = (struct upgrade_ctx *) ctx; unsigned short solver_flags; diff --git a/src/ver.c b/src/ver.c index 3f1efea..d41c601 100644 --- a/src/ver.c +++ b/src/ver.c @@ -17,12 +17,12 @@ #include "apk_print.h" struct ver_ctx { - int (*action)(struct apk_database *db, int argc, char **argv); + int (*action)(struct apk_database *db, struct apk_string_array *args); const char *limchars; int all_tags : 1; }; -static int ver_indexes(struct apk_database *db, int argc, char **argv) +static int ver_indexes(struct apk_database *db, struct apk_string_array *args) { struct apk_repository *repo; int i; @@ -41,29 +41,31 @@ static int ver_indexes(struct apk_database *db, int argc, char **argv) return 0; } -static int ver_test(struct apk_database *db, int argc, char **argv) +static int ver_test(struct apk_database *db, struct apk_string_array *args) { int r; - if (argc != 2) + if (args->num != 2) return 1; - r = apk_version_compare(argv[0], argv[1]); + r = apk_version_compare(args->item[0], args->item[1]); printf("%s\n", apk_version_op_string(r)); return 0; } -static int ver_validate(struct apk_database *db, int argc, char **argv) +static int ver_validate(struct apk_database *db, struct apk_string_array *args) { - int i, r = 0; - for (i = 0; i < argc; i++) { - if (!apk_version_validate(APK_BLOB_STR(argv[i]))) { + char **parg; + int errors = 0; + + foreach_array_item(parg, args) { + if (!apk_version_validate(APK_BLOB_STR(*parg))) { if (apk_verbosity > 0) - printf("%s\n", argv[i]); - r++; + printf("%s\n", *parg); + errors++; } } - return r; + return errors; } static int ver_parse(void *ctx, struct apk_db_options *dbopts, @@ -150,28 +152,29 @@ 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, int argc, char **argv) +static int ver_main(void *ctx, 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; - int i, ret = 0; + char **parg; + int ret = 0; if (ictx->limchars) { if (strlen(ictx->limchars) == 0) ictx->limchars = NULL; - } else if (argc == 0 && apk_verbosity == 1) { + } else if (args->num == 0 && apk_verbosity == 1) { ictx->limchars = "<"; } if (ictx->action != NULL) - return ictx->action(db, argc, argv); + return ictx->action(db, args); if (apk_verbosity > 0) printf("%-42sAvailable:\n", "Installed:"); - if (argc == 0) { + if (args->num == 0) { list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) { ver_print_package_status(ictx, db, ipkg->pkg); @@ -179,10 +182,10 @@ static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv) goto ver_exit; } - for (i = 0; i < argc; i++) { - name = apk_db_query_name(db, APK_BLOB_STR(argv[i])); + foreach_array_item(parg, args) { + name = apk_db_query_name(db, APK_BLOB_STR(*parg)); if (name == NULL) { - apk_error("Not found: %s", name); + apk_error("Not found: %s", *parg); ret = 1; goto ver_exit; } diff --git a/src/verify.c b/src/verify.c index cfb800a..ee3ecd6 100644 --- a/src/verify.c +++ b/src/verify.c @@ -17,21 +17,22 @@ #include "apk_database.h" #include "apk_print.h" -static int verify_main(void *ctx, struct apk_database *db, int argc, char **argv) +static int verify_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { struct apk_sign_ctx sctx; struct apk_istream *is; - int i, r, ok, rc = 0; + char **parg; + int r, ok, rc = 0; - for (i = 0; i < argc; i++) { + foreach_array_item(parg, args) { apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); - is = apk_bstream_gunzip_mpart(apk_bstream_from_file(AT_FDCWD, argv[i]), + is = apk_bstream_gunzip_mpart(apk_bstream_from_file(AT_FDCWD, *parg), apk_sign_ctx_mpart_cb, &sctx); if (is == NULL) { if (apk_verbosity >= 1) - apk_error("%s: %s", argv[i], strerror(errno)); + apk_error("%s: %s", *parg, strerror(errno)); else - printf("%s\n", argv[i]); + printf("%s\n", *parg); apk_sign_ctx_free(&sctx); rc++; continue; @@ -40,11 +41,11 @@ static int verify_main(void *ctx, struct apk_database *db, int argc, char **argv is->close(is); ok = sctx.control_verified && sctx.data_verified; if (apk_verbosity >= 1) - apk_message("%s: %d - %s", argv[i], r, + apk_message("%s: %d - %s", *parg, r, ok ? "OK" : !sctx.control_verified ? "UNTRUSTED" : "FAILED"); else if (!ok) - printf("%s\n", argv[i]); + printf("%s\n", *parg); if (!ok) rc++; apk_sign_ctx_free(&sctx);