]> pd.if.org Git - zpackage/blobdiff - src/search.c
support for package dependencies
[zpackage] / src / search.c
index fd8d793fce6c1711b273deaa7065989dd3c69162..1943f3b26265012e5ad3d8685dd73be0d02db746 100644 (file)
@@ -62,7 +62,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 +70,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 +150,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 +200,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;
@@ -232,7 +302,7 @@ struct pkgloc *find_package(char *pkgstr, struct search_ctl *opt) {
                                ) {
                        continue;
                }
-               found = checkfile(pkgstr, opt->repos.gl_pathv[i]);
+               found = checkfile(pkgstr, opt->repos.gl_pathv[i], 0);
                if (found) {
                        rv = zpm_vercmp(found, latest);
                        if (rv == 1) {
@@ -272,6 +342,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 +355,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 +400,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 +452,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);