libopkg: remove support for "dist" config
[project/opkg-lede.git] / libopkg / pkg_hash.c
index edc51886d691af8c8815688069724441de2dc4cf..879c0ec0e693a62ce507c303f6c1fa2249895a23 100644 (file)
@@ -20,6 +20,7 @@
 #include "hash_table.h"
 #include "pkg.h"
 #include "opkg_message.h"
+#include "pkg_depends.h"
 #include "pkg_vec.h"
 #include "pkg_hash.h"
 #include "parse_util.h"
@@ -68,34 +69,10 @@ void pkg_hash_deinit(void)
        hash_table_deinit(&conf->pkg_hash);
 }
 
-int dist_hash_add_from_file(const char *lists_dir, pkg_src_t * dist)
-{
-       nv_pair_list_elt_t *l;
-       char *list_file, *subname;
-
-       list_for_each_entry(l, &conf->arch_list.head, node) {
-               nv_pair_t *nv = (nv_pair_t *) l->data;
-               sprintf_alloc(&subname, "%s-%s", dist->name, nv->name);
-               sprintf_alloc(&list_file, "%s/%s", lists_dir, subname);
-
-               if (file_exists(list_file)) {
-                       if (pkg_hash_add_from_file(list_file, dist, NULL, 0)) {
-                               free(list_file);
-                               return -1;
-                       }
-                       pkg_src_list_append(&conf->pkg_src_list, subname,
-                                           dist->value, "__dummy__", 0);
-               }
-
-               free(list_file);
-       }
-
-       return 0;
-}
-
 int
 pkg_hash_add_from_file(const char *file_name,
-                      pkg_src_t * src, pkg_dest_t * dest, int is_status_file)
+                      pkg_src_t * src, pkg_dest_t * dest, int is_status_file, int state_flags,
+                      void (*cb)(pkg_t *, void *), void *priv)
 {
        pkg_t *pkg;
        FILE *fp;
@@ -121,6 +98,7 @@ pkg_hash_add_from_file(const char *file_name,
                pkg = pkg_new();
                pkg->src = src;
                pkg->dest = dest;
+               pkg->state_flag |= state_flags;
 
                ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, 0,
                                                 &buf, len);
@@ -141,7 +119,14 @@ pkg_hash_add_from_file(const char *file_name,
                        continue;
                }
 
-               if (!pkg->architecture || !pkg->arch_priority) {
+               if (!(pkg->state_flag & SF_NEED_DETAIL)) {
+                       //opkg_msg(DEBUG, "Package %s is unrelated, ignoring.\n", pkg->name);
+                       pkg_deinit(pkg);
+                       free(pkg);
+                       continue;
+               }
+
+               if (!pkg_get_architecture(pkg) || !pkg_get_arch_priority(pkg)) {
                        char *version_str = pkg_version_str_alloc(pkg);
                        opkg_msg(NOTICE, "Package %s version %s has no "
                                 "valid architecture, ignoring.\n",
@@ -150,7 +135,10 @@ pkg_hash_add_from_file(const char *file_name,
                        continue;
                }
 
-               hash_insert_pkg(pkg, is_status_file);
+               if (cb)
+                       cb(pkg, priv);
+               else
+                       hash_insert_pkg(pkg, is_status_file);
 
        } while (!feof(fp));
 
@@ -166,10 +154,10 @@ pkg_hash_add_from_file(const char *file_name,
 /*
  * Load in feed files from the cached "src" and/or "src/gz" locations.
  */
-int pkg_hash_load_feeds(void)
+int pkg_hash_load_feeds(int state_flags, void (*cb)(pkg_t *, void *), void *priv)
 {
        pkg_src_list_elt_t *iter;
-       pkg_src_t *src, *subdist;
+       pkg_src_t *src;
        char *list_file, *lists_dir;
 
        opkg_msg(INFO, "\n");
@@ -185,7 +173,7 @@ int pkg_hash_load_feeds(void)
                sprintf_alloc(&list_file, "%s/%s", lists_dir, src->name);
 
                if (file_exists(list_file)) {
-                       if (pkg_hash_add_from_file(list_file, src, NULL, 0)) {
+                       if (pkg_hash_add_from_file(list_file, src, NULL, 0, state_flags, cb, priv)) {
                                free(list_file);
                                return -1;
                        }
@@ -199,7 +187,7 @@ int pkg_hash_load_feeds(void)
 /*
  * Load in status files from the configured "dest"s.
  */
-int pkg_hash_load_status_files(void)
+int pkg_hash_load_status_files(void (*cb)(pkg_t *, void *), void *priv)
 {
        pkg_dest_list_elt_t *iter;
        pkg_dest_t *dest;
@@ -213,7 +201,7 @@ int pkg_hash_load_status_files(void)
 
                if (file_exists(dest->status_file_name)) {
                        if (pkg_hash_add_from_file
-                           (dest->status_file_name, NULL, dest, 1))
+                           (dest->status_file_name, NULL, dest, 1, SF_NEED_DETAIL, cb, priv))
                                return -1;
                }
        }
@@ -221,9 +209,67 @@ int pkg_hash_load_status_files(void)
        return 0;
 }
 
-static abstract_pkg_t *abstract_pkg_fetch_by_name(const char *pkg_name)
+static void
+pkg_hash_load_package_details_helper(const char *pkg_name, void *entry, void *data)
+{
+       int *count = data;
+       abstract_pkg_t *ab_pkg = (abstract_pkg_t *) entry;
+
+       if (ab_pkg->state_flag & SF_NEED_DETAIL) {
+               if (ab_pkg->state_flag & SF_MARKED) {
+                       opkg_msg(DEBUG, "skipping already seen flagged abpkg %s\n",
+                                ab_pkg->name);
+                       return;
+               }
+
+               opkg_msg(DEBUG, "found yet incomplete flagged abpkg %s\n",
+                        ab_pkg->name);
+
+               (*count)++;
+               ab_pkg->state_flag |= SF_MARKED;
+       }
+}
+
+int pkg_hash_load_package_details(void)
+{
+       int n_need_detail;
+
+       while (1) {
+               pkg_hash_load_feeds(0, NULL, NULL);
+
+               n_need_detail = 0;
+               hash_table_foreach(&conf->pkg_hash, pkg_hash_load_package_details_helper, &n_need_detail);
+
+               if (n_need_detail > 0)
+                       opkg_msg(DEBUG, "Found %d packages requiring details, reloading feeds\n", n_need_detail);
+               else
+                       break;
+       }
+
+       return 0;
+}
+
+static int
+pkg_hash_check_unresolved(pkg_t *maybe)
 {
-       return (abstract_pkg_t *) hash_table_get(&conf->pkg_hash, pkg_name);
+       char **unresolved = NULL;
+       char **tmp;
+       pkg_vec_t *depends;
+       int res = 0;
+
+       depends = pkg_vec_alloc();
+       pkg_hash_fetch_unsatisfied_dependencies(maybe, depends, &unresolved, 1);
+
+       if (unresolved) {
+               res = 1;
+               tmp = unresolved;
+               while (tmp)
+                       free(*(tmp++));
+               free(unresolved);
+       }
+       pkg_vec_free(depends);
+
+       return res;
 }
 
 pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
@@ -237,6 +283,7 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
        int nprovides = 0;
        int nmatching = 0;
        int wrong_arch_found = 0;
+       int arch_priority;
        pkg_vec_t *matching_pkgs;
        abstract_pkg_vec_t *matching_apkgs;
        abstract_pkg_vec_t *provided_apkg_vec;
@@ -317,19 +364,23 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                        /* count packages matching max arch priority and keep track of last one */
                        for (j = 0; j < vec->len; j++) {
                                pkg_t *maybe = vec->pkgs[j];
+                               arch_priority = pkg_get_arch_priority(maybe);
+
                                opkg_msg(DEBUG,
                                         "%s arch=%s arch_priority=%d version=%s.\n",
-                                        maybe->name, maybe->architecture,
-                                        maybe->arch_priority, maybe->version);
+                                        maybe->name, pkg_get_architecture(maybe),
+                                        arch_priority, pkg_get_string(maybe, PKG_VERSION));
                                /* We make sure not to add the same package twice. Need to search for the reason why
                                   they show up twice sometimes. */
-                               if ((maybe->arch_priority > 0)
+                               if ((arch_priority > 0)
                                    &&
                                    (!pkg_vec_contains(matching_pkgs, maybe))) {
-                                       max_count++;
-                                       abstract_pkg_vec_insert(matching_apkgs,
-                                                               maybe->parent);
-                                       pkg_vec_insert(matching_pkgs, maybe);
+                                       if (!pkg_hash_check_unresolved(maybe)) {
+                                               max_count++;
+                                               abstract_pkg_vec_insert(matching_apkgs,
+                                                                       maybe->parent);
+                                               pkg_vec_insert(matching_pkgs, maybe);
+                                       }
                                }
                        }
 
@@ -353,13 +404,13 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                pkg_vec_sort(matching_pkgs,
                             pkg_name_version_and_architecture_compare);
        if (matching_apkgs->len > 1)
-               abstract_pkg_vec_sort(matching_pkgs, abstract_pkg_name_compare);
+               abstract_pkg_vec_sort(matching_apkgs, abstract_pkg_name_compare);
 
        for (i = 0; i < matching_pkgs->len; i++) {
                pkg_t *matching = matching_pkgs->pkgs[i];
                if (constraint_fcn(matching, cdata)) {
                        opkg_msg(DEBUG, "Candidate: %s %s.\n",
-                                matching->name, matching->version);
+                                matching->name, pkg_get_string(matching, PKG_VERSION));
                        good_pkg_by_name = matching;
                        /* It has been provided by hand, so it is what user want */
                        if (matching->provided_by_hand == 1)
@@ -389,9 +440,10 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                int prio = 0;
                for (i = 0; i < matching_pkgs->len; i++) {
                        pkg_t *matching = matching_pkgs->pkgs[i];
-                       if (matching->arch_priority > prio) {
+                       arch_priority = pkg_get_arch_priority(matching);
+                       if (arch_priority > prio) {
                                priorized_matching = matching;
-                               prio = matching->arch_priority;
+                               prio = arch_priority;
                                opkg_msg(DEBUG, "Match %s with priority %i.\n",
                                         matching->name, prio);
                        }
@@ -405,8 +457,8 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                for (i = 0; i < matching_pkgs->len; i++) {
                        pkg_t *matching = matching_pkgs->pkgs[i];
                        opkg_msg(INFO, "%s %s %s\n",
-                                matching->name, matching->version,
-                                matching->architecture);
+                                matching->name, pkg_get_string(matching, PKG_VERSION),
+                                pkg_get_architecture(matching));
                }
        }
 
@@ -431,8 +483,8 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
        }
        if (priorized_matching) {
                opkg_msg(INFO, "Using priorized matching %s %s %s.\n",
-                        priorized_matching->name, priorized_matching->version,
-                        priorized_matching->architecture);
+                        priorized_matching->name, pkg_get_string(priorized_matching, PKG_VERSION),
+                        pkg_get_architecture(priorized_matching));
                return priorized_matching;
        }
        if (nmatching > 1) {
@@ -442,8 +494,8 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
        }
        if (latest_matching) {
                opkg_msg(INFO, "Using latest matching %s %s %s.\n",
-                        latest_matching->name, latest_matching->version,
-                        latest_matching->architecture);
+                        latest_matching->name, pkg_get_string(latest_matching, PKG_VERSION),
+                        pkg_get_architecture(latest_matching));
                return latest_matching;
        }
        return NULL;
@@ -648,6 +700,8 @@ void hash_insert_pkg(pkg_t * pkg, int set_status)
 
        buildProvides(ab_pkg, pkg);
 
+       init_providelist(pkg, NULL);
+
        /* Need to build the conflicts graph before replaces for correct
         * calculation of replaced_by relation.
         */