X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=src%2Fsearch.c;h=a546d6ce808868422091ce528f9e9887ec2a9677;hb=be765ec4d3dc14dd27826326e29da8a62d5603f7;hp=dd324d55a7d1664d0006b283a6f5a6aab292bbd7;hpb=b9eb4486d50a2af606c6b776fcb5dfe065ccee9e;p=zpackage diff --git a/src/search.c b/src/search.c index dd324d5..a546d6c 100644 --- a/src/search.c +++ b/src/search.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include @@ -33,6 +35,16 @@ struct search_ctl { int dbrepos; }; +void trace(int level, struct search_ctl *ctl, char *fmt, ...) { + va_list ap; + + if (level <= ctl->verbose) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + } +} + char *pathcat(char *dir, char *path) { size_t dirlen = 0, pathlen = 0; char *cat; @@ -62,7 +74,7 @@ char *pathcat(char *dir, char *path) { return cat; } -char *checkfile(char *pkgstr, char *path) { +char *checkfile(char *pkgstr, char *path, int orgreater) { struct zpm pkgfile; char *pkgid = 0; @@ -70,7 +82,11 @@ char *checkfile(char *pkgstr, char *path) { return NULL; } - pkgid = zpm_findpkg(&pkgfile, pkgstr, NULL); + if (orgreater) { + pkgid = zpm_findpkg_range(&pkgfile, pkgstr, 0, 0, 0); + } else { + pkgid = zpm_findpkg(&pkgfile, pkgstr, NULL); + } zpm_close(&pkgfile); return pkgid; @@ -146,6 +162,9 @@ int find_globs(struct search_ctl *opt) { return 1; } +/* + * find a package and packagefile that supplies a library + */ int find_lib(char *soname, struct search_ctl *opt, struct pkgloc *pkg) { char *latest = 0; char *installed = 0, *found = 0; @@ -193,6 +212,69 @@ int find_lib(char *soname, struct search_ctl *opt, struct pkgloc *pkg) { return 0; } +struct pkgloc *find_atleast_package(char *pkgstr, struct search_ctl *opt, int stopifinstalled) { + char *latest = 0; + char *installed = 0, *found = 0; + char *pkgfile = 0; + struct pkgloc *pkg = 0; + int rv; + unsigned int i; + + if (opt->localdb) { + installed = zpm_findpkg_range(opt->zpmdb, pkgstr, 0, "status = 'installed'", 0); + if (installed) { + latest = installed; + pkgfile = opt->zpmdb->path; + if (stopifinstalled) { + pkg = malloc(sizeof *pkg); + pkg->id = strdup(latest); + pkg->file = pkgfile; + pkg->installed = 1; + return pkg; + } + } + if (!opt->onlylocalinstalled) { + found = zpm_findpkg_range(opt->zpmdb, pkgstr, 0, NULL, 0); + if (found) { + rv = zpm_vercmp(found, latest); + if (rv == 1) { + latest = found; + pkgfile = opt->zpmdb->path; + } + } + } + } + + for (i = 0; i < opt->repos.gl_pathc; i++) { + if (!opt->matchallpkgfile + && !strstr(opt->repos.gl_pathv[i], pkgstr) + && !strstr(opt->repos.gl_pathv[i], ".repo") + ) { + continue; + } + found = checkfile(pkgstr, opt->repos.gl_pathv[i], 1); + if (found) { + rv = zpm_vercmp(found, latest); + if (rv == 1) { + latest = found; + pkgfile = strdup(opt->repos.gl_pathv[i]); + } + } + } + + if (latest && pkgfile) { + pkg = malloc(sizeof *pkg); + pkg->id = strdup(latest); + pkg->file = pkgfile; + pkg->installed = 0; + if (installed) { + pkg->installed = !strcmp(latest, installed); + } + } + + return pkg; +} + struct pkgloc *find_package(char *pkgstr, struct search_ctl *opt) { char *latest = 0; char *installed = 0, *found = 0; @@ -202,14 +284,19 @@ struct pkgloc *find_package(char *pkgstr, struct search_ctl *opt) { unsigned int i; if (opt->localdb) { + trace(1, opt, "checking local database for installed %s\n", pkgstr); installed = zpm_findpkg(opt->zpmdb, pkgstr, "status = 'installed'"); if (installed) { + trace(1, opt, "found installed %s as %s\n", pkgstr, installed); latest = installed; pkgfile = opt->zpmdb->path; } + if (!opt->onlylocalinstalled) { + trace(1, opt, "checking local database for any %s\n", pkgstr); found = zpm_findpkg(opt->zpmdb, pkgstr, NULL); if (found) { + trace(1, opt, "found %s as %s\n", pkgstr, installed); rv = zpm_vercmp(found, latest); if (rv == 1) { latest = found; @@ -225,20 +312,26 @@ struct pkgloc *find_package(char *pkgstr, struct search_ctl *opt) { #endif } + trace(1, opt, "checking repositories\n"); for (i = 0; i < opt->repos.gl_pathc; i++) { + trace(1, opt, "checking repo/pkg %s\n", opt->repos.gl_pathv[i]); if (!opt->matchallpkgfile && !strstr(opt->repos.gl_pathv[i], pkgstr) && !strstr(opt->repos.gl_pathv[i], ".repo") ) { + trace(1, opt, "skipping repo/pkg %s\n", opt->repos.gl_pathv[i]); continue; } - found = checkfile(pkgstr, opt->repos.gl_pathv[i]); + found = checkfile(pkgstr, opt->repos.gl_pathv[i], 0); + trace(1, opt, "found %s\n", found); if (found) { + trace(1, opt, "comparing found %s to latest (%s)\n", found, latest); rv = zpm_vercmp(found, latest); if (rv == 1) { latest = found; pkgfile = strdup(opt->repos.gl_pathv[i]); } + trace(1, opt, "latest %s\n", latest); } } @@ -250,6 +343,7 @@ struct pkgloc *find_package(char *pkgstr, struct search_ctl *opt) { if (installed) { pkg->installed = !strcmp(latest, installed); } + trace(1, opt, "set up pkgloc = {%s, %s, %d}\n", pkg->id, pkg->file, pkg->installed); } return pkg; @@ -272,6 +366,8 @@ with pkglibs as (\ where PL.pkgid = %Q\ "; +char *pkgdeps = "select requires from packagedeps_pkgid where pkgid = %Q"; + static int afind_strcmp(const void *a, const void *b) { return strcmp(a, b); } @@ -283,13 +379,13 @@ void checklibs(struct search_ctl *opts, /* checked_libs is a list of checked sonames * checked is a list of checked packages - * needed is list of libs for package + * needed is list of libs for package, or list of package deps */ jsw_atree_t *needed = 0, *checked, *checked_libs; - int libs; + int libs, count; jsw_atrav_t *i; - char *soname; + char *soname, *package; checked = jsw_anew(afind_strcmp, (dup_f)strdup, (rel_f)free); checked_libs = jsw_anew(afind_strcmp, (dup_f)strdup, (rel_f)free); @@ -328,14 +424,45 @@ void checklibs(struct search_ctl *opts, exit(EXIT_FAILURE); } - /* get the libraries needed by this package */ + /* get the libraries and packages needed by this package */ if (!zpm_open(&src, pkgfile)) { fprintf(stderr, "can't zpm open %s\n", pkgfile); break; } - if (needed) jsw_adelete(needed); - needed = jsw_anew(afind_strcmp, (dup_f)strdup, (rel_f)free); + jsw_adelete(needed); + needed = jsw_anew_str(); + count = zpm_packages_needed(&src, pkgid, needed); + if (count) { + struct pkgloc *pkg = 0; + i = jsw_atnew(); + + if (pkg) { + free(pkg->file); + free(pkg->id); + free(pkg); + } + + for (package = jsw_atfirst(i, needed); package; package = jsw_atnext(i)) { + pkg = find_atleast_package(package, opts, 1); + if (!pkg || pkg->installed) { + continue; + } + /* look for a package at least that version */ + /* if package is installed, or already + * handled, skip. Otherwise, add it + * to the list of installed + */ + } + if (pkg) { + free(pkg->file); + free(pkg->id); + free(pkg); + } + } + + jsw_adelete(needed); + needed = jsw_anew_str(); libs = zpm_libraries_needed(&src, pkgid, needed); zpm_close(&src); @@ -349,7 +476,8 @@ void checklibs(struct search_ctl *opts, int found; struct pkgloc pkginfo; - /* if it's in checked_libs, we've already looked at this one */ + /* if it's in checked_libs, we've already looked at + * this one */ if (jsw_afind(checked_libs, soname)) { if (opts->verbose > 1) { fprintf(stderr, "already checked %s\n", soname); @@ -459,7 +587,6 @@ int main(int ac, char *av[]) { opt.repodir = getenv("ZPM_REPO_DIR"); if (!opt.repodir) opt.repodir = "/var/lib/zpm/repo"; - /* -l also find packages needed for libs * -j output json * -q quiet - suppress output