#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <stdarg.h>
+#include <stdio.h>
#include <glob.h>
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;
return cat;
}
-char *checkfile(char *pkgstr, char *path) {
+char *checkfile(char *pkgstr, char *path, int orgreater) {
struct zpm pkgfile;
char *pkgid = 0;
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;
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;
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;
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;
#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);
}
}
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;
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);
}
/* 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);
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);
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);
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